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

Support yarn and pnpm@4 and upgrade deps including the godforsaken linter #365

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
10 changes: 10 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,13 @@ node_js:
- 8
- 6
- 4

script:
# Avoid linting on older node
- |
nodever=$(node --version | cut -d. -f1)
if [[ $nodever == v12 ]]; then
npm run test
else
npm run main
fi
9 changes: 6 additions & 3 deletions appveyor.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
environment:
matrix:
- nodejs_version: ''
- nodejs_version: 7
- nodejs_version: 6
- nodejs_version: 4
Expand All @@ -11,11 +12,13 @@ install:
- set CI=true

test_script:
- ver
- node --version
- npm --version
- npm run lint
- "node lib\\cli.js || ver > null"
- "echo Exit code: %errorlevel%"
- ps: if ($env:nodejs_version -like '') { npm run lint }
- ps: |
node bin/cli.js
if ($LASTEXITCODE -ge 2) { Write-Output "Exit status: $LASTEXITCODE"; exit $LASTEXITCODE } else { Write-Output "All good" }

build: off
shallow_clone: true
Expand Down
93 changes: 51 additions & 42 deletions lib/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ const meow = require('meow');
const updateNotifier = require('update-notifier');
const isCI = require('is-ci');
const createCallsiteRecord = require('callsite-record');
const pkgDir = require('pkg-dir');
const detectPreferredPM = require('preferred-pm');
const execa = require('execa');
const pkg = require('../package.json');
const npmCheck = require('./index');
const staticOutput = require('./out/static-output');
const interactiveUpdate = require('./out/interactive-update');
const updateAll = require('./out/update-all');
const debug = require('./state/debug');
const pkgDir = require('pkg-dir');
const detectPreferredPM = require('preferred-pm');
const npmCheck = require('.');

updateNotifier({pkg}).notify();

Expand Down Expand Up @@ -43,39 +44,39 @@ const cli = meow({
$ npm-check ../foo # Check another path.
$ npm-check -gu # Update globally installed modules by picking which ones to upgrade.
`},
{
alias: {
u: 'update',
y: 'update-all',
g: 'global',
s: 'skip-unused',
p: 'production',
d: 'dev-only',
E: 'save-exact',
i: 'ignore'
},
default: {
dir: pkgDir.sync() || process.cwd(),
emoji: !isCI,
spinner: !isCI
},
boolean: [
'update',
'update-all',
'global',
'skip-unused',
'production',
'dev-only',
'save-exact',
'color',
'emoji',
'spinner'
],
string: [
'ignore',
'specials'
]
});
{
alias: {
u: 'update',
y: 'update-all',
g: 'global',
s: 'skip-unused',
p: 'production',
d: 'dev-only',
E: 'save-exact',
i: 'ignore'
},
default: {
dir: pkgDir.sync() || process.cwd(),
emoji: !isCI,
spinner: !isCI
},
boolean: [
'update',
'update-all',
'global',
'skip-unused',
'production',
'dev-only',
'save-exact',
'color',
'emoji',
'spinner'
],
string: [
'ignore',
'specials'
]
});

const options = {
cwd: cli.input[0] || cli.flags.dir,
Expand Down Expand Up @@ -115,28 +116,36 @@ Promise.resolve()
if (options.updateAll) {
return updateAll(currentState);
}

if (options.update) {
return interactiveUpdate(currentState);
}

return staticOutput(currentState);
})
.catch(err => {
console.log(err.message);
.catch(error => {
console.log(error.message);
if (options.debug) {
console.log(createCallsiteRecord(err).renderSync());
console.log(createCallsiteRecord(error).renderSync());
} else {
console.log('For more detail, add `--debug` to the command');
}
process.exit(1);

process.exit(2);
});

const SUPPORTED_INSTALLERS = ['npm', 'pnpm', 'ied'];
const SUPPORTED_INSTALLERS = ['npm', 'pnpm', 'ied', 'yarn'];

function detectPreferredInstaller(cwd) {
return detectPreferredPM(cwd)
.then(preferredPM => {
return preferredPM && SUPPORTED_INSTALLERS.indexOf(preferredPM.name) !== -1 ?
let pm = preferredPM && SUPPORTED_INSTALLERS.includes(preferredPM.name) ?
preferredPM.name : 'npm';
// Suffix the major version for pnpm@4.
if (pm === 'pnpm' && preferredPM.version === '>=3') {
pm = 'pnpm@' + execa.sync('pnpm', ['--version']).stdout.toString().split('.')[0];
}

return pm;
});
}
5 changes: 5 additions & 0 deletions lib/in/best-guess-homepage.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

const gitUrl = require('giturl');

/**
* Guess the homepage from package.json
* @param {import('package-json').HoistedData} data
* @returns {string}
*/
function bestGuessHomepage(data) {
if (!data) {
return false;
Expand Down
24 changes: 12 additions & 12 deletions lib/in/create-package-summary.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
'use strict';

const readPackageJson = require('./read-package-json');
const getLatestFromRegistry = require('./get-latest-from-registry');
const findModulePath = require('./find-module-path');
const path = require('path');
const _ = require('lodash');
const semverDiff = require('semver-diff');
const pathExists = require('path-exists');
const path = require('path');
const semver = require('semver');
const minimatch = require('minimatch');
const findModulePath = require('./find-module-path');
const getLatestFromRegistry = require('./get-latest-from-registry');
const readPackageJson = require('./read-package-json');

function createPackageSummary(moduleName, currentState) {
const cwdPackageJson = currentState.get('cwdPackageJson');
Expand Down Expand Up @@ -72,14 +72,14 @@ function createPackageSummary(moduleName, currentState) {
const unused = _.includes(unusedDependencies, moduleName);

return {
// info
moduleName: moduleName,
// Info
moduleName,
homepage: fromRegistry.homepage,
regError: fromRegistry.error,
pkgError: modulePackageJson.error,

// versions
latest: latest,
// Versions
latest,
installed: versionToUse,
isInstalled: packageIsInstalled,
notInstalled: !packageIsInstalled,
Expand All @@ -89,10 +89,10 @@ function createPackageSummary(moduleName, currentState) {
// Missing from package json
notInPackageJson: foundIn(missingFromPackageJson[moduleName]),

// meta
// Meta
devDependency: _.has(cwdPackageJson.devDependencies, moduleName),
usedInScripts: _.findKey(cwdPackageJson.scripts, script => {
return script.indexOf(moduleName) !== -1;
return script.includes(moduleName);
}),
mismatch: semver.validRange(packageJsonVersion) &&
semver.valid(versionToUse) &&
Expand All @@ -103,9 +103,9 @@ function createPackageSummary(moduleName, currentState) {
semver.valid(versionToUse) &&
semver.satisfies(latest, packageJsonVersion) &&
bump !== 'major',
bump: bump,
bump,

unused: unused
unused
};
});
}
Expand Down
6 changes: 5 additions & 1 deletion lib/in/find-module-path.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ const pathExists = require('path-exists');
/**
* Searches the directory hierarchy to return the path to the requested node module.
* If the module can't be found, returns the initial (deepest) tried path.
*
* @param {string} moduleName
* @param {INpmCheckCurrentState} currentState
* @returns {string}
*/
function findModulePath(moduleName, currentState) {
const cwd = currentState.get('cwd');
Expand All @@ -23,7 +27,7 @@ function findModulePath(moduleName, currentState) {
const possibleModulePaths = nodeModulesPaths.map(x => path.join(x, moduleName));
const modulePath = possibleModulePaths.find(pathExists.sync);

// if no existing path was found, return the first tried path anyway
// If no existing path was found, return the first tried path anyway
return modulePath || path.join(cwd, moduleName);
}

Expand Down
4 changes: 2 additions & 2 deletions lib/in/get-installed-packages.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
'use strict';
const path = require('path');
const _ = require('lodash');
const globby = require('globby');
const readPackageJson = require('./read-package-json');
const path = require('path');

module.exports = function (cwd) {
const GLOBBY_PACKAGE_JSON = '{*/package.json,@*/*/package.json}';
const installedPackages = globby.sync(GLOBBY_PACKAGE_JSON, {cwd: cwd});
const installedPackages = globby.sync(GLOBBY_PACKAGE_JSON, {cwd});

return _(installedPackages)
.map(pkgPath => {
Expand Down
21 changes: 11 additions & 10 deletions lib/in/get-latest-from-registry.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
'use strict';

const _ = require('lodash');
const bestGuessHomepage = require('./best-guess-homepage');
const semver = require('semver');
const packageJson = require('package-json');
const cpuCount = require('os').cpus().length;
const throat = require('throat')(cpuCount);

const _ = require('lodash');
const packageJson = require('package-json');
const semver = require('semver');
const bestGuessHomepage = require('./best-guess-homepage');

function getNpmInfo(packageName) {
return throat(() => packageJson(packageName, { fullMetadata: true, allVersions: true }))
return throat(() => packageJson(packageName, {fullMetadata: true, allVersions: true}))
.then(rawData => {
const CRAZY_HIGH_SEMVER = '8000.0.0';

Expand All @@ -18,19 +19,19 @@ function getNpmInfo(packageName) {
.sort(semver.compare)
.valueOf();

const latest = rawData['dist-tags'].latest;
const next = rawData['dist-tags'].next;
const {latest} = rawData['dist-tags'];
const {next} = rawData['dist-tags'];
const latestStableRelease = semver.satisfies(latest, '*') ?
latest :
semver.maxSatisfying(sortedVersions, '*');
return {
latest: latestStableRelease,
next: next,
next,
versions: sortedVersions,
homepage: bestGuessHomepage(rawData)
};
}).catch(err => {
const errorMessage = `Registry error ${err.message}`;
}).catch(error => {
const errorMessage = `Registry error ${error.message}`;
return {
error: errorMessage
};
Expand Down
21 changes: 12 additions & 9 deletions lib/in/get-unused-packages.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,26 @@ const ora = require('ora');
const _ = require('lodash');

function skipUnused(currentState) {
return currentState.get('skipUnused') || // manual option to ignore this
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

…god. Sometimes linters are just bad at understanding human intent.

currentState.get('global') || // global modules
currentState.get('update') || // in the process of doing an update
!currentState.get('cwdPackageJson').name; // there's no package.json
return currentState.get('skipUnused') || // Manual option to ignore this
currentState.get('global') || // global modules
currentState.get('update') || // In the process of doing an update
!currentState.get('cwdPackageJson').name; // There's no package.json
}

function getSpecialParsers(currentState) {
const specialsInput = currentState.get('specials');
if (!specialsInput) return;
if (!specialsInput) {
return;
}

return specialsInput
.split(',')
.map((special) => depcheck.special[special])
.map(special => depcheck.special[special])
.filter(Boolean);
}

function checkUnused(currentState) {
const spinner = ora(`Checking for unused packages. --skip-unused if you don't want this.`);
const spinner = ora('Checking for unused packages. --skip-unused if you don\'t want this.');
spinner.enabled = spinner.enabled && currentState.get('spinner');
spinner.start();

Expand Down Expand Up @@ -65,9 +68,9 @@ function checkUnused(currentState) {

const cwdPackageJson = currentState.get('cwdPackageJson');

// currently missing will return devDependencies that aren't really missing
// Currently missing will return devDependencies that aren't really missing
const missingFromPackageJson = _.omit(depCheckResults.missing || {},
Object.keys(cwdPackageJson.dependencies), Object.keys(cwdPackageJson.devDependencies));
Object.keys(cwdPackageJson.dependencies), Object.keys(cwdPackageJson.devDependencies));
currentState.set('missingFromPackageJson', missingFromPackageJson);
return currentState;
});
Expand Down
4 changes: 2 additions & 2 deletions lib/in/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ const getUnusedPackages = require('./get-unused-packages');
const createPackageSummary = require('./create-package-summary');

module.exports = function (currentState) {
return co(function *() {
return co(function * () {
yield getUnusedPackages(currentState);

const spinner = ora(`Checking npm registries for updated packages.`);
const spinner = ora('Checking npm registries for updated packages.');
spinner.enabled = spinner.enabled && currentState.get('spinner');
spinner.start();

Expand Down
Loading