Skip to content
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

feat: migration command #5506

Merged
merged 30 commits into from
Mar 10, 2025
Merged

feat: migration command #5506

merged 30 commits into from
Mar 10, 2025

Conversation

ldez
Copy link
Member

@ldez ldez commented Mar 5, 2025

I want to explain my journey on this topic because it was not an easy one.

My first thought was to try to keep comments by using several YAML parsing libs, but it was very complex, only for YAML (we should handle YAML, TOML, JSON), and at the end it was not working mainly due to the migration path of some elements.

So I gave up on migrating the comments.

I tried to use the v2 configuration structures directly, but it's not possible to serialize the configuration as expected (even with additional struct tags), mainly because of default non-zero values (e.g. boolean true by default, explicit 0 or false, ...). So it didn't work.

My next try was the working solution: using a clone of the v2 configuration that uses pointer for builtin types and struct tags.

I created a "cloner" which clones the v2 configuration structures (only) and modifies them by changing types and adds struct tags.
So the "cloned" configuration structures can be recreated if needed (make clone_config).

The solution is stable, maintainable, and tested, but I'm sad that I couldn't find a solution to keep the comments.

The migration file format is based on the extension of the configuration file.
The format can be overridden by using --format flag. (ex: golangci-lint migrate --format yml)

Before the migration, the previous configuration file is copied and saved to a file named <config_file_name>.bck.<config_file_extention>.

By default, before the migration process the configuration file is validated on the JSONSchema of the configuration v1.
If you want to skip this validation, you can use --skip-validation. (ex: golangci-lint migrate --skip-validation)

Some notable elements

The migration command also enforced some new default values:

  • run.timeout: the existing value is ignored, because, in v2, by default, there is no timeout.
  • issues.show-stats: the existing value is ignored, in v2, by default, the stats are enabled.
  • run.concurrency: if the existing value was 0, as it's the new default, the key is removed.
  • run.relative-path-mode: if the existing value was cfg, as it's the new default, the key is removed.

issues.exclude-generated has a new default value (v1 lax, v2 strict), then this field will be added during the migration to keep the previous behavior.

issues.exclude-dirs-use-default has been removed, so this is converted to linters.exclusions.paths and, if needed, formatters.exclusions.paths.

Deprecated options from the v1 or unknown fields are not migrated.

Other fields, which are explicitly defined in the configuration file, are migrated even if the value is the same as the default value.

A migration guide will be added to the documentation #5439

I created more than 150 test configuration files, and added dedicated tests on complex migration paths.

The command documentation will be added to the migration guide.

Migrate configuration file from v1 to v2

Usage:
  golangci-lint migrate [flags]

Flags:
  -c, --config PATH       Read config from file path PATH
      --no-config         Don't read config file
      --format string     By default, the file format is based on the configuration file extension.
                          Overrides file format detection.
                          It can be 'yml', 'yaml', 'toml', 'json'.
      --skip-validation   Skip validating the configuration file against the JSON schema of the v1.

Global Flags:
  -h, --help           Help for a command

@ldez ldez added enhancement New feature or improvement area: CLI Related to CLI labels Mar 5, 2025
@ldez ldez added this to the v2-unreleased milestone Mar 5, 2025
@ldez ldez requested review from alexandear and bombsimon March 5, 2025 16:48
Copy link
Member

@bombsimon bombsimon left a comment

Choose a reason for hiding this comment

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

Nice!! I've yet to review the individual migrations but everything else looks great! I don't think there's much to add for the rest of the code given all the tests but I saw you did a great job on documenting all permutations of enabled and disabled linters that I plan to give an extra read.

🔥

@ldez ldez force-pushed the feat/migration-cmd branch from 39a9e2e to ca11e3e Compare March 5, 2025 22:53
Copy link
Member

@alexandear alexandear left a comment

Choose a reason for hiding this comment

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

Awesome work.

Left some comments.

Will take a look again later today, still need to review few files.

@ldez ldez force-pushed the feat/migration-cmd branch from 07a3dc8 to 8a3fbff Compare March 6, 2025 14:14
Copy link
Member

@bombsimon bombsimon left a comment

Choose a reason for hiding this comment

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

Awesome, LGTM

@ldez ldez requested a review from alexandear March 7, 2025 15:26
@SuperSandro2000
Copy link
Contributor

Did you think about using the new omitzero tag from go 1.24?

We used that in https://github.com/majewsky/gg . See sapcc/keppel#489 as an example where we used it.

@ldez
Copy link
Member Author

ldez commented Mar 7, 2025

Did you think about using the new omitzero tag from go 1.24?

Yes, but:

  1. We need to compile with go1.23
  2. it doesn't solve default non-zero value (true, 8, etc.)
  3. my implementation is simple, no plumbing

@ldez ldez force-pushed the feat/migration-cmd branch from 8cefc9d to fdf27fc Compare March 8, 2025 12:19
@ldez ldez force-pushed the feat/migration-cmd branch from 1882036 to e809f59 Compare March 8, 2025 17:52
@ldez ldez force-pushed the feat/migration-cmd branch from c0142fe to d35e0d4 Compare March 10, 2025 00:42
@ldez ldez merged commit 6a37088 into golangci:main Mar 10, 2025
18 checks passed
@ldez ldez deleted the feat/migration-cmd branch March 10, 2025 13:31
@busser busser mentioned this pull request Mar 14, 2025
Closed
@ldez ldez modified the milestones: v2-unreleased, v2 Mar 24, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: CLI Related to CLI area: migration enhancement New feature or improvement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants