Skip to content

Redesign checksum config and add migration tool#342

Draft
kindermax wants to merge 1 commit intomasterfrom
codex/redesign-checksums-and-migration
Draft

Redesign checksum config and add migration tool#342
kindermax wants to merge 1 commit intomasterfrom
codex/redesign-checksums-and-migration

Conversation

@kindermax
Copy link
Copy Markdown
Collaborator

@kindermax kindermax commented Apr 26, 2026

Summary

  • Add the new checksum config shape with checksum.files, checksum.sh, and checksum.persist while keeping legacy checksum syntax working
  • Add lets self fix to migrate local configs and mixins, with dry-run preview output
  • Preserve backward compatibility in runtime behavior and add deprecation warnings for persist_checksum
  • Update docs, schema, and tests for the new checksum flow

Testing

  • go test ./...
  • lets lint
  • lets test-bats command_checksum.bats
  • lets test-bats command_persist_checksum.bats
  • lets test-bats self_fix.bats

Summary by Sourcery

Redesign command checksum configuration to support new schema options and introduce an automated migration path, while keeping legacy behavior compatible and deprecated.

New Features:

  • Add command checksum configuration fields checksum.files, checksum.sh, and checksum.persist alongside existing checksum support.
  • Add execution of checksum via shell scripts to compute LETS_CHECKSUM from an arbitrary command.
  • Introduce lets self fix command with optional --dry-run to automatically migrate configs and mixins from deprecated checksum syntax to the new format.
  • Track deprecated persist_checksum usage and emit runtime warnings when it is used.

Enhancements:

  • Refine checksum validation and error messages to prevent invalid combinations of checksum configuration options.
  • Extend logging to support colored warn-level output and add a warn-level logger method.
  • Improve YAML formatting for commands when writing migrated configs to preserve readable spacing.

Documentation:

  • Update configuration and advanced usage docs to describe the new checksum schema, script-based checksums, and checksum.persist.
  • Document the lets self fix CLI command and note the deprecation of direct list/map checksum with command-level persist_checksum.
  • Record the checksum config redesign and migration command in the changelog.

Tests:

  • Add unit tests for new checksum parsing, script-based checksum calculation, and backward-compatible behavior.
  • Add bats tests for checksum behavior with the new syntax and for deprecated persist_checksum warnings.
  • Add migration tests for the checksum config fixer and formatting of migrated configs.

@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented Apr 26, 2026

Reviewer's Guide

Refactors command checksum configuration to support a new object-based syntax with files/shell/persist options while keeping legacy behavior, adds a lets self fix migration command (with dry-run) to rewrite old checksum config in root and mixin files, wires checksum execution through the executor with shell/env support, and updates logging, docs, tests, and examples accordingly.

Class diagram for updated command checksum configuration

classDiagram
  direction LR

  class Command {
    +string Name
    +string GroupName
    +Cmds Cmds
    +string After
    +string Shell
    +string WorkDir
    +string Description
    +Env Env
    +EnvFiles EnvFiles
    +string Docopts
    +bool SkipDocopts
    +map~string,string~ Options
    +map~string,string~ CliOptions
    +Deps Depends
    +map~string,string~ ChecksumMap
    +bool PersistChecksum
    +bool DeprecatedPersistChecksum
    +string ChecksumSh
    +map~string,[]string~ ChecksumSources
    +map~string,string~ persistedChecksums
    +[]string Args
    +UnmarshalYAML(unmarshal func_any_error) error
    +Clone() *Command
    +ChecksumCalculator(workDir string, shell string, env map~string,string~) error
  }

  class CommandChecksum {
    +ChecksumFiles Files
    +string Sh
    +*bool Persist
    +UnmarshalYAML(node *yaml_Node) error
  }

  class ChecksumFiles {
    <<type>>
    +map~string,[]string~ (alias)
    +UnmarshalYAML(unmarshal func_any_error) error
  }

  class Checksum {
    <<type alias>>
    +ChecksumFiles (alias for env checksum)
  }

  class Executor {
    +Config cfg
    +initCmd(ctx *Context) error
  }

  class Config {
    +string Shell
    +string WorkDir
    +map~string,string~ GetEnv()
    +map~string,string~ CommandBuiltinEnv(cmd *Command, shell string, workDir string)
  }

  class Context {
    +*Command command
    +ExecLogger logger
  }

  class ExecLogger {
    +string prefix
    +Warn(format string, a ...any)
    +Info(format string, a ...any)
    +Debug(format string, a ...any)
  }

  class checksum_pkg {
    +CalculateChecksumFromSources(workDir string, checksumSources map~string,[]string~) (map~string,string~, error)
    +CalculateChecksumFromConfig(workDir string, checksumSources map~string,[]string~, shell string, script string, env map~string,string~) (map~string,string~, error)
    +CalculateChecksumFromScript(workDir string, shell string, script string, env map~string,string~) (string, error)
  }

  Command "1" --> "0..1" CommandChecksum : yaml field checksum
  Command --> ChecksumFiles : uses as ChecksumSources
  Command --> checksum_pkg : calls
  Command --> Executor : used by
  Executor --> Command : initCmd operates on
  Executor --> Config : uses cfg
  Executor --> Context : receives
  Context --> ExecLogger : has
  Config --> Command : passed into CommandBuiltinEnv
  checksum_pkg ..> ChecksumFiles : input type
  CommandChecksum ..> ChecksumFiles : field Files
  Command o--> ChecksumFiles : ChecksumSources
  Command o--> string : ChecksumSh
  Command o--> bool : PersistChecksum
  Command o--> bool : DeprecatedPersistChecksum
Loading

Class diagram for migration framework and checksum migration

classDiagram
  direction LR

  class Migration {
    <<interface>>
    +Name() string
    +Apply(root *yaml_Node) (bool, error)
  }

  class ChecksumMigration {
    +Name() string
    +Apply(root *yaml_Node) (bool, error)
    +migrateCommandChecksum(command *yaml_Node) (bool, error)
    +isNewChecksumNode(node *yaml_Node) bool
    +mappingIndex(node *yaml_Node, key string) int
    +appendMapping(node *yaml_Node, key *yaml_Node, value *yaml_Node)
    +removeMappingIndex(node *yaml_Node, idx int)
    +scalar(value string) *yaml_Node
    +cloneNode(node *yaml_Node) *yaml_Node
  }

  class Result {
    +[]string ChangedFiles
    +[]string RemoteMixins
    +[]string Applied
    +bool Changed
    +bool DryRun
    +[]string Previews
  }

  class migrate_pkg {
    +DefaultMigrations() []Migration
    +Fix(configName string, configDir string, dryRun bool, out io_Writer) (Result, error)
    +fixFile(path string, dryRun bool, migrations []Migration) (bool, []string, string, error)
    +decodeYAML(data []byte) (*yaml_Node, error)
    +encodeYAML(root *yaml_Node) ([]byte, error)
    +formatCommandSpacing(data []byte) []byte
    +isCommandEntryLine(line string) bool
    +collectConfigPaths(rootPath string, workDir string) ([]string, []string, error)
    +document(root *yaml_Node) *yaml_Node
    +mappingValue(node *yaml_Node, key string) *yaml_Node
    +writeResult(out io_Writer, result Result)
  }

  class FixCommand {
    +bool dryRun
    +initFixCommand() *cobra_Command
  }

  class Cobra_Command {
    +Use string
    +Short string
    +RunE(func(cmd *cobra_Command, args []string) error)
    +Flags() *pflag_FlagSet
    +Root() *cobra_Command
    +OutOrStdout() io_Writer
  }

  Migration <|.. ChecksumMigration
  migrate_pkg --> Migration : uses
  migrate_pkg --> Result : returns
  migrate_pkg --> ChecksumMigration : DefaultMigrations
  FixCommand --> Cobra_Command : constructs
  FixCommand --> migrate_pkg : calls Fix
  ChecksumMigration --> yaml_Node : operates on
  migrate_pkg --> yaml_Node : parses and writes YAML
  migrate_pkg --> Result : populates
  migrate_pkg --> ChecksumMigration : applies checksum migration
  Cobra_Command --> FixCommand : created by initFixCommand
Loading

File-Level Changes

Change Details Files
Introduce new command checksum config shape with files/sh/persist while preserving legacy syntax and enforcing validation rules.
  • Extend Command struct and YAML unmarshalling to support CommandChecksum object, checksum shell script, and track deprecated persist_checksum usage.
  • Add CommandChecksum and ChecksumFiles types with custom YAML unmarshalling that accepts legacy list/map forms and new object form, enforcing mutual exclusivity between files and sh and allowed keys.
  • Add validation around combinations of checksum.files, checksum.sh, checksum.persist, and legacy persist_checksum, including conflict and missing-field errors.
internal/config/config/command.go
internal/config/config/checksum.go
internal/config/config/command_test.go
Route checksum calculation through a new checksum-from-config helper that can execute shell scripts with the correct working directory and environment.
  • Add CalculateChecksumFromConfig and CalculateChecksumFromScript helpers that either compute from file sources or run a shell script to obtain a checksum value.
  • Update Command.ChecksumCalculator signature to accept workDir, shell, and env and to use the new CalculateChecksumFromConfig helper.
  • Update Executor.initCmd to compute checksum shell, workDir, and combined env (builtin + global) and pass them to ChecksumCalculator.
internal/checksum/checksum.go
internal/checksum/checksum_test.go
internal/config/config/command.go
internal/executor/executor.go
Surface deprecation of command-level persist_checksum via logging and adjust logger formatting to colorize warnings.
  • Track DeprecatedPersistChecksum on Command when legacy persist_checksum is set and emit a warn log from Executor.initCmd recommending checksum.persist instead.
  • Extend ExecLogger with Warn method and color formatter to render warn level messages with yellow prefix/message and add tests for warning formatting.
  • Adjust existing logging tests to account for color/no-color behavior changes.
internal/config/config/command.go
internal/executor/executor.go
internal/logging/log.go
internal/logging/formatter.go
internal/logging/log_test.go
Add a config migration framework and a checksum migration that rewrites legacy checksum + persist_checksum into the new checksum.files/checksum.persist form across root configs and mixins, exposed via lets self fix.
  • Introduce a generic migrate package with Migration interface, YAML (de)serialization helpers, mixin path discovery (including local and remote mixins), and result reporting with dry-run previews.
  • Implement ChecksumMigration that rewrites checksum sequence/map nodes into checksum.files, moves persist_checksum into checksum.persist, removes persist_checksum keys, and preserves command spacing and structure.
  • Wire a new lets self fix cobra command that runs migrations against the resolved config graph with optional --dry-run, and add bats tests plus fixture configs for verifying behavior and remote mixin messaging.
internal/config/migrate/migrate.go
internal/config/migrate/checksum.go
internal/config/migrate/checksum_test.go
internal/cmd/fix.go
internal/cmd/self.go
tests/self_fix.bats
tests/self_fix/lets.old.yaml
tests/self_fix/mixin.old.yaml
Update documentation, schema, examples, and bats tests to reflect the new checksum API and deprecation behavior.
  • Revise config and advanced usage docs to document checksum.files, checksum.sh, checksum.persist, deprecate direct list/map checksum and persist_checksum, and add notes about using lets self fix and dry-run.
  • Extend changelog and CLI docs to mention the new checksum options and the self fix command.
  • Update test lets.yaml files and bats tests for command checksum and persist_checksum to cover new syntax, new sh-based checksums, deprecation warnings in output, and a sample project-level checksum on test-bats.
docs/docs/config.md
docs/docs/advanced_usage.md
docs/docs/changelog.md
docs/docs/cli.md
tests/command_checksum/lets.yaml
tests/command_checksum.bats
tests/command_persist_checksum/lets.yaml
tests/command_persist_checksum.bats
lets.yaml
docs/static/schema.json

Possibly linked issues

  • #Redesign checksum: PR delivers the new checksum.files/sh/persist config, deprecates persist_checksum, updates docs, and adds migration tooling.
  • Add lets self fix subcommand for config migrations #305: PR adds the lets self fix migration command (with dry-run, mixin handling, and deprecation docs) requested in the issue.

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant