diff --git a/__tests__/commands/remove.js b/__tests__/commands/remove.js index 416899c0a1..01ee88672e 100644 --- a/__tests__/commands/remove.js +++ b/__tests__/commands/remove.js @@ -78,9 +78,9 @@ test.concurrent('removes multiple installed packages', (): Promise => { }); -test.concurrent('removes scoped packages', (): Promise => { - return runRemove(['@scoped/package'], {}, 'scoped-package', async (config): Promise => { - assert(!await fs.exists(path.join(config.cwd, 'node_modules/@scoped'))); +test.concurrent('removes the whole scope when all scoped packages are removed', (): Promise => { + return runRemove(['@dengorbachev/foo', '@dengorbachev/bar'], {}, 'scoped-package', async (config): Promise => { + assert(!await fs.exists(path.join(config.cwd, 'node_modules/@dengorbachev'))); assert.deepEqual( JSON.parse(await fs.readFile(path.join(config.cwd, 'package.json'))).dependencies, @@ -93,6 +93,23 @@ test.concurrent('removes scoped packages', (): Promise => { }); }); +test.concurrent('removes a single scoped package', (): Promise => { + return runRemove(['@dengorbachev/foo'], {}, 'scoped-package', async (config): Promise => { + assert(!await fs.exists(path.join(config.cwd, 'node_modules/@dengorbachev/foo'))); + + assert.deepEqual( + JSON.parse(await fs.readFile(path.join(config.cwd, 'package.json'))).dependencies, + { + '@dengorbachev/bar': '^1.0.0', + }, + ); + + const lockFileContent = await fs.readFile(path.join(config.cwd, 'yarn.lock')); + const lockFileLines = explodeLockfile(lockFileContent); + assert.equal(lockFileLines.length, 3); + }); +}); + test.concurrent('removes subdependencies', (): Promise => { // A@1 -> B@1 // C@1 diff --git a/__tests__/fixtures/remove/scoped-package/node_modules/.yarn-integrity b/__tests__/fixtures/remove/scoped-package/node_modules/.yarn-integrity index 531c001f2f..ff230ab017 100644 --- a/__tests__/fixtures/remove/scoped-package/node_modules/.yarn-integrity +++ b/__tests__/fixtures/remove/scoped-package/node_modules/.yarn-integrity @@ -1 +1 @@ -474bcc9efc4057590d34522e69b2321efbd7eafcd557a56c66b08d8ad6334cfd \ No newline at end of file +638fae19c136efd6d59f7519ecd8e02255b254d9c68d27af5198305d115a8533 \ No newline at end of file diff --git a/__tests__/fixtures/remove/scoped-package/node_modules/@dengorbachev/bar/package.json b/__tests__/fixtures/remove/scoped-package/node_modules/@dengorbachev/bar/package.json new file mode 100644 index 0000000000..2449e98f41 --- /dev/null +++ b/__tests__/fixtures/remove/scoped-package/node_modules/@dengorbachev/bar/package.json @@ -0,0 +1,11 @@ +{ + "name": "@dengorbachev/bar", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC" +} diff --git a/__tests__/fixtures/remove/scoped-package/node_modules/@dengorbachev/foo/package.json b/__tests__/fixtures/remove/scoped-package/node_modules/@dengorbachev/foo/package.json new file mode 100644 index 0000000000..9f4ceed929 --- /dev/null +++ b/__tests__/fixtures/remove/scoped-package/node_modules/@dengorbachev/foo/package.json @@ -0,0 +1,11 @@ +{ + "name": "@dengorbachev/foo", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC" +} diff --git a/__tests__/fixtures/remove/scoped-package/node_modules/@scoped/package/.npmignore b/__tests__/fixtures/remove/scoped-package/node_modules/@scoped/package/.npmignore deleted file mode 100644 index 3b3a32f78f..0000000000 --- a/__tests__/fixtures/remove/scoped-package/node_modules/@scoped/package/.npmignore +++ /dev/null @@ -1,22 +0,0 @@ -tmp -node_modules -*._ -*.tmp -.monitor -*.diff -*.err -*.orig -*.log -*.rej -*.swo -*.swp -*.vi -*~ -.DS_Store -Thumbs.db -.cache -.project -.settings -.tmproj -*.esproj -nbproject diff --git a/__tests__/fixtures/remove/scoped-package/node_modules/@scoped/package/.travis.yml b/__tests__/fixtures/remove/scoped-package/node_modules/@scoped/package/.travis.yml deleted file mode 100644 index b8e1f17207..0000000000 --- a/__tests__/fixtures/remove/scoped-package/node_modules/@scoped/package/.travis.yml +++ /dev/null @@ -1,3 +0,0 @@ -language: node_js -node_js: - - 0.6 \ No newline at end of file diff --git a/__tests__/fixtures/remove/scoped-package/node_modules/@scoped/package/History.md b/__tests__/fixtures/remove/scoped-package/node_modules/@scoped/package/History.md deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/__tests__/fixtures/remove/scoped-package/node_modules/@scoped/package/Makefile b/__tests__/fixtures/remove/scoped-package/node_modules/@scoped/package/Makefile deleted file mode 100644 index 277485cbc9..0000000000 --- a/__tests__/fixtures/remove/scoped-package/node_modules/@scoped/package/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -TESTS = $(shell find test -iname \*.test.js) - -test: - @NODE_ENV=test ./node_modules/.bin/mocha \ - --require should \ - --reporter spec \ - $(TESTS) - -clean: - rm -f examples/tmp/* - -.PHONY: test clean \ No newline at end of file diff --git a/__tests__/fixtures/remove/scoped-package/node_modules/@scoped/package/Readme.md b/__tests__/fixtures/remove/scoped-package/node_modules/@scoped/package/Readme.md deleted file mode 100644 index c531965867..0000000000 --- a/__tests__/fixtures/remove/scoped-package/node_modules/@scoped/package/Readme.md +++ /dev/null @@ -1,54 +0,0 @@ -[![Build Status](https://secure.travis-ci.org/vesln/package.png)](http://travis-ci.org/vesln/package) - -# package - Easy package.json exports. - -## Intro - -This module provides an easy and simple way to export package.json data. - -## Installation - - $ npm install package - -## Usage - - var package = require('package')(module); // contains package.json data. - var yourAwesomeModule = {}; - yourAwesomeModule.version = package.version; - -## Tests - - $ make test - -## Contribution - -Bug fixes and features are welcomed. - -## Other similar modules - -- pkginfo (https://github.com/indexzero/node-pkginfo) by indexzero. -- JSON.parse + fs.readFile - -## License - -MIT License - -Copyright (C) 2012 Veselin Todorov - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file diff --git a/__tests__/fixtures/remove/scoped-package/node_modules/@scoped/package/examples/custom_path.js b/__tests__/fixtures/remove/scoped-package/node_modules/@scoped/package/examples/custom_path.js deleted file mode 100644 index a03c0cc01a..0000000000 --- a/__tests__/fixtures/remove/scoped-package/node_modules/@scoped/package/examples/custom_path.js +++ /dev/null @@ -1,14 +0,0 @@ -/** - * package - Easy package.json exports. - * - * Author: Veselin Todorov - * Licensed under the MIT License. - */ - -/** - * Dependencies. - */ - -var package = require('../')(__dirname + '/..'); // parent dir. - -console.log(package); // This will contain the package.json data. \ No newline at end of file diff --git a/__tests__/fixtures/remove/scoped-package/node_modules/@scoped/package/examples/module.js b/__tests__/fixtures/remove/scoped-package/node_modules/@scoped/package/examples/module.js deleted file mode 100644 index c4790692d9..0000000000 --- a/__tests__/fixtures/remove/scoped-package/node_modules/@scoped/package/examples/module.js +++ /dev/null @@ -1,14 +0,0 @@ -/** - * package - Easy package.json exports. - * - * Author: Veselin Todorov - * Licensed under the MIT License. - */ - -/** - * Dependencies. - */ - -var package = require('../')(module); - -console.log(package); // This will contain the package.json data. \ No newline at end of file diff --git a/__tests__/fixtures/remove/scoped-package/node_modules/@scoped/package/lib/package.js b/__tests__/fixtures/remove/scoped-package/node_modules/@scoped/package/lib/package.js deleted file mode 100644 index 348db0ce44..0000000000 --- a/__tests__/fixtures/remove/scoped-package/node_modules/@scoped/package/lib/package.js +++ /dev/null @@ -1,64 +0,0 @@ -/** - * package - Easy package.json exports. - * - * Author: Veselin Todorov - * Licensed under the MIT License. - */ - -/** - * Dependencies. - */ -var fs = require('fs'); -var path = require('path'); -var exists = fs.existsSync || path.existsSync; - -/** - * Package. - * - * @param {String|null} location - * @returns {Object} package.json data - */ -var package = function(location) { - if (location === Object(location)) { - location = package.discover(location); - } - return package.read(path.normalize(location + '/package.json')); -}; - -/** - * Reads and parses a package.json file. - * - * @param {String} file - * @returns {Object} package.json data - */ -package.read = function(file) { - var data = fs.readFileSync(file, 'utf8'); - return JSON.parse(data); -}; - -/** - * Makes an atempt to find package.json file. - * - * @returns {Object} package.json data - */ -package.discover = function(module) { - var location = path.dirname(module.filename); - var found = null; - - while (!found) { - if (exists(location + '/package.json')) { - found = location; - } else if (location !== '/') { - location = path.dirname(location); - } else { - throw new Error('package.json can not be located'); - } - } - - return found; -}; - -/** - * Exporting the lib. - */ -module.exports = package; diff --git a/__tests__/fixtures/remove/scoped-package/node_modules/@scoped/package/package.json b/__tests__/fixtures/remove/scoped-package/node_modules/@scoped/package/package.json deleted file mode 100644 index 2b171b0524..0000000000 --- a/__tests__/fixtures/remove/scoped-package/node_modules/@scoped/package/package.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "name": "package" - , "version": "1.0.1" - , "description": "Easy package.json exports." - , "keywords": ["package.json"] - , "author": "Veselin Todorov " - , "devDependencies": { - "mocha": "0.3.3" - , "should": "0.3.2" - } - , "repository" : { - "type" : "git", - "url" : "http://github.com/vesln/package.git" - } - , "homepage": "http://github.com/vesln/package" - , "scripts": { - "test": "make test" - } - , "main": "./lib/package" - , "engines": { "node": ">= 0.6.0" } -} diff --git a/__tests__/fixtures/remove/scoped-package/node_modules/@scoped/package/test/index.test.js b/__tests__/fixtures/remove/scoped-package/node_modules/@scoped/package/test/index.test.js deleted file mode 100644 index c43364bc46..0000000000 --- a/__tests__/fixtures/remove/scoped-package/node_modules/@scoped/package/test/index.test.js +++ /dev/null @@ -1,42 +0,0 @@ -/** - * package - Easy package.json exports. - * - * Author: Veselin Todorov - * Licensed under the MIT License. - */ - -/** - * Dependencies. - */ -var package = require('../'); - -describe('package', function() { - describe('read', function() { - it('should read and parse .json file', function() { - var result = package.read(__dirname + '/support/package.json'); - result.should.eql({ - name: 'test-package-json-file', - version: '0.0.1', - private: true - }); - }); - }); - - it('should read and parse given .json file', function() { - var result = package(__dirname + '/support'); - result.should.eql({ - name: 'test-package-json-file', - version: '0.0.1', - private: true - }); - }); - - it('should autodiscover, read and parse package.json', function() { - var result = package(module); - result.should.eql({ - name: 'test-package-json-file', - version: '0.0.1', - private: true - }); - }); -}); \ No newline at end of file diff --git a/__tests__/fixtures/remove/scoped-package/node_modules/@scoped/package/test/nested/two/nested.test.js b/__tests__/fixtures/remove/scoped-package/node_modules/@scoped/package/test/nested/two/nested.test.js deleted file mode 100644 index 99c012ed9e..0000000000 --- a/__tests__/fixtures/remove/scoped-package/node_modules/@scoped/package/test/nested/two/nested.test.js +++ /dev/null @@ -1,22 +0,0 @@ -/** - * package - Easy package.json exports. - * - * Author: Veselin Todorov - * Licensed under the MIT License. - */ - -/** - * Dependencies. - */ -var package = require('../../../'); - -describe('nested package json', function() { - it('should autodiscover, read and parse package.json', function() { - var result = package(module); - result.should.eql({ - name: 'test-package-json-file', - version: '0.0.1', - private: true - }); - }); -}); \ No newline at end of file diff --git a/__tests__/fixtures/remove/scoped-package/node_modules/@scoped/package/test/package.json b/__tests__/fixtures/remove/scoped-package/node_modules/@scoped/package/test/package.json deleted file mode 100644 index ed5e67177d..0000000000 --- a/__tests__/fixtures/remove/scoped-package/node_modules/@scoped/package/test/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "test-package-json-file" - , "version": "0.0.1" - , "private": true -} \ No newline at end of file diff --git a/__tests__/fixtures/remove/scoped-package/node_modules/@scoped/package/test/support/package.json b/__tests__/fixtures/remove/scoped-package/node_modules/@scoped/package/test/support/package.json deleted file mode 100644 index ed5e67177d..0000000000 --- a/__tests__/fixtures/remove/scoped-package/node_modules/@scoped/package/test/support/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "test-package-json-file" - , "version": "0.0.1" - , "private": true -} \ No newline at end of file diff --git a/__tests__/fixtures/remove/scoped-package/package.json b/__tests__/fixtures/remove/scoped-package/package.json index 2bd6715d5a..693e7c8ce5 100644 --- a/__tests__/fixtures/remove/scoped-package/package.json +++ b/__tests__/fixtures/remove/scoped-package/package.json @@ -1,5 +1,6 @@ { "dependencies": { - "@scoped/package": "^1.0.1" + "@dengorbachev/bar": "^1.0.0", + "@dengorbachev/foo": "^1.0.0" } } diff --git a/__tests__/fixtures/remove/scoped-package/yarn.lock b/__tests__/fixtures/remove/scoped-package/yarn.lock index 9825bb12aa..78e3e53bc0 100644 --- a/__tests__/fixtures/remove/scoped-package/yarn.lock +++ b/__tests__/fixtures/remove/scoped-package/yarn.lock @@ -1,6 +1,11 @@ # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. # yarn lockfile v1 -"@scoped/package": - version "1.0.1" - resolved package-1.0.1.tgz#d25a1f99e2506dcb27d6704b83dca8a312e4edcc + +"@dengorbachev/bar@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@dengorbachev/bar/-/bar-1.0.0.tgz#f01d868a938353e52703a6751ebf07e92016060d" + +"@dengorbachev/foo@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@dengorbachev/foo/-/foo-1.0.0.tgz#67a8228a6cc54d7062b1de314bad734882302205" diff --git a/src/package-linker.js b/src/package-linker.js index b637348374..b991859f5b 100644 --- a/src/package-linker.js +++ b/src/package-linker.js @@ -150,15 +150,23 @@ export default class PackageLinker { }); } - // register root packages as being possibly extraneous + // register root & scoped packages as being possibly extraneous const possibleExtraneous: Set = new Set(); for (const folder of this.config.registryFolders) { const loc = path.join(this.config.cwd, folder); if (await fs.exists(loc)) { const files = await fs.readdir(loc); + let filepath; for (const file of files) { - possibleExtraneous.add(path.join(loc, file)); + filepath = path.join(loc, file); + possibleExtraneous.add(filepath); + if (file[0] === '@') { // it's a scope, not a package + const subfiles = await fs.readdir(filepath); + for (const subfile of subfiles) { + possibleExtraneous.add(path.join(filepath, subfile)); + } + } } } }