yarnpkg / yarn

The 1.x line is frozen - features and bugfixes now happen on https://github.com/yarnpkg/berry
https://classic.yarnpkg.com
Other
41.41k stars 2.72k forks source link

`yarn upgrade --latest` not upgrading packages with *-beta.* version names #5393

Open riwu opened 6 years ago

riwu commented 6 years ago

Do you want to request a feature or report a bug?

Bug

What is the current behavior?

yarn upgrade --latest does not upgrade packages with non-numerics in version names.

If the current behavior is a bug, please provide the steps to reproduce.

package.json:

  "dependencies": {
    "axios": "^0.17.1",
    "react-native-router-flux": "^4.0.0-beta.24"
  }

Run yarn upgrade --latest

axios gets upgraded to ^0.18.0 but react-native-router-flux does not get upgraded to v4.0.0-beta.28 (yarn upgrade react-native-router-flux@latest does).

I believe this applies to all packages with non-numerics in minor version, eg. "@babel/cli": "^7.0.0-beta.35"

Please mention your node.js, yarn and operating system version.

node: v9.3.0 yarn: v1.3.2 OS: macOS Sierra 10.12.6

rally25rs commented 6 years ago

This seemed to work OK for me.

~/Projects/yarn-test 🐒   yarn init -y
yarn init v1.3.2
warning The yes flag has been set. This will automatically answer yes to all questions which may have security implications.
success Saved package.json
✨  Done in 0.03s.

~/Projects/yarn-test 🐒   yarn add react-native-router-flux@4.0.0-beta.24
yarn add v1.3.2
info No lockfile found.
...output omitted...
✨  Done in 3.47s.

~/Projects/yarn-test 🐒   grep version node_modules/react-native-router-flux/package.json
  "version": "4.0.0-beta.24",

~/Projects/yarn-test 🐒   yarn upgrade --latest
yarn upgrade v1.3.2
...output omitted...
✨  Done in 2.77s.

~/Projects/yarn-test 🐒   grep version node_modules/react-native-router-flux/package.json
  "version": "4.0.0-beta.28",

Maybe I missed something? I tried it with and without a leading ^ on the original version (beta.24) as well.

rally25rs commented 6 years ago

I tried it without --latest as well:

~/Projects/yarn-test 🐒   cat package.json
{
  "name": "yarn-test",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "dependencies": {
    "react-native-router-flux": "^4.0.0-beta.24"
  }
}

~/Projects/yarn-test 🐒   grep version node_modules/react-native-router-flux/package.json
  "version": "4.0.0-beta.24",

~/Projects/yarn-test 🐒   yarn upgrade
yarn upgrade v1.3.2
...output omitted...
✨  Done in 1.91s.

~/Projects/yarn-test 🐒   grep version node_modules/react-native-router-flux/package.json
  "version": "4.0.0-beta.28",
riwu commented 6 years ago

Can you try it with ^ and grep react-native-router-flux package.json?

I just tested it again, node_modules gets updated but not package.json. package.json only gets updated without ^.

rally25rs commented 6 years ago

Without --latest package.json is never updated (because there is nothing to update. the new version will match the semver range).

With --latest package.json will be updated (if there was an update needed. If the current is already up to date then the package.json update is skipped).

~/Projects/yarn-test 🐒   cat package.json
{
  "name": "yarn-test",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "dependencies": {
    "react-native-router-flux": "^4.0.0-beta.24"
  }
}

~/Projects/yarn-test 🐒   yarn upgrade --latest
yarn upgrade v1.3.2
...output omitted...

~/Projects/yarn-test 🐒   cat package.json
{
  "name": "yarn-test",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "dependencies": {
    "react-native-router-flux": "^4.0.0-beta.28"
  }
}

It gets a little weird if you run yarn upgrade first, then yarn upgrade --latest because the first upgrade would install beta.28 but not update package.json (yarn.lock would be updated to beta.28). The second upgrade would then just exit immediately because no packages are out of date, and package.json wouldn't be altered. Though in both cases it's valid if looking at it from the mindset of "package.json is the set of ranges I will allow" and "yarn.lock is the exact locked version". (yarn.lock is the important update, not necessarily package.json.)

riwu commented 6 years ago

Here's the output when I run it with yarn 1.3.2 on both Mac and Linux:

yarn-test$ yarn add react-native-router-flux@^4.0.0-beta.24
...output omitted...
yarn-test$ grep version node_modules/react-native-router-flux/package.json
  "version": "4.0.0-beta.28",
yarn-test$ grep react-native-router-flux package.json
    "react-native-router-flux": "^4.0.0-beta.24"
yarn-test$ yarn upgrade --latest
...output omitted...
yarn-test$ grep react-native-router-flux package.json
    "react-native-router-flux": "^4.0.0-beta.24"

2 problems here:

  1. yarn add react-native-router-flux@^4.0.0-beta.24 installed .28 in node_modules. This is resolved if i run yarn cache clean first.
  2. yarn upgrade --latest is not updating package.json. I'm not sure why this is not replicated on your side...perhaps someone else with different environments can try it?

yarn.lock after yarn upgrade --latest:

react-native-router-flux@^4.0.0-beta.24:
  version "4.0.0-beta.28"
  resolved "https://registry.yarnpkg.com/react-native-router-flux/-/react-native-router-flux-4.0.0-beta.28.tgz#1d39cf176c88d0658af03cfa80dfb4a8eb284619"
  dependencies:
    lodash.isequal "^4.5.0"
    mobx "^3.3.1"
    mobx-react "^4.3.4"
    opencollective "^1.0.3"
    path-to-regexp "^2.1.0"
    prop-types "^15.6.0"
    react-navigation "1.0.0-beta.22"
rally25rs commented 6 years ago

Based on your output:

yarn-test$ yarn add react-native-router-flux@^4.0.0-beta.24
...output omitted...
yarn-test$ grep version node_modules/react-native-router-flux/package.json
  "version": "4.0.0-beta.28",

This is correct so far. You asked it to install the newest version matching ^4.0.0-beta.24 which is 4.0.0-beta.28 so that version was installed. In other words, 4.0.0-beta.28 is the newest version that satisfies the range ^4.0.0-beta.24

yarn-test$ grep react-native-router-flux package.json
    "react-native-router-flux": "^4.0.0-beta.24"

This is also correct. It recorded the range that you specified from the add command in package.json.

yarn-test$ yarn upgrade --latest
...output omitted...
yarn-test$ grep react-native-router-flux package.json
    "react-native-router-flux": "^4.0.0-beta.24"

So this part is debatably correct or incorrect, based on my previous comment about "sometimes" updating package.json. What's happening here is that you requested an upgrade of that package, yarn says "beta.28 is the latest according to the registry. beta.28 is already installed. I'll just exit (skipping the package.json update)" Could it / should it change package.json to .28? Maybe. It's a bit of undefined territory. I could see an argument for either case. Do I think not updating it completely breaks yarn? not really. You still get the right version installed either way, and the currently installed version fits the specified range (assuming your lock file isn't deleted). However if someone submitted a PR that always updated package.json when --latest was run, I would approve it. Actually even if your lock file was deleted it wouldn't change the version that would be installed, so functionally it doesn't really matter is package.json says ^4.0.0-beta.24 or ^4.0.0-beta.28, you will get beta.28 on install (as long as that remains the latest version)

Hopefully that helps explain what yarn is doing in this scenario...

riwu commented 6 years ago

Thanks for the explanation!

I think it should definitely change package.json to .28.

If I look at package.json and see .24, the package in my node_modules could either be:

  1. .24 if I installed it before .25 is released.
  2. anywhere from .25 to the acceptable range if I installed it after the newer versions were released.

While I agree that it's not huge issue, it'd be much preferable for package.json to specify the exact versions currently installed in node_modules instead of having to run additional commands to confirm, especially when we explicitly execute yarn upgrade.

riwu commented 6 years ago

~/Projects/yarn-test 🐒 cat package.json { "name": "yarn-test", "version": "1.0.0", "main": "index.js", "license": "MIT", "dependencies": { "react-native-router-flux": "^4.0.0-beta.24" } }

~/Projects/yarn-test 🐒 yarn upgrade --latest yarn upgrade v1.3.2 ...output omitted...

~/Projects/yarn-test 🐒 cat package.json { "name": "yarn-test", "version": "1.0.0", "main": "index.js", "license": "MIT", "dependencies": { "react-native-router-flux": "^4.0.0-beta.28" } }

I still don't understand how you managed to get the above output. When you run the first command above (cat package.json), the react-native-router-flux in your node_modules will already be at .28, so yarn upgrade --latest shouldn't change the package.json in our current behavior?

rally25rs commented 6 years ago

I think in that particular example I faked it a bit so that upgrade would actually do something. I think I actually started with yarn add react-native-router-flux@4.0.0-beta.24 then manually edited package.json and yarn.lock to add the ^, which would reproduce the scenario where beta.24 was the latest at the time it was added, and now beta.28 has become available. Basically just trying to simulate the actual case. Sorry for the confusion.

Based on your comment:

it'd be much preferable for package.json to specify the exact versions currently installed in node_modules

I think you might be mistaking the version in package.json to mean "the version that is installed", which it is not. It really just specifies "an acceptable range of version that I am OK with installing". yarn.lock on the other hand specifies "the exact installed version" which I think is what you are expecting to see.

So if right now I run yarn add react-native-router-flux@^4.0.0-beta.24 what I'm saying is:

this project has a dependency on react-native-router-flux, and will accept and be compatible with any version that is >=4.0.0-beta.24 and <5.0.0

then yarn will install the newest version to satisfy that range, which is beta.28. So immediately after add package.json contains ^4.0.0-beta.24 (caret range) and node_modules contains 4.0.0-beta.28 and yarn.lock contains 4.0.0-beta.28 (exact version, not a range).

riwu commented 6 years ago

I understand that the current behavior might be the "intended" behavior. I'm suggesting that altering package.json might be a better behavior since package.json can provide a quick/convenient reference of not just the acceptable range, but the exact versions currently installed as well.

Perhaps add a flag or config to optionally allow this behavior, so that we can have the best of both worlds?

I'm no expert in theories of package manager though, so go ahead and close this if you think this behavior is an unnecessary complication. At least I understand the current behavior now, thanks!

strobox commented 5 years ago

It is strange. Why not upgrade alpha beta

damianobarbati commented 5 years ago

Yeah, broken for me too: latest should follow the currently installed channel (alpha, beta or whatever).