UNPKG

can-i-ignore-scripts

Version:

A service and cli to analyze your dependencies and check what'll break when you switch from `npm ci` to `npm ci --ignore-scripts`

91 lines (83 loc) 4.48 kB
#!/usr/bin/env node const fs = require('fs') const glob = require('glob') const util = require('util') const _ = require('lodash') const { request } = require('undici') const localData = require('./data.json') const scriptNames = ['preinstall', 'postinstall', 'install'] console.log(` █▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█ ▄▄· ▄▄▄· ▐ ▄ ▄ ▪ ▄▄ ▐ ▄ ▄▄▄ ▄▄▄ ▄▄▄▄· ▐█ ▌ ▐█ ▀█ ·█▌▐█ ██ ██ ▐█ ▀ █▌▐█ ▐▄ █· █ ▀· .▀ .█▌ ██ ▄▄▄█▀▀█ ▐█▐▐▌ ▐█· ▐█· ▄█ ▀█▄ ▐█▐▐▌ ▄█▀▄ ▐▀▀▄ ▐█▀ ▄█▀▀▀· ▐███▌▐█ ▪▐▌██▐█▌ ▐█▌ ▐█▌ ▐█▄ ▐█ ██▐█▌▐█▌.▐▌▐▄ █▌▐█▄▄▄▌ ▀ ·▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀ ▀▀▀ ·▀▀▀▀ ▀▀ █▪ ▀█▄▀▪.▀ ▀ ▀▀▀ ▀ `) const files = glob.sync('node_modules/**/package.json') const found = _.chain(files) .map(file => { let json try { json = JSON.parse(fs.readFileSync(file)) } catch (e) { console.error(`Oops, ${file} doesn't seem to be a valid JSON`) return null } const { name, scripts, version } = json return { name, version, scripts: _.pick(scripts, scriptNames), path: file.substr(0, file.length - 12) } }) .filter(pkg => pkg && Object.keys(pkg.scripts).length > 0) .groupBy(pkg => pkg.name) .value() if (Object.keys(found).length === 0) { console.log('No scripts found') process.exit(0) } console.log('▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀') request(`https://can-i-ignore-scripts.vercel.app/api/check?packages=${Object.keys(found).join(',')}`) .then(response => response.body.json()) .catch(err => { console.error(` // Falling back to offline data, couldn't fetch. Error: ${err.message} \n`) return localData; }) .then(data => { console.log(`Found following packages with scripts:`) const keep = []; const check = []; console.log(Object.keys(found).map(name => { if (data.ignore[name]) { return `[ ignore ] '${name}' has scripts but they can be ignored \n reason: ${data.ignore[name]}` } else if (data.keep[name]) { keep.push(name) return `[ keep ] '${name}' needs its scripts to run \n reason: ${data.keep[name]}` } else { let tip = '' if (found[name].flatMap(pkg => Object.values(pkg.scripts)).join('').includes('gyp ')) { tip = '(it uses gyp, so you probably need it)' keep.push(name) } else { check.push(name) } return `[ check? ] '${name}' needs reviewing ${tip}\n${util.inspect(found[name])}` } }).sort().reverse().join('\n')) console.log(` ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ What now? Run rebuild after 'npm ci --ignore-scripts' to trigger scripts you need to keep. `) if (keep.length > 0) { console.log(` A suggestion to get you started: npm rebuild ${keep.join(' ')} Or run all except the ones you can ignore now: npm rebuild ${[...keep,...check].join(' ')}`) } else { console.log(` Just use something like this: npm rebuild package1 package2`) } console.log('█▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█\n') console.log('If you check some packages, consider contributing your findings on github.') }).catch(err => { console.error(err) })