mirror of
https://github.com/balena-io/etcher.git
synced 2025-04-22 06:17:20 +00:00

* refactor(scripts): Update clean-shrinkwrap script This updates the `postshrinkwrap` script to traverse the dependency tree and remove all `from` fields to avoid inconsistent diffs across platforms, environments and installs when shrinkwrapping anew. * chore(shrinkwrap): Update npm-shrinkwrap.json * fix(scripts): Ensure `resolved` field in shrinkwrap is HTTPS * fix(scripts): Only strip "from" of registry packages * fix(clean-shrinkwrap): Fix linter errors * chore(shrinkwrap): Update npm-shrinkwrap.json * fix(scripts): fix spelling typo Change-Type: patch
114 lines
3.7 KiB
JavaScript
114 lines
3.7 KiB
JavaScript
/**
|
|
* This script is in charge of generating the `shrinkwrap` file.
|
|
*
|
|
* `npm shrinkwrap` has a bug where it will add optional dependencies
|
|
* to `npm-shrinkwrap.json`, therefore causing errors if these optional
|
|
* dependendencies are platform dependent and you then try to build
|
|
* the project in another platform.
|
|
*
|
|
* As a workaround, we keep a list of platform dependent dependencies in
|
|
* the `platformSpecificDependencies` property of `package.json`,
|
|
* and manually remove them from `npm-shrinkwrap.json` if they exist.
|
|
*
|
|
* See: https://github.com/npm/npm/issues/2679
|
|
*/
|
|
|
|
/* eslint-disable lodash/prefer-lodash-method */
|
|
/* eslint-disable no-magic-numbers */
|
|
/* eslint-disable no-undefined */
|
|
|
|
'use strict'
|
|
|
|
const fs = require('fs')
|
|
const path = require('path')
|
|
|
|
const JSON_INDENT = 2
|
|
const SHRINKWRAP_FILENAME = path.join(__dirname, '..', 'npm-shrinkwrap.json')
|
|
|
|
const packageInfo = require('../package.json')
|
|
const shrinkwrap = require('../npm-shrinkwrap.json')
|
|
|
|
/**
|
|
* @summary Traverse a shrinkwrap tree and call
|
|
* a given function on each dependency
|
|
* @param {Object} tree - shrinkwrap
|
|
* @param {Function} onNode - callback({Object} parent, {String} parentName, {String} name, {Object} info)
|
|
* @param {String} [parentName] - name of dependent (used internally)
|
|
* @example
|
|
* traverseDeps(shrinkwrap, (parent, parentName, name, info) => {
|
|
* // ...
|
|
* })
|
|
*/
|
|
const traverseDeps = (tree, onNode, parentName) => {
|
|
if (!tree.dependencies) {
|
|
return
|
|
}
|
|
|
|
const keys = Object.keys(tree.dependencies)
|
|
|
|
let name = null
|
|
|
|
for (let index = 0; index < keys.length; index += 1) {
|
|
name = keys[index]
|
|
|
|
// Check for this dependency to still exist,
|
|
// as a node might have been removed just before this iteration
|
|
if (tree.dependencies[name]) {
|
|
onNode(tree, parentName || tree.name, name, tree.dependencies[name])
|
|
|
|
// Check that the walking function didn't remove the dependency;
|
|
// if so, skip it and continue with the next one
|
|
if (tree.dependencies[name] && tree.dependencies[name].dependencies) {
|
|
traverseDeps(tree.dependencies[name], onNode, name)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
console.log('Cleaning shrinkwrap...')
|
|
|
|
// Walk the generated shrinkwrap tree & apply modifications if necessary
|
|
traverseDeps(shrinkwrap, (parent, parentName, name, info) => {
|
|
// If this dependency depends on a "blacklisted" optional
|
|
// dependency; remove it from the shrinkwrap
|
|
if (packageInfo.platformSpecificDependencies.includes(name)) {
|
|
console.log(' - Removing "%s" from "%s"', name, parentName)
|
|
parent.dependencies[name] = undefined
|
|
Reflect.deleteProperty(parent.dependencies, name)
|
|
return
|
|
}
|
|
|
|
// Ensure the `resolved` field contains a HTTPS registry URL,
|
|
// as some versions of npm apparently fall back to HTTP on some platforms
|
|
// under some circumstances
|
|
if (/^http:\/\//.test(info.resolved)) {
|
|
info.resolved = info.resolved.replace(/^http/, 'https')
|
|
}
|
|
|
|
// Delete `from` fields to avoid different diffs on different platforms
|
|
// NOTE: Only do this if it's a npm package version range,
|
|
// as direct installs from github or git need this field
|
|
// to resolve properly during shrinkwrapping
|
|
const isScoped = /^@/.test(name)
|
|
const fromNpm = !/^[a-z0-9-]+\//i.test(info.from)
|
|
if (isScoped || fromNpm) {
|
|
info.from = undefined
|
|
Reflect.deleteProperty(info, 'from')
|
|
}
|
|
})
|
|
|
|
// Generate the new shrinkwrap JSON
|
|
const shrinkwrapJson = `${JSON.stringify(shrinkwrap, null, JSON_INDENT)}\n`
|
|
|
|
// Write back the modified npm-shrinkwrap.json
|
|
fs.writeFile(SHRINKWRAP_FILENAME, shrinkwrapJson, (error) => {
|
|
if (error) {
|
|
console.log(`[ERROR] Couldn't write shrinkwrap file: ${error.stack}`)
|
|
process.exit(1)
|
|
} else {
|
|
console.log(`[OK] Wrote shrinkwrap file to ${path.relative(__dirname, SHRINKWRAP_FILENAME)}`)
|
|
}
|
|
})
|
|
|
|
console.log('')
|