-
Notifications
You must be signed in to change notification settings - Fork 53
refactor: restructure commit-generation config to [commit.generation] #809
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
- Move `[commit-generation]` to `[commit.generation]` (nested under commit) - Replace `command` + `args` with single `command` string (shell execution) - Add deprecation warning for old format with backward compatibility - Update docs to present Claude CLI and llm as equal options The new format uses shell execution (`sh -c`) so environment variables can be set inline in the command string. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Fix test regressions identified by Codex review where tests using WORKTRUNK_COMMIT_GENERATION__ARGS were silently failing because args is now ignored with the new shell-based command format. Tests now use the correct pattern: WORKTRUNK_COMMIT_GENERATION__COMMAND="cat >/dev/null && echo 'message'" Also update CLI docs to show: - New config path: commit.generation.command (not commit-generation.command) - New env var format: WORKTRUNK_COMMIT__GENERATION__COMMAND - Remove args documentation (no longer applicable) Co-Authored-By: Claude <noreply@anthropic.com>
Address Codex review feedback: - Update per-project doc example to show new format (commit.generation instead of commit-generation) - Update env var comment to show new format (COMMIT__GENERATION__COMMAND instead of COMMIT_GENERATION__COMMAND) - Add validation for projects.*.commit.generation path (was only validating deprecated commit-generation path) Co-Authored-By: Claude <noreply@anthropic.com>
- Use ShellConfig for LLM command execution (Windows compatibility) - Improve error handling when LLM stderr is empty - Format reproduction commands with conditional sh -c wrapping - Update tests to use new env var format (WORKTRUNK_COMMIT__GENERATION__) - Make test assertion more specific ([commit] not just "commit") - Document cformat safety for shell commands in output guidelines Co-Authored-By: Claude <noreply@anthropic.com>
Replace manual single-quote escaping with the shell_escape crate which is already a dependency used elsewhere in the codebase. Co-Authored-By: Claude <noreply@anthropic.com>
Consolidate all deprecation handling into deprecation.rs: - Add [commit-generation] → [commit.generation] section migration - Merge deprecated `args` field into `command` string - Generate single .new file with all migrations (template vars + sections) - Skip migration if new section already exists (don't overwrite) - Skip warning for empty deprecated sections - Use shell_escape for proper quoting when merging args - Rename hint from deprecated-project-config to deprecated-config Remove separate warn_deprecated_commit_generation() from user.rs. Co-Authored-By: Claude <noreply@anthropic.com>
Fixes found during adversarial testing:
1. Args data loss prevention: merge_args_into_command() now validates
preconditions (args is array, command is string) BEFORE removing
the args field. Previously, table.remove("args") happened
unconditionally, losing data if command was missing or non-string.
2. Malformed generation detection: When checking if new [commit.generation]
exists, now verify it's actually a table (is_table || is_inline_table).
A malformed value like `generation = "string"` no longer suppresses
deprecation warnings for the old section.
3. Inline table support: Both detection and migration now handle inline
table format (e.g., `commit-generation = { command = "..." }`).
Detection uses as_inline_table() in addition to as_table().
Migration converts InlineTable to Table via into_table().
Added comprehensive tests for all edge cases.
Co-Authored-By: Claude <noreply@anthropic.com>
Add tests for: - Project-level inline table migration - Preserving existing [commit] fields during migration - Empty inline table detection (should not flag as deprecated) Co-Authored-By: Claude <noreply@anthropic.com>
Add test that exercises the full deprecation path through check_and_migrate() for commit-generation section rename and args merge. This improves coverage on the warning output and migration file generation paths. Co-Authored-By: Claude <noreply@anthropic.com>
…ation Add test that exercises the project_keys iteration path in check_and_migrate() for project-level commit-generation deprecation warnings. This covers the warning message format that includes project identifiers. Co-Authored-By: Claude <noreply@anthropic.com>
Cover the early-return paths in merge_args_into_command(): - Args without command: args preserved (no command to merge into) - Non-string command: args preserved (can't merge into non-string) - Command-only: clean migration without args field These tests exercise the !can_merge validation path. Co-Authored-By: Claude <noreply@anthropic.com>
Add tests for the `_ => None` fallback branches that handle unusual cases where commit-generation is neither a table nor inline table (e.g., a string value like `commit-generation = "not a table"`). These tests exercise lines 264 and 305 in deprecation.rs. Co-Authored-By: Claude <noreply@anthropic.com>
Add unit tests for: - Empty command with args: args become the command when command="" - Invalid TOML parsing: returns content unchanged - Deduplication path: second call with same path hits early return These tests cover previously uncovered code paths in deprecation.rs. Co-Authored-By: Claude <noreply@anthropic.com>
Add tests for format_reproduction_command and is_lock_file to improve code coverage. Co-Authored-By: Claude <noreply@anthropic.com>
Add tests for: - CommitConfig merge when only base/override has generation - CommitConfig merge when both have generation - CommitGenerationConfig merge for squash_template fields These cover previously uncovered branches in the Merge implementations. Co-Authored-By: Claude <noreply@anthropic.com>
Add tests for validation error paths in the new [commit.generation] config format (both top-level and per-project). Co-Authored-By: Claude <noreply@anthropic.com>
| /// | ||
| /// Simple commands like `llm -m haiku` are shown as-is. | ||
| /// Complex commands with shell syntax are wrapped: `sh -c 'complex && command'` | ||
| fn format_reproduction_command(base_cmd: &str, llm_command: &str) -> String { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@claude wouldn't it be easier to just do a single format? why have both?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Claude finished @max-sixty's task in 43s —— View job
Answer
Good question! Supporting both formats is required because worktrunk has a growing user base who are already using the old [commit-generation] format in their config files.
From CLAUDE.md:
This project has a growing user base. Balance clean design with reasonable compatibility.
External interfaces to protect:
- Config file format (
wt.toml, user config) — avoid breaking changes; provide migration guidance when necessary
Why backward compatibility matters here:
- Breaking user workflows: If we just switched to
[commit.generation]without supporting the old format, existing users' config would stop working immediately when they upgrade - Graceful migration path: The deprecation system (
src/config/deprecation.rs) does three things:- Detects the old format in config files
- Continues to work with the old format (no breakage)
- Generates a
.newmigration file with the updated format that users can apply when ready
The implementation:
Line 25 isn't actually where both formats are handled - that's just a helper function for reproduction commands. The actual dual-format handling is in:
src/config/deprecation.rs(lines 153-233): Detects both[commit-generation]and[commit.generation]formatssrc/config/user.rs: Deserializes both old and new structures, preferring new when both exist- Migration: Automatically generates a migrated config file for users to review and apply
Why not force migration immediately?
Per project guidelines, "Prefer deprecation warnings over silent breaks" - users get warnings and migration files, but their existing config keeps working until they're ready to update. This is better UX than forcing everyone to manually fix their config the moment they upgrade.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do you see the line that I'm commenting on? my comment is very specific to tuos area of code
Cover the "create from scratch" branch in save_to() which serializes commit.generation and deprecated commit-generation sections to new files. Previously only the "update existing file" branch was tested. Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Remove Claude Code/llm setup examples from config docs since they duplicate llm-commits.md. Config page now links to llm-commits.md for setup and keeps only the custom prompt templates section. Co-Authored-By: Claude <noreply@anthropic.com>
# Conflicts: # src/config/user.rs
Previously `config show` read files directly without calling the config loaders, so deprecation warnings weren't shown. Now we call UserConfig::load() and repo.load_project_config() to trigger warnings while still displaying invalid configs (the deprecation check runs on raw content before parsing). Co-Authored-By: Claude <noreply@anthropic.com>
Move aichat example from "Alternative tools" into the Setup section as "Option 3: aichat" alongside Claude CLI and llm. Add "Custom scripts" subsection for the generic example. Remove the now-redundant "Alternative tools" section. Co-Authored-By: Claude <noreply@anthropic.com>
Change from "Option 1/2/3" to just showing examples of tools that work. Lead with the concept: any command that reads stdin and outputs a commit message. Simplify Claude Code example and condense install instructions. Co-Authored-By: Claude <noreply@anthropic.com>
Summary
[commit-generation]→[commit.generation](nested under existing commit section)command+argswith singlecommandstring (shell execution viash -c)llmas two equal setup optionsChanges
Config format:
Shell execution: Commands now run via
sh -c(Git Bash on Windows), allowing inline environment variables likeMAX_THINKING_TOKENS=0 claude -p ...Environment variables:
WORKTRUNK_COMMIT__GENERATION__COMMAND(note double underscore for nested path)Test plan
wt hook pre-merge --yes)[commit-generation]formatShellConfig(uses Git Bash)