Skip to content

Commit d8395ea

Browse files
rally25rscpojer
authored andcommitted
Finish upgrade command consistency (#77)
* Add rfc for upgrade command consistency * moved upgrade-command-consistency to implemented
1 parent 6bf9cd7 commit d8395ea

File tree

2 files changed

+142
-0
lines changed

2 files changed

+142
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
- Start Date: 2017-06-21
2+
- RFC PR: https://github.com/yarnpkg/yarn/pull/3847
3+
- Yarn Issue: https://github.com/yarnpkg/yarn/issues/3603
4+
5+
# Summary
6+
7+
Spawned from https://github.com/yarnpkg/yarn/issues/3603
8+
9+
There is a lot of confusion among new users of Yarn as to how the `upgrade` and `upgrade-interactive` commands work.
10+
11+
A lot of that confusion is due to those commands not working the same way (nor are they implemented the same).
12+
13+
The purpose of this RFC is to align those commands, and begin to share implementation between them.
14+
15+
# Motivation
16+
17+
## Currently (yarn <=0.26):
18+
19+
`upgrade` = upgrade all packages to their latest version, **respecting** the range in `package.json`
20+
`upgrade left-pad` = upgrade only the left-pad package to it's `latest` tag, **ignoring** the range in `package.json`
21+
`upgrade-interactive` = upgrade all packages to their `latest` tag, **ignoring** the range in `package.json`
22+
23+
It is very confusing that `upgrade` vs `upgrade-interactive` chose different versions, and `upgrade` vs `upgrade {package}` chose different versions.
24+
25+
# Detailed design
26+
27+
Major design ideas:
28+
29+
1. `upgrade-interactive` should just be an "interactive" version of `upgrade`.
30+
2. Both commands should respect the package.json semver range by default.
31+
2. PR #3510 added a `--latest` flag to `upgrade` to tell it to ignore package.json range. Utilize this change across both commands to have them ignore package.json range and use `latest` tag instead.
32+
33+
## New Logic:
34+
35+
* Leave upgrade with no additional parameters how it is:
36+
> yarn upgrade
37+
>
38+
> This command updates all dependencies to their latest version based on the version range specified in the package.json file.
39+
40+
* Change passing a package without an explicit version to respect package.json
41+
> yarn upgrade [package]
42+
>
43+
> This upgrades a single named package to the latest version based on the version range specified in the package.json file.
44+
45+
* Leave handling an explicit version the same as how it is
46+
> yarn upgrade [package@version]
47+
>
48+
> This will upgrade (or downgrade) an installed package to the specified version. You can use any SemVer version number or range.
49+
50+
* Utilize the --latest flag from PR #3510 for an upgrade without a specific package, and add it to the docs
51+
> yarn upgrade --latest
52+
>
53+
> This command updates all dependencies to the version specified by the latest tag (potentially upgrading the package across major versions).
54+
55+
* Utilize the --latest flag from PR #3510 for an upgrade with a specific package, and add it to the docs
56+
> yarn upgrade [package] --latest
57+
>
58+
> This upgrades a single named package to the version specified by the latest tag (potentially upgrading the package across major versions).
59+
60+
For `upgrade-interactive` it would internally just call the `upgrade` logic to follow the same rules above, but would then present the list of packages to the user for them to chose which to upgrade. The exception is that `upgrade-interactive` does not have the ability to take specific package names in its parameters (because the user would chose them from the interactive selection list instead of specifying them on the cmd line)
61+
62+
63+
## Implementation Details
64+
65+
Currently, `upgrade` reads all packages and ranges from package.json and forwards them to `add`. `upgrade-interactive` is implemented differently; it uses `PackageRequest.getOutdatedPackages()` to determine only the packages that are out of date, and what version they would update to.
66+
67+
As part of this work, the upgrade-interactive logic to use `getOutdatedPackages` would be moved over to `upgrade`.
68+
69+
`PackageRequest.getOutdatedPackages()` already reports the "wanted" (latest respecting package.json specified range) and the "latest" (latest specified by registry, ignoring package.json) versions for all outdated packages. `upgrade` would look for the `--latest` flag to decide which of these version to upgrade each package to.
70+
71+
The `upgrade-interactive` command's output will include an additional column named "range". This column will show what the current package.json specified range is. If the `--latest` flag is passed, then the word "latest" will be displayed. In other words, this column is showing the range specifier that upgrade is using to determine what to upgrade to.
72+
73+
example:
74+
75+
```
76+
dependencies
77+
name range from to url
78+
❯◯ chai ^3.0.0 3.4.0 ❯ 3.5.8 http://chaijs.com
79+
```
80+
81+
Which indicates "You have chai@^3.0.0 as a dependency. Currently 3.4.0 is installed. Upgrade will move to 3.5.8"
82+
83+
or when using the --latest flag:
84+
85+
```
86+
dependencies
87+
name range from to url
88+
❯◯ chai latest 3.4.0 ❯ 4.0.2 http://chaijs.com
89+
```
90+
91+
The goal here is to better explain to the user why this version was selected to upgrade to.
92+
93+
94+
## Preserve package.json range operator
95+
96+
Related to #2367 and #3609 there have been requests that `upgrade` and `upgrade-interactive` when upgrading to a new major version will preserve the `package.json` specified version range, if it exists.
97+
98+
So for example if package.json specifies the dependency
99+
100+
```
101+
"foo": "~0.1.2",
102+
"bar": "^1.2.3",
103+
"baz": "2.3.4"
104+
```
105+
106+
Then if `upgrade --latest` jumps to a new major version, it will preserve the range specifiers, and upgrade to something like:
107+
108+
```
109+
"foo": "~5.0.0",
110+
"bar": "^6.0.0",
111+
"baz": "7.0.0"
112+
```
113+
114+
(with the current implementation, all 3 packags would be changed to use caret `@^x.x.x`)
115+
116+
* This only has an affect when `--latest` is specified, otherwise package.json file would not be modified.
117+
118+
* This only works for simple range operators (exact, ^, ~, =, <=, >). Complex operators are not handled. When a range operator is not one of these simple cases, `^` will be used as the default., since that is the normal range operator when adding a package the first time.
119+
120+
* This behavior is overriden by the following flags: `--caret` `--tilde` `--exact`. If any of these are passed, then that range operator will always be used.
121+
122+
123+
# How We Teach This
124+
125+
Docs will need to be updated to reflect these changes.
126+
127+
128+
# Drawbacks
129+
130+
This is a change to the version ranges selected by `upgrade-interactive` so could cause additional confusion to those who use it in previous Yarn versions.
131+
132+
However, I beleive that overall it would reduce the confusion between these commands, and make them overall more versitile.
133+
134+
135+
# Alternatives
136+
137+
Do not change the behavior. Deal with user confusion and issues that arrise from it as they come up.
138+
139+
140+
# Unresolved questions
141+
142+
None at this time.

0 commit comments

Comments
 (0)