Skip to content

Commit

Permalink
Merge pull request #27 from snyk/feat/dont-fail-out-of-sync
Browse files Browse the repository at this point in the history
Feat/dont fail out of sync
  • Loading branch information
lili2311 authored Nov 29, 2018
2 parents 7d876e4 + bf58b62 commit ab43cb5
Show file tree
Hide file tree
Showing 13 changed files with 10,408 additions and 18 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ npm-debug.log
dist
.DS_Store
*.log
package-lock.json
/package-lock.json
11 changes: 7 additions & 4 deletions lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ export {

async function buildDepTree(
manifestFileContents: string, lockFileContents: string,
includeDev = false, lockfileType?: LockfileType): Promise<PkgTree> {
includeDev = false, lockfileType?: LockfileType,
strict: boolean = true): Promise<PkgTree> {

if (!lockfileType) {
lockfileType = LockfileType.npm;
Expand Down Expand Up @@ -52,11 +53,12 @@ async function buildDepTree(
const manifestFile: ManifestFile = parseManifestFile(manifestFileContents);

const lockFile: Lockfile = lockfileParser.parseLockFile(lockFileContents);
return lockfileParser.getDependencyTree(manifestFile, lockFile, includeDev);
return lockfileParser.getDependencyTree(manifestFile, lockFile, includeDev, strict);
}

async function buildDepTreeFromFiles(
root: string, manifestFilePath: string, lockFilePath: string, includeDev = false): Promise<PkgTree> {
root: string, manifestFilePath: string, lockFilePath: string, includeDev = false,
strict = true): Promise<PkgTree> {
if (!root || !manifestFilePath || !lockFilePath) {
throw new Error('Missing required parameters for buildDepTreeFromFiles()');
}
Expand Down Expand Up @@ -86,5 +88,6 @@ async function buildDepTreeFromFiles(
const manifestFileContents = fs.readFileSync(manifestFileFullPath, 'utf-8');
const lockFileContents = fs.readFileSync(lockFileFullPath, 'utf-8');

return await buildDepTree(manifestFileContents, lockFileContents, includeDev, lockFileType);
return await buildDepTree(manifestFileContents, lockFileContents, includeDev,
lockFileType, strict);
}
4 changes: 3 additions & 1 deletion lib/parsers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export interface PkgTree {
depType?: DepType;
hasDevDependencies?: boolean;
cyclic?: boolean;
missingLockFileEntry?: boolean;
}

export enum DepType {
Expand All @@ -44,7 +45,8 @@ export enum LockfileType {
export interface LockfileParser {
parseLockFile: (lockFileContents: string)
=> Lockfile;
getDependencyTree: (manifestFile: ManifestFile, lockfile: Lockfile, includeDev?: boolean)
getDependencyTree: (manifestFile: ManifestFile, lockfile: Lockfile,
includeDev?: boolean, strict?: boolean)
=> Promise<PkgTree>;
}

Expand Down
11 changes: 9 additions & 2 deletions lib/parsers/package-lock-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ export class PackageLockParser implements LockfileParser {
}

public async getDependencyTree(
manifestFile: ManifestFile, lockfile: Lockfile, includeDev = false): Promise<PkgTree> {
manifestFile: ManifestFile, lockfile: Lockfile, includeDev = false,
strict = true): Promise<PkgTree> {
if (lockfile.type !== LockfileType.npm) {
throw new InvalidUserInputError('Unsupported lockfile provided. Please ' +
'provide `package-lock.json`.');
Expand Down Expand Up @@ -119,7 +120,13 @@ export class PackageLockParser implements LockfileParser {
} else if (/^file:/.test(dep.version)) {
depTree.dependencies[dep.name] = createPkgTreeFromDep(dep);
} else {
throw new OutOfSyncError(depName, 'npm');
// TODO: also check the package version
// for a stricter check
if (strict) {
throw new OutOfSyncError(depName, 'npm');
}
depTree.dependencies[dep.name] = createPkgTreeFromDep(dep);
depTree.dependencies[dep.name].missingLockFileEntry = true;
}
}
return depTree;
Expand Down
21 changes: 15 additions & 6 deletions lib/parsers/yarn-lock-parse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ export class YarnLockParser implements LockfileParser {
}

public async getDependencyTree(
manifestFile: ManifestFile, lockfile: Lockfile, includeDev = false): Promise<PkgTree> {
manifestFile: ManifestFile, lockfile: Lockfile, includeDev = false,
strict = true ): Promise<PkgTree> {
if (lockfile.type !== LockfileType.yarn) {
throw new InvalidUserInputError('Unsupported lockfile provided. ' +
'Please provide `package-lock.json`.');
Expand All @@ -83,15 +84,16 @@ export class YarnLockParser implements LockfileParser {
depTree.dependencies[dep.name] = createPkgTreeFromDep(dep);
} else {
depTree.dependencies[dep.name] = await this.buildSubTreeRecursiveFromYarnLock(
dep, yarnLock, []);
dep, yarnLock, [], strict);
}
}));

return depTree;
}

private async buildSubTreeRecursiveFromYarnLock(
searchedDep: Dep, lockFile: YarnLock, depPath: string[] ): Promise<PkgTree> {
searchedDep: Dep, lockFile: YarnLock, depPath: string[],
strict = true): Promise<PkgTree> {
const depSubTree: PkgTree = {
depType: searchedDep.dev ? DepType.dev : DepType.prod,
dependencies: {},
Expand All @@ -100,18 +102,25 @@ export class YarnLockParser implements LockfileParser {
};

const depKey = `${searchedDep.name}@${searchedDep.version}`;

const dep = _.get(lockFile.object, depKey);

if (!dep) {
throw new OutOfSyncError(searchedDep.name, 'yarn');

if (strict) {
throw new OutOfSyncError(searchedDep.name, 'yarn');
}

depSubTree.version = searchedDep.version;
depSubTree.missingLockFileEntry = true;
return depSubTree;
}

depSubTree.version = dep.version;

if (depPath.indexOf(depKey) >= 0) {
depSubTree.cyclic = true;
} else {
depPath.push(depKey);
depSubTree.version = dep.version;
const newDeps = _.entries({...dep.dependencies, ...dep.optionalDependencies});

await Promise.all(newDeps.map(async ([name, version]) => {
Expand Down
192 changes: 192 additions & 0 deletions test/lib/fixtures/out-of-sync-tree/expected-tree.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
{
"dependencies": {
"debug": {
"depType": "prod",
"dependencies": {
"ms": {
"depType": "prod",
"dependencies": {},
"name": "ms",
"version": "2.1.1"
}
},
"name": "debug",
"version": "4.1.0"
},
"body-parser": {
"depType": "prod",
"missingLockFileEntry": true,
"dependencies": {},
"name": "body-parser",
"version": "^1.18.2"
},
"undefsafe": {
"depType": "prod",
"dependencies": {
"debug": {
"depType": "prod",
"dependencies": {
"ms": {
"depType": "prod",
"dependencies": {},
"name": "ms",
"version": "2.0.0"
}
},
"name": "debug",
"version": "2.6.9"
}
},
"name": "undefsafe",
"version": "1.3.1"
},
"aws-sdk": {
"depType": "prod",
"dependencies": {
"buffer": {
"depType": "prod",
"dependencies": {
"base64-js": {
"depType": "prod",
"dependencies": {},
"name": "base64-js",
"version": "1.3.0"
},
"ieee754": {
"depType": "prod",
"dependencies": {},
"name": "ieee754",
"version": "1.1.8"
},
"isarray": {
"depType": "prod",
"dependencies": {},
"name": "isarray",
"version": "1.0.0"
}
},
"name": "buffer",
"version": "4.9.1"
},
"events": {
"depType": "prod",
"dependencies": {},
"name": "events",
"version": "1.1.1"
},
"ieee754": {
"depType": "prod",
"dependencies": {},
"name": "ieee754",
"version": "1.1.8"
},
"jmespath": {
"depType": "prod",
"dependencies": {},
"name": "jmespath",
"version": "0.15.0"
},
"querystring": {
"depType": "prod",
"dependencies": {},
"name": "querystring",
"version": "0.2.0"
},
"sax": {
"depType": "prod",
"dependencies": {},
"name": "sax",
"version": "1.2.1"
},
"url": {
"depType": "prod",
"dependencies": {
"punycode": {
"depType": "prod",
"dependencies": {},
"name": "punycode",
"version": "1.3.2"
},
"querystring": {
"depType": "prod",
"dependencies": {},
"name": "querystring",
"version": "0.2.0"
}
},
"name": "url",
"version": "0.10.3"
},
"uuid": {
"depType": "prod",
"dependencies": {},
"name": "uuid",
"version": "3.1.0"
},
"xml2js": {
"depType": "prod",
"dependencies": {
"sax": {
"depType": "prod",
"dependencies": {},
"name": "sax",
"version": "1.2.1"
},
"xmlbuilder": {
"depType": "prod",
"dependencies": {},
"name": "xmlbuilder",
"version": "9.0.7"
}
},
"name": "xml2js",
"version": "0.4.19"
}
},
"name": "aws-sdk",
"version": "2.362.0"
},
"axios": {
"depType": "prod",
"dependencies": {
"follow-redirects": {
"depType": "prod",
"dependencies": {
"debug": {
"depType": "prod",
"dependencies": {
"ms": {
"depType": "prod",
"dependencies": {},
"name": "ms",
"version": "2.0.0"
}
},
"name": "debug",
"version": "3.1.0"
}
},
"name": "follow-redirects",
"version": "1.5.10"
},
"is-buffer": {
"depType": "prod",
"dependencies": {},
"name": "is-buffer",
"version": "1.1.6"
}
},
"name": "axios",
"version": "0.18.0"
},
"bignumber.js": {
"depType": "prod",
"dependencies": {},
"name": "bignumber.js",
"version": "7.2.1"
}
},
"hasDevDependencies": true,
"name": "out-of-sync-small",
"version": "1.0.0"
}
Loading

0 comments on commit ab43cb5

Please sign in to comment.