gempilot 0.2.2 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,166 +0,0 @@
1
- # Inflection Tests and ERB Rename Implementation Plan
2
-
3
- > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
4
-
5
- **Goal:** Add unit tests for `String::Inflectable` and rename `version.rake.erb` to `version.rake` since it no longer contains ERB tags.
6
-
7
- **Architecture:** Two independent tasks. Task 1 adds an RSpec spec for the inflection refinement covering `camelize`, `underscore`, and `dasherize` with edge cases. Task 2 renames the template file and switches `gem_builder.rb` from `erb` to `cp`.
8
-
9
- **Tech Stack:** Ruby, RSpec
10
-
11
- ---
12
-
13
- ## File Structure
14
-
15
- | Action | Path | Responsibility |
16
- |--------|------|----------------|
17
- | Create | `spec/core_ext/string/inflectable_spec.rb` | Unit tests for inflection refinement |
18
- | Rename | `data/templates/gem/rakelib/version.rake.erb` → `data/templates/gem/rakelib/version.rake` | Remove misleading ERB extension |
19
- | Modify | `lib/gempilot/cli/gem_builder.rb:48` | Switch from `erb` to `cp` for version.rake |
20
-
21
- ---
22
-
23
- ### Task 1: Add inflection unit tests
24
-
25
- **Files:**
26
- - Create: `spec/core_ext/string/inflectable_spec.rb`
27
-
28
- - [ ] **Step 1: Write the spec**
29
-
30
- ```ruby
31
- require_relative "../../lib/core_ext/string/refinements/inflectable"
32
-
33
- using String::Inflectable
34
-
35
- RSpec.describe String::Inflectable do
36
- describe "#camelize" do
37
- it "camelizes a snake_case string" do
38
- expect("my_gem".camelize).to eq("MyGem")
39
- end
40
-
41
- it "camelizes a path with slashes into namespaces" do
42
- expect("my/gem".camelize).to eq("My::Gem")
43
- end
44
-
45
- it "handles a single word" do
46
- expect("gem".camelize).to eq("Gem")
47
- end
48
-
49
- it "handles a hyphenated string" do
50
- expect("my-gem".camelize).to eq("MyGem")
51
- end
52
-
53
- it "preserves numeric segments" do
54
- expect("v_2".camelize).to eq("V_2")
55
- end
56
- end
57
-
58
- describe "#underscore" do
59
- it "underscores a CamelCase string" do
60
- expect("MyGem".underscore).to eq("my_gem")
61
- end
62
-
63
- it "underscores consecutive capitals" do
64
- expect("CLI".underscore).to eq("cli")
65
- end
66
-
67
- it "underscores mixed case with acronyms" do
68
- expect("HTTPClient".underscore).to eq("http_client")
69
- end
70
-
71
- it "preserves existing underscores" do
72
- expect("my_gem".underscore).to eq("my_gem")
73
- end
74
-
75
- it "converts hyphens to underscores" do
76
- expect("my-gem".underscore).to eq("my_gem")
77
- end
78
- end
79
-
80
- describe "#dasherize" do
81
- it "converts underscores to hyphens" do
82
- expect("my_gem".dasherize).to eq("my-gem")
83
- end
84
-
85
- it "leaves non-underscored strings alone" do
86
- expect("mygem".dasherize).to eq("mygem")
87
- end
88
- end
89
-
90
- describe "class method form" do
91
- it "camelizes via String.camelize" do
92
- expect(String.camelize("my_gem")).to eq("MyGem")
93
- end
94
-
95
- it "underscores via String.underscore" do
96
- expect(String.underscore("MyGem")).to eq("my_gem")
97
- end
98
-
99
- it "dasherizes via String.dasherize" do
100
- expect(String.dasherize("my_gem")).to eq("my-gem")
101
- end
102
- end
103
- end
104
- ```
105
-
106
- - [ ] **Step 2: Run the spec**
107
-
108
- Run: `bundle exec rspec spec/core_ext/string/inflectable_spec.rb --format documentation`
109
- Expected: All examples pass
110
-
111
- - [ ] **Step 3: Run rubocop**
112
-
113
- Run: `bundle exec rubocop spec/core_ext/string/inflectable_spec.rb`
114
- Expected: No offenses
115
-
116
- - [ ] **Step 4: Commit**
117
-
118
- ```bash
119
- git add spec/core_ext/string/inflectable_spec.rb
120
- git commit -m "Add unit tests for String::Inflectable refinement"
121
- ```
122
-
123
- ---
124
-
125
- ### Task 2: Rename version.rake.erb to version.rake
126
-
127
- **Files:**
128
- - Rename: `data/templates/gem/rakelib/version.rake.erb` → `data/templates/gem/rakelib/version.rake`
129
- - Modify: `lib/gempilot/cli/gem_builder.rb:48`
130
-
131
- - [ ] **Step 1: Rename the template file**
132
-
133
- ```bash
134
- git mv data/templates/gem/rakelib/version.rake.erb data/templates/gem/rakelib/version.rake
135
- ```
136
-
137
- - [ ] **Step 2: Update `gem_builder.rb`**
138
-
139
- In `lib/gempilot/cli/gem_builder.rb` line 48, change:
140
-
141
- ```ruby
142
- erb "rakelib/version.rake.erb", "#{@gem_name}/rakelib/version.rake"
143
- ```
144
-
145
- To:
146
-
147
- ```ruby
148
- cp "rakelib/version.rake", "#{@gem_name}/rakelib/version.rake"
149
- ```
150
-
151
- - [ ] **Step 3: Run tests**
152
-
153
- Run: `bundle exec rake test spec`
154
- Expected: All pass
155
-
156
- - [ ] **Step 4: Run rubocop**
157
-
158
- Run: `bundle exec rubocop`
159
- Expected: No offenses
160
-
161
- - [ ] **Step 5: Commit**
162
-
163
- ```bash
164
- git add data/templates/gem/rakelib/version.rake lib/gempilot/cli/gem_builder.rb
165
- git commit -m "Rename version.rake.erb to version.rake — no ERB tags remain"
166
- ```
@@ -1,162 +0,0 @@
1
- # Package Version Tools as Gem Dependency
2
-
3
- ## Context
4
-
5
- Generated gems currently get 8 files copied into them (rakelib support classes + core_ext inflection files). This creates maintenance burden — files diverge, every gem carries duplicate code, updates require regenerating. The CLI `bump` command also reimplements version logic that `Project` already provides.
6
-
7
- Instead: the domain model (`Project`, `Project::Version`, `VersionTag`, `GithubRelease`) lives in `lib/gempilot/` as first-class autoloaded classes. A `VersionTasks` class provides the rake integration. Generated gems add `gem "gempilot"` and `require "gempilot/version_tasks"`. The CLI `bump` command delegates to `rake version:bump` like `release` already delegates to `rake release`.
8
-
9
- ## Architecture
10
-
11
- ```
12
- lib/gempilot/
13
- project.rb — Gempilot::Project (gem introspection)
14
- project/
15
- version.rb — Gempilot::Project::Version (semver value object)
16
- version_tag.rb — Gempilot::VersionTag (git release ops)
17
- github_release.rb — Gempilot::GithubRelease (github release ops)
18
- strict_shell.rb — Gempilot::StrictShell (shared shell mixin)
19
- version_tasks.rb — Gempilot::VersionTasks < Rake::TaskLib (entry point)
20
- ```
21
-
22
- Only `VersionTasks` depends on Rake. The rest are plain Ruby domain objects that Zeitwerk autoloads normally. `VersionTasks` is ignored by Zeitwerk (requires Rake as a side effect) and loaded via explicit `require "gempilot/version_tasks"`.
23
-
24
- ## Files
25
-
26
- ### Create
27
- | Path | Class |
28
- |------|-------|
29
- | `lib/gempilot/strict_shell.rb` | `Gempilot::StrictShell` |
30
- | `lib/gempilot/project.rb` | `Gempilot::Project` |
31
- | `lib/gempilot/project/version.rb` | `Gempilot::Project::Version` |
32
- | `lib/gempilot/version_tag.rb` | `Gempilot::VersionTag` |
33
- | `lib/gempilot/github_release.rb` | `Gempilot::GithubRelease` |
34
- | `lib/gempilot/version_tasks.rb` | `Gempilot::VersionTasks` |
35
-
36
- ### Delete
37
- | Path | Reason |
38
- |------|--------|
39
- | `rakelib/project.rb` | Moved to lib/gempilot/ |
40
- | `rakelib/project_version.rb` | Moved to lib/gempilot/project/version.rb |
41
- | `rakelib/version_tag.rb` | Moved to lib/gempilot/ |
42
- | `rakelib/github_release.rb` | Moved to lib/gempilot/ |
43
- | `rakelib/strict_shell.rb` | Moved to lib/gempilot/ |
44
- | `rakelib/version.rake` | Replaced by VersionTasks |
45
- | `data/templates/gem/rakelib/` | Entire directory (6 symlinks) |
46
- | `data/templates/gem/lib/core_ext/` | Entire directory (2 symlinks) |
47
-
48
- ### Modify
49
- | Path | Change |
50
- |------|--------|
51
- | `lib/gempilot.rb` | Add `LOADER.ignore` for `version_tasks.rb` |
52
- | `gempilot.gemspec` | Add `warning` runtime dep, fix fallback glob |
53
- | `Gemfile` | Remove `gem "warning"` |
54
- | `Rakefile` | Use `require "gempilot/version_tasks"` + `Gempilot::VersionTasks.new` |
55
- | `lib/gempilot/cli/commands/bump.rb` | Delegate to `rake version:bump[SEGMENT]` |
56
- | `lib/gempilot/cli/commands/release.rb` | Delegate to `rake version:release` (already similar) |
57
- | `data/templates/gem/Rakefile.erb` | Add require + VersionTasks.new |
58
- | `data/templates/gem/Gemfile.erb` | Add `gem "gempilot", require: false` |
59
- | `data/templates/gem/gemspec.erb` | Change fallback glob `{lib,exe,rakelib}` → `{lib,exe}` |
60
- | `data/templates/gem/lib/gem_name.rb.erb` | Remove `LOADER.ignore("#{__dir__}/core_ext")` |
61
- | `lib/gempilot/cli/gem_builder.rb` | Remove `render_version_rake`, `render_core_ext` + calls |
62
- | Specs | Update require paths + class references |
63
- | `test/gempilot/cli/create_command_test.rb` | Update assertions for new generated gem structure |
64
-
65
- ## Domain Model Changes
66
-
67
- ### `Project::Version#bump(segment)` — add segment support
68
-
69
- Currently `next_version` only increments the last segment. Add `bump(segment = :patch)`:
70
-
71
- ```ruby
72
- def bump(segment = :patch)
73
- major, minor, patch = value.split(".").map(&:to_i)
74
- new_value = case segment.to_sym
75
- when :major then "#{major + 1}.0.0"
76
- when :minor then "#{major}.#{minor + 1}.0"
77
- when :patch then "#{major}.#{minor}.#{patch + 1}"
78
- end
79
- with(value: new_value)
80
- end
81
- ```
82
-
83
- `next_version` stays as an alias for `bump(:patch)` for backwards compatibility with the existing specs.
84
-
85
- ### `version:bump` rake task — accept segment argument
86
-
87
- ```ruby
88
- desc "Bump version (patch default, or rake version:bump[minor])"
89
- task :bump, [:segment] do |_t, args|
90
- segment = (args[:segment] || :patch).to_sym
91
- old_version = project.version
92
- new_version = old_version.bump(segment)
93
- project.write_version!(old_version, new_version)
94
- project.refresh_version!
95
- puts "Version bumped from #{old_version.value} to #{project.version_value}"
96
- end
97
- ```
98
-
99
- ### `Bump` CLI command — delegate to rake
100
-
101
- Replace the 104-line implementation with a thin rake delegation (same pattern as `Release`):
102
-
103
- ```ruby
104
- def run(segment = "patch")
105
- detect_gem_context
106
- validate_segment(segment)
107
- run_rake_bump(segment)
108
- end
109
-
110
- private
111
-
112
- def run_rake_bump(segment)
113
- success = Bundler.with_unbundled_env do
114
- system("bundle", "exec", "rake", "version:bump[#{segment}]")
115
- end
116
- exit 1 unless success
117
- end
118
- ```
119
-
120
- ## Tasks
121
-
122
- ### Task 1: Create domain classes in lib/gempilot/
123
-
124
- Move and namespace the 5 domain classes + create `VersionTasks`. Each is a mechanical translation wrapping in `module Gempilot`. Add `Version#bump(segment)` method. Add `LOADER.ignore` for `version_tasks.rb` only (the rest autoload normally). Add `warning` to gemspec runtime deps.
125
-
126
- ### Task 2: Dogfood — switch gempilot's Rakefile
127
-
128
- Add `require "gempilot/version_tasks"` + `Gempilot::VersionTasks.new`. Delete all 6 `rakelib/` files. Verify `rake -T version` and `rake version:current`.
129
-
130
- ### Task 3: Update specs
131
-
132
- Change require paths and class references in all rakelib specs. Add spec for `Version#bump(:minor)` and `Version#bump(:major)`. Run specs.
133
-
134
- ### Task 4: Simplify CLI Bump command
135
-
136
- Replace the 104-line implementation with rake delegation. Keep `validate_segment` for the CLI-side error message. Remove duplicate `VERSION_PATTERN`, `read_current_version`, `write_new_version`, `increment` methods.
137
-
138
- ### Task 5: Update templates + generator
139
-
140
- - `Rakefile.erb`: add `require "gempilot/version_tasks"` + `Gempilot::VersionTasks.new`
141
- - `Gemfile.erb`: add `gem "gempilot", require: false`
142
- - `gemspec.erb`: change fallback glob to `{lib,exe}`
143
- - `gem_name.rb.erb`: remove `LOADER.ignore("#{__dir__}/core_ext")`
144
- - `gem_builder.rb`: remove `render_version_rake`, `render_core_ext` + calls
145
- - Delete `data/templates/gem/rakelib/` and `data/templates/gem/lib/core_ext/`
146
-
147
- ### Task 6: Update create_command_test.rb
148
-
149
- Remove assertions about rakelib/core_ext files in generated gems. Add assertions for Gemfile containing `gempilot` and Rakefile containing `VersionTasks`.
150
-
151
- ### Task 7: Integration test
152
-
153
- Generate a test gem. Verify: no `rakelib/` support files, no `lib/core_ext/`, `gem "gempilot"` in Gemfile, `rake -T version` lists 12 tasks, `rake version:current` works, `bundle exec rake` passes.
154
-
155
- ## Verification
156
-
157
- 1. `bundle exec rake test spec` — gempilot suite passes
158
- 2. `bundle exec rubocop` — 0 offenses
159
- 3. `bundle exec rake -T version` — 12 tasks via the new require
160
- 4. `bundle exec rake version:bump[minor]` — segment argument works
161
- 5. `gempilot bump minor` — CLI delegates to rake
162
- 6. Generate a test gem — works end-to-end with gempilot as a Gemfile dependency
@@ -1,185 +0,0 @@
1
- # New README Implementation Plan
2
-
3
- > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
4
-
5
- **Goal:** Replace the default bundler scaffold README with a real project README documenting gempilot's commands, generated gem features, and version management tasks.
6
-
7
- **Architecture:** Single file rewrite. Content sourced from command implementations in `lib/gempilot/cli/commands/`, template files in `data/templates/gem/`, and the CLAUDE.md project notes.
8
-
9
- **Tech Stack:** Markdown
10
-
11
- ---
12
-
13
- ## File Structure
14
-
15
- | Action | Path | Responsibility |
16
- |--------|------|----------------|
17
- | Rewrite | `README.md` | Project documentation |
18
-
19
- ---
20
-
21
- ### Task 1: Write the README
22
-
23
- **Files:**
24
- - Rewrite: `README.md`
25
-
26
- - [ ] **Step 1: Write `README.md`**
27
-
28
- ```markdown
29
- # Gempilot
30
-
31
- A CLI toolkit for creating and managing Ruby gems with modern conventions.
32
-
33
- Gempilot scaffolds production-ready gems with Zeitwerk autoloading, RuboCop,
34
- GitHub Actions CI, and integrated version management. It also generates
35
- classes, modules, and commands within existing gems.
36
-
37
- ## Installation
38
-
39
- ```bash
40
- gem install gempilot
41
- ```
42
-
43
- Requires Ruby >= 3.4.
44
-
45
- ## Quick Start
46
-
47
- ```bash
48
- gempilot create my_gem
49
- cd my_gem
50
- bundle exec rake
51
- ```
52
-
53
- This creates a fully configured gem with tests, linting, CI, and version
54
- management — ready to develop.
55
-
56
- ## Commands
57
-
58
- ### `gempilot create`
59
-
60
- Scaffold a new gem.
61
-
62
- ```bash
63
- gempilot create my_gem
64
- gempilot create --test rspec --exe my_gem
65
- gempilot create --test minitest --no-git my_gem
66
- ```
67
-
68
- Options:
69
-
70
- | Option | Description | Default |
71
- |--------|-------------|---------|
72
- | `--test {minitest\|rspec}` | Test framework | prompted |
73
- | `--[no-]exe` | Create executable in `exe/` | prompted |
74
- | `--[no-]git` | Initialize git repo | prompted |
75
- | `--branch NAME` | Git branch name | `master` |
76
- | `--summary TEXT` | One-line gem description | prompted |
77
- | `--author NAME` | Author name | `git config user.name` |
78
- | `--email EMAIL` | Author email | `git config user.email` |
79
- | `--ruby-version VER` | Minimum Ruby version | current Ruby |
80
-
81
- All options are prompted interactively if omitted.
82
-
83
- ### `gempilot new`
84
-
85
- Generate a class, module, or command in an existing gem. Run from the gem root.
86
-
87
- ```bash
88
- gempilot new class MyGem::Services::Authentication
89
- gempilot new module MyGem::Middleware
90
- gempilot new command deploy
91
- ```
92
-
93
- Creates the source file under `lib/` and a corresponding test file. For
94
- commands, generates a CommandKit command class in `lib/<gem>/cli/commands/`.
95
-
96
- ### `gempilot destroy`
97
-
98
- Remove a class, module, or command. Cleans up empty parent directories.
99
-
100
- ```bash
101
- gempilot destroy class MyGem::Services::Authentication
102
- gempilot destroy command deploy
103
- ```
104
-
105
- ### `gempilot bump`
106
-
107
- Bump the version in `lib/<gem>/version.rb`.
108
-
109
- ```bash
110
- gempilot bump # patch (default)
111
- gempilot bump minor
112
- gempilot bump major
113
- ```
114
-
115
- ### `gempilot release`
116
-
117
- Delegates to `rake release` to build and push the gem.
118
-
119
- ### `gempilot console`
120
-
121
- Delegates to `bin/console` for an interactive IRB session with the gem loaded.
122
-
123
- ## Generated Gem Features
124
-
125
- Every gem scaffolded by `gempilot create` includes:
126
-
127
- - **Zeitwerk autoloading** with `LOADER` constant and `rake zeitwerk:validate`
128
- - **Test framework** — Minitest or RSpec, with a Zeitwerk eager-load test
129
- - **RuboCop** with `rubocop-claude`, `rubocop-performance`, `rubocop-rake`, and
130
- framework-specific plugins (`rubocop-minitest` or `rubocop-rspec`)
131
- - **GitHub Actions CI** running tests and RuboCop
132
- - **Version management** rake tasks (see below)
133
- - **`bin/console`** and **`bin/setup`** scripts
134
- - **Gemspec** with `git ls-files` and glob fallback, MFA required for RubyGems
135
-
136
- ### Version Management Tasks
137
-
138
- Generated gems include rake tasks for the full version lifecycle:
139
-
140
- | Task | Description |
141
- |------|-------------|
142
- | `rake version:current` | Display the current version |
143
- | `rake version:bump` | Increment the patch version |
144
- | `rake version:commit` | Commit the version file change |
145
- | `rake version:tag` | Create a git tag for the version |
146
- | `rake version:untag` | Delete the version git tag |
147
- | `rake version:reset` | Reset the version bump commit |
148
- | `rake version:revert` | Revert the version bump commit |
149
- | `rake version:release` | Bump, commit, and tag (combined) |
150
- | `rake version:unrelease` | Untag and reset (combined) |
151
- | `rake version:github:release` | Push and create a GitHub release |
152
- | `rake version:github:unrelease` | Delete the GitHub release |
153
- | `rake version:github:list` | List GitHub releases |
154
-
155
- ## Development
156
-
157
- ```bash
158
- git clone https://github.com/gillisd/gempilot.git
159
- cd gempilot
160
- bundle install
161
- bundle exec rake
162
- ```
163
-
164
- `rake` runs the Minitest suite, RSpec suite, and RuboCop.
165
-
166
- ## License
167
-
168
- MIT License. See [LICENSE.txt](LICENSE.txt).
169
- ```
170
-
171
- - [ ] **Step 2: Review for accuracy**
172
-
173
- Cross-check against:
174
- - `lib/gempilot/cli/commands/create.rb` — verify all `--options` are listed
175
- - `lib/gempilot/cli/commands/new.rb` — verify types (class, module, command)
176
- - `lib/gempilot/cli/commands/bump.rb` — verify patch/minor/major
177
- - `rakelib/version.rake` — verify all 12 task names match
178
- - `gempilot.gemspec` — verify Ruby version requirement
179
-
180
- - [ ] **Step 3: Commit**
181
-
182
- ```bash
183
- git add README.md
184
- git commit -m "Replace scaffold README with project documentation"
185
- ```