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(versions): preserve semver group rules when fixing mismatches #157

Closed
sgarfinkel opened this issue Aug 22, 2023 · 4 comments
Closed

Comments

@sgarfinkel
Copy link

sgarfinkel commented Aug 22, 2023

Description

Workspace dependencies are always set to the exact version regardless of the existing semver contraints. We use "^x.x.x" for our workspace dependencies to enable npm deduping of the libraries. However, when running syncpack fix-mismatches the exact version is always used.

Suggested Solution

Use the existing semantic versioning scheme for workspace dependencies if one is already set.

Help Needed

This bug only impacts npm fortunately. On other package managers you can use pinVersion: "workspace:^" to workaround this.

@JamieMason
Copy link
Owner

JamieMason commented Aug 23, 2023

Hey @sgarfinkel,
I really need to write or record some kind of tutorial or guide but haven't had the time, let's see if we can figure it out...

I can't see any of your code so this could be wrong, but one idea I have is:

  1. To ensure that ^ is used where you need it to be, define a semver group which applies to where ^ should be used in your project (eg. only devDependencies and/or only specific packages or dependencies etc, whatever your rules are).
  2. Try a same range group which applies only to your workspace packages, using the dependencies property.

Syncpack's default policy is for everything to have exact version numbers which are identical everywhere, but a lot of projects have their own preferences/policies, like for example:

  • production dependencies should always be exact
  • devDependencies should always use ^
  • peerDependencies should always use >= or maybe *

So across a monorepo, any specific dependency (let's say react) could appear in more than one of the above locations – so its version cannot be identical across the entire monorepo – so that's where the need for versionGroups and semverGroups comes in, to tell syncpack what those policies are.

Hopefully this makes sense, like I said I'm flying a bit blind here, please hit me back with some more information 👍🏻

@JamieMason JamieMason changed the title Maintain semver for workspace dependencies How to configure workspace/local dependencies? Aug 23, 2023
@sgarfinkel
Copy link
Author

Hi Jamie, the issue is that I have a mix of semvers, some use ~ to ensure that dependencies remain at a particular version for compatibility reasons. Ideally, I was hoping that I could just run syncpack fix-mismatches and it would maintain the current semver while also synchronizing the dependency version appropriately.

@JamieMason JamieMason changed the title How to configure workspace/local dependencies? feat(versions): preserve semver group rules when fixing mismatches Sep 3, 2023
@JamieMason
Copy link
Owner

I see what you mean now @sgarfinkel, I should hopefully have a fix for this soon.

This is the failing test I've added for what I think this scenario is, let me know if we're not both thinking of the same thing:

describe('when versions are not identical and span multiple semver groups', () => {
  const createProject = () =>
    mockIo({
      '.syncpackrc': {
        semverGroups: [
          {
            dependencies: ['**'],
            dependencyTypes: ['dev'],
            packages: ['**'],
            range: '^',
          },
        ],
      },
      'package.json': {
        name: 'a',
        dependencies: { foo: '0.3.0' },
      },
      'packages/b/package.json': {
        name: 'b',
        devDependencies: { foo: '^0.3.0' },
      },
    });

  describe('fix-mismatches', () => {
    it('considers them valid because the version number matches and the ranges are correct for each dependency type', () => {
      const project = createProject();
      Effect.runSyncExit(fixMismatches(project.io, {}));
      const filesByPath: any = project.readAllPackageJsonSync();
      expect(filesByPath['a'].dependencies.foo).toEqual('0.3.0');
      expect(filesByPath['b'].devDependencies.foo).toEqual('^0.3.0');
      expect(project.io.process.exit).not.toHaveBeenCalled();
      project.tearDown();
    });
  });
});

@JamieMason JamieMason pinned this issue Sep 13, 2023
JamieMason added a commit that referenced this issue Nov 5, 2023
This is the biggest syncpack release to date and has taken a couple of months to complete. There will be other improvements and bug fixes which I've lost track of along the way and are not listed here. The tests have been rewritten to be easier to maintain and bugs were found along the way there.

Given the scale of the changes, this is an alpha release. Please give it a try in a local branch and [submit an issue](https://github.com/JamieMason/syncpack/issues/new/choose) if you find any problems.

There is also a brand new [Getting Started](https://jamiemason.github.io/syncpack/guide/getting-started) guide which I encourage you to read.

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!

## Bug Fixes

- **npm:** update dependencies

## Features

- **cli:** display an error code/reason for every kind of mismatch
- **cli:** output a count of ignored instances
- **docs:** huge [documentation](https://jamiemason.github.io/syncpack/guide/getting-started) overhaul
- **groups:** add support for `$LOCAL` keyword in config, Closes #161
- **groups:** allow `dependencies: ["**"]` and `packages: ["**"]` to be omitted
- **list:** add usage count next to each dependency in `syncpack list`, Closes #162
- **options:** add support for `--indent ‘\t’`
- **update:** group and filter npm updates by major, minor, patch etc
- **update:** show more information while querying npm for updates
- **versions:** add support for `workspace:~` and `workspace:*`
- **versions:** preserve semver group rules when fixing mismatches, Closes #157
- **versions:** support `npm:foo@0.1.0`
- **versions:** support semver boundaries `>=1.0.0 <=3.0.0`
- **versions:** support semver git tags `git://github.com/user/project.git#0.3.0`
- **versions:** support semver tags `4.0.0-alpha.61`

## Breaking Changes

1. `semverRange` has been deprecated in config files, if you'd like to define a global policy for semver ranges you can achieve this with a semver group.

   ```diff
   {
   -  "semverRange": "^",
   +  "semverGroups": [{ "range": "^" }]
   }
   ```

1. There is no longer a default Semver Group. By default, version mismatches will be fixed while leaving the semver ranges as they were. This is intended to make it easier for new users to onboard, but it is recommended that you define Semver Groups yourself which match your project's requirements.

   See the [Getting Started](https://jamiemason.github.io/syncpack/guide/getting-started) guide for a walkthrough on this.
@JamieMason
Copy link
Owner

Released in 12.0.0-alpha.0

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

2 participants