diff --git a/lib/packExternalModules.js b/lib/packExternalModules.js index a097a7f08..66db7ad64 100644 --- a/lib/packExternalModules.js +++ b/lib/packExternalModules.js @@ -9,9 +9,9 @@ const isBuiltinModule = require('is-builtin-module'); const Packagers = require('./packagers'); function rebaseFileReferences(pathToPackageRoot, moduleVersion) { - if (/^file:[^/]{2}/.test(moduleVersion)) { + if (/^(?:file:[^/]{2}|\.\/|\.\.\/)/.test(moduleVersion)) { const filePath = _.replace(moduleVersion, /^file:/, ''); - return _.replace(`file:${pathToPackageRoot}/${filePath}`, /\\/g, '/'); + return _.replace(`${_.startsWith(moduleVersion, 'file:') ? 'file:' : ''}${pathToPackageRoot}/${filePath}`, /\\/g, '/'); } return moduleVersion; @@ -246,7 +246,7 @@ module.exports = { if (exists) { this.serverless.cli.log('Package lock found - Using locked versions'); try { - let packageLockJson = this.serverless.utils.readFileSync(packageLockPath); + let packageLockFile = this.serverless.utils.readFileSync(packageLockPath); /** * We should not be modifying 'package-lock.json' * because this file should be treat as internal to npm. @@ -254,12 +254,12 @@ module.exports = { * Rebase package-lock is a temporary workaround and must be * removed as soon as https://github.com/npm/npm/issues/19183 gets fixed. */ - packager.rebaseLockfile(relPath, packageLockJson); - if (_.isObject(packageLockJson)) { - packageLockJson = JSON.stringify(packageLockJson, null, 2); + packageLockFile = packager.rebaseLockfile(relPath, packageLockFile); + if (_.isObject(packageLockFile)) { + packageLockFile = JSON.stringify(packageLockFile, null, 2); } - this.serverless.utils.writeFileSync(path.join(compositeModulePath, packager.lockfileName), packageLockJson); + this.serverless.utils.writeFileSync(path.join(compositeModulePath, packager.lockfileName), packageLockFile); hasPackageLock = true; } catch(err) { this.serverless.cli.log(`Warning: Could not read lock file: ${err.message}`); diff --git a/lib/packagers/npm.js b/lib/packagers/npm.js index 2a947ff20..443f7b9c8 100644 --- a/lib/packagers/npm.js +++ b/lib/packagers/npm.js @@ -76,6 +76,8 @@ class NPM { NPM.rebaseLockfile(pathToPackageRoot, lockedDependency); }); } + + return lockfile; } static install(cwd) { diff --git a/lib/packagers/yarn.js b/lib/packagers/yarn.js index 4dde35712..bcd961a64 100644 --- a/lib/packagers/yarn.js +++ b/lib/packagers/yarn.js @@ -79,8 +79,23 @@ class Yarn { }); } - // TODO: Check if we need that for Yarn - static rebaseLockfile(/* pathToPackageRoot, lockfile */) { + static rebaseLockfile(pathToPackageRoot, lockfile) { + const fileVersionMatcher = /[^"/]@(?:file:)?((?:\.\/|\.\.\/).*?)[":,]/gm; + const replacements = []; + let match; + + // Detect all references and create replacement line strings + while ((match = fileVersionMatcher.exec(lockfile)) !== null) { + replacements.push({ + oldRef: match[1], + newRef: _.replace(`${pathToPackageRoot}/${match[1]}`, /\\/g, '/') + }); + } + + // Replace all lines in lockfile + return _.reduce(replacements, (__, replacement) => { + return _.replace(__, replacement.oldRef, replacement.newRef); + }, lockfile); } static install(cwd, packagerOptions) { diff --git a/lib/packagers/yarn.test.js b/lib/packagers/yarn.test.js index 7b35e5a38..a20edb733 100644 --- a/lib/packagers/yarn.test.js +++ b/lib/packagers/yarn.test.js @@ -115,8 +115,87 @@ describe('yarn', () => { it('should return the original lockfile', () => { const testContent = 'eugfogfoigqwoeifgoqwhhacvaisvciuviwefvc'; const testContent2 = 'eugfogfoigqwoeifgoqwhhacvaisvciuviwefvc'; - yarnModule.rebaseLockfile('.', testContent); - expect(testContent).to.equal(testContent2); + expect(yarnModule.rebaseLockfile('.', testContent)).to.equal(testContent2); + }); + + it('should rebase file references', () => { + const testContent = ` + acorn@^2.1.0, acorn@^2.4.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-2.7.0.tgz#ab6e7d9d886aaca8b085bc3312b79a198433f0e7" + + acorn@^3.0.4: + version "3.3.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" + + otherModule@file:../../otherModule/the-new-version: + version "1.2.0" + + acorn@^2.1.0, acorn@^2.4.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-2.7.0.tgz#ab6e7d9d886aaca8b085bc3312b79a198433f0e7" + + "@myCompany/myModule@../../myModule/the-new-version": + version "6.1.0" + dependencies: + aws-xray-sdk "^1.1.6" + aws4 "^1.6.0" + base-x "^3.0.3" + bluebird "^3.5.1" + chalk "^1.1.3" + cls-bluebird "^2.1.0" + continuation-local-storage "^3.2.1" + lodash "^4.17.4" + moment "^2.20.0" + redis "^2.8.0" + request "^2.83.0" + ulid "^0.1.0" + uuid "^3.1.0" + + acorn@^5.0.0, acorn@^5.5.0: + version "5.5.3" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.5.3.tgz#f473dd47e0277a08e28e9bec5aeeb04751f0b8c9" + `; + + const expectedContent = ` + acorn@^2.1.0, acorn@^2.4.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-2.7.0.tgz#ab6e7d9d886aaca8b085bc3312b79a198433f0e7" + + acorn@^3.0.4: + version "3.3.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" + + otherModule@file:../../project/../../otherModule/the-new-version: + version "1.2.0" + + acorn@^2.1.0, acorn@^2.4.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-2.7.0.tgz#ab6e7d9d886aaca8b085bc3312b79a198433f0e7" + + "@myCompany/myModule@../../project/../../myModule/the-new-version": + version "6.1.0" + dependencies: + aws-xray-sdk "^1.1.6" + aws4 "^1.6.0" + base-x "^3.0.3" + bluebird "^3.5.1" + chalk "^1.1.3" + cls-bluebird "^2.1.0" + continuation-local-storage "^3.2.1" + lodash "^4.17.4" + moment "^2.20.0" + redis "^2.8.0" + request "^2.83.0" + ulid "^0.1.0" + uuid "^3.1.0" + + acorn@^5.0.0, acorn@^5.5.0: + version "5.5.3" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.5.3.tgz#f473dd47e0277a08e28e9bec5aeeb04751f0b8c9" + `; + + expect(yarnModule.rebaseLockfile('../../project', testContent)).to.equal(expectedContent); }); });