Skip to content

Commit

Permalink
Merge pull request #50 from mydea/fn/update-all
Browse files Browse the repository at this point in the history
feat: Add `--all-dependencies` and `--all-dev-dependencies`
  • Loading branch information
mydea authored Nov 30, 2021
2 parents 4e3c099 + 5642f8b commit 1c3b0e5
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 33 deletions.
56 changes: 29 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ Update a yarn dependency across a project/workspace & sub-dependencies.

```bash
yu my-dependency 0.5.1 # my-dependency@~0.5.1
yu my-dependency 0.5.1 --exact # [email protected]
yu my-dependency 0.5.1 --caret # my-dependency@^0.5.1
yu my-dependency ^0.5.1 # my-dependency@^0.5.1 (no matter if it used to be caret or tilde)
yu my-dependency ~0.5.1 # my-dependency@^0.5.1 (no matter if it used to be caret or tilde)
yu my-dependency # update to current latest version
yu --all-dependencies # update all `dependencies` to the latest version
yu --all-dev-dependencies # update all `devDependencies` to the latest version
yu -h # Output all available options
```

Expand All @@ -22,44 +24,44 @@ yarn global add yarn-update-dependency

Running this command will:

* Update the specified package to the specified version in the `package.json`
* If run inside of a Yarn Workspace, it will also update all `package.json` in all workspace packages to the same version.
* It will then remove all entries for this package from the `yarn.lock` file
* Finally, it will run `yarn install` to update the dependencies
- Update the specified package to the specified version in the `package.json`
- If run inside of a Yarn Workspace, it will also update all `package.json` in all workspace packages to the same version.
- It will then remove all entries for this package from the `yarn.lock` file
- Finally, it will run `yarn install` to update the dependencies

## Why do I need this?

This package solves two problems.
This package solves two problems.

First, it can be annoying to keep a dependency in sync in a Yarn Workspace. You'll often want to have the same dependency of a package in all workspace packages, which requires you to manually keep this in sync everywhere. With the help of `yu`, the version will be the same in all workspace packages.

Second, it can be tricky to actually update a specific version in Yarn. Just updating the version in the `package.json` and running `yarn` can lead to the package being installed multiple times - e.g. if a dependency also relies on this package.

Take this structure:

* my-app
* [email protected]
* my-dependency-b@^2.0.0
* my-dependency-b@~2.0.1
- my-app
- [email protected]
- my-dependency-b@^2.0.0
- my-dependency-b@~2.0.1

Now you might end up with these packages installed:

* my-app
* [email protected]
* [email protected]
- my-app
- [email protected]
- [email protected]

Now, you want to update `my-dependency-b` to 2.1.0. The version range specified in `my-dependency-a` allows for that, so you might just update this like this:

* my-app
* [email protected]
* my-dependency-b@^2.0.0
* my-dependency-b@~2.1.0
- my-app
- [email protected]
- my-dependency-b@^2.0.0
- my-dependency-b@~2.1.0

And run `yarn` again. However, this will NOT replace the previously installed version, but actually result in this:

* my-app
* [email protected]
* [email protected]
* [email protected]
Which is usually not what you want. The only way to really ensure that all sub-dependencies are also updated (as far as their version ranges allow), is to remove the entry from the `yarn.lock` file first - which is what this package does for you.
- my-app
- [email protected]
- [email protected]
- [email protected]

Which is usually not what you want. The only way to really ensure that all sub-dependencies are also updated (as far as their version ranges allow), is to remove the entry from the `yarn.lock` file first - which is what this package does for you.
4 changes: 2 additions & 2 deletions bin/yarn-update
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
#! /usr/bin/env node
#!/usr/bin/env node

require('../lib/update-dep')();
require('../lib/update-dep')();
70 changes: 66 additions & 4 deletions lib/update-dep.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,48 @@ async function yarnUpdateDependency() {
.option('-v, --target-version <value>', 'The version to update to')
.option('-p, --package <value>', 'The package to update')
.option('-ny, --no-yarn', 'Do not auto-run "yarn install"')
.option('-ad, --all-dependencies', 'Update all dependencies')
.option('-adev, --all-dev-dependencies', 'Update all devDependencies')
.parse(process.argv);

let { targetVersion, package, yarn: runYarn } = program.opts();
let {
targetVersion,
package,
yarn: runYarn,
allDependencies,
allDevDependencies,
} = program.opts();

package = package || posPackage;
let version = targetVersion || posVersion;

if (!package) {
throw new Error('You have to specify a package.');
if (!package && !allDependencies && !allDevDependencies) {
throw new Error(
'You have to specify a package, --all-dependencies or --all-dev-dependencies'
);
}

if (package) {
await updateDependency(package, version);
}

await updateDependency(package, version);
if (allDependencies) {
let packages = getDependencies();
for (let package of packages) {
log('');
log(`Trying to update ${package}...`);
await updateDependency(package, version, {});
}
}

if (allDevDependencies) {
let packages = getDevDependencies();
for (let package of packages) {
log('');
log(`Trying to update ${package}...`);
await updateDependency(package, version, {});
}
}

if (!runYarn) {
log('');
Expand All @@ -53,6 +83,38 @@ async function yarnUpdateDependency() {
log(chalk.green('Done!'));
}

function getDependencies() {
let packageJsonFilePaths = getPackageJsonFiles();

let dependencies = new Set();
packageJsonFilePaths.forEach((filePath) => {
let packageJsonFile = readPackageJson(filePath);

let deps = packageJsonFile.dependencies || {};
Object.keys(deps).forEach((dep) => {
dependencies.add(dep);
});
});

return Array.from(dependencies);
}

function getDevDependencies() {
let packageJsonFilePaths = getPackageJsonFiles();

let dependencies = new Set();
packageJsonFilePaths.forEach((filePath) => {
let packageJsonFile = readPackageJson(filePath);

let deps = packageJsonFile.devDependencies || {};
Object.keys(deps).forEach((dep) => {
dependencies.add(dep);
});
});

return Array.from(dependencies);
}

function updateVersion(deps, package, version) {
// If not specifying a full version with ~ or ^, we want to keep the current symbol
if (!version.startsWith('~') && !version.startsWith('^')) {
Expand Down

0 comments on commit 1c3b0e5

Please sign in to comment.