├── .gitignore ├── LICENSE ├── README.md ├── __fixtures__ ├── npm │ ├── package.json │ └── pnpm-debug.log ├── pnpm │ └── package.json └── yarn │ ├── package.json │ └── pnpm-debug.log ├── bin.js ├── package.json └── pnpm-lock.yaml /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2020 Zoltan Kochan 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # only-allow 2 | 3 | > Force a specific package manager to be used on a project 4 | 5 | ## Usage 6 | 7 | Add a `preinstall` script to your project's `package.json`. 8 | 9 | If you want to force [npm](https://docs.npmjs.com/cli/npm), add: 10 | 11 | ```json 12 | { 13 | "scripts": { 14 | "preinstall": "npx only-allow npm" 15 | } 16 | } 17 | ``` 18 | 19 | If you want to force [cnpm](https://npmmirror.com/), add: 20 | 21 | ```json 22 | { 23 | "scripts": { 24 | "preinstall": "npx only-allow cnpm" 25 | } 26 | } 27 | ``` 28 | 29 | If you want to force [pnpm](https://pnpm.js.org/), add: 30 | 31 | ```json 32 | { 33 | "scripts": { 34 | "preinstall": "npx only-allow pnpm" 35 | } 36 | } 37 | ``` 38 | 39 | If you want to force [yarn](https://yarnpkg.com/), add: 40 | 41 | ```json 42 | { 43 | "scripts": { 44 | "preinstall": "npx only-allow yarn" 45 | } 46 | } 47 | ``` 48 | 49 | If you want to force [bun](https://bun.sh/), add: 50 | 51 | ```json 52 | { 53 | "scripts": { 54 | "preinstall": "npx only-allow bun" 55 | } 56 | } 57 | ``` 58 | 59 | ## License 60 | 61 | [MIT](LICENSE) 62 | -------------------------------------------------------------------------------- /__fixtures__/npm/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "preinstall": "node ../../bin.js npm" 4 | } 5 | } 6 | 7 | -------------------------------------------------------------------------------- /__fixtures__/npm/pnpm-debug.log: -------------------------------------------------------------------------------- 1 | { 2 | "0 debug pnpm:scope": { 3 | "selected": 1 4 | }, 5 | "1 debug pnpm:package-manifest": { 6 | "initial": { 7 | "scripts": { 8 | "preinstall": "node ../../bin.js npm" 9 | } 10 | }, 11 | "prefix": "/home/zoltan/src/pnpm/only-allow/__fixtures__/npm" 12 | }, 13 | "2 error pnpm": { 14 | "message": { 15 | "errno": 1, 16 | "code": "ELIFECYCLE", 17 | "pkgid": "@", 18 | "stage": "preinstall", 19 | "script": "node ../../bin.js npm" 20 | }, 21 | "err": { 22 | "name": "Error", 23 | "message": "@ preinstall: `node ../../bin.js npm`\nExit status 1", 24 | "code": "ELIFECYCLE", 25 | "stack": "Error: @ preinstall: `node ../../bin.js npm`\nExit status 1\n at EventEmitter. (/home/zoltan/.nvs/node/12.14.1/x64/pnpm-global/3/node_modules/.pnpm/registry.npmjs.org/pnpm/5.0.0-alpha.2/node_modules/pnpm/lib/node_modules/@zkochan/npm-lifecycle/index.js:302:16)\n at EventEmitter.emit (events.js:223:5)\n at ChildProcess. (/home/zoltan/.nvs/node/12.14.1/x64/pnpm-global/3/node_modules/.pnpm/registry.npmjs.org/pnpm/5.0.0-alpha.2/node_modules/pnpm/lib/node_modules/@zkochan/npm-lifecycle/lib/spawn.js:55:14)\n at ChildProcess.emit (events.js:223:5)\n at maybeClose (internal/child_process.js:1021:16)\n at Process.ChildProcess._handle.onexit (internal/child_process.js:283:5)" 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /__fixtures__/pnpm/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "preinstall": "node ../../bin.js pnpm" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /__fixtures__/yarn/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "preinstall": "node ../../bin.js yarn" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /__fixtures__/yarn/pnpm-debug.log: -------------------------------------------------------------------------------- 1 | { 2 | "0 debug pnpm:scope": { 3 | "selected": 1 4 | }, 5 | "1 debug pnpm:package-manifest": { 6 | "initial": { 7 | "scripts": { 8 | "preinstall": "node ../../bin.js yarn" 9 | } 10 | }, 11 | "prefix": "/home/zoltan/src/pnpm/only-allow/__fixtures__/yarn" 12 | }, 13 | "2 error pnpm": { 14 | "message": { 15 | "errno": 1, 16 | "code": "ELIFECYCLE", 17 | "pkgid": "@", 18 | "stage": "preinstall", 19 | "script": "node ../../bin.js yarn" 20 | }, 21 | "err": { 22 | "name": "Error", 23 | "message": "@ preinstall: `node ../../bin.js yarn`\nExit status 1", 24 | "code": "ELIFECYCLE", 25 | "stack": "Error: @ preinstall: `node ../../bin.js yarn`\nExit status 1\n at EventEmitter. (/home/zoltan/.nvs/node/12.14.1/x64/pnpm-global/3/node_modules/.pnpm/registry.npmjs.org/pnpm/5.0.0-alpha.2/node_modules/pnpm/lib/node_modules/@zkochan/npm-lifecycle/index.js:302:16)\n at EventEmitter.emit (events.js:223:5)\n at ChildProcess. (/home/zoltan/.nvs/node/12.14.1/x64/pnpm-global/3/node_modules/.pnpm/registry.npmjs.org/pnpm/5.0.0-alpha.2/node_modules/pnpm/lib/node_modules/@zkochan/npm-lifecycle/lib/spawn.js:55:14)\n at ChildProcess.emit (events.js:223:5)\n at maybeClose (internal/child_process.js:1021:16)\n at Process.ChildProcess._handle.onexit (internal/child_process.js:283:5)" 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /bin.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | const whichPMRuns = require('which-pm-runs') 3 | const availablePMList = ['npm', 'cnpm', 'pnpm', 'yarn', 'bun'] 4 | 5 | function box(s) { 6 | const lines = s.trim().split("\n") 7 | const width = lines.reduce((a, b) => Math.max(a, b.length), 0) 8 | const surround = x => '║ \x1b[0m' + x.padEnd(width) + '\x1b[31m ║' 9 | const bar = '═'.repeat(width) 10 | const top = '\x1b[31m╔═══' + bar + '═══╗' 11 | const pad = surround('') 12 | const bottom = '╚═══' + bar + '═══╝\x1b[0m' 13 | return [top, pad, ...lines.map(surround), pad, bottom].join('\n') 14 | } 15 | 16 | const argv = process.argv.slice(2) 17 | if (argv.length === 0) { 18 | console.log(`Please specify the wanted package manager: only-allow <${availablePMList.join('|')}>`) 19 | process.exit(1) 20 | } 21 | const wantedPM = argv[0] 22 | if (!availablePMList.includes(wantedPM)) { 23 | const pmStr = `${availablePMList.slice(0, -1).join(', ')} or ${availablePMList[availablePMList.length - 1]}` 24 | console.log(`"${wantedPM}" is not a valid package manager. Available package managers are: ${pmStr}.`) 25 | process.exit(1) 26 | } 27 | const usedPM = whichPMRuns() 28 | const cwd = process.env.INIT_CWD || process.cwd() 29 | const isInstalledAsDependency = cwd.includes('node_modules') 30 | if (usedPM && usedPM.name !== wantedPM && !isInstalledAsDependency) { 31 | switch (wantedPM) { 32 | case 'npm': 33 | console.log(box('Use "npm install" for installation in this project')) 34 | break 35 | case 'cnpm': 36 | console.log(box('Use "cnpm install" for installation in this project')) 37 | break 38 | case 'pnpm': 39 | console.log(box(`Use "pnpm install" for installation in this project. 40 | 41 | If you don't have pnpm, install it via "npm i -g pnpm". 42 | For more details, go to https://pnpm.io/`)) 43 | break 44 | case 'yarn': 45 | console.log(box(`Use "yarn" for installation in this project. 46 | 47 | If you don't have Yarn, install it via "npm i -g yarn". 48 | For more details, go to https://yarnpkg.com/`)) 49 | break 50 | 51 | case 'bun': 52 | console.log(box(`Use "bun install" for installation in this project. 53 | 54 | If you don't have Bun, go to https://bun.sh/docs/installation and find installation method that suits your environment.`)) 55 | break 56 | } 57 | process.exit(1) 58 | } 59 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "only-allow", 3 | "version": "1.2.1", 4 | "description": "Force a specific package manager to be used on a project", 5 | "main": "bin.js", 6 | "bin": "bin.js", 7 | "files": [ 8 | "bin.js" 9 | ], 10 | "scripts": {}, 11 | "keywords": [ 12 | "pnpm", 13 | "cnpm", 14 | "npm", 15 | "yarn", 16 | "bun" 17 | ], 18 | "author": "Zoltan Kochan ", 19 | "license": "MIT", 20 | "repository": { 21 | "type": "git", 22 | "url": "git+https://github.com/pnpm/only-allow.git" 23 | }, 24 | "bugs": { 25 | "url": "https://github.com/pnpm/only-allow/issues" 26 | }, 27 | "homepage": "https://github.com/pnpm/only-allow#readme", 28 | "dependencies": { 29 | "which-pm-runs": "^1.1.0" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: '6.0' 2 | 3 | settings: 4 | autoInstallPeers: true 5 | excludeLinksFromLockfile: false 6 | 7 | dependencies: 8 | which-pm-runs: 9 | specifier: ^1.1.0 10 | version: 1.1.0 11 | 12 | packages: 13 | 14 | /which-pm-runs@1.1.0: 15 | resolution: {integrity: sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==} 16 | engines: {node: '>=4'} 17 | dev: false 18 | --------------------------------------------------------------------------------