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

Syncpack replaces workspace:* with version number #121

Closed
Alxandr opened this issue Feb 16, 2023 · 19 comments
Closed

Syncpack replaces workspace:* with version number #121

Alxandr opened this issue Feb 16, 2023 · 19 comments

Comments

@Alxandr
Copy link

Alxandr commented Feb 16, 2023

Description

After upgrading to syncpack 9.0.2 (from 8.5.14) syncpack has suddenly started replacing my workspace:* versions with the concrete package version, which I do not want. I have workspace: false in the config, but it does not seem to help.

Suggested Solution

Revert this to how it worked in < v9. The workspace:* versions should be kept.

Help Needed

I'm using PNPM workspaces.

@JamieMason
Copy link
Owner

Thanks @Alxandr 👍

@JamieMason
Copy link
Owner

JamieMason commented Feb 16, 2023

I started looking into this @Alxandr but will need some more information from you.

There's a test scenario which shows that this is expected behaviour. Can you tell me a bit more about your setup and the expected and actual behaviour? Then we can figure it out, maybe I've missed something I don't know.

EDIT: If I change the following in the test scenario, the behaviour is the same (workspace: versions are not supported)

{
  path: 'packages/b/package.json',
-  before: mockPackage('b', { deps: ['foo@link:vendor/foo-0.2.0'] }),
+  before: mockPackage('b', { deps: ['foo@workspace:*'] }),
  after: mockPackage('b', { deps: ['foo@0.3.0'] }),
},

EDIT: The workspace dependencyType is confusing, there are some new docs which try to explain it better. Let me know if you have any ideas to try and make this clearer.

@Alxandr
Copy link
Author

Alxandr commented Feb 16, 2023

What I have is the following:

{
  "name": "@namespace/whatever",
  "dependencies": {
    "@namespace/tsconfig": "workspace:*"
  }
}

and I just want to (somehow, I'm OK with having to configure it) have syncpack ignore all dependencies where the version starts with workspace:. That's about it. I'm not entirely sure about how that matches with the deps syntax you use in the tests there. Basically, the idea is that workspace:* is guaranteed to be the correct version, because it uses the exact package version.

@JamieMason
Copy link
Owner

Got you, thanks.

@JamieMason
Copy link
Owner

Hopefully this is fixed by https://github.com/JamieMason/syncpack/releases/tag/9.1.2, please let me know of any problems.

@markmartirosian
Copy link

@JamieMason I think this is happening again

@JamieMason
Copy link
Owner

Thanks @markmartirosian, yeah I've seen this in my own projects too, need to take a look 👍🏻

@webpro
Copy link

webpro commented Jul 18, 2023

Also, when workspace:* is used in each package, list-mismatches reports as if they're not the same.

@webpro
Copy link

webpro commented Jul 19, 2023

Willing to work on it, feel free to close or chime in: #149

@JamieMason
Copy link
Owner

JamieMason commented Jul 19, 2023

Mentioning a fix here from the discussion at #149.

{
  "versionGroups": [
    {
      "packages": ["**"],
      "dependencies": ["each", "package", "name", "developed", "in", "this", "monorepo"],
      "dependencyTypes": ["dev"],
      "pinVersion": "workspace:*"
    }
  ]
}

Whenever a package developed in your monorepo is used in devDependencies, its version will be pinned at workspace:* (if a package didn't use it in the first place, it won't be added).

/cc @nicu-chiciuc (referenced this issue)

@JamieMason
Copy link
Owner

Another problem example here, need a fix and/or improved getting started guides to help with this

MintterHypermedia/mintter@b15c9c9#diff-c94a275588709f8cb5ffda807da029027477098cdb2b8b77a3f8e962290b8202

/cc @burdiyan, apologies I would revert that commit

@apetta
Copy link

apetta commented Sep 9, 2023

Similar problem in yarn workspaces with:
'*' being replaced with version number

@JamieMason
Copy link
Owner

This should be fixed in the next release, but will take a little while as it involves a big overhaul of the internals and tests.

@JamieMason
Copy link
Owner

JamieMason commented Sep 21, 2023

@Alxandr Something I've just realised about your original comment, you mentioned 9.0.2 and workspace: false not working.

Fix 1

That form of config was deprecated in 9.0.0 (instructions in the release notes). If you update your config then you should be able to ignore local dependencies.

Fix 2

Another approach to fixing this is to tell syncpack that you don't want your packages to have identical exact versions (the default) but that local packages should be referenced using "workspace": "*" whenever they're used in say devDependencies.

(By omitting peer and prod for example, any local packages used in those places would continue to be enforced to be identical to the canonical .version property of each local package).

Use the following config to do that:

{
  "versionGroups": [
    {
      "packages": ["**"],
      "dependencies": ["each", "package", "name", "developed", "in", "this", "monorepo"],
      "dependencyTypes": ["dev"],
      "pinVersion": "workspace:*"
    }
  ]
}

#161 will come in the next release to make this easier to manage, so it would become:

{
  "versionGroups": [
    {
      "packages": ["**"],
      "dependencies": ["$LOCAL"],
      "dependencyTypes": ["dev"],
      "pinVersion": "workspace:*"
    }
  ]
}

Summary

If a given monorepo has deeper requirements to it than a monorepo-wide exact version policy, config will be needed to tell syncpack what and where those exceptions to the norm are.

I think this is actually the fix for this issue, as I don't think there is a universal policy which syncpack can adopt which would be suitable for every repo out there. I've gone with an exact single version policy as a sensible default, then the various kinds of version and semver group should allow you to tune various parts of it to suit any custom needs you have.

I will close this issue on that basis, but please continue to ask questions or send suggestions.

I really want to improve the docs and site but first is working on the next release which as mentioned above is a big job. Once done it should make it easier to support other kinds of non-semver versions such as git tags etc, but it'll take a while yet.

Finally

If anyone reading this finds syncpack useful, please tell people about it – it's completely free and has been a ton of work, please help spread the word ❤️ Thanks!

@audunolsen
Copy link

audunolsen commented Sep 22, 2023

Similar problem in yarn workspaces with: '*' being replaced with version number

Is there any existing way to prevent syncpack from editing the version field of local workspace packages?

Just discovered syncpack, amazing work @JamieMason 🔥

EDIT: guess its dependencyTypes

Why does the array entries need to alias names of package.json fields? Makes it a little hard to grok.
Maybe syncpack should support some kind of access control list for dependency types, so that you can deny or allow it to process certain fields.

@JamieMason
Copy link
Owner

JamieMason commented Sep 22, 2023

Thanks @audunolsen.

Is there any existing way to prevent syncpack from editing the version field of local workspace packages?

That's a definite bug, if the version number is eg. * or workspace:* which is higher/newer than the .version of the source package it can end up winning out and replacing the .version, which is obviously something that should never be allowed.

The next release has tests that ensure this will not happen but for now I would go with Fix 1 and basically disable the local dependencyType.

You can do that by not including local in the array:

{
  "dependencyTypes": ["dev", "prod"]
}

Or by excluding it like so: (from syncpack 11.2.1 only)

{
  "dependencyTypes": ["!local"]
}

EDIT: Can you expand on your edit comment? I don't 100% follow you yet.

@audunolsen
Copy link

Why does the array entries need to alias names of package.json fields? Makes it a little hard to grok.
Maybe syncpack should support some kind of access control list for dependency types, so that you can deny or allow it to process certain fields.

Didn't know you could negate/exclude dependency with !, so that part of my edit was covered by your answer.

The first question was about what's the rationale for mapping special keywords to package.json fields? For me it wasn't particularly intuitive understanding e.g. prod meant dependencies. Not really relevant to the thread just curious.

@JamieMason
Copy link
Owner

JamieMason commented Sep 22, 2023

The first question was about what's the rationale for mapping special keywords to package.json fields? For me it wasn't particularly intuitive understanding e.g. prod meant dependencies. Not really relevant to the thread just curious.

It's a good question. They were originally just CLI arguments before the config files were added and looked like this:

# list all the dev and peer dependencies in the monorepo
syncpack list --dev --peer

I thought people would be put off by something like this as being too much to type / not nice to read:

syncpack list --devDependencies --peerDependencies

So it's stuck around from there. I could fairly easily add optional support to also use the long form I guess, to save tripping people up.

@JamieMason
Copy link
Owner

12.0.0-alpha.0 was just released today and with it is an overhaul to the documentation.

There is a new Getting Started guide and Local Package Versions guide which aim to improve understanding around the things we encountered in this issue.

Thanks everyone for your help.

@JamieMason JamieMason unpinned this issue Nov 23, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants