diff --git a/lib/index.ts b/lib/index.ts index d1a6f6e3..dd4f30ad 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -99,11 +99,30 @@ async function buildDepTreeFromFiles( throw new Error('Missing required parameters for buildDepTreeFromFiles()'); } + const manifestFileFullPath = path.resolve(root, manifestFilePath); + const lockFileFullPath = path.resolve(root, lockFilePath); + + if (!fs.existsSync(manifestFileFullPath)) { + throw new InvalidUserInputError( + 'Target file package.json not found at ' + + `location: ${manifestFileFullPath}`, + ); + } + if (!fs.existsSync(lockFileFullPath)) { + throw new InvalidUserInputError( + 'Lockfile not found at location: ' + lockFileFullPath, + ); + } + + const manifestFileContents = fs.readFileSync(manifestFileFullPath, 'utf-8'); + const lockFileContents = fs.readFileSync(lockFileFullPath, 'utf-8'); + let lockFileType: LockfileType; if (lockFilePath.endsWith('package-lock.json')) { lockFileType = LockfileType.npm; } else if (lockFilePath.endsWith('yarn.lock')) { if ( + lockFileContents.includes('__metadata') || fs.existsSync( path.resolve(root, lockFilePath.replace('yarn.lock', '.yarnrc.yml')), ) @@ -119,24 +138,6 @@ async function buildDepTreeFromFiles( ); } - const manifestFileFullPath = path.resolve(root, manifestFilePath); - const lockFileFullPath = path.resolve(root, lockFilePath); - - if (!fs.existsSync(manifestFileFullPath)) { - throw new InvalidUserInputError( - 'Target file package.json not found at ' + - `location: ${manifestFileFullPath}`, - ); - } - if (!fs.existsSync(lockFileFullPath)) { - throw new InvalidUserInputError( - 'Lockfile not found at location: ' + lockFileFullPath, - ); - } - - const manifestFileContents = fs.readFileSync(manifestFileFullPath, 'utf-8'); - const lockFileContents = fs.readFileSync(lockFileFullPath, 'utf-8'); - return await buildDepTree( manifestFileContents, lockFileContents, diff --git a/package.json b/package.json index 898b4427..c4c4830d 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ "yaml": "^1.9.2" }, "devDependencies": { - "@types/node": "^14.0.13", + "@types/node": "^10.17.26", "@types/uuid": "^3.4.4", "@typescript-eslint/eslint-plugin": "^2.29.0", "@typescript-eslint/parser": "^2.29.0", diff --git a/test/lib/fixtures/missing-dot-yarnrc-yarn2/package.json b/test/lib/fixtures/missing-dot-yarnrc-yarn2/package.json new file mode 100644 index 00000000..04939fb1 --- /dev/null +++ b/test/lib/fixtures/missing-dot-yarnrc-yarn2/package.json @@ -0,0 +1,22 @@ +{ + "name": "goof", + "version": "0.0.3", + "description": "A vulnerable todo demo application", + "homepage": "https://snyk.io/", + "repository": { + "type": "git", + "url": "https://github.com/Snyk/snyk-todo-list-demo-app/" + }, + "scripts": { + "start": "node app.js", + "build": "browserify -r jquery > public/js/bundle.js", + "cleanup": "mongo express-todo --eval 'db.todos.remove({});'" + }, + "engines": { + "node": "6.14.1" + }, + "dependencies": { + "adm-zip": "0.4.7" + }, + "devDependencies": {} +} diff --git a/test/lib/fixtures/missing-dot-yarnrc-yarn2/yarn.lock b/test/lib/fixtures/missing-dot-yarnrc-yarn2/yarn.lock new file mode 100644 index 00000000..a513c0d4 --- /dev/null +++ b/test/lib/fixtures/missing-dot-yarnrc-yarn2/yarn.lock @@ -0,0 +1,20 @@ +# This file is generated by running "yarn install" inside your project. +# Manual changes might be lost - proceed with caution! + +__metadata: + version: 4 + +"adm-zip@npm:0.4.7": + version: 0.4.7 + resolution: "adm-zip@npm:0.4.7" + checksum: 2/11a1c45712be29358e9e62b8b7111c2af6b13ee8e954443f64b5f6e7e869473219f4601f34537e960cf98968b9e7d46a376abb650c4095adcbe402b98a1c8af0 + languageName: node + linkType: hard + +"goof@workspace:.": + version: 0.0.0-use.local + resolution: "goof@workspace:." + dependencies: + adm-zip: 0.4.7 + languageName: unknown + linkType: soft diff --git a/test/lib/yarn.test.ts b/test/lib/yarn.test.ts index f687768a..59bf95f0 100644 --- a/test/lib/yarn.test.ts +++ b/test/lib/yarn.test.ts @@ -313,3 +313,14 @@ for (const version of ['yarn1', 'yarn2']) { } }); } + +// Yarn v2 specific test +test('.yarnrc.yaml is missing, but still resolving to yarn2 version', async (t) => { + const depTree = await buildDepTreeFromFiles( + `${__dirname}/fixtures/missing-dot-yarnrc-yarn2/`, + 'package.json', + `yarn.lock`, + ); + + t.equal(depTree.meta?.packageManagerVersion, '2', 'resolved to yarn v2'); +});