@hashicorp/danger-pkg-differ
Advanced tools
Comparing version 0.0.3 to 0.0.4
{ | ||
"name": "@hashicorp/danger-pkg-differ", | ||
"description": "a dangerfile that adds diff files for updated node modules", | ||
"version": "0.0.3", | ||
"version": "0.0.4", | ||
"author": "Hashicorp - Michael Schonfeld", | ||
"dependencies": { | ||
"@octokit/rest": "^16.3.0", | ||
"bluebird": "^3.5.3", | ||
"danger": "^6.1.12", | ||
@@ -18,3 +19,3 @@ "semver": "^5.6.0" | ||
}, | ||
"gitHead": "cd7c0f3545419965805b8fe3edb3276b118b563c" | ||
"gitHead": "51e320b072e9023b451ebe52aadf383b577aca6b" | ||
} |
import { schedule, danger, warn } from 'danger' | ||
const Promise = require('bluebird') | ||
const semver = require('semver') | ||
@@ -6,2 +7,3 @@ const octokit = require('@octokit/rest')() | ||
const path = require('path') | ||
const fs = require('fs') | ||
@@ -30,6 +32,7 @@ octokit.authenticate({ | ||
function runDiffer(name, beforeVersion, afterVersion) { | ||
function runDiffer(name, beforeVersion, afterVersion, packageLockJson = '') { | ||
return new Promise((resolve, reject) => { | ||
console.log( | ||
`Generating diff for "${name}" ${beforeVersion} => ${afterVersion}` | ||
`Generating diff for "${name}" ${beforeVersion} => ${afterVersion} (with lock file "${packageLockJson || | ||
'(none)'}")` | ||
) | ||
@@ -40,3 +43,4 @@ | ||
beforeVersion, | ||
afterVersion | ||
afterVersion, | ||
packageLockJson | ||
]) | ||
@@ -66,74 +70,96 @@ let diff = '' | ||
schedule(done => { | ||
// when in Travis, only run for PR builds | ||
if ( | ||
process.env.hasOwnProperty('TRAVIS_PULL_REQUEST') && | ||
process.env.TRAVIS_PULL_REQUEST == 'false' | ||
) { | ||
console.warn(`Not a PR, will not run Danger...`) | ||
return | ||
} | ||
schedule(() => | ||
Promise.resolve() | ||
.then(() => { | ||
// when in Travis, only run for PR builds | ||
if ( | ||
process.env.hasOwnProperty('TRAVIS_PULL_REQUEST') && | ||
process.env.TRAVIS_PULL_REQUEST == 'false' | ||
) { | ||
throw new Error(`Not a PR, will not run Danger...`) | ||
} | ||
// no need to run if there aren't any [nested] changed package.json files | ||
const changedPackageFiles = danger.git.modified_files.filter( | ||
file => path.basename(file) === 'package.json' | ||
) | ||
const hasPackageChanges = changedPackageFiles.length > 0 | ||
if (!hasPackageChanges) { | ||
console.warn(`No package changes, will not run Danger...`) | ||
return | ||
} | ||
return ( | ||
// find which actual packages changed in the affected package.json files | ||
Promise.all( | ||
changedPackageFiles.map(packageFile => | ||
danger.git.JSONDiffForFile(packageFile).then(packageDiff => [ | ||
// include changes in "dependencies" | ||
...getChangedPackages(packageDiff.dependencies), | ||
// include changes in "devDependencies" | ||
...getChangedPackages(packageDiff.devDependencies), | ||
// include changes in "peerDependencies" | ||
...getChangedPackages(packageDiff.peerDependencies) | ||
]) | ||
// no need to run if there aren't any [nested] changed package.json files | ||
const changedPackageJsons = danger.git.modified_files.filter( | ||
file => path.basename(file) === 'package.json' | ||
) | ||
) | ||
.then(nestedChangedPackages => { | ||
// flatten resulting nested array [[]] => [] | ||
const changedPackages = [].concat(...nestedChangedPackages) | ||
if (!changedPackageJsons.length) { | ||
throw new Error(`No package changes, will not run Danger...`) | ||
} | ||
// no need to run if there aren't any actual changed packages | ||
if (!changedPackages.length) { | ||
console.warn(`No package changes, will not run Danger...`) | ||
done() | ||
// for every changed package.json file, find which actual | ||
// dependencies were changed | ||
return Promise.mapSeries(changedPackageJsons, packageJson => { | ||
console.log(`=========================================`) | ||
console.log(`Processing changes in ${packageJson}`) | ||
const packageLockPath = path.resolve( | ||
path.join(path.dirname(packageJson), 'package-lock.json') | ||
) | ||
const packageLockExists = fs.existsSync(packageLockPath) | ||
if (packageLockExists) { | ||
console.log(`Found package-lock.json file at ${packageLockPath}`) | ||
} | ||
// Generate and read .diff files for each changed node package | ||
return Promise.all( | ||
changedPackages.map(({ name, beforeVersion, afterVersion }) => | ||
runDiffer(name, beforeVersion, afterVersion) | ||
// find all changed dependencies in any | ||
// of {dependencies,devDependencies,peerDependencies} | ||
return danger.git | ||
.JSONDiffForFile(packageJson) | ||
.then(packageDiff => { | ||
return [ | ||
// include changes in "dependencies" | ||
...getChangedPackages(packageDiff.dependencies), | ||
// include changes in "devDependencies" | ||
...getChangedPackages(packageDiff.devDependencies), | ||
// include changes in "peerDependencies" | ||
...getChangedPackages(packageDiff.peerDependencies) | ||
] | ||
}) | ||
.then(changedDependecies => { | ||
// no need to run if there aren't any actual changed dependencies | ||
if (!changedDependecies.length) { | ||
throw new Error(`No dependency changes, will not run Danger...`) | ||
} | ||
// Generate and read .diff files for each changed dependency | ||
return Promise.map( | ||
changedDependecies, | ||
({ name, beforeVersion, afterVersion }) => | ||
runDiffer( | ||
name, | ||
beforeVersion, | ||
afterVersion, | ||
packageLockExists ? packageLockPath : '' | ||
) | ||
) | ||
}) | ||
.then(diffs => { | ||
// upload each .diff file as a GitHub | ||
console.log(`Uploading diffs to gist...`) | ||
const description = `Package diff files for "${ | ||
danger.github.pr.title | ||
} #${danger.github.pr.number}"` | ||
return Promise.map(diffs, diff => uploadGist(diff, description)) | ||
}) | ||
.catch(err => console.warn(`Skipping danger: ${err}`)) | ||
}).then(nestedGists => { | ||
// flatten [[gists]] to one-dimesntinal array, and remove | ||
// non-objects from failed attempts (.catch() blocks) | ||
const gists = [].concat(...nestedGists).filter(x => x) | ||
// report resulting gists in the original PR | ||
if (gists.length) { | ||
warn( | ||
`This PR is updating a dependency. You should carefully read through the attached diff files to make sure no evil code has been injected.` | ||
) | ||
) | ||
}) | ||
// upload each .diff file as a GitHub | ||
.then(diffs => { | ||
console.log(`Uploading diffs to gist...`) | ||
const description = `Package diff files for "${ | ||
danger.github.pr.title | ||
} #${danger.github.pr.number}"` | ||
gists.forEach(gist => { | ||
warn(`[${gist.filename}](${gist.url})`) | ||
}) | ||
} | ||
return Promise.all(diffs.map(diff => uploadGist(diff, description))) | ||
}) | ||
// report resulting gists in the original PR | ||
.then(gists => { | ||
warn( | ||
`This PR is updating a dependency. You should carefully read through the attached diff files to make sure no evil code has been injected.` | ||
) | ||
gists.forEach(gist => { | ||
warn(`[${gist.filename}](${gist.url})`) | ||
}) | ||
console.time('Done!') | ||
}) | ||
) | ||
}) | ||
}) | ||
.catch(err => console.warn(`Skipping danger: ${err}`)) | ||
) |
Sorry, the diff of this file is not supported yet
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
8243
147
1
4
5
+ Addedbluebird@^3.5.3
+ Addedbluebird@3.7.2(transitive)