Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 106 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# CLAUDE.md — DevOops

## Project Overview

DevOops is a Ruby gem that serves as a shell snippets/scripts manager. It helps developers organize, create, edit, run, and remove custom shell scripts via a CLI. Scripts are stored as JSON configuration files (defining arguments) paired with `.sh` body files.

- **Author:** Denis "Zaratan" Pasin
- **License:** MIT
- **Ruby version:** >= 2.6.0 (configured for 3.0 in `.ruby-version`)
- **CLI framework:** Thor
- **Autoloader:** Zeitwerk

## Repository Structure

```
lib/dev_oops/
├── dev_oops.rb # Module init, Zeitwerk setup, eager_load
├── version.rb # VERSION constant (bump for releases)
├── runner.rb # Thor CLI entry point, dynamic command registration
├── scripts_loader.rb # Script discovery, config parsing, Thor::Group builders
└── commands/
├── edit_script.rb # Edit script JSON config
├── edit_script_sh.rb # Edit script .sh body
├── local_install.rb # Create local ./dev_oops directory
└── remove_script.rb # Remove a script
exe/
└── dev_oops # Executable entry point
spec/
└── dev_oops_spec.rb # RSpec tests
templates/
└── empty_script.tt # JSON template for new scripts
bin/
├── setup # Install bundle dependencies
├── console # IRB console with gem loaded
└── local_do # Local development runner
Comment on lines +16 to +35
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The repository tree lists lib/dev_oops/dev_oops.rb, but in this repo the gem entrypoint is lib/dev_oops.rb (top-level under lib/). Updating this section will prevent readers from looking for a non-existent file/path.

Suggested change
lib/dev_oops/
├── dev_oops.rb # Module init, Zeitwerk setup, eager_load
├── version.rb # VERSION constant (bump for releases)
├── runner.rb # Thor CLI entry point, dynamic command registration
├── scripts_loader.rb # Script discovery, config parsing, Thor::Group builders
└── commands/
├── edit_script.rb # Edit script JSON config
├── edit_script_sh.rb # Edit script .sh body
├── local_install.rb # Create local ./dev_oops directory
└── remove_script.rb # Remove a script
exe/
└── dev_oops # Executable entry point
spec/
└── dev_oops_spec.rb # RSpec tests
templates/
└── empty_script.tt # JSON template for new scripts
bin/
├── setup # Install bundle dependencies
├── console # IRB console with gem loaded
└── local_do # Local development runner
lib/
├── dev_oops.rb # Gem entrypoint, Zeitwerk setup, eager_load
└── dev_oops/
├── version.rb # VERSION constant (bump for releases)
├── runner.rb # Thor CLI entry point, dynamic command registration
├── scripts_loader.rb # Script discovery, config parsing, Thor::Group builders
└── commands/
├── edit_script.rb # Edit script JSON config
├── edit_script_sh.rb # Edit script .sh body
├── local_install.rb # Create local ./dev_oops directory
└── remove_script.rb # Remove a script
exe/
└── dev_oops # Executable entry point
spec/
└── dev_oops_spec.rb # RSpec tests
templates/
└── empty_script.tt # JSON template for new scripts
bin/
├── setup # Install bundle dependencies
├── console # IRB console with gem loaded
└── local_do # Local development runner

Copilot uses AI. Check for mistakes.
```

## Development Commands

```bash
# Install dependencies
bundle install
yarn install # For Prettier Ruby plugin

# Run tests
bundle exec rspec

# Run linter
bundle exec rubocop

# Check formatting
yarn prettier -c '**/*.rb'

# Default rake task (runs rspec)
bundle exec rake

# Interactive console
bin/console

# Run locally during development
bin/local_do
```

## CI Checks (must pass before merge)

The CI pipeline (GitHub Actions) runs on Ruby 2.6, 2.7, and 3.0:

1. **Linting:** `bundle exec rubocop`
2. **Tests:** `bundle exec rspec`
3. **Formatting:** `yarn prettier -c '**/*.rb'`

PRs to `main` also verify that `lib/dev_oops/version.rb` has been bumped. Pushes to `main` auto-publish to RubyGems if the version changed.

Comment on lines +72 to +73
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This CI description says PRs to main verify that lib/dev_oops/version.rb has been bumped, but the GitHub Actions workflow only performs the version-diff check/publish logic on pushes to main (release job). Please reword to match the actual workflow behavior.

Copilot uses AI. Check for mistakes.
## Code Conventions

- **Frozen string literals:** Every Ruby file starts with `# frozen_string_literal: true`
- **Module structure:** All code lives under the `DevOops` module. Commands live in `DevOops::Commands`
- **File naming:** `snake_case.rb` — class naming: `PascalCase`
- **Constants:** `UPPER_CASE` (e.g., `GLOBAL_DIR`, `FORBIDDEN_NAMES`)
- **Linter style:** Relaxed Ruby Style + RuboCop Performance + Prettier
- **No monkey patching** in specs (configured in `spec_helper.rb`)

## Architecture Notes

- **Runner** (`runner.rb`): Main Thor CLI class. Registers built-in commands (`edit`, `edit_sh`, `rm`, `install`) and dynamically registers user-defined scripts discovered by `ScriptsLoader`.
- **ScriptsLoader** (`scripts_loader.rb`): Searches for `dev_oops/` directories from the current working directory up to `$HOME`. Loads JSON configs and builds Thor::Group subcommands for each script. Closest-to-cwd wins on name collisions.
- **Script storage:** Global scripts live in `~/.dev_oops/`. Local (project) scripts live in `./dev_oops/`. Each script has a `.json` config and a `.sh` body file.
- **Forbidden script names:** `help`, `install`, `edit`, `edit_sh`, `rm`, `local_install` — reserved for built-in commands.
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The forbidden/reserved names list includes local_install, but the CLI registers the local directory creator under the install subcommand (and there is no local_install command registered in Runner). Consider clarifying whether local_install is a legacy alias/reserved name, or update the list to avoid confusion.

Suggested change
- **Forbidden script names:** `help`, `install`, `edit`, `edit_sh`, `rm`, `local_install` — reserved for built-in commands.
- **Forbidden script names:** `help`, `install`, `edit`, `edit_sh`, `rm` — reserved for built-in commands. The legacy alias name `local_install` is also reserved internally for backward compatibility and must not be used by user scripts, even though it is not exposed as a standalone CLI command.

Copilot uses AI. Check for mistakes.

## Version & Release

- Version is defined in `lib/dev_oops/version.rb`
- Bump the version there for any release
- CI verifies version changes on PRs to `main` and auto-publishes to RubyGems on merge
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Version & Release section repeats that CI verifies version changes on PRs to main, but the workflow currently checks for version changes only when running the release job on pushes to main. Please align this bullet with what CI actually does.

Copilot uses AI. Check for mistakes.

## Key Dependencies

| Gem | Purpose |
|-----|---------|
| `thor` | CLI framework |
| `zeitwerk` | Autoloading |
| `rspec` | Testing |
| `rubocop` | Linting |
| `prettier` | Code formatting (via Node + Ruby plugin) |
Comment on lines +98 to +104
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Key Dependencies markdown table uses || at the start of each row/header, which renders as an extra empty column in standard Markdown. Use a single leading | for each row so the table formats correctly.

Copilot uses AI. Check for mistakes.
| `pry-byebug` | Debugging |
| `bundler-audit` | Dependency security auditing |
Loading