├── .gitignore ├── LICENSE ├── README.md ├── bin.js ├── index.js ├── package.json └── test ├── app.js └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Mathias Buus 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 13 | all 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 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # link-bin 2 | 3 | Make bin scripts work local npm dependencies. 4 | 5 | ``` 6 | npm install link-bin 7 | ``` 8 | 9 | Should be used as a post-install npm hook 10 | 11 | ## Usage 12 | 13 | Let's say you wanna put the following atom-shell app on npm 14 | 15 | ``` js 16 | #!/usr/bin/env atom-shell 17 | 18 | // this is an atom-shell app that just shows an empty screen 19 | var app = require('app') 20 | var BrowserWindow = require('browser-window') 21 | 22 | app.on('ready', function () { 23 | var win = new BrowserWindow({ 24 | width: 800, 25 | height: 600, 26 | show: true 27 | }) 28 | }) 29 | ``` 30 | 31 | Luckily [atom-shell](https://github.com/mafintosh/atom-shell) is installable through npm. 32 | If you save the above file as `app.js` you can then create the following `package.json` file 33 | 34 | ``` json 35 | { 36 | "name": "my-atom-shell-app", 37 | "version": "1.0.0", 38 | "description": "my atom-shell app", 39 | "bin": "app.js", 40 | "scripts": { 41 | "install": "link-bin" 42 | }, 43 | "dependencies": { 44 | "atom-shell": "^0.21.3-1", 45 | "link-bin": "^1.0.0" 46 | } 47 | } 48 | ``` 49 | 50 | If you publish the above program to npm other people will be able to `npm install -g my-atom-shell-app` 51 | and run `my-atom-shell-app` to execute the atom-shell app (even if they don't have atom-shell installed already) 52 | 53 | To test it you can also run `npm install -g .` in the folder where you added the above `app.js` and `package.json` files. 54 | 55 | ## License 56 | 57 | MIT 58 | -------------------------------------------------------------------------------- /bin.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | var link = require('./') 4 | var path = require('path') 5 | var fs = require('fs') 6 | 7 | if (!process.env.npm_package_name) { 8 | console.error('You should run link-bin as an npm install hook') 9 | process.exit(1) 10 | } 11 | 12 | var filenames = [].concat(process.argv[2] || []) 13 | 14 | if (!filenames.length) { 15 | try { 16 | var pkg = require(path.resolve('./package.json')) 17 | if (typeof pkg.bin === 'string') { 18 | filenames.push(pkg.bin) 19 | } else { 20 | Object.keys(pkg.bin).forEach(function (key) { 21 | filenames.push(pkg.bin[key]) 22 | }) 23 | } 24 | } catch (err) { 25 | // ... 26 | } 27 | } 28 | 29 | filenames.forEach(function (filename) { 30 | filename = path.resolve(filename) 31 | var target = path.join(path.dirname(filename), 'link-bin-' + path.basename(filename)) 32 | link(filename, target, function (err, bin) { 33 | if (err) throw err 34 | if (!fs.existsSync(target)) fs.renameSync(filename, target) 35 | fs.writeFileSync(filename, bin) 36 | fs.chmodSync(filename, 33261) 37 | }) 38 | }) 39 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | var os = require('os') 2 | var fs = require('fs') 3 | var path = require('path') 4 | 5 | var getPath = function (cb) { 6 | var dirs = [] 7 | 8 | var loop = function (cwd) { 9 | var bin = path.join(cwd, 'node_modules', '.bin') 10 | fs.exists(bin, function (exists) { 11 | if (exists) dirs.push(bin) 12 | var next = path.join(cwd, '..') 13 | if (next === cwd) return cb(null, dirs) 14 | loop(next) 15 | }) 16 | } 17 | 18 | loop(__dirname) 19 | } 20 | 21 | module.exports = function (filename, target, cb) { 22 | if (typeof target === 'function') return module.exports(filename, null, target) 23 | getPath(function (err, dirs) { 24 | if (err) return cb(err) 25 | cb(null, 'export PATH="' + dirs.join(':') + ':$PATH"' + os.EOL + (target || filename) + ' "$@"' + os.EOL) 26 | }) 27 | } 28 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "link-bin", 3 | "version": "2.0.2", 4 | "description": "Make bin scripts work local npm dependencies", 5 | "main": "index.js", 6 | "dependencies": {}, 7 | "devDependencies": { 8 | "standard": "^3.1.2" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "https://github.com/mafintosh/link-bin.git" 13 | }, 14 | "bin": { 15 | "link-bin": "./bin.js" 16 | }, 17 | "scripts": { 18 | "test": "standard" 19 | }, 20 | "keywords": [ 21 | "npm", 22 | "install", 23 | "hook", 24 | "bin", 25 | "local" 26 | ], 27 | "author": "Mathias Buus (@mafintosh)", 28 | "license": "MIT", 29 | "bugs": { 30 | "url": "https://github.com/mafintosh/link-bin/issues" 31 | }, 32 | "homepage": "https://github.com/mafintosh/link-bin" 33 | } 34 | -------------------------------------------------------------------------------- /test/app.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env atom-shell 2 | 3 | var app = require('app') 4 | var BrowserWindow = require('browser-window') 5 | 6 | var createWindow = function () { 7 | return new BrowserWindow({ 8 | width: 800, 9 | height: 600, 10 | show: true 11 | }) 12 | } 13 | 14 | app.on('ready', createWindow) 15 | -------------------------------------------------------------------------------- /test/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "my-atom-shell-app", 3 | "version": "1.0.4", 4 | "description": "my atom-shell app", 5 | "bin": "app.js", 6 | "scripts": { 7 | "install": "link-bin" 8 | }, 9 | "dependencies": { 10 | "atom-shell": "^0.21.3-1", 11 | "link-bin": "^2.0.0" 12 | } 13 | } 14 | --------------------------------------------------------------------------------