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

[QUESTION] How to increment a version with a prefix / range in the dependency string #343

Closed
soundstep opened this issue Sep 18, 2020 · 1 comment

Comments

@soundstep
Copy link

soundstep commented Sep 18, 2020

What / Why

What would be the best approach to increment the version of a dependency.
Some libraries are doing this writing their own string parser, like https://github.com/raineorshine/npm-check-updates

I'm writing a CLI for a monorepo that bumps version, and possibly change versions specified as dependencies.

If I'm parsing a package.json and find that kind of string for a dependency:

{
  "dependency": {
    "my-package-1": "^1.0.0",
    "my-package-2": "~1.0.0",
    "my-package-3": ">=1.0.0",

What would be the best way to change this string:

>=1.0.0

to:

>=1.0.1

I tried a few things like:

semver.inc('>=1.0.0', patch);

But that doesn't work. I also tried to find a way to extract the version from the range but didn't find anything. I suppose I would need something like:

const extracted = semver.extract('>=1.0.0');
console.log(extracted.version); // 1.0.0
console.log(extracted.range); // >=

I'm kinda guessing that this would be hard with some ranges like "1.0.x"?

lerna version --exact is somewhat close because they use npm version --save-prefix but that's for the versions themselves, not the dependency ranges.

npm-check-update do that writing their own parser.

Any advice?

Update:

I'm still after a lighter solution, until then I will use the npm-check-updates cli:

ncu my-package --dep prod,dev --target patch

Another solution with a slightly updated regex from:

https://gist.github.com/jhorsman/62eeea161a13b80e39f5249281e17c39
#32

/(.*)([0-9]+\.[0-9]+\.[0-9])+(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z-]+)?$/g

And another one:

https://regex101.com/r/Ly7O1x/196

Converted to:

/^(=|>=|<=|=>|=<|>|<|!=|~|~>|\^)?(0|[1-9]\d*)\.?(0|[1-9]\d*)\.?(0|[1-9]\d*)(?:-?((?:[0-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+?([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/g

Where

In a private monorepo context

References

Originally posted there:
semver/semver#613

@soundstep soundstep changed the title [QUESTION] <title> [QUESTION] How to increment a version with a prefix / range in the dependency string Sep 18, 2020
@lukekarrys
Copy link
Contributor

You should be able to parse those ranges and then examine the sets of comparators inside the range. Here's an example of the internals of Range.set:

new semver.Range('^1.0.0').set

[
  [
    Comparator {
      options: {},
      loose: false,
      operator: '>=',
      semver: SemVer {
        options: {},
        loose: false,
        includePrerelease: false,
        raw: '1.0.0',
        major: 1,
        minor: 0,
        patch: 0,
        prerelease: [],
        build: [],
        version: '1.0.0'
      },
      value: '>=1.0.0'
    },
    Comparator {
      options: {},
      loose: false,
      operator: '<',
      semver: SemVer {
        options: {},
        loose: false,
        includePrerelease: false,
        raw: '2.0.0-0',
        major: 2,
        minor: 0,
        patch: 0,
        prerelease: [Array],
        build: [],
        version: '2.0.0-0'
      },
      value: '<2.0.0-0'
    }
  ]
]

So to use your initial example, here is how you could accomplish that.

const comparator = new semver.Range('^1.0.0').set[0][0]
const incRange = comparator.operator + semver.inc(comparator.semver.version, 'patch')
// >=1.0.1

It should be noted that this is reaching into the internal implementation, so this is not 100% guaranteed against breaking changes. See this thread for more details on past changes here and their effects: #323 (comment).

There was discussion of a more solid API for this, but that was never implemented. This current workaround should work for your stated use case, but might not be feasible for more complex ranges.

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

No branches or pull requests

2 participants