Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: edwmurph/upgrade-deps
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 0.0.5
Choose a base ref
...
head repository: edwmurph/upgrade-deps
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: master
Choose a head ref
  • 10 commits
  • 8 files changed
  • 3 contributors

Commits on Nov 16, 2021

  1. upgrade lint

    edwmurph committed Nov 16, 2021
    Copy the full SHA
    fc519bc View commit details

Commits on Jan 10, 2022

  1. readme tweak

    edwmurph committed Jan 10, 2022
    Copy the full SHA
    551d6df View commit details

Commits on Mar 15, 2022

  1. Copy the full SHA
    54a2cac View commit details
  2. Copy the full SHA
    0faeea8 View commit details

Commits on Mar 20, 2022

  1. Copy the full SHA
    0d33e3b View commit details
  2. 0.3.0 added reset command

    edwmurph committed Mar 20, 2022
    Copy the full SHA
    868d6d8 View commit details
  3. 0.3.1 better logs

    edwmurph committed Mar 20, 2022
    Copy the full SHA
    9d91b6f View commit details

Commits on Mar 21, 2022

  1. Copy the full SHA
    ac68fea View commit details

Commits on Apr 8, 2022

  1. Copy the full SHA
    a070996 View commit details

Commits on Nov 5, 2022

  1. Unverified

    This user has not yet uploaded their public signing key.
    Copy the full SHA
    5c6dc98 View commit details
Showing with 174 additions and 177 deletions.
  1. +1 −1 .eslintrc.js
  2. +1 −1 .nvmrc
  3. +7 −40 README.md
  4. +10 −6 bin/cli.js
  5. +0 −124 index.js
  6. +144 −0 lib/upgrade-deps.js
  7. +6 −0 lib/util/exec-async.js
  8. +5 −5 package.json
2 changes: 1 addition & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module.exports = {
root: true,
extends: '@edwmurph/eslint-config',
extends: '@edwmurph/eslint-config'
};
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
12.18.0
16.13.0
47 changes: 7 additions & 40 deletions README.md
Original file line number Diff line number Diff line change
@@ -13,53 +13,20 @@ Features:

# Usage

## `npx`

```
npx upgrade-deps
```

```
Usage: cli [options]
Usage: npx upgrade-deps [options]
CLI for automating upgrading package.json dependencies. Semver prefixes will be stripped in favor of using exact versions.
Options:
-b, --breaking include breaking/major version upgrades
-v, --version output the version
-h, --help display help for command
```

## global install

```
npm install -g upgrade-deps
```

and then just:

```
upgrade-deps
```

## local install

```
npm install --save-dev upgrade-deps
-v, --version output the version
-b, --breaking include breaking/major version upgrades
-d, --dry-run just print which packages are out of date
-h, --help display help for command
```

and then add a package.json script:
## npx

```
{
"scripts": {
"upgrade-deps": "upgrade-deps"
}
}
```

and then just:

```
npm run upgrade-deps
npx upgrade-deps
```
16 changes: 10 additions & 6 deletions bin/cli.js
Original file line number Diff line number Diff line change
@@ -2,15 +2,19 @@

const { program } = require('commander');
const { version } = require('../package.json');
const upgradeDeps = require('../');
const upgrade_deps = require('../lib/upgrade-deps');

program
.option('-b, --breaking', 'include breaking/major version upgrades')
.version( version, '-v, --version', 'output the version')
.name('npx upgrade-deps')
.version( version, '-v, --version', 'output the version' );

program
.option( '-b, --breaking', 'include breaking/major version upgrades' )
.option( '-d, --dry-run', 'just print which packages are out of date' )
.description([
'CLI for automating upgrading package.json dependencies.',
'Semver prefixes will be stripped in favor of using exact versions.',
].join(' '))
.action( upgradeDeps );
'Semver prefixes will be stripped in favor of using exact versions.'
].join(' ') )
.action( upgrade_deps );

program.parse( process.argv );
124 changes: 0 additions & 124 deletions index.js

This file was deleted.

144 changes: 144 additions & 0 deletions lib/upgrade-deps.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
const fs = require('fs');
const { promisify } = require('util');
const path = require('path');
const exec_async = require('./util/exec-async');

const storage = '~/.upgrade-deps';

const write_file_async = promisify( fs.writeFile );
const semver_regex_str = '[0-9]+\\.[0-9]+\\.[0-9]+';
const semver_regex = new RegExp( semver_regex_str );
const git_semver_regex = new RegExp( `^.+#${ semver_regex_str }$` );

async function get_latest_npm( pkg_name ) {
const { stdout, stderr } = await exec_async( `npm show ${ pkg_name } version` );

if ( stderr ) {
throw new Error( stderr );
}

return stdout.trim();
}

async function get_latest_git( version ) {
const [ repo ] = version.split('#');

const destination = `${ storage }/${ repo }`;

await exec_async( `git clone git@github.com:${ repo } ${ destination }` );

const { stdout: latest_tag } = await exec_async([
`cd ${ destination }`,
'&& git describe --tags `git rev-list --tags --max-count=1`'
].join(' ') );

return `${ repo }#${ latest_tag.trim() }`;
}

async function get_latest([ pkg_name, version ]) {
let latest = version;

if ( git_semver_regex.test( version ) ) {
latest = await get_latest_git( version );
} else if ( semver_regex.test( version ) ) {
latest = await get_latest_npm( pkg_name );
}

return [ pkg_name, latest ];
}

function get_pkg_json() {
const pkg_json_path = path.join( process.cwd(), 'package.json' );

try {
return require( pkg_json_path );
} catch ( ex ) {
if ( ex.code === 'MODULE_NOT_FOUND' ) {
throw new Error( `couldnt find package.json in current directory: ${ pkg_json_path }` );
}
throw ex;
}
}

async function upgrade_deps({ breaking, dryRun: dry_run }) {
try {
const pkg_json = get_pkg_json();

await exec_async( `[ ! -d ${ storage } ]` ).catch( () => {
console.log( `State directory "${ storage }" must be deleted to continue` );
process.exit( 1 );
});

await exec_async( `mkdir -p ${ storage }` );

const deps_promise = Promise.all(
Object.entries( pkg_json.dependencies || {} ).map( get_latest )
);

const dev_deps_promise = Promise.all(
Object.entries( pkg_json.devDependencies || {} ).map( get_latest )
);

const [ dependencies, dev_dependencies ] = await Promise.all([
deps_promise,
dev_deps_promise
]);

const updated = Object.assign( {}, pkg_json );
const dry_run_updates = { dependencies: {}, devDependencies: {} };

if ( dependencies.length ) {
updated.dependencies = Object.fromEntries(
dependencies.map( ([name, version]) => {
const prev_version = pkg_json.dependencies[name];
const major_bump = prev_version.split('.')[0] !== version.split('.')[0];
const new_version = !major_bump || breaking ? version : prev_version;

if ( prev_version !== new_version ) {
dry_run_updates.dependencies[ name ] = `${ prev_version } -> ${ new_version }`;
}

return [name, new_version];
})
);
}

if ( dev_dependencies.length ) {
updated.devDependencies = Object.fromEntries(
dev_dependencies.map( ([name, version]) => {
const prev_version = pkg_json.devDependencies[name];
const major_bump = prev_version.split('.')[0] !== version.split('.')[0];
const new_version = !major_bump || breaking ? version : prev_version;

if ( prev_version !== new_version ) {
dry_run_updates.devDependencies[ name ] = `${ prev_version } -> ${ new_version }`;
}

return [name, new_version];
})
);
}

if ( dry_run ) {
console.log('Dry run package updates:\n');
console.log( JSON.stringify( dry_run_updates, null, 2 ) );
} else {
await write_file_async(
'package.json',
JSON.stringify( updated, null, 2 ).trim() + '\n'
);
}

await exec_async( `rm -rf ${ storage }` );

process.exit( 0 );
} catch ( ex ) {
console.error( 'Failure upgrading deps', ex );

await exec_async( `rm -rf ${ storage }` );

process.exit( 1 );
}
}

module.exports = upgrade_deps;
6 changes: 6 additions & 0 deletions lib/util/exec-async.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
const { exec } = require('child_process');
const { promisify } = require('util');

const exec_async = promisify( exec );

module.exports = exec_async;
Loading