syncpack icon indicating copy to clipboard operation
syncpack copied to clipboard

feat(groups): add `sameMajor` and `sameMinor` policies

Open nwidynski opened this issue 9 months ago • 7 comments

Description

Our team would love to enforce version range locks for related dependencies, e.g. nx, @nx/*, to ensure these packages are maintained in sync. This shall apply even inside a single package.json, not only across projects.

Example: <root>/.syncpackrc

"versionGroups": [
    {
      "label": "Nx Version Group",
      "dependencies": ["nx", "@nx/*"],
      "policy": "strict"
    }
]

❌ Bad (<root>/package.json)

"devDependencies": {
  "@nx/devkit": "20.8.0",
  "nx": "20.9.0"
}

✅ Good (<root>/package.json)

"devDependencies": {
  "@nx/devkit": "20.9.0",
  "nx": "20.9.0"
}

Suggested Solution

Maybe this feature is already covered by policy: "sameRange", but at least it currently does not apply for mismatches within the root package.json.

Optional comments

No response

Code of Conduct

nwidynski avatar Apr 27 '25 12:04 nwidynski

Hey @nwidynski, this landed in #204 but I'm really behind on updating the website.

This should be what you need in your config file, there is a fairly new addition called "dependencyGroups" (rather than "versionGroups") which lets us merge/alias many dependencies together.

{
  "dependencyGroups": [
    {
      // the dependencies to group together
      "dependencies": ["@nx/**", "nx"],
      // (optional) omit if not needed
      "dependencyTypes": ["**"], 
      // (optional) omit if not needed
      "specifierTypes": ["**"], 
      // (optional) omit if not needed
      "packages": ["**"], 
      // (required) name to use when displaying log output. 
      "aliasName": "all-nx-dependencies",
    }
  ]
}

You can do whatever else you want with these dependencies, but they will be treated as if they are all instances of one dependency called "all-nx-dependencies" and the terninal output will show a (aliased) hint next to them.

JamieMason avatar Apr 27 '25 13:04 JamieMason

I should mention, this is in v14 alpha and not v13

JamieMason avatar Apr 27 '25 13:04 JamieMason

@JamieMason Awesome, we aren't ready just yet to switch to v14 due to lack of list-mismatches. Also does this support sameRange policy? Some dependencies are related but not for an exact version match, for example node in engines and @types/node differing only by patch release version.

nwidynski avatar Apr 27 '25 13:04 nwidynski

  1. schema.json is at eg https://www.unpkg.com/[email protected]/schema.json but I do need to check it's up to date.
  2. (Again, not documented yet but) syncpack list-mismatches is basically now syncpack lint, which no longer outputs valid instances, only errors if there are any.
  3. The sameRange policy should work the same in v14 and v13, yes. If you were asking if your nx alias will also work with them it will do yes, it'll be treated as if it was one normal dependency.

JamieMason avatar Apr 27 '25 14:04 JamieMason

@JamieMason That looks great, just upgraded 👍

As far as 3.) was concerned, i was asking whether its possible to relax the version matching within a group to allow for patch version mismatches, e.g. [email protected] but @nx/[email protected]. I was also wondering whether customTypes are considered for dependencyGroups in order to make it possible to keep @types/node in sync with engines.node.

nwidynski avatar Apr 27 '25 15:04 nwidynski

It's not possible right now, but maybe some kind of sameMajor and sameMinor policy could be added that would do that.

JamieMason avatar Apr 27 '25 16:04 JamieMason

I was also wondering whether customTypes are considered for dependencyGroups in order to make it possible to keep @types/node in sync with engines.node.

I missed this question. Yes that all works - instances which are discovered by a custom type can be used in dependencyGroups.

JamieMason avatar Apr 28 '25 07:04 JamieMason

Same exact situation here with Nx. I thought "sameRange" would mean "same exact range specified in package.json", but syncpack is failing to sync @nx/js: 21.4.0 with nx: 21.4.1, showing no errors.

My config is:

"versionGroups": [
    {
      "dependencies": ["nx", "@nx/*"],
      "policy": "sameRange"
    }
]

fregante avatar Aug 24 '25 04:08 fregante

Thanks @fregante, the docs for sameRange are here.

This issue will add something like sameMajor and sameMinor policies.

JamieMason avatar Aug 24 '25 04:08 JamieMason

My issue is identical as OP's, how you decide to fix it is not relevant. sameRange does not work the way I expect it to in this case.

ensure that all versions have semver ranges which all satisfy each other, instead of having to be identical.

That's not happening. My version is strictly 21.4.0 in one and 21.4.1 in the other. The ranges do not match, but syncpack is not reporting them.

fregante avatar Aug 24 '25 05:08 fregante

My issue is identical as OP's, how you decide to fix it is not relevant.

I use GitHub issues to help me understand problems and decide how to fix them. From my perspective the entire point of this issue is to help me decide how to fix it, and to communicate what will happen.

You might do things differently in your projects and that's ok.

sameRange does not work the way I expect it to

I sensed that, which is why I shared the docs. I'm trying to help you, maybe the doc needs improving, ok, I'll look for ways to do that.

That's not happening. My version is strictly 21.4.0 in one and 21.4.1 in the other. The ranges do not match, but syncpack is not reporting them.

If you want these to match like the OP did in https://github.com/JamieMason/syncpack/issues/280#issuecomment-2833511914 then the sameMajor and sameMinor policies would ~report~ (EDIT: consider those valid).

If you want something else than that, please can you open a new issue so I can focus properly on this issue, while also helping you with yours? Does that sound fair?

For sameRange, two exact versions do not satisfy eachother because they are mutually exclusive.

JamieMason avatar Aug 24 '25 05:08 JamieMason

For sameRange, two exact versions do not satisfy eachother because they are mutually exclusive.

Correct, we agree on this, so why isn't syncpack warning that they're not the same range?

fregante avatar Aug 24 '25 06:08 fregante

For sameRange, two exact versions do not satisfy eachother because they are mutually exclusive.

Correct, we agree on this, so why isn't syncpack warning that they're not the same range?

I don't know, I need to see your config, what version of syncpack you're using etc. Please open a new issue

JamieMason avatar Aug 24 '25 07:08 JamieMason

A new sameMinor policy is available in 14.0.0-alpha.23.

@nwidynski, this is new so there may be some snags, but I think something like the following should offer what you need:

{
  "dependencyGroups": [
    {
      "label": "Treat all nx dependencies as one",
      "dependencies": ["@nx/**", "nx"],
      "aliasName": "all-nx-dependencies"
    }
  ],
  "versionGroups": [
    {
      "label": "Allow patch versions of nx dependencies to diverge",
      "dependencies": ["all-nx-dependencies"],
      "policy": "sameMinor"
    }
  ]
}

JamieMason avatar Sep 29 '25 22:09 JamieMason

@JamieMason Works great!

nwidynski avatar Oct 10 '25 21:10 nwidynski