Skip to content

Commit 237a902

Browse files
authored
Merge pull request #6 from kettle-dev/fix/templating-dependency-preflight
kettle-jem event streaming
2 parents 70fb709 + 8382d9b commit 237a902

76 files changed

Lines changed: 2242 additions & 538 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/coverage.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,16 @@ jobs:
7979
if: ${{ steps.bundleAppraisalAttempt1.outcome == 'failure' }}
8080
run: bundle exec appraisal ${{ matrix.appraisal }} install
8181

82+
- name: Restore RSpec status log
83+
if: "${{!env.ACT}}"
84+
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
85+
with:
86+
path: .rspec_status
87+
key: rspec-status-coverage-${{matrix.ruby}}-${{matrix.appraisal}}-${{hashFiles('**/Gemfile.lock','Appraisal.root.gemfile','gemfiles/**/*.gemfile')}}-${{github.run_id}}-${{github.run_attempt}}
88+
restore-keys: |
89+
rspec-status-coverage-${{matrix.ruby}}-${{matrix.appraisal}}-${{hashFiles('**/Gemfile.lock','Appraisal.root.gemfile','gemfiles/**/*.gemfile')}}-
90+
rspec-status-coverage-${{matrix.ruby}}-${{matrix.appraisal}}-
91+
8292
- name: Tests for ${{ matrix.ruby }}@current via ${{ matrix.exec_cmd }}
8393
run: bundle exec appraisal ${{ matrix.appraisal }} bundle exec ${{ matrix.exec_cmd }}
8494

.github/workflows/current.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,5 +70,15 @@ jobs:
7070
if: ${{ steps.bundleAppraisalAttempt1.outcome == 'failure' }}
7171
run: bundle exec appraisal ${{ matrix.appraisal }} install
7272

73+
- name: Restore RSpec status log
74+
if: "${{!env.ACT}}"
75+
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
76+
with:
77+
path: .rspec_status
78+
key: rspec-status-current-${{matrix.ruby}}-${{matrix.appraisal}}-${{hashFiles('**/Gemfile.lock','Appraisal.root.gemfile','gemfiles/**/*.gemfile')}}-${{github.run_id}}-${{github.run_attempt}}
79+
restore-keys: |
80+
rspec-status-current-${{matrix.ruby}}-${{matrix.appraisal}}-${{hashFiles('**/Gemfile.lock','Appraisal.root.gemfile','gemfiles/**/*.gemfile')}}-
81+
rspec-status-current-${{matrix.ruby}}-${{matrix.appraisal}}-
82+
7383
- name: Tests for ${{ matrix.ruby }} via ${{ matrix.exec_cmd }}
7484
run: bundle exec appraisal ${{ matrix.appraisal }} bundle exec ${{ matrix.exec_cmd }}

.github/workflows/dep-heads.yml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,16 @@ jobs:
7676
if: ${{ !env.ACT && steps.bundleAppraisalAttempt1.outcome == 'failure' }}
7777
run: bundle exec appraisal ${{ matrix.appraisal }} install
7878

79+
- name: Restore RSpec status log
80+
if: "${{!env.ACT}}"
81+
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
82+
with:
83+
path: .rspec_status
84+
key: rspec-status-dep-heads-${{matrix.ruby}}-${{matrix.appraisal}}-${{hashFiles('**/Gemfile.lock','Appraisal.root.gemfile','gemfiles/**/*.gemfile')}}-${{github.run_id}}-${{github.run_attempt}}
85+
restore-keys: |
86+
rspec-status-dep-heads-${{matrix.ruby}}-${{matrix.appraisal}}-${{hashFiles('**/Gemfile.lock','Appraisal.root.gemfile','gemfiles/**/*.gemfile')}}-
87+
rspec-status-dep-heads-${{matrix.ruby}}-${{matrix.appraisal}}-
88+
7989
- name: Tests for ${{ matrix.ruby }} via Appraisal and ${{ matrix.exec_cmd }}
8090
if: ${{ !env.ACT }}
8191
run: bundle exec appraisal ${{ matrix.appraisal }} bundle exec ${{ matrix.exec_cmd }}
@@ -94,6 +104,11 @@ jobs:
94104
- ruby: "truffleruby"
95105
appraisal: "dep-heads"
96106
exec_cmd: "kettle-test"
107+
# TruffleRuby's bundled RubyGems/Bundler path cannot reliably
108+
# bootstrap Appraisal against all configured gem servers here.
109+
# Run directly from the generated appraisal Gemfile instead.
110+
# This makes gemfiles/dep_heads.gemfile required checked-in output
111+
# for repositories using this generated workflow.
97112
bundle_gemfile: "gemfiles/dep_heads.gemfile"
98113
direct_bundle: true
99114
rubygems: default
@@ -115,6 +130,16 @@ jobs:
115130
bundler: ${{ matrix.bundler }}
116131
bundler-cache: true
117132

133+
- name: Restore RSpec status log
134+
if: "${{!env.ACT}}"
135+
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
136+
with:
137+
path: .rspec_status
138+
key: rspec-status-dep-heads-${{matrix.ruby}}-${{matrix.appraisal}}-${{hashFiles('**/Gemfile.lock','Appraisal.root.gemfile','gemfiles/**/*.gemfile')}}-${{github.run_id}}-${{github.run_attempt}}
139+
restore-keys: |
140+
rspec-status-dep-heads-${{matrix.ruby}}-${{matrix.appraisal}}-${{hashFiles('**/Gemfile.lock','Appraisal.root.gemfile','gemfiles/**/*.gemfile')}}-
141+
rspec-status-dep-heads-${{matrix.ruby}}-${{matrix.appraisal}}-
142+
118143
- name: Tests for ${{ matrix.ruby }} via ${{ matrix.exec_cmd }}
119144
if: ${{ !env.ACT }}
120145
run: bundle exec ${{ matrix.exec_cmd }}
@@ -164,6 +189,16 @@ jobs:
164189
if: ${{ !env.ACT && steps.bundleAppraisalAttempt1.outcome == 'failure' }}
165190
run: bundle exec appraisal ${{ matrix.appraisal }} install
166191

192+
- name: Restore RSpec status log
193+
if: "${{!env.ACT}}"
194+
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
195+
with:
196+
path: .rspec_status
197+
key: rspec-status-dep-heads-${{matrix.ruby}}-${{matrix.appraisal}}-${{hashFiles('**/Gemfile.lock','Appraisal.root.gemfile','gemfiles/**/*.gemfile')}}-${{github.run_id}}-${{github.run_attempt}}
198+
restore-keys: |
199+
rspec-status-dep-heads-${{matrix.ruby}}-${{matrix.appraisal}}-${{hashFiles('**/Gemfile.lock','Appraisal.root.gemfile','gemfiles/**/*.gemfile')}}-
200+
rspec-status-dep-heads-${{matrix.ruby}}-${{matrix.appraisal}}-
201+
167202
- name: Tests for ${{ matrix.ruby }} via Appraisal and ${{ matrix.exec_cmd }}
168203
if: ${{ !env.ACT }}
169204
run: bundle exec appraisal ${{ matrix.appraisal }} bundle exec ${{ matrix.exec_cmd }}

.github/workflows/dependency-review.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,5 @@ jobs:
1919
with:
2020
persist-credentials: false
2121
- name: 'Dependency Review'
22+
continue-on-error: true
2223
uses: actions/dependency-review-action@a1d282b36b6f3519aa1f3fc636f609c47dddb294 # v5.0.0

.github/workflows/heads.yml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,16 @@ jobs:
7575
if: ${{ !env.ACT && steps.bundleAppraisalAttempt1.outcome == 'failure' }}
7676
run: bundle exec appraisal ${{ matrix.appraisal }} install
7777

78+
- name: Restore RSpec status log
79+
if: "${{!env.ACT}}"
80+
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
81+
with:
82+
path: .rspec_status
83+
key: rspec-status-heads-${{matrix.ruby}}-${{matrix.appraisal}}-${{hashFiles('**/Gemfile.lock','Appraisal.root.gemfile','gemfiles/**/*.gemfile')}}-${{github.run_id}}-${{github.run_attempt}}
84+
restore-keys: |
85+
rspec-status-heads-${{matrix.ruby}}-${{matrix.appraisal}}-${{hashFiles('**/Gemfile.lock','Appraisal.root.gemfile','gemfiles/**/*.gemfile')}}-
86+
rspec-status-heads-${{matrix.ruby}}-${{matrix.appraisal}}-
87+
7888
- name: Tests for ${{ matrix.ruby }} via ${{ matrix.exec_cmd }}
7989
if: ${{ !env.ACT }}
8090
run: bundle exec appraisal ${{ matrix.appraisal }} bundle exec ${{ matrix.exec_cmd }}
@@ -123,6 +133,16 @@ jobs:
123133
if: ${{ !env.ACT && steps.bundleAppraisalAttempt1.outcome == 'failure' }}
124134
run: bundle exec appraisal ${{ matrix.appraisal }} install
125135

136+
- name: Restore RSpec status log
137+
if: "${{!env.ACT}}"
138+
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
139+
with:
140+
path: .rspec_status
141+
key: rspec-status-heads-${{matrix.ruby}}-${{matrix.appraisal}}-${{hashFiles('**/Gemfile.lock','Appraisal.root.gemfile','gemfiles/**/*.gemfile')}}-${{github.run_id}}-${{github.run_attempt}}
142+
restore-keys: |
143+
rspec-status-heads-${{matrix.ruby}}-${{matrix.appraisal}}-${{hashFiles('**/Gemfile.lock','Appraisal.root.gemfile','gemfiles/**/*.gemfile')}}-
144+
rspec-status-heads-${{matrix.ruby}}-${{matrix.appraisal}}-
145+
126146
- name: Tests for ${{ matrix.ruby }} via ${{ matrix.exec_cmd }}
127147
if: ${{ !env.ACT }}
128148
run: bundle exec appraisal ${{ matrix.appraisal }} bundle exec ${{ matrix.exec_cmd }}
@@ -171,6 +191,16 @@ jobs:
171191
if: ${{ !env.ACT && steps.bundleAppraisalAttempt1.outcome == 'failure' }}
172192
run: bundle exec appraisal ${{ matrix.appraisal }} install
173193

194+
- name: Restore RSpec status log
195+
if: "${{!env.ACT}}"
196+
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
197+
with:
198+
path: .rspec_status
199+
key: rspec-status-heads-${{matrix.ruby}}-${{matrix.appraisal}}-${{hashFiles('**/Gemfile.lock','Appraisal.root.gemfile','gemfiles/**/*.gemfile')}}-${{github.run_id}}-${{github.run_attempt}}
200+
restore-keys: |
201+
rspec-status-heads-${{matrix.ruby}}-${{matrix.appraisal}}-${{hashFiles('**/Gemfile.lock','Appraisal.root.gemfile','gemfiles/**/*.gemfile')}}-
202+
rspec-status-heads-${{matrix.ruby}}-${{matrix.appraisal}}-
203+
174204
- name: Tests for ${{ matrix.ruby }} via ${{ matrix.exec_cmd }}
175205
if: ${{ !env.ACT }}
176206
run: bundle exec appraisal ${{ matrix.appraisal }} bundle exec ${{ matrix.exec_cmd }}

.kettle-drift.lock

Lines changed: 6 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
"file": ".github/workflows/dep-heads.yml",
55
"lines": [
66
44,
7-
95,
8-
134
7+
105,
8+
159
99
]
1010
}
1111
],
@@ -14,8 +14,8 @@
1414
"file": ".github/workflows/heads.yml",
1515
"lines": [
1616
43,
17-
94,
18-
142
17+
104,
18+
162
1919
]
2020
}
2121
],
@@ -24,26 +24,8 @@
2424
"file": ".github/workflows/heads.yml",
2525
"lines": [
2626
44,
27-
95,
28-
143
29-
]
30-
}
31-
],
32-
"if: ${{ !env.ACT }}\nuses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0": [
33-
{
34-
"file": ".github/workflows/dep-heads.yml",
35-
"lines": [
36-
51,
37-
104,
38-
142
39-
]
40-
},
41-
{
42-
"file": ".github/workflows/heads.yml",
43-
"lines": [
44-
50,
45-
101,
46-
149
27+
105,
28+
163
4729
]
4830
}
4931
]

.rubocop_gradual.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"kettle-family.gemspec:1846487200": [
2+
"kettle-family.gemspec:4065920391": [
33
[19, 32, 10, "Gemspec/RequiredRubyVersion: `required_ruby_version` and `TargetRubyVersion` (3.2, which may be specified in .rubocop.yml) should be equal.", 3888670706]
44
]
55
}

CHANGELOG.md

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ Please file a bug if you notice a violation of semantic versioning.
2020

2121
### Added
2222

23+
- `kettle-family template` now uses `kettle-jem --events` as its default
24+
templating interface, including verbose and single-job runs, and streams
25+
newline-delimited JSON template phase, recipe, post-apply, command-step,
26+
diagnostic, and summary events as member-prefixed progress lines.
27+
2328
### Changed
2429

2530
### Deprecated
@@ -28,8 +33,50 @@ Please file a bug if you notice a violation of semantic versioning.
2833

2934
### Fixed
3035

36+
- `kettle-family` template preparation now handles custom non-`kettle-jem`
37+
template commands without treating no-op dependency preparation as failure.
38+
- `kettle-family release-state` now counts `ahead` from the release tag to the
39+
checked-out member `HEAD`.
40+
- Generated docs now retain the YARD `_index.html` content wrapper after
41+
regeneration with the shared YARD postprocessing stack.
42+
3143
### Security
3244

45+
## [1.0.1] - 2026-07-19
46+
47+
- TAG: [v1.0.1][1.0.1t]
48+
- COVERAGE: 95.32% -- 2466/2587 lines in 23 files
49+
- BRANCH COVERAGE: 77.16% -- 838/1086 branches in 23 files
50+
- 29.10% documented
51+
52+
### Added
53+
54+
- `kettle-family release-state` now includes an `ahead` column counting commits
55+
from the latest release tag to the local default branch when available.
56+
- `kettle-family release` now accepts `--skip-remotes` and forwards the
57+
comma-separated remote skip list to member `kettle-release` runs.
58+
- `kettle-family --only` now accepts release-state tokens `unreleased`,
59+
`prepared`, and `pending`; multiple tokens are combined with logical AND.
60+
- `kettle-family template` now accepts `--verbose` and forwards verbose mode to
61+
member `kettle-jem` runs instead of forcing quiet JSON output.
62+
63+
- `kettle-family template` now runs `kettle-jem prepare` before full templating
64+
for Kettle Jem-powered members so templating-only dependency bootstraps, such
65+
as parser packages, are available before the full template command loads.
66+
67+
### Deprecated
68+
69+
- `kettle-family bump-version` is now deprecated in favor of `kettle-family bump`.
70+
71+
### Fixed
72+
73+
- The templating prepare phase now disables only the implicit family local path
74+
environment variable unless it was explicitly provided, avoiding stale local
75+
Gemfile activation failures before the prepare payload can refresh generated
76+
modular Gemfiles.
77+
- The templating prepare phase now runs outside each member's Bundler context so
78+
it can repair stale generated Gemfiles before Bundler evaluates them.
79+
3380
## [1.0.0] - 2026-07-17
3481

3582
- TAG: [v1.0.0][1.0.0t]
@@ -736,7 +783,9 @@ Please file a bug if you notice a violation of semantic versioning.
736783
- Fixed CI load failures on engines without compatible `pty` support by falling back to Open3 for interactive release commands.
737784
- Fixed Ruby 3.2 version-bump support by loading Prism lazily and wiring the Prism gem only for MRI versions that need it.
738785

739-
[Unreleased]: https://github.com/kettle-dev/kettle-family/compare/v1.0.0...HEAD
786+
[Unreleased]: https://github.com/kettle-dev/kettle-family/compare/v1.0.1...HEAD
787+
[1.0.1]: https://github.com/kettle-dev/kettle-family/compare/v1.0.0...v1.0.1
788+
[1.0.1t]: https://github.com/kettle-dev/kettle-family/releases/tag/v1.0.1
740789
[1.0.0]: https://github.com/kettle-dev/kettle-family/compare/v0.2.7...v1.0.0
741790
[1.0.0t]: https://github.com/kettle-dev/kettle-family/releases/tag/v1.0.0
742791
[0.2.7]: https://github.com/kettle-dev/kettle-family/compare/v0.2.6...v0.2.7

CONTRIBUTING.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,20 @@ Follow these instructions:
3030
8. Create new Pull Request.
3131
9. Announce it in the channel for this org in the [Discord][✉️discord-invite]!
3232

33+
## Ruby engine CI branches
34+
35+
Pull requests run MRI workflows by default. JRuby and TruffleRuby workflows are
36+
available by branch naming convention so ordinary PRs do not spend CI time on
37+
alternate Ruby engines.
38+
39+
- Use a branch named `jruby/*` to run JRuby workflows for a pull request.
40+
- Use a branch named `truffleruby/*` to run TruffleRuby workflows for a pull
41+
request.
42+
- Use a branch named `engines/*` to run both JRuby and TruffleRuby workflows for
43+
a pull request.
44+
45+
Pushes to the default branch continue to run the configured engine workflows.
46+
3347
## Executables vs Rake tasks
3448

3549
Executables shipped by dependencies, such as kettle-dev, and stone_checksums, are available
@@ -116,7 +130,7 @@ Troubleshooting Git diffs
116130
- Use `git diff --no-ext-diff` to compare against Git's built-in diff output.
117131
- Use `git diff --no-textconv` when a textconv projection obscures the raw file bytes you need to inspect.
118132
- If Git reports a missing `smorg-*` executable, rerun `bundle install` and the setup command above, then check `git config --local --get-regexp '^diff\.smorg-'`.
119-
- To remove managed local entries, run `K_JEM_TEMPLATING=true kettle-jem install --undo`; remove global command registrations with `git config --global --unset-all diff.smorg-ruby.command`.
133+
- To remove managed local entries, run `K_JEM_TEMPLATING=true kettle-jem install --undo`; remove global command registrations with `git config --global --unset-all diff.smorg-rb.command`, `git config --global --unset-all merge.smorg-rb.driver`, and `git config --global --unset-all merge.smorg-rb.name`.
120134

121135
For a quick starting point, this repository’s `mise.toml` defines the shared defaults, and `.env.local` can override them locally. Copy `.env.local.example` to `.env.local`, use `KEY=value` lines, and either activate `mise` in your shell or run commands through `mise exec -C /path/to/project -- ...`.
122136

Gemfile

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,13 +76,27 @@ if direct_sibling_gems.any? &&
7676
end
7777
end
7878

79-
# Templating (env-switched: SMORG_RB_DEV=/path/to/structuredmerge/ruby/gems for local paths)
79+
# Use the StructuredMerge TSLP branch until upstream ships parser API bindings.
80+
vendored_gems = ENV.fetch("VENDORED_GEMS", "").split(",").map(&:strip)
81+
tslp_declared_by_templating =
82+
ENV.fetch("K_JEM_TEMPLATING", "false").casecmp("true").zero? &&
83+
vendored_gems.include?("tree_sitter_language_pack")
84+
unless tslp_declared_by_templating
85+
gem(
86+
"tree_sitter_language_pack",
87+
git: "https://github.com/structuredmerge/tree-sitter-language-pack.git",
88+
branch: "fix/ruby-parser-api-methods",
89+
glob: "packages/ruby/*.gemspec"
90+
)
91+
end
92+
93+
# Templating (env-switched: STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local paths)
8094
eval_gemfile "gemfiles/modular/templating.gemfile" if ENV.fetch("K_JEM_TEMPLATING", "false").casecmp("true").zero?
8195

8296
# Debugging
8397
eval_gemfile "gemfiles/modular/debug.gemfile"
8498

85-
# Code Coverage (env-switched: KETTLE_RB_DEV=true for local paths)
99+
# Code Coverage (env-switched: KETTLE_DEV_DEV=true for local paths)
86100
eval_gemfile "gemfiles/modular/coverage.gemfile"
87101

88102
# Linting

0 commit comments

Comments
 (0)