├── .eslintignore ├── README.md ├── .eslintrc.js ├── cli.js ├── package.json └── .gitignore /.eslintignore: -------------------------------------------------------------------------------- 1 | *.* 2 | !*.ts 3 | !*.js 4 | node_modules 5 | dist 6 | /lib/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # concurrently-cd 2 | 3 | [concurrently](https://www.npmjs.com/package/concurrently), but also cd into directories. 4 | 5 | ## Usage 6 | 7 | ```sh 8 | concurrently-cd 'packages/*:npm:dev' 'packages/pyserver:poetry:flask' 9 | ``` 10 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | es6: true, 4 | node: true 5 | }, 6 | extends: [ 7 | 'standard' 8 | ], 9 | globals: { 10 | Atomics: 'readonly', 11 | SharedArrayBuffer: 'readonly' 12 | }, 13 | parser: '@typescript-eslint/parser', 14 | parserOptions: { 15 | ecmaVersion: 2018, 16 | sourceType: 'module' 17 | }, 18 | plugins: [ 19 | '@typescript-eslint' 20 | ], 21 | rules: { 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /cli.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const concurrently = require('concurrently') 4 | const glob = require('glob') 5 | const { quote } = require('shlex') 6 | 7 | const cmds = process.argv.slice(2).map(c => { 8 | let [, path, cmd = ''] = /^([^:]+):(.+)$/.exec(c) || [] 9 | const [, cmd1, cmd2] = /^([^:]+):(.+)$/.exec(cmd) || [] 10 | cmd = cmd2 11 | ? `${cmd1} run ${cmd2} --if-present` 12 | : cmd ? `if command -v ${quote(cmd)} > /dev/null; then ${cmd} fi` : '' 13 | 14 | return cmd ? glob.sync(path).map(p => [ 15 | `cd ${quote(p)}`, 16 | cmd 17 | ].join(' && ')) : [c] 18 | }).reduce((prev, c) => [...prev, ...c], []) 19 | 20 | concurrently(cmds) 21 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "concurrently-cd", 3 | "version": "1.0.1", 4 | "description": "Concurrently, but also cd into directories", 5 | "repository": "github:patarapolw/concurrently-cd", 6 | "main": "cli.js", 7 | "bin": { 8 | "concurrently-cd": "cli.js" 9 | }, 10 | "scripts": { 11 | "build": "tsc", 12 | "test": "echo \"Error: no test specified\" && exit 1" 13 | }, 14 | "keywords": [ 15 | "concurrently" 16 | ], 17 | "author": { 18 | "email": "patarapolw@gmail.com", 19 | "name": "Pacharapol Withayasakpunt" 20 | }, 21 | "license": "ISC", 22 | "dependencies": { 23 | "glob": "^7.1.6", 24 | "shlex": "^2.0.2" 25 | }, 26 | "devDependencies": { 27 | "@typescript-eslint/eslint-plugin": "^2.30.0", 28 | "@typescript-eslint/parser": "^2.30.0", 29 | "concurrently": "^5.2.0", 30 | "eslint": "^6.8.0", 31 | "eslint-config-standard": "^14.1.1", 32 | "eslint-plugin-import": "^2.20.2", 33 | "eslint-plugin-node": "^11.1.0", 34 | "eslint-plugin-promise": "^4.2.1", 35 | "eslint-plugin-standard": "^4.0.1", 36 | "typescript": "^3.8.3" 37 | }, 38 | "peerDependencies": { 39 | "concurrently": "5.x" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/macos,node 3 | # Edit at https://www.gitignore.io/?templates=macos,node 4 | 5 | ### macOS ### 6 | # General 7 | .DS_Store 8 | .AppleDouble 9 | .LSOverride 10 | 11 | # Icon must end with two \r 12 | Icon 13 | 14 | # Thumbnails 15 | ._* 16 | 17 | # Files that might appear in the root of a volume 18 | .DocumentRevisions-V100 19 | .fseventsd 20 | .Spotlight-V100 21 | .TemporaryItems 22 | .Trashes 23 | .VolumeIcon.icns 24 | .com.apple.timemachine.donotpresent 25 | 26 | # Directories potentially created on remote AFP share 27 | .AppleDB 28 | .AppleDesktop 29 | Network Trash Folder 30 | Temporary Items 31 | .apdisk 32 | 33 | ### Node ### 34 | # Logs 35 | logs 36 | *.log 37 | npm-debug.log* 38 | yarn-debug.log* 39 | yarn-error.log* 40 | lerna-debug.log* 41 | 42 | # Diagnostic reports (https://nodejs.org/api/report.html) 43 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 44 | 45 | # Runtime data 46 | pids 47 | *.pid 48 | *.seed 49 | *.pid.lock 50 | 51 | # Directory for instrumented libs generated by jscoverage/JSCover 52 | lib-cov 53 | 54 | # Coverage directory used by tools like istanbul 55 | coverage 56 | *.lcov 57 | 58 | # nyc test coverage 59 | .nyc_output 60 | 61 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 62 | .grunt 63 | 64 | # Bower dependency directory (https://bower.io/) 65 | bower_components 66 | 67 | # node-waf configuration 68 | .lock-wscript 69 | 70 | # Compiled binary addons (https://nodejs.org/api/addons.html) 71 | build/Release 72 | 73 | # Dependency directories 74 | node_modules/ 75 | jspm_packages/ 76 | 77 | # TypeScript v1 declaration files 78 | typings/ 79 | 80 | # TypeScript cache 81 | *.tsbuildinfo 82 | 83 | # Optional npm cache directory 84 | .npm 85 | 86 | # Optional eslint cache 87 | .eslintcache 88 | 89 | # Optional REPL history 90 | .node_repl_history 91 | 92 | # Output of 'npm pack' 93 | *.tgz 94 | 95 | # Yarn Integrity file 96 | .yarn-integrity 97 | 98 | # dotenv environment variables file 99 | .env 100 | .env.test 101 | 102 | # parcel-bundler cache (https://parceljs.org/) 103 | .cache 104 | 105 | # next.js build output 106 | .next 107 | 108 | # nuxt.js build output 109 | .nuxt 110 | 111 | # rollup.js default build output 112 | dist/ 113 | 114 | # Uncomment the public line if your project uses Gatsby 115 | # https://nextjs.org/blog/next-9-1#public-directory-support 116 | # https://create-react-app.dev/docs/using-the-public-folder/#docsNav 117 | # public 118 | 119 | # Storybook build outputs 120 | .out 121 | .storybook-out 122 | 123 | # vuepress build output 124 | .vuepress/dist 125 | 126 | # Serverless directories 127 | .serverless/ 128 | 129 | # FuseBox cache 130 | .fusebox/ 131 | 132 | # DynamoDB Local files 133 | .dynamodb/ 134 | 135 | # Temporary folders 136 | tmp/ 137 | temp/ 138 | 139 | # End of https://www.gitignore.io/api/macos,node 140 | 141 | /lib/ 142 | --------------------------------------------------------------------------------