├── .circleci ├── config.yml └── loadgpg ├── .editorconfig ├── .eslintignore ├── .eslintrc ├── .gitattributes ├── .github ├── CODEOWNERS ├── dependabot.yml └── workflows │ ├── ci.yml │ └── stale.yml ├── .gitignore ├── .mocharc.json ├── .releaserc.json ├── CHANGELOG.md ├── LICENSE ├── README.md ├── bin ├── run └── run.cmd ├── package.json ├── src ├── aws.ts ├── commands │ ├── manifest.ts │ ├── pack │ │ ├── deb.ts │ │ ├── index.ts │ │ ├── macos.ts │ │ └── win.ts │ ├── publish │ │ ├── deb.ts │ │ ├── github.ts │ │ ├── index.ts │ │ ├── macos.ts │ │ └── win.ts │ └── readme.ts ├── help-compatibility.ts ├── index.ts ├── log.ts ├── tarballs │ ├── bin.ts │ ├── build.ts │ ├── config.ts │ ├── index.ts │ └── node.ts └── util.ts ├── test ├── deb.test.ts ├── fixtures │ ├── cli-with-custom-help-no-format-command │ │ ├── README.md │ │ ├── package.json │ │ ├── src │ │ │ ├── commands │ │ │ │ └── hello.ts │ │ │ ├── help.ts │ │ │ └── index.ts │ │ └── tsconfig.json │ ├── cli-with-custom-help │ │ ├── README.md │ │ ├── package.json │ │ ├── src │ │ │ ├── commands │ │ │ │ └── hello.ts │ │ │ ├── help.ts │ │ │ └── index.ts │ │ └── tsconfig.json │ └── cli-with-old-school-custom-help │ │ ├── README.md │ │ ├── package.json │ │ ├── src │ │ ├── commands │ │ │ └── hello.ts │ │ ├── help.ts │ │ └── index.ts │ │ └── tsconfig.json ├── helpers │ └── init.js ├── macos.test.ts ├── manifest.test.ts ├── publish.test.ts ├── readme.test.ts ├── release.key ├── tsconfig.json └── win.test.ts ├── tsconfig.json └── yarn.lock /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: 2.1 3 | orbs: 4 | node: circleci/node@4.7.0 5 | jobs: 6 | test-node: &test 7 | parameters: 8 | node-version: 9 | type: string 10 | description: "node.js version to install" 11 | docker: 12 | - image: oclif/nsis:12.0.0-16 13 | working_directory: ~/cli 14 | environment: 15 | NYC: "yarn exec nyc -- --nycrc-path node_modules/@oclif/nyc-config/.nycrc" 16 | steps: 17 | - checkout 18 | - run: &setup_yarn 19 | name: Setup Yarn 20 | command: | 21 | mkdir -p .yarn 22 | echo "--install.cache-path $(pwd)/.yarn/cache" >> .yarnrc 23 | echo "--install.prefer-offline" >> .yarnrc 24 | echo "yarn-offline-mirror $(pwd)/.yarn/offline-mirror" >> .yarnrc 25 | - node/install: &install_node 26 | node-version: << parameters.node-version >> 27 | - run: 28 | name: Yarn Install 29 | command: | 30 | npm install yarn -g 31 | - run: &create_cache_key_file 32 | name: "Create Cache Key File" 33 | command: | 34 | echo "node: $(node --version)" >> .circleci-cache-key 35 | echo "yarn: $(yarn --version)" >> .circleci-cache-key 36 | echo "yarnrc: $(sha256sum .yarnrc)" >> .circleci-cache-key 37 | echo ".circleci/config.yml: $(sha256sum .circleci/config.yml)" >> .circleci-cache-key 38 | - node/install-packages: &install_node_packages 39 | cache-path: ".yarn" 40 | cache-version: &cache_key | 41 | {{checksum ".circleci-cache-key"}} 42 | pkg-manager: yarn 43 | include-branch-in-cache-key: false 44 | - run: 'echo "Node: `node --version`"' 45 | - run: .circleci/loadgpg 46 | - run: yarn add -D nyc@13 @oclif/nyc-config@1 47 | - run: ./node_modules/.bin/tsc 48 | - run: ./bin/run --version 49 | - run: ./bin/run --help 50 | release: 51 | <<: *test 52 | steps: 53 | - add_ssh_keys 54 | - checkout 55 | - run: *setup_yarn 56 | - node/install: *install_node 57 | - run: 58 | name: Yarn Install 59 | command: | 60 | npm install yarn -g 61 | - run: *create_cache_key_file 62 | - node/install-packages: *install_node_packages 63 | - run: .circleci/loadgpg 64 | - run: yarn global add @oclif/semantic-release@3 semantic-release@17 65 | - run: yarn --frozen-lockfile 66 | - run: ./bin/run pack 67 | - run: ./bin/run pack:deb 68 | - run: ./bin/run pack:win 69 | # - run: ./bin/run publish 70 | # - run: ./bin/run publish:deb 71 | # - run: ./bin/run publish:win 72 | - run: | 73 | export PATH=/usr/local/share/.config/yarn/global/node_modules/.bin:$PATH 74 | semantic-release -e @oclif/semantic-release 75 | - run: yarn add -D nyc@13 @oclif/nyc-config@1 76 | - save_cache: 77 | key: v6-yarn-{{checksum ".circleci/config.yml"}}-{{checksum "yarn.lock"}} 78 | paths: 79 | - ~/cli/node_modules 80 | - ~/cli/tmp/cache 81 | - /usr/local/share/.cache/yarn 82 | - /usr/local/share/.config/yarn 83 | 84 | workflows: 85 | version: 2.1 86 | build: 87 | jobs: 88 | - test-node: 89 | matrix: 90 | parameters: 91 | node-version: 92 | - "12" 93 | - "14" 94 | - "16" 95 | - release: 96 | node-version: "14" 97 | context: SF-CLI-RELEASE-PROCESS 98 | filters: 99 | branches: {only: main} 100 | requires: 101 | - test-node 102 | -------------------------------------------------------------------------------- /.circleci/loadgpg: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | echo "$OCLIF_DEV_DEB_SECRET_KEY" | base64 -d | gpg --import 4 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | charset = utf-8 7 | trim_trailing_whitespace = true 8 | insert_final_newline = true 9 | 10 | [*.md] 11 | trim_trailing_whitespace = false 12 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | /lib 2 | /tmp 3 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "oclif", 4 | "oclif-typescript" 5 | ], 6 | "rules": { 7 | "unicorn/no-abusive-eslint-disable": "off" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | *.js text eol=lf 3 | *.ts text eol=lf 4 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @heroku/cli 2 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "npm" 4 | directory: "/" 5 | schedule: 6 | interval: "monthly" 7 | labels: 8 | - "dependencies" 9 | open-pull-requests-limit: 100 10 | pull-request-branch-name: 11 | separator: "-" 12 | ignore: 13 | - dependency-name: "typescript" 14 | - dependency-name: "fs-extra" 15 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: Node.js CI 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | jobs: 10 | build: 11 | runs-on: windows-latest 12 | strategy: 13 | matrix: 14 | node-version: [14.x, 16.x] 15 | steps: 16 | - uses: actions/checkout@v2 17 | - name: Use Node.js ${{ matrix.node-version }} 18 | uses: actions/setup-node@v1 19 | with: 20 | node-version: ${{ matrix.node-version }} 21 | - run: yarn install 22 | env: 23 | CI: true 24 | - run: yarn test 25 | env: 26 | CI: true 27 | -------------------------------------------------------------------------------- /.github/workflows/stale.yml: -------------------------------------------------------------------------------- 1 | name: Close stale issues 2 | 3 | on: 4 | schedule: 5 | - cron: 0 0 * * * 6 | 7 | jobs: 8 | stale: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/stale@v3 12 | with: 13 | repo-token: ${{ secrets.GITHUB_TOKEN }} 14 | days-before-stale: -1 # do not mark issues or pull requests as stale automatically 15 | days-before-close: 7 # wait 7 days before closing a stale issue 16 | stale-issue-label: stale 17 | stale-pr-label: stale 18 | close-issue-message: 19 | A week has passed since we marked this issue as stale and 20 | we’ve received no further feedback or input. As a result, 21 | we are automatically closing it. 22 | See https://oclif.io/docs/how_we_work for more 23 | information on our stale issue policy. 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *-debug.log 2 | *-error.log 3 | .oclif.manifest.json 4 | /dist 5 | /lib 6 | /node_modules 7 | /package-lock.json 8 | /tmp 9 | -------------------------------------------------------------------------------- /.mocharc.json: -------------------------------------------------------------------------------- 1 | { 2 | "require": [ 3 | "test/helpers/init.js", 4 | "ts-node/register", 5 | "source-map-support/register" 6 | ], 7 | "watch-extensions": [ 8 | "ts" 9 | ], 10 | "recursive": true, 11 | "reporter": "spec", 12 | "timeout": 0 13 | } 14 | -------------------------------------------------------------------------------- /.releaserc.json: -------------------------------------------------------------------------------- 1 | { 2 | "branches": ["main"] 3 | } 4 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [1.26.10](https://github.com/oclif/dev-cli/compare/v1.26.9...v1.26.10) (2021-12-15) 2 | 3 | 4 | ### Bug Fixes 5 | 6 | * remove transient dep on lodash.template ([#457](https://github.com/oclif/dev-cli/issues/457)) ([f84acd8](https://github.com/oclif/dev-cli/commit/f84acd8afbd5a225f925153e5b8fe18be1d63a07)) 7 | 8 | 9 | 10 | ## [1.26.9](https://github.com/oclif/dev-cli/compare/v1.26.8...v1.26.9) (2021-12-09) 11 | 12 | 13 | ### Bug Fixes 14 | 15 | * add release branches ([c53b572](https://github.com/oclif/dev-cli/commit/c53b572faff81cfb996441345a989f023caa5c05)) 16 | * nump deps ([#454](https://github.com/oclif/dev-cli/issues/454)) ([4fd0538](https://github.com/oclif/dev-cli/commit/4fd0538a0ddb47aaec0feb88baac31be4720a356)) 17 | 18 | 19 | 20 | ## [1.26.8](https://github.com/oclif/dev-cli/compare/v1.26.7...v1.26.8) (2021-12-06) 21 | 22 | 23 | ### Bug Fixes 24 | 25 | * more dep bumps ([#448](https://github.com/oclif/dev-cli/issues/448)) ([1d1899c](https://github.com/oclif/dev-cli/commit/1d1899c9d3c7dd4667cb75bb42e0816c80adca2f)) 26 | 27 | 28 | 29 | ## [1.26.7](https://github.com/oclif/dev-cli/compare/v1.26.6...v1.26.7) (2021-12-06) 30 | 31 | 32 | ### Bug Fixes 33 | 34 | * bump deps ([#445](https://github.com/oclif/dev-cli/issues/445)) ([7d1e5e1](https://github.com/oclif/dev-cli/commit/7d1e5e1a63f4bfea5aa7a00d0b2ab6f8f488353d)) 35 | 36 | 37 | 38 | ## [1.26.6](https://github.com/oclif/dev-cli/compare/v1.26.5...v1.26.6) (2021-12-01) 39 | 40 | 41 | ### Bug Fixes 42 | 43 | * bump deps ([#442](https://github.com/oclif/dev-cli/issues/442)) ([af0968e](https://github.com/oclif/dev-cli/commit/af0968eee92a33fed25b05bd8c4f85ba3b709652)) 44 | 45 | 46 | 47 | ## [1.26.5](https://github.com/oclif/dev-cli/compare/v1.26.4...v1.26.5) (2021-11-29) 48 | 49 | 50 | ### Bug Fixes 51 | 52 | * lodash.template all gone ([#441](https://github.com/oclif/dev-cli/issues/441)) ([8c63403](https://github.com/oclif/dev-cli/commit/8c6340390fd7af5c45345adb4ecf83762399470c)) 53 | 54 | 55 | 56 | ## [1.26.4](https://github.com/oclif/dev-cli/compare/v1.26.3...v1.26.4) (2021-11-29) 57 | 58 | 59 | ### Bug Fixes 60 | 61 | * remove transitive dep on lodash.template ([#438](https://github.com/oclif/dev-cli/issues/438)) ([80ffc53](https://github.com/oclif/dev-cli/commit/80ffc53e9fe57f62d04e66fec5572f9d57335253)) 62 | 63 | 64 | 65 | ## [1.26.3](https://github.com/oclif/dev-cli/compare/v1.26.2...v1.26.3) (2021-11-24) 66 | 67 | 68 | ### Bug Fixes 69 | 70 | * bump more deps ([#437](https://github.com/oclif/dev-cli/issues/437)) ([adc0b19](https://github.com/oclif/dev-cli/commit/adc0b19ec4d032f91d16b6b0d6a471b80400ebbb)) 71 | 72 | 73 | 74 | ## [1.26.2](https://github.com/oclif/dev-cli/compare/v1.26.1...v1.26.2) (2021-11-24) 75 | 76 | 77 | ### Bug Fixes 78 | 79 | * remove deps ([#434](https://github.com/oclif/dev-cli/issues/434)) ([915df62](https://github.com/oclif/dev-cli/commit/915df6260e7209bd3311160881183ee4e371f0e9)) 80 | 81 | 82 | 83 | ## [1.26.1](https://github.com/oclif/dev-cli/compare/v1.26.0...v1.26.1) (2021-11-22) 84 | 85 | 86 | ### Bug Fixes 87 | 88 | * bump deps ([#423](https://github.com/oclif/dev-cli/issues/423)) ([8a90ff2](https://github.com/oclif/dev-cli/commit/8a90ff2002faa0dd9f1381d04001f703509b5114)) 89 | 90 | 91 | 92 | # [1.26.0](https://github.com/oclif/dev-cli/compare/v1.25.1...v1.26.0) (2020-12-10) 93 | 94 | 95 | ### Features 96 | 97 | * adding region, sslEnabled and s3ForcePathStyle through env vars ([#280](https://github.com/oclif/dev-cli/issues/280)) ([9a31738](https://github.com/oclif/dev-cli/commit/9a317382e198a0c04c039f9432ec9f13f918624a)) 98 | 99 | 100 | 101 | ## [1.25.1](https://github.com/oclif/dev-cli/compare/v1.25.0...v1.25.1) (2020-12-02) 102 | 103 | 104 | ### Bug Fixes 105 | 106 | * find yarn.lock in a yarn workspace ([#156](https://github.com/oclif/dev-cli/issues/156)) ([fd59d36](https://github.com/oclif/dev-cli/commit/fd59d36b249afbfe4d6b25b56442be57eb98a9e4)) 107 | 108 | 109 | 110 | # [1.25.0](https://github.com/oclif/dev-cli/compare/v1.24.4...v1.25.0) (2020-12-02) 111 | 112 | 113 | ### Features 114 | 115 | * add macos uninstaller ([#137](https://github.com/oclif/dev-cli/issues/137)) ([6e3b34b](https://github.com/oclif/dev-cli/commit/6e3b34bba96de037211fd9699b0a59a41fc2f654)) 116 | 117 | 118 | 119 | ## [1.24.4](https://github.com/oclif/dev-cli/compare/v1.24.3...v1.24.4) (2020-12-02) 120 | 121 | 122 | ### Bug Fixes 123 | 124 | * delete the uninstall registry key ([#136](https://github.com/oclif/dev-cli/issues/136)) ([0949b0d](https://github.com/oclif/dev-cli/commit/0949b0d985ca49192118e5ebe92a49e7f89140ea)) 125 | 126 | 127 | 128 | ## [1.24.3](https://github.com/oclif/dev-cli/compare/v1.24.2...v1.24.3) (2020-12-02) 129 | 130 | 131 | ### Reverts 132 | 133 | * Revert "chore(deps): bump fs-extra from 8.1.0 to 9.0.1 (#274)" (#275) ([dbdbd8b](https://github.com/oclif/dev-cli/commit/dbdbd8b05efba57a36de3b1bbc7fd0d505e92dd3)), closes [#274](https://github.com/oclif/dev-cli/issues/274) [#275](https://github.com/oclif/dev-cli/issues/275) 134 | 135 | 136 | 137 | ## [1.24.2](https://github.com/oclif/dev-cli/compare/v1.24.1...v1.24.2) (2020-12-01) 138 | 139 | 140 | ### Bug Fixes 141 | 142 | * restore command descriptions in README generation ([#268](https://github.com/oclif/dev-cli/issues/268)) ([e02ebe7](https://github.com/oclif/dev-cli/commit/e02ebe70539e2d812331dd74e10c079014f7ce67)), closes [#267](https://github.com/oclif/dev-cli/issues/267) 143 | 144 | 145 | 146 | ## [1.24.1](https://github.com/oclif/dev-cli/compare/v1.24.0...v1.24.1) (2020-11-20) 147 | 148 | 149 | ### Bug Fixes 150 | 151 | * README links generation on Windows ([#266](https://github.com/oclif/dev-cli/issues/266)) ([dea13d8](https://github.com/oclif/dev-cli/commit/dea13d8912e5ba8f5d1fa6538d5bade04f40bf2a)) 152 | 153 | 154 | 155 | # [1.24.0](https://github.com/oclif/dev-cli/compare/v1.23.1...v1.24.0) (2020-11-19) 156 | 157 | 158 | ### Features 159 | 160 | * add support for custom help classes ([#141](https://github.com/oclif/dev-cli/issues/141)) ([810e7c1](https://github.com/oclif/dev-cli/commit/810e7c1dff69356fbeaedf6213d03bbadfd27c11)) 161 | 162 | 163 | 164 | ## [1.23.1](https://github.com/oclif/dev-cli/compare/v1.23.0...v1.23.1) (2020-11-16) 165 | 166 | 167 | ### Bug Fixes 168 | 169 | * downgrade fs-extras ([#264](https://github.com/oclif/dev-cli/issues/264)) ([5a75e79](https://github.com/oclif/dev-cli/commit/5a75e79abd44d762a80b675a7c8650d0ee2cb110)) 170 | 171 | 172 | 173 | # [1.23.0](https://github.com/oclif/dev-cli/compare/v1.22.2...v1.23.0) (2020-11-12) 174 | 175 | 176 | ### Bug Fixes 177 | 178 | * rename publish.test.ts ([#130](https://github.com/oclif/dev-cli/issues/130)) ([1a90ece](https://github.com/oclif/dev-cli/commit/1a90ece6882e5385eda887e3de8ba28a87e125dd)) 179 | 180 | 181 | ### Features 182 | 183 | * publish only specified targets ([#117](https://github.com/oclif/dev-cli/issues/117)) ([6e7c356](https://github.com/oclif/dev-cli/commit/6e7c356d29a8c4318d69059f56e091eb834d0ddb)) 184 | 185 | 186 | 187 | ## [1.22.2](https://github.com/oclif/dev-cli/compare/v1.22.1...v1.22.2) (2019-07-29) 188 | 189 | 190 | ### Bug Fixes 191 | 192 | * add write-json-file types back ([f638bca](https://github.com/oclif/dev-cli/commit/f638bcaadba2d51b1e50f1f269da189b40e9ac91)) 193 | 194 | 195 | 196 | ## [1.22.1](https://github.com/oclif/dev-cli/compare/v1.22.0...v1.22.1) (2019-04-25) 197 | 198 | 199 | ### Bug Fixes 200 | 201 | * armv6l -> armv7l ([a2eff7a](https://github.com/oclif/dev-cli/commit/a2eff7a5911a78dd1fb0bed4d392a4238c446293)) 202 | 203 | 204 | 205 | # [1.22.0](https://github.com/oclif/dev-cli/compare/v1.21.4...v1.22.0) (2019-03-28) 206 | 207 | 208 | ### Features 209 | 210 | * configure s3 endpoint with env variable ([#93](https://github.com/oclif/dev-cli/issues/93)) ([2ce9b39](https://github.com/oclif/dev-cli/commit/2ce9b39e785b95c680749ede963469f4a66fb0a1)) 211 | 212 | 213 | 214 | ## [1.21.4](https://github.com/oclif/dev-cli/compare/v1.21.3...v1.21.4) (2019-03-27) 215 | 216 | 217 | ### Bug Fixes 218 | 219 | * template usage like plugin-help ([9c9be3d](https://github.com/oclif/dev-cli/commit/9c9be3dff5e063b9ce06feb700c79317a6e84e21)) 220 | 221 | 222 | 223 | ## [1.21.3](https://github.com/oclif/dev-cli/compare/v1.21.2...v1.21.3) (2019-03-08) 224 | 225 | 226 | ### Bug Fixes 227 | 228 | * correct required node version ([2b1b942](https://github.com/oclif/dev-cli/commit/2b1b9427a8f01104c02f50dfc2f2a57ac913fbe2)) 229 | * remove unused flag ([77d1d1e](https://github.com/oclif/dev-cli/commit/77d1d1ee1039c739783d6266ad8835190dc9139d)) 230 | 231 | 232 | 233 | ## [1.21.2](https://github.com/oclif/dev-cli/compare/v1.21.1...v1.21.2) (2019-02-21) 234 | 235 | 236 | ### Bug Fixes 237 | 238 | * https://github.com/oclif/dev-cli/issues/91 ([91a2f4e](https://github.com/oclif/dev-cli/commit/91a2f4e8c6f84d711fe7bd6a61a8b9a0809e2fcc)) 239 | 240 | 241 | 242 | ## [1.21.1](https://github.com/oclif/dev-cli/compare/v1.21.0...v1.21.1) (2019-02-20) 243 | 244 | 245 | ### Bug Fixes 246 | 247 | * allow custom git domains ([#81](https://github.com/oclif/dev-cli/issues/81)) ([37e28d9](https://github.com/oclif/dev-cli/commit/37e28d9ded4807fa3e7f8fded87497160818fcc6)) 248 | * improve slugging ([#89](https://github.com/oclif/dev-cli/issues/89)) ([d3aef73](https://github.com/oclif/dev-cli/commit/d3aef73dcd9e0b15bf37d97575b14deacc08f2c4)) 249 | 250 | 251 | 252 | # [1.21.0](https://github.com/oclif/dev-cli/compare/v1.20.0...v1.21.0) (2018-12-18) 253 | 254 | 255 | 256 | # [1.20.0](https://github.com/oclif/dev-cli/compare/v1.19.5...v1.20.0) (2018-12-18) 257 | 258 | 259 | ### Features 260 | 261 | * Allow custom "acl" key in oclif.update.s3 ([#79](https://github.com/oclif/dev-cli/issues/79)) ([5ac8fff](https://github.com/oclif/dev-cli/commit/5ac8fff08733e0f2bc0859482f380c86ca51442a)) 262 | 263 | 264 | 265 | ## [1.19.5](https://github.com/oclif/dev-cli/compare/v1.19.4...v1.19.5) (2018-11-27) 266 | 267 | 268 | ### Bug Fixes 269 | 270 | * Removes extra spaces around TOC items ([#76](https://github.com/oclif/dev-cli/issues/76)) ([f739c1c](https://github.com/oclif/dev-cli/commit/f739c1cd6332626847d88741314c9265cb523b25)) 271 | 272 | 273 | 274 | ## [1.19.4](https://github.com/oclif/dev-cli/compare/v1.19.3...v1.19.4) (2018-10-22) 275 | 276 | 277 | ### Bug Fixes 278 | 279 | * **publish:** support temporary aws credentials ([#70](https://github.com/oclif/dev-cli/issues/70)) ([a1a1cd6](https://github.com/oclif/dev-cli/commit/a1a1cd6f504284c6e770891d85c3c82a34ab4bc4)) 280 | 281 | 282 | 283 | ## [1.19.3](https://github.com/oclif/dev-cli/compare/v1.19.2...v1.19.3) (2018-10-20) 284 | 285 | 286 | ### Bug Fixes 287 | 288 | * **pack:** Change macos preinstall/postinstall scripts path ([#68](https://github.com/oclif/dev-cli/issues/68)) ([b181ad4](https://github.com/oclif/dev-cli/commit/b181ad4d710ad8a20698eaa7a1e7e70f0cacdc40)) 289 | 290 | 291 | 292 | ## [1.19.2](https://github.com/oclif/dev-cli/compare/v1.19.1...v1.19.2) (2018-10-13) 293 | 294 | 295 | ### Bug Fixes 296 | 297 | * remove greenkeeper badge ([d946f0d](https://github.com/oclif/dev-cli/commit/d946f0dfdba8b0ea4554b9f07ad00d98c64fb100)) 298 | 299 | 300 | 301 | ## [1.19.1](https://github.com/oclif/dev-cli/compare/v1.19.0...v1.19.1) (2018-10-13) 302 | 303 | 304 | ### Bug Fixes 305 | 306 | * use package-lock or npm-shrinkwrap ([1ce4cbe](https://github.com/oclif/dev-cli/commit/1ce4cbe637c893ddb66a4104c7217efdb001622c)) 307 | 308 | 309 | 310 | # [1.19.0](https://github.com/oclif/dev-cli/compare/v1.18.1...v1.19.0) (2018-10-02) 311 | 312 | 313 | ### Features 314 | 315 | * add dir flag to readme ([#65](https://github.com/oclif/dev-cli/issues/65)) ([4874a22](https://github.com/oclif/dev-cli/commit/4874a224ac5b75ff45f5120112dfd51673bcb400)) 316 | 317 | 318 | 319 | ## [1.18.1](https://github.com/oclif/dev-cli/compare/v1.18.0...v1.18.1) (2018-09-14) 320 | 321 | 322 | ### Bug Fixes 323 | 324 | * lint issue ([6650cc1](https://github.com/oclif/dev-cli/commit/6650cc1509b920ac7b7a7ceb8c8d3c3d206cbb70)) 325 | * remove greenkeeper-lockfile ([b3287b7](https://github.com/oclif/dev-cli/commit/b3287b70fdb12cd198172ad6360ccdd0cf682512)) 326 | * updated nyc ([3d9318f](https://github.com/oclif/dev-cli/commit/3d9318fd1016e46b0d13e60d595c5de594407d0c)) 327 | 328 | 329 | 330 | # [1.18.0](https://github.com/oclif/dev-cli/compare/v1.17.0...v1.18.0) (2018-09-01) 331 | 332 | 333 | ### Features 334 | 335 | * --targets flag on pack ([b1fdd21](https://github.com/oclif/dev-cli/commit/b1fdd21e5161567a73a8636006d6d2a6d00cb3e5)) 336 | * add --no-xz flag to pack ([c0a1fbb](https://github.com/oclif/dev-cli/commit/c0a1fbb922620592af56007628c65cf1792e3c3c)) 337 | 338 | 339 | 340 | # [1.17.0](https://github.com/oclif/dev-cli/compare/v1.16.0...v1.17.0) (2018-08-17) 341 | 342 | 343 | ### Features 344 | 345 | * typescript 3 ([08b2a22](https://github.com/oclif/dev-cli/commit/08b2a22495bc116e7e259289bfedc3c7bb16f6ed)) 346 | 347 | 348 | 349 | # [1.16.0](https://github.com/oclif/dev-cli/compare/v1.15.4...v1.16.0) (2018-08-17) 350 | 351 | 352 | ### Features 353 | 354 | * typescript 3.x ([df5ef71](https://github.com/oclif/dev-cli/commit/df5ef71459487db5d544e9c07813d0ee24d18ce4)) 355 | 356 | 357 | 358 | ## [1.15.4](https://github.com/oclif/dev-cli/compare/v1.15.3...v1.15.4) (2018-06-26) 359 | 360 | 361 | ### Bug Fixes 362 | 363 | * **deb:** UPDATE_INSTRUCTIONS env var ([4f81da8](https://github.com/oclif/dev-cli/commit/4f81da8ed0431896e7daee16c70e7891bde1dd34)) 364 | 365 | 366 | 367 | ## [1.15.3](https://github.com/oclif/dev-cli/compare/v1.15.2...v1.15.3) (2018-06-21) 368 | 369 | 370 | ### Bug Fixes 371 | 372 | * **readme:** windows readme generation ([98576ab](https://github.com/oclif/dev-cli/commit/98576ab5002a088bb423df3f9fb20fd80c9250fb)) 373 | 374 | 375 | 376 | ## [1.15.2](https://github.com/oclif/dev-cli/compare/v1.15.1...v1.15.2) (2018-06-20) 377 | 378 | 379 | ### Bug Fixes 380 | 381 | * fixed doc urls when only ts files are available ([01945c3](https://github.com/oclif/dev-cli/commit/01945c3c8b2066dad4a2713903ac45f64e32e615)) 382 | 383 | 384 | 385 | ## [1.15.1](https://github.com/oclif/dev-cli/compare/v1.15.0...v1.15.1) (2018-06-20) 386 | 387 | 388 | ### Bug Fixes 389 | 390 | * index commands readme links ([039907f](https://github.com/oclif/dev-cli/commit/039907fa7f89e30ec64dbe09e4273a081f0eb22e)) 391 | 392 | 393 | 394 | # [1.15.0](https://github.com/oclif/dev-cli/compare/v1.14.0...v1.15.0) (2018-06-20) 395 | 396 | 397 | ### Features 398 | 399 | * added repositoryPrefix to allow customizing code URLs ([bce2fe4](https://github.com/oclif/dev-cli/commit/bce2fe4a7ce8f8d1494de65a81f542d490a8cf60)) 400 | 401 | 402 | 403 | # [1.14.0](https://github.com/oclif/dev-cli/compare/v1.13.34...v1.14.0) (2018-06-19) 404 | 405 | 406 | ### Features 407 | 408 | * support OCLIF_CLIENT_HOME env var ([#46](https://github.com/oclif/dev-cli/issues/46)) ([a49ddb8](https://github.com/oclif/dev-cli/commit/a49ddb8fb35e27ec702054245f9cd17e3cd7a8fa)) 409 | 410 | 411 | 412 | ## [1.13.34](https://github.com/oclif/dev-cli/compare/v1.13.33...v1.13.34) (2018-06-18) 413 | 414 | 415 | ### Bug Fixes 416 | 417 | * Modify prune to only remove *.d.ts files, not all .ts files ([#44](https://github.com/oclif/dev-cli/issues/44)) ([a831bdc](https://github.com/oclif/dev-cli/commit/a831bdc565de29935a2451357442db524c2c45f0)) 418 | * remove prune ([fd25750](https://github.com/oclif/dev-cli/commit/fd25750800e41b134948025440f9f3efafcfbd1d)) 419 | 420 | 421 | 422 | ## [1.13.33](https://github.com/oclif/dev-cli/compare/v1.13.32...v1.13.33) (2018-06-16) 423 | 424 | 425 | ### Bug Fixes 426 | 427 | * better error if aws-sdk is missing ([#43](https://github.com/oclif/dev-cli/issues/43)) ([3694551](https://github.com/oclif/dev-cli/commit/3694551d3001f6f6f3a8c863e0555a691c1b3086)) 428 | 429 | 430 | 431 | ## [1.13.32](https://github.com/oclif/dev-cli/compare/v1.13.31...v1.13.32) (2018-06-15) 432 | 433 | 434 | ### Bug Fixes 435 | 436 | * node 8 ([54fb6bb](https://github.com/oclif/dev-cli/commit/54fb6bb0d82d5235855b44079491abaca823dd72)) 437 | * readme ([4ca47f2](https://github.com/oclif/dev-cli/commit/4ca47f2b05b2a7ef2f1d3ee2c5d6fc13b9dfeeae)) 438 | 439 | 440 | 441 | ## [1.13.31](https://github.com/oclif/dev-cli/compare/v1.13.30...v1.13.31) (2018-06-12) 442 | 443 | 444 | ### Bug Fixes 445 | 446 | * updated deps ([d5b4631](https://github.com/oclif/dev-cli/commit/d5b46313716c285592e9b46ea799be2b051a44e7)) 447 | 448 | 449 | 450 | ## [1.13.30](https://github.com/oclif/dev-cli/compare/v1.13.29...v1.13.30) (2018-06-01) 451 | 452 | 453 | ### Bug Fixes 454 | 455 | * typescript 2.9 ([59ba01a](https://github.com/oclif/dev-cli/commit/59ba01ab2f40f69aaa1f572fa9ad7c4b9d929511)) 456 | * updated deps ([82ff451](https://github.com/oclif/dev-cli/commit/82ff4510de968e7c83b532662f9ebef587e303de)) 457 | * updated deps ([2e32621](https://github.com/oclif/dev-cli/commit/2e3262102c5ce75bf13ec37b867c7363ccd614fa)) 458 | 459 | 460 | 461 | ## [1.13.29](https://github.com/oclif/dev-cli/compare/v1.13.28...v1.13.29) (2018-05-31) 462 | 463 | 464 | ### Bug Fixes 465 | 466 | * use COLUMNS ([b0b4715](https://github.com/oclif/dev-cli/commit/b0b4715ce76dd3aef5837c82f704913c3b9579e3)) 467 | 468 | 469 | 470 | ## [1.13.28](https://github.com/oclif/dev-cli/compare/v1.13.27...v1.13.28) (2018-05-31) 471 | 472 | 473 | ### Bug Fixes 474 | 475 | * ensure topic docs only have specific topic ([d9c0386](https://github.com/oclif/dev-cli/commit/d9c038602f36e1abd0fd7c1e6c826876dce13d9a)) 476 | 477 | 478 | 479 | ## [1.13.27](https://github.com/oclif/dev-cli/compare/v1.13.26...v1.13.27) (2018-05-30) 480 | 481 | 482 | ### Bug Fixes 483 | 484 | * config root finding ([89e8ac3](https://github.com/oclif/dev-cli/commit/89e8ac3ed49000f15b0e5354f28931400e720086)) 485 | 486 | 487 | 488 | ## [1.13.26](https://github.com/oclif/dev-cli/compare/v1.13.25...v1.13.26) (2018-05-30) 489 | 490 | 491 | ### Bug Fixes 492 | 493 | * path of index.js commands ([15ed4c5](https://github.com/oclif/dev-cli/commit/15ed4c50d930554a9df6ebbfff12218e84f3eb1c)) 494 | 495 | 496 | 497 | ## [1.13.25](https://github.com/oclif/dev-cli/compare/v1.13.24...v1.13.25) (2018-05-30) 498 | 499 | 500 | ### Bug Fixes 501 | 502 | * templatize topic descriptions ([22cc896](https://github.com/oclif/dev-cli/commit/22cc8967d62e99b1737260cc99e49f339691cb5e)) 503 | * use first line of topic descriptions ([8d6e1ce](https://github.com/oclif/dev-cli/commit/8d6e1ce0a77da6a2ea3b7fd7d74a6b5663ed89f1)) 504 | 505 | 506 | 507 | ## [1.13.24](https://github.com/oclif/dev-cli/compare/v1.13.23...v1.13.24) (2018-05-29) 508 | 509 | 510 | ### Bug Fixes 511 | 512 | * updated deps ([5326b98](https://github.com/oclif/dev-cli/commit/5326b9877a22909b079ce26d3c12019964170a38)) 513 | 514 | 515 | 516 | ## [1.13.23](https://github.com/oclif/dev-cli/compare/v1.13.22...v1.13.23) (2018-05-26) 517 | 518 | 519 | ### Bug Fixes 520 | 521 | * check for nsis and 7zip earlier ([4d69079](https://github.com/oclif/dev-cli/commit/4d6907940886ce4e58dfd7421c13c7ce7d64cbf9)) 522 | * makensis check ([b689a48](https://github.com/oclif/dev-cli/commit/b689a4836e2af7bbb6e239cd569e07a9c26e7a51)) 523 | * rollout type ([e9005cb](https://github.com/oclif/dev-cli/commit/e9005cbe4e1a777090b9ceeed3d8a28d7aa272c1)) 524 | 525 | 526 | 527 | ## [1.13.22](https://github.com/oclif/dev-cli/compare/v1.13.21...v1.13.22) (2018-05-16) 528 | 529 | 530 | ### Bug Fixes 531 | 532 | * check earlier if macos.identifier is set ([#35](https://github.com/oclif/dev-cli/issues/35)) ([2e0e4eb](https://github.com/oclif/dev-cli/commit/2e0e4eb0218a7e7fd8e73888a19aca0e202a58ec)) 533 | 534 | 535 | 536 | ## [1.13.21](https://github.com/oclif/dev-cli/compare/v1.13.20...v1.13.21) (2018-05-15) 537 | 538 | 539 | ### Bug Fixes 540 | 541 | * updated deps ([ffa87a0](https://github.com/oclif/dev-cli/commit/ffa87a062fb4e4b0b9d4b105dc523c7910e49b91)) 542 | 543 | 544 | 545 | ## [1.13.20](https://github.com/oclif/dev-cli/compare/v1.13.19...v1.13.20) (2018-05-10) 546 | 547 | 548 | ### Bug Fixes 549 | 550 | * updated deps ([a0b8ab7](https://github.com/oclif/dev-cli/commit/a0b8ab77a7d488ac81e2388b8b6e226201e97c3e)) 551 | * use armv6l for better raspberry pi support ([be0e385](https://github.com/oclif/dev-cli/commit/be0e38539b2bf517298fa1c6faecc1b001846ad6)) 552 | 553 | 554 | 555 | ## [1.13.19](https://github.com/oclif/dev-cli/compare/v1.13.18...v1.13.19) (2018-05-07) 556 | 557 | 558 | ### Bug Fixes 559 | 560 | * updated deps ([1556e1e](https://github.com/oclif/dev-cli/commit/1556e1eea52f852e730121bbcdcc070c4a38d5c9)) 561 | 562 | 563 | 564 | ## [1.13.18](https://github.com/oclif/dev-cli/compare/v1.13.17...v1.13.18) (2018-05-04) 565 | 566 | 567 | ### Bug Fixes 568 | 569 | * add deb update instructions ([45c62de](https://github.com/oclif/dev-cli/commit/45c62de6645bb08763fccd2496525c24abbe309a)) 570 | * quote escaping ([1c9724f](https://github.com/oclif/dev-cli/commit/1c9724fae42c45851e60c5b528eafb76647cad1b)) 571 | 572 | 573 | 574 | ## [1.13.17](https://github.com/oclif/dev-cli/compare/v1.13.16...v1.13.17) (2018-05-04) 575 | 576 | 577 | ### Bug Fixes 578 | 579 | * do not require s3 credentials to pack ([a5b73e0](https://github.com/oclif/dev-cli/commit/a5b73e0e843f10909aea0cfe10675544b4635b23)) 580 | 581 | 582 | 583 | ## [1.13.16](https://github.com/oclif/dev-cli/compare/v1.13.15...v1.13.16) (2018-05-04) 584 | 585 | 586 | ### Bug Fixes 587 | 588 | * use dotfile manifest when set like that in files ([75aa0f5](https://github.com/oclif/dev-cli/commit/75aa0f52005ec04095c215bcbb2dc1195521a248)) 589 | 590 | 591 | 592 | ## [1.13.15](https://github.com/oclif/dev-cli/compare/v1.13.14...v1.13.15) (2018-05-03) 593 | 594 | 595 | ### Bug Fixes 596 | 597 | * path of pjson reading for oclif manifest renaming ([4b301f6](https://github.com/oclif/dev-cli/commit/4b301f6ac8a6020013051e9ad6beee0684a2ddb6)) 598 | 599 | 600 | 601 | ## [1.13.14](https://github.com/oclif/dev-cli/compare/v1.13.13...v1.13.14) (2018-05-03) 602 | 603 | 604 | ### Bug Fixes 605 | 606 | * manifest with leading slash ([f6ec36e](https://github.com/oclif/dev-cli/commit/f6ec36e33e84615fc5fc87bb9672e1dcddd6bac5)) 607 | * rename oclif manifest to not be a dotfile ([6fb3dc6](https://github.com/oclif/dev-cli/commit/6fb3dc63050ba146b1ec042a865992bda915bcc6)) 608 | 609 | 610 | 611 | ## [1.13.13](https://github.com/oclif/dev-cli/compare/v1.13.12...v1.13.13) (2018-05-01) 612 | 613 | 614 | ### Bug Fixes 615 | 616 | * updated deps ([963fc49](https://github.com/oclif/dev-cli/commit/963fc49428becba112d734be498e85b8fc51a329)) 617 | 618 | 619 | 620 | ## [1.13.12](https://github.com/oclif/dev-cli/compare/v1.13.11...v1.13.12) (2018-05-01) 621 | 622 | 623 | ### Bug Fixes 624 | 625 | * updated deps ([99b65be](https://github.com/oclif/dev-cli/commit/99b65bef1314f1d8fb4471424f71f20c52bc8e86)) 626 | 627 | 628 | 629 | ## [1.13.11](https://github.com/oclif/dev-cli/compare/v1.13.10...v1.13.11) (2018-04-27) 630 | 631 | 632 | ### Bug Fixes 633 | 634 | * default to all targets ([fa495f8](https://github.com/oclif/dev-cli/commit/fa495f808546c105819e74729b2b96eeb0eafdf4)) 635 | 636 | 637 | 638 | ## [1.13.10](https://github.com/oclif/dev-cli/compare/v1.13.9...v1.13.10) (2018-04-27) 639 | 640 | 641 | ### Bug Fixes 642 | 643 | * updated deps ([744e4dd](https://github.com/oclif/dev-cli/commit/744e4dd0b79891ef18b7c5d1a9e3204445d6b0a2)) 644 | 645 | 646 | 647 | ## [1.13.9](https://github.com/oclif/dev-cli/compare/v1.13.8...v1.13.9) (2018-04-27) 648 | 649 | 650 | ### Bug Fixes 651 | 652 | * error if identifier is not set ([9de6c28](https://github.com/oclif/dev-cli/commit/9de6c28a5593b32717c1d09e5a14fbd80316c5be)) 653 | * only set signing key if defined ([46085f1](https://github.com/oclif/dev-cli/commit/46085f1e6c4285062983808c792e34936ff7ced5)) 654 | 655 | 656 | 657 | ## [1.13.8](https://github.com/oclif/dev-cli/compare/v1.13.7...v1.13.8) (2018-04-25) 658 | 659 | 660 | ### Bug Fixes 661 | 662 | * node 10 no longer has linux-x86 ([ac9c5f3](https://github.com/oclif/dev-cli/commit/ac9c5f3a59d876a7025e01b5d79ad65614246bef)) 663 | * only use linux targets ([1e9b078](https://github.com/oclif/dev-cli/commit/1e9b0781962591ca14653e9e8b4dfeda5a400275)) 664 | 665 | 666 | 667 | ## [1.13.7](https://github.com/oclif/dev-cli/compare/v1.13.6...v1.13.7) (2018-04-24) 668 | 669 | 670 | ### Bug Fixes 671 | 672 | * updated deps ([c31fcaf](https://github.com/oclif/dev-cli/commit/c31fcaffc7c067590e4363f0294bdeb07d8d127c)) 673 | 674 | 675 | 676 | ## [1.13.6](https://github.com/oclif/dev-cli/compare/v1.13.5...v1.13.6) (2018-04-22) 677 | 678 | 679 | ### Bug Fixes 680 | 681 | * windows script fix ([b58916f](https://github.com/oclif/dev-cli/commit/b58916f979510197622e5f9e1dcab83d568444bd)) 682 | 683 | 684 | 685 | ## [1.13.5](https://github.com/oclif/dev-cli/compare/v1.13.4...v1.13.5) (2018-04-21) 686 | 687 | 688 | ### Bug Fixes 689 | 690 | * add AUTHOR env var ([cbd5d64](https://github.com/oclif/dev-cli/commit/cbd5d643b315c85fd3788a5ad4e7acad8cada9d1)) 691 | 692 | 693 | 694 | ## [1.13.4](https://github.com/oclif/dev-cli/compare/v1.13.3...v1.13.4) (2018-04-20) 695 | 696 | 697 | ### Bug Fixes 698 | 699 | * setlocal ([39ba94b](https://github.com/oclif/dev-cli/commit/39ba94b76689027b4bc139604bac02c748e71579)) 700 | * windows script fix ([e7275b4](https://github.com/oclif/dev-cli/commit/e7275b4dfca601c0a41006a0b542b92135d4d2f6)) 701 | 702 | 703 | 704 | ## [1.13.3](https://github.com/oclif/dev-cli/compare/v1.13.2...v1.13.3) (2018-04-20) 705 | 706 | 707 | ### Bug Fixes 708 | 709 | * defaulting binpath ([9341f87](https://github.com/oclif/dev-cli/commit/9341f87dedf79b9abb41987fb8a59676169e67ad)) 710 | 711 | 712 | 713 | ## [1.13.2](https://github.com/oclif/dev-cli/compare/v1.13.1...v1.13.2) (2018-04-20) 714 | 715 | 716 | ### Bug Fixes 717 | 718 | * always set binpath ([66e5206](https://github.com/oclif/dev-cli/commit/66e520680f7e3e73d369a21fe8410d466ba2e70b)) 719 | * do not overwrite binpath ([3099bac](https://github.com/oclif/dev-cli/commit/3099bacfe7788ff059129a513ae688391ced9d16)) 720 | * updated deps ([d731695](https://github.com/oclif/dev-cli/commit/d7316952bcff57321a80fe0028a7478dd276dc56)) 721 | * windows script ([f475609](https://github.com/oclif/dev-cli/commit/f47560959aaa7b32cc179c9eee021676898be36e)) 722 | 723 | 724 | 725 | ## [1.13.1](https://github.com/oclif/dev-cli/compare/v1.13.0...v1.13.1) (2018-04-17) 726 | 727 | 728 | ### Bug Fixes 729 | 730 | * readme fixes ([e172d18](https://github.com/oclif/dev-cli/commit/e172d18e65f3e32aa4f3a05a112be503cd6b6fbf)) 731 | 732 | 733 | 734 | # [1.13.0](https://github.com/oclif/dev-cli/compare/v1.12.1...v1.13.0) (2018-04-10) 735 | 736 | 737 | ### Bug Fixes 738 | 739 | * add tmp/cache to circle ([3429f5a](https://github.com/oclif/dev-cli/commit/3429f5a3b92398f5708d2fffac303a776bdf5cf7)) 740 | * added tests for macos publishing ([53f39fb](https://github.com/oclif/dev-cli/commit/53f39fb9b9abf880441f9bbc4b227778cb7c155b)) 741 | * empty deb dir before building anything ([8ef1c85](https://github.com/oclif/dev-cli/commit/8ef1c85aa00a0ac3deed77f3ffbd8ee3a4eb0d2d)) 742 | * fixes with pack:deb ([e691a62](https://github.com/oclif/dev-cli/commit/e691a628cd7292ec568f852f0c9f892b6068a1ad)) 743 | * fixes with pack:deb ([a5e65d5](https://github.com/oclif/dev-cli/commit/a5e65d5d5155fcad565d812aa508959de446e9a2)) 744 | * set cwd for gpg signing ([c031baf](https://github.com/oclif/dev-cli/commit/c031baf37dbf0e98a66a87250880cba2ab9a6c4a)) 745 | * tests ([28e60a8](https://github.com/oclif/dev-cli/commit/28e60a8894b5d2c68138c024f31a36b1762bacfc)) 746 | * windows test exe names ([cad4f43](https://github.com/oclif/dev-cli/commit/cad4f43a55375215b5332947302c0d1d7eb0e7ea)) 747 | * write out deb manifest after building targets ([91f9baa](https://github.com/oclif/dev-cli/commit/91f9baa8297b04ee4667957f287be9b631d562cd)) 748 | 749 | 750 | ### Features 751 | 752 | * added publish:win and publish:deb ([145078c](https://github.com/oclif/dev-cli/commit/145078c0e9387757d980ffabe148b1e806e2fb11)) 753 | 754 | 755 | 756 | ## [1.12.1](https://github.com/oclif/dev-cli/compare/v1.12.0...v1.12.1) (2018-04-10) 757 | 758 | 759 | ### Bug Fixes 760 | 761 | * add ftparchive to deb ([b81bd1e](https://github.com/oclif/dev-cli/commit/b81bd1e6f1162c68bb54c724f440e56c73fbabae)) 762 | 763 | 764 | 765 | # [1.12.0](https://github.com/oclif/dev-cli/compare/v1.11.0...v1.12.0) (2018-04-10) 766 | 767 | 768 | ### Features 769 | 770 | * added pack:win ([8dd06d5](https://github.com/oclif/dev-cli/commit/8dd06d5c0e75b38b50b188eb4a616a316b5334a4)) 771 | 772 | 773 | 774 | # [1.11.0](https://github.com/oclif/dev-cli/compare/v1.10.2...v1.11.0) (2018-04-10) 775 | 776 | 777 | ### Features 778 | 779 | * added pack:deb and pack:macos ([a781e37](https://github.com/oclif/dev-cli/commit/a781e3703104d9ff5f69b31d3dfa8486d8f6d020)) 780 | 781 | 782 | 783 | ## [1.10.2](https://github.com/oclif/dev-cli/compare/v1.10.1...v1.10.2) (2018-04-10) 784 | 785 | 786 | ### Bug Fixes 787 | 788 | * remove warn-if-update-available ([b6fb76f](https://github.com/oclif/dev-cli/commit/b6fb76fead5abd4bf7c9fcb835b161d305718ec4)) 789 | * set --unsafe-perm on npm pack ([c7c4bc8](https://github.com/oclif/dev-cli/commit/c7c4bc8dd74f0917918583e70f49a726c9f46fc4)) 790 | 791 | 792 | 793 | ## [1.10.1](https://github.com/oclif/dev-cli/compare/v1.10.0...v1.10.1) (2018-04-10) 794 | 795 | 796 | ### Bug Fixes 797 | 798 | * refactor to use s3Key/s3Url from @oclif/config ([8c96067](https://github.com/oclif/dev-cli/commit/8c96067ae94416885783f684856753dd310d4027)) 799 | 800 | 801 | 802 | # [1.10.0](https://github.com/oclif/dev-cli/compare/v1.9.19...v1.10.0) (2018-04-10) 803 | 804 | 805 | ### Features 806 | 807 | * added unversioned tarballs ([8306017](https://github.com/oclif/dev-cli/commit/83060178597d86f5dcc19926608fc340914334e9)) 808 | 809 | 810 | 811 | ## [1.9.19](https://github.com/oclif/dev-cli/compare/v1.9.18...v1.9.19) (2018-04-09) 812 | 813 | 814 | ### Bug Fixes 815 | 816 | * debug output ([a6aa8c7](https://github.com/oclif/dev-cli/commit/a6aa8c7742bf2dc7318888bc60eab9849c74deab)) 817 | 818 | 819 | 820 | ## [1.9.18](https://github.com/oclif/dev-cli/compare/v1.9.17...v1.9.18) (2018-04-09) 821 | 822 | 823 | ### Bug Fixes 824 | 825 | * add cloudfront distribution invalidation ([486642a](https://github.com/oclif/dev-cli/commit/486642a3f5439e07e1b036504634d01bb077974b)) 826 | * updated command ([1b79c16](https://github.com/oclif/dev-cli/commit/1b79c1614f3371a4025fb09320a79f4a61d7618b)) 827 | * updated command ([353228a](https://github.com/oclif/dev-cli/commit/353228a49450ac9b502d0b597e77c7c9d074edff)) 828 | 829 | 830 | 831 | ## [1.9.17](https://github.com/oclif/dev-cli/compare/v1.9.16...v1.9.17) (2018-04-09) 832 | 833 | 834 | ### Bug Fixes 835 | 836 | * updated config ([bca1a6f](https://github.com/oclif/dev-cli/commit/bca1a6f8aba033167b44f05a0d64a3358ed23de8)) 837 | 838 | 839 | 840 | ## [1.9.16](https://github.com/oclif/dev-cli/compare/v1.9.15...v1.9.16) (2018-04-09) 841 | 842 | 843 | ### Bug Fixes 844 | 845 | * use baseDir ([1157fb5](https://github.com/oclif/dev-cli/commit/1157fb566d8f3bd416f4587fafa33b3c9795fa69)) 846 | 847 | 848 | 849 | ## [1.9.15](https://github.com/oclif/dev-cli/compare/v1.9.14...v1.9.15) (2018-04-09) 850 | 851 | 852 | ### Bug Fixes 853 | 854 | * add baseDir ([a1f030c](https://github.com/oclif/dev-cli/commit/a1f030c761370fbbb8fde7181db0e62960836ff2)) 855 | 856 | 857 | 858 | ## [1.9.14](https://github.com/oclif/dev-cli/compare/v1.9.13...v1.9.14) (2018-04-09) 859 | 860 | 861 | ### Bug Fixes 862 | 863 | * simplify config template ([c338ee8](https://github.com/oclif/dev-cli/commit/c338ee863102596d7b6b35db81df01665ac228da)) 864 | 865 | 866 | 867 | ## [1.9.13](https://github.com/oclif/dev-cli/compare/v1.9.12...v1.9.13) (2018-04-09) 868 | 869 | 870 | ### Bug Fixes 871 | 872 | * add channel back to manifest ([e5fc84b](https://github.com/oclif/dev-cli/commit/e5fc84b113f469f9cf4495491239707758eef57e)) 873 | 874 | 875 | 876 | ## [1.9.12](https://github.com/oclif/dev-cli/compare/v1.9.11...v1.9.12) (2018-04-09) 877 | 878 | 879 | ### Bug Fixes 880 | 881 | * use version string for channel ([3da71a3](https://github.com/oclif/dev-cli/commit/3da71a3111126f9349d8185e13a86264a5224c29)) 882 | 883 | 884 | 885 | ## [1.9.11](https://github.com/oclif/dev-cli/compare/v1.9.10...v1.9.11) (2018-04-09) 886 | 887 | 888 | ### Bug Fixes 889 | 890 | * move script debug output to stderr ([737ba54](https://github.com/oclif/dev-cli/commit/737ba549d8f52a4db12ebd42e62c72d7beaa58a0)) 891 | 892 | 893 | 894 | ## [1.9.10](https://github.com/oclif/dev-cli/compare/v1.9.9...v1.9.10) (2018-04-09) 895 | 896 | 897 | ### Bug Fixes 898 | 899 | * updated command and qqjs ([3c6767e](https://github.com/oclif/dev-cli/commit/3c6767eb63f88d7a0fea4c841abb80c6972ed450)) 900 | 901 | 902 | 903 | ## [1.9.9](https://github.com/oclif/dev-cli/compare/v1.9.8...v1.9.9) (2018-04-09) 904 | 905 | 906 | ### Bug Fixes 907 | 908 | * updated qqjs and cli-ux ([b508c70](https://github.com/oclif/dev-cli/commit/b508c70beeba76b9be46c34146ba1bf48c62289f)) 909 | 910 | 911 | 912 | ## [1.9.8](https://github.com/oclif/dev-cli/compare/v1.9.7...v1.9.8) (2018-04-09) 913 | 914 | 915 | ### Bug Fixes 916 | 917 | * cleanup deps ([3a36ee0](https://github.com/oclif/dev-cli/commit/3a36ee042b71c0a77a21e1e7a000e5750c933b3c)) 918 | 919 | 920 | 921 | ## [1.9.7](https://github.com/oclif/dev-cli/compare/v1.9.6...v1.9.7) (2018-04-09) 922 | 923 | 924 | ### Bug Fixes 925 | 926 | * disable node uploads for now ([2be4bec](https://github.com/oclif/dev-cli/commit/2be4bec1e3b42004c8bd1b1c33886309f12a0c50)) 927 | 928 | 929 | 930 | ## [1.9.6](https://github.com/oclif/dev-cli/compare/v1.9.5...v1.9.6) (2018-04-09) 931 | 932 | 933 | ### Bug Fixes 934 | 935 | * improved debug output and export IManifest ([afdd520](https://github.com/oclif/dev-cli/commit/afdd5202df4ca1b7973fd8792e6eef5e443dbaf2)) 936 | 937 | 938 | 939 | ## [1.9.5](https://github.com/oclif/dev-cli/compare/v1.9.4...v1.9.5) (2018-04-09) 940 | 941 | 942 | ### Bug Fixes 943 | 944 | * updated config ([9278257](https://github.com/oclif/dev-cli/commit/92782574b73d84c0283deb28433052053494dbaa)) 945 | * updated qqjs ([061cae7](https://github.com/oclif/dev-cli/commit/061cae7a623c5e17a666c7e70562335f539312cf)) 946 | 947 | 948 | 949 | ## [1.9.4](https://github.com/oclif/dev-cli/compare/v1.9.3...v1.9.4) (2018-04-09) 950 | 951 | 952 | ### Bug Fixes 953 | 954 | * rename update env vars ([30688dc](https://github.com/oclif/dev-cli/commit/30688dc0f92ee1394472bd3ccd60cc678c9f0aea)) 955 | 956 | 957 | 958 | ## [1.9.3](https://github.com/oclif/dev-cli/compare/v1.9.2...v1.9.3) (2018-04-09) 959 | 960 | 961 | ### Bug Fixes 962 | 963 | * improve debugging ([7e781bc](https://github.com/oclif/dev-cli/commit/7e781bcc695804bd53945def7e98e7284870e62d)) 964 | * prefix output ([4a9dcb6](https://github.com/oclif/dev-cli/commit/4a9dcb6c7e6d0287aacf1b2644c0741f0ade5fea)) 965 | * rename publish:s3 to publish ([5936199](https://github.com/oclif/dev-cli/commit/59361990b745821fd144fa3fb793bc1a11ea5803)) 966 | * use dirname for paths ([f1e5c2d](https://github.com/oclif/dev-cli/commit/f1e5c2d32e44162ed3c63ec9e2c23a7354a1e6d9)) 967 | 968 | 969 | 970 | ## [1.9.2](https://github.com/oclif/dev-cli/compare/v1.9.1...v1.9.2) (2018-04-08) 971 | 972 | 973 | ### Bug Fixes 974 | 975 | * fixed error message when s3 is not configured ([e8f67af](https://github.com/oclif/dev-cli/commit/e8f67af6343db02abdabab0dd6b57fdf742ed503)) 976 | 977 | 978 | 979 | ## [1.9.1](https://github.com/oclif/dev-cli/compare/v1.9.0...v1.9.1) (2018-04-08) 980 | 981 | 982 | ### Bug Fixes 983 | 984 | * add linux-x64 target ([16e40f8](https://github.com/oclif/dev-cli/commit/16e40f8680edb8aad5e5cc4fc2fd4cb93f1d5d01)) 985 | * add tests for publish ([7f6dc4c](https://github.com/oclif/dev-cli/commit/7f6dc4c84fce14e32ffb1e7f8bdee4029ea0d3e2)) 986 | * fixed build ([fb3ec67](https://github.com/oclif/dev-cli/commit/fb3ec67ab31a002ff892fe0731bd1ad1c3065d03)) 987 | * fixed tests on linux ([bfe60b2](https://github.com/oclif/dev-cli/commit/bfe60b2bfb1bb3cadfc4e8167106e1eb109a81ce)) 988 | * split pack and publish into separate steps ([c199458](https://github.com/oclif/dev-cli/commit/c19945877c34365177c47fb9038b5d30bd1e439a)) 989 | 990 | 991 | 992 | # [1.9.0](https://github.com/oclif/dev-cli/compare/v1.8.0...v1.9.0) (2018-04-08) 993 | 994 | 995 | ### Features 996 | 997 | * upload node binaries to s3 on publish ([26b86ac](https://github.com/oclif/dev-cli/commit/26b86ac9df8365ad30fbc03b8f2c71b4e0cb91c9)) 998 | 999 | 1000 | 1001 | # [1.8.0](https://github.com/oclif/dev-cli/compare/v1.7.13...v1.8.0) (2018-04-08) 1002 | 1003 | 1004 | ### Features 1005 | 1006 | * check sha checksums of node binaries ([a892b58](https://github.com/oclif/dev-cli/commit/a892b58070287cf9429346901bf909651dabf7f5)) 1007 | 1008 | 1009 | 1010 | ## [1.7.13](https://github.com/oclif/dev-cli/compare/v1.7.12...v1.7.13) (2018-04-07) 1011 | 1012 | 1013 | ### Bug Fixes 1014 | 1015 | * bump config ([aa0ab3d](https://github.com/oclif/dev-cli/commit/aa0ab3d11c552bfd6fba20a987d0e366d3c3c19e)) 1016 | * fixed template strings ([5597ab0](https://github.com/oclif/dev-cli/commit/5597ab0e2fe741b64ff509bbb34070648fbbe45e)) 1017 | * tests ([a3064ca](https://github.com/oclif/dev-cli/commit/a3064cabaca8c8568ab79b050060eeae79f9d652)) 1018 | 1019 | 1020 | 1021 | ## [1.7.12](https://github.com/oclif/dev-cli/compare/v1.7.11...v1.7.12) (2018-04-07) 1022 | 1023 | 1024 | ### Bug Fixes 1025 | 1026 | * use config.name as prefix to match cli-engine ([020fa2d](https://github.com/oclif/dev-cli/commit/020fa2d44792cf2c5782fb2bc935ff09cfd63a65)) 1027 | 1028 | 1029 | 1030 | ## [1.7.11](https://github.com/oclif/dev-cli/compare/v1.7.10...v1.7.11) (2018-04-07) 1031 | 1032 | 1033 | ### Bug Fixes 1034 | 1035 | * set content type of tar files ([38f45f3](https://github.com/oclif/dev-cli/commit/38f45f353d60643a66e9f4039f0543d89e736bb1)) 1036 | 1037 | 1038 | 1039 | ## [1.7.10](https://github.com/oclif/dev-cli/compare/v1.7.9...v1.7.10) (2018-04-07) 1040 | 1041 | 1042 | ### Bug Fixes 1043 | 1044 | * set content type of manifest files ([cf7b4cc](https://github.com/oclif/dev-cli/commit/cf7b4cc7508492727a0918bd73baf999011e859f)) 1045 | 1046 | 1047 | 1048 | ## [1.7.9](https://github.com/oclif/dev-cli/compare/v1.7.8...v1.7.9) (2018-04-07) 1049 | 1050 | 1051 | ### Bug Fixes 1052 | 1053 | * skip pack test on windows ([14dd2fe](https://github.com/oclif/dev-cli/commit/14dd2fe5087f9027388a8b90ab298587f95d053c)) 1054 | 1055 | 1056 | 1057 | ## [1.7.8](https://github.com/oclif/dev-cli/compare/v1.7.7...v1.7.8) (2018-04-07) 1058 | 1059 | 1060 | ### Bug Fixes 1061 | 1062 | * lint issues ([fe7aafb](https://github.com/oclif/dev-cli/commit/fe7aafbac27083f2544ea83932e853fe88eb20cc)) 1063 | * re-enable xz and fixed some issues with publish:s3 ([377233b](https://github.com/oclif/dev-cli/commit/377233bbf70247791821986019e747885e533d12)) 1064 | 1065 | 1066 | 1067 | ## [1.7.7](https://github.com/oclif/dev-cli/compare/v1.7.6...v1.7.7) (2018-04-07) 1068 | 1069 | 1070 | ### Bug Fixes 1071 | 1072 | * export just the base tarball ([ee057ac](https://github.com/oclif/dev-cli/commit/ee057ac29280f1959fd6c0ee840ce13f6c68646a)) 1073 | * fixup scripts ([3165694](https://github.com/oclif/dev-cli/commit/31656945de9855acd2f423f78172c61de35cb912)) 1074 | 1075 | 1076 | 1077 | ## [1.7.6](https://github.com/oclif/dev-cli/compare/v1.7.5...v1.7.6) (2018-04-07) 1078 | 1079 | 1080 | ### Bug Fixes 1081 | 1082 | * fixup scripts ([bc0d8e4](https://github.com/oclif/dev-cli/commit/bc0d8e4a2ab40a4a79fa10521be10f907584150e)) 1083 | 1084 | 1085 | 1086 | ## [1.7.5](https://github.com/oclif/dev-cli/compare/v1.7.4...v1.7.5) (2018-04-07) 1087 | 1088 | 1089 | ### Bug Fixes 1090 | 1091 | * hide github for now ([59c39c0](https://github.com/oclif/dev-cli/commit/59c39c0ad3ac9d6a11315f387761e714cdd2da3c)) 1092 | 1093 | 1094 | 1095 | ## [1.7.4](https://github.com/oclif/dev-cli/compare/v1.7.3...v1.7.4) (2018-04-07) 1096 | 1097 | 1098 | ### Bug Fixes 1099 | 1100 | * skip postpublish ([0a1c90c](https://github.com/oclif/dev-cli/commit/0a1c90c68c544314837bc95eb4503cbe22d01165)) 1101 | 1102 | 1103 | 1104 | ## [1.7.3](https://github.com/oclif/dev-cli/compare/v1.7.2...v1.7.3) (2018-04-07) 1105 | 1106 | 1107 | ### Bug Fixes 1108 | 1109 | * arm arch ([3ae39c0](https://github.com/oclif/dev-cli/commit/3ae39c09b13368d948678bf089bf814c6015842b)) 1110 | * s3 bucket fixes ([af60ee5](https://github.com/oclif/dev-cli/commit/af60ee5505b1e008645bc1adc548947d2d5f4d3b)) 1111 | 1112 | 1113 | 1114 | ## [1.7.2](https://github.com/oclif/dev-cli/compare/v1.7.1...v1.7.2) (2018-04-07) 1115 | 1116 | 1117 | ### Bug Fixes 1118 | 1119 | * move targets to pjson ([35a077b](https://github.com/oclif/dev-cli/commit/35a077b0056b6481f15059b2f9832978d5c94f14)) 1120 | 1121 | 1122 | 1123 | ## [1.7.1](https://github.com/oclif/dev-cli/compare/v1.7.0...v1.7.1) (2018-04-07) 1124 | 1125 | 1126 | ### Bug Fixes 1127 | 1128 | * fix commitish ([0eb2ea1](https://github.com/oclif/dev-cli/commit/0eb2ea1928fe2a33cca336be79643e588b1150a9)) 1129 | 1130 | 1131 | 1132 | # [1.7.0](https://github.com/oclif/dev-cli/compare/v1.6.0...v1.7.0) (2018-04-07) 1133 | 1134 | 1135 | ### Features 1136 | 1137 | * idempotent github release creation/updating ([d71c63e](https://github.com/oclif/dev-cli/commit/d71c63e2e9e168225d518dfd5c84044e22ae5ec4)) 1138 | 1139 | 1140 | 1141 | # [1.6.0](https://github.com/oclif/dev-cli/compare/v1.5.0...v1.6.0) (2018-04-07) 1142 | 1143 | 1144 | ### Bug Fixes 1145 | 1146 | * move publish to publish:s3 ([40e844e](https://github.com/oclif/dev-cli/commit/40e844ea48ffe1bf5aec8ca6db86df6afb1b4e94)) 1147 | * tests ([a037cfe](https://github.com/oclif/dev-cli/commit/a037cfe9150d0c6969b5924846fa4857fcafb2b1)) 1148 | * updated qqjs ([cf0a9e9](https://github.com/oclif/dev-cli/commit/cf0a9e9a55dc76f14023667f69c8adf6a31303d5)) 1149 | 1150 | 1151 | ### Features 1152 | 1153 | * added publish command ([dacf57b](https://github.com/oclif/dev-cli/commit/dacf57b86f6c6bfa95adcc209e9c75d4c661d3d9)) 1154 | * added publish:github ([37d56f3](https://github.com/oclif/dev-cli/commit/37d56f3ad953fffbde7e56c014d325ec358fa2c9)) 1155 | 1156 | 1157 | 1158 | # [1.5.0](https://github.com/oclif/dev-cli/compare/v1.4.4...v1.5.0) (2018-04-07) 1159 | 1160 | 1161 | ### Features 1162 | 1163 | * pack ([b6b11bb](https://github.com/oclif/dev-cli/commit/b6b11bb8cf9b54ab12e27b3b2fd4b27f137036c1)) 1164 | 1165 | 1166 | 1167 | ## [1.4.4](https://github.com/oclif/dev-cli/compare/v1.4.3...v1.4.4) (2018-03-28) 1168 | 1169 | 1170 | ### Bug Fixes 1171 | 1172 | * updated plugin-help ([f64ae1d](https://github.com/oclif/dev-cli/commit/f64ae1dc28639775171c7ffcc2b27f6ea14bdf75)) 1173 | 1174 | 1175 | 1176 | ## [1.4.3](https://github.com/oclif/dev-cli/compare/v1.4.2...v1.4.3) (2018-03-28) 1177 | 1178 | 1179 | ### Bug Fixes 1180 | 1181 | * updated deps ([62b142c](https://github.com/oclif/dev-cli/commit/62b142ccfb86d16f9becfc95bf0ab0f9cc995224)) 1182 | 1183 | 1184 | 1185 | ## [1.4.2](https://github.com/oclif/dev-cli/compare/v1.4.1...v1.4.2) (2018-03-24) 1186 | 1187 | 1188 | ### Bug Fixes 1189 | 1190 | * fixed command anchor links ([b42656b](https://github.com/oclif/dev-cli/commit/b42656b099edb33d0e030ab385e4a5df3983eb69)) 1191 | 1192 | 1193 | 1194 | ## [1.4.1](https://github.com/oclif/dev-cli/compare/v1.4.0...v1.4.1) (2018-03-23) 1195 | 1196 | 1197 | ### Bug Fixes 1198 | 1199 | * put config.bin in title ([f498214](https://github.com/oclif/dev-cli/commit/f498214fb0ce6aae970eeefdb2f6c21371d10a6f)) 1200 | 1201 | 1202 | 1203 | # [1.4.0](https://github.com/oclif/dev-cli/compare/v1.3.1...v1.4.0) (2018-03-23) 1204 | 1205 | 1206 | ### Features 1207 | 1208 | * remove headers to allow them to be customized ([adf8097](https://github.com/oclif/dev-cli/commit/adf809740afba0439e24d590a2beb6544f659ed5)) 1209 | 1210 | 1211 | 1212 | ## [1.3.1](https://github.com/oclif/dev-cli/compare/v1.3.0...v1.3.1) (2018-03-22) 1213 | 1214 | 1215 | ### Bug Fixes 1216 | 1217 | * use OCLIF_NEXT_VERSION ([7c43aa9](https://github.com/oclif/dev-cli/commit/7c43aa94b04e869ffbfec6d49ac1e7f2562d34d0)) 1218 | 1219 | 1220 | 1221 | # [1.3.0](https://github.com/oclif/dev-cli/compare/v1.2.20...v1.3.0) (2018-03-22) 1222 | 1223 | 1224 | ### Bug Fixes 1225 | 1226 | * fixed platform/arch to match real output ([415dd77](https://github.com/oclif/dev-cli/commit/415dd77e736cf12fe42755ecfac8b13cd8bdb0ef)) 1227 | 1228 | 1229 | ### Features 1230 | 1231 | * combine install/usage steps ([901445d](https://github.com/oclif/dev-cli/commit/901445d5758c07143237e8018a208060dc724be7)) 1232 | 1233 | 1234 | 1235 | ## [1.2.20](https://github.com/oclif/dev-cli/compare/v1.2.19...v1.2.20) (2018-03-15) 1236 | 1237 | 1238 | ### Bug Fixes 1239 | 1240 | * throw an error on plugin warnings when creating the colif manifest ([ef86e2d](https://github.com/oclif/dev-cli/commit/ef86e2d2109433bee66013084de007b5b76b276d)) 1241 | * up version of config to get the error on manifest fix ([452ad4c](https://github.com/oclif/dev-cli/commit/452ad4c61a75f851338d107af153aebb79405308)) 1242 | * updated deps ([f55e27b](https://github.com/oclif/dev-cli/commit/f55e27b143d6f172051ea5b970e3dbe77b0b7033)) 1243 | * use the option to throw instead of listening on process ([4d3fd4f](https://github.com/oclif/dev-cli/commit/4d3fd4fdbe8cdaaeb145fe26f615630245f932d1)) 1244 | 1245 | 1246 | 1247 | ## [1.2.19](https://github.com/oclif/dev-cli/compare/v1.2.18...v1.2.19) (2018-02-28) 1248 | 1249 | 1250 | ### Bug Fixes 1251 | 1252 | * updated deps ([c05aae9](https://github.com/oclif/dev-cli/commit/c05aae9c4c335e738899e9bf6343e7a33dc61bf0)) 1253 | 1254 | 1255 | 1256 | ## [1.2.18](https://github.com/oclif/dev-cli/compare/v1.2.17...v1.2.18) (2018-02-17) 1257 | 1258 | 1259 | ### Bug Fixes 1260 | 1261 | * updated command ([8e87251](https://github.com/oclif/dev-cli/commit/8e8725193a59ce425a603fd18503bbd6110d3c5f)) 1262 | 1263 | 1264 | 1265 | ## [1.2.17](https://github.com/oclif/dev-cli/compare/v1.2.16...v1.2.17) (2018-02-17) 1266 | 1267 | 1268 | ### Bug Fixes 1269 | 1270 | * updated config ([cc99c5e](https://github.com/oclif/dev-cli/commit/cc99c5e268493915a7743a39d947f9ce1d8103ab)) 1271 | 1272 | 1273 | 1274 | ## [1.2.16](https://github.com/oclif/dev-cli/compare/v1.2.15...v1.2.16) (2018-02-17) 1275 | 1276 | 1277 | ### Bug Fixes 1278 | 1279 | * fixed slug with : ([db916ff](https://github.com/oclif/dev-cli/commit/db916ffe57964f67fd6098b3abcab3c8665821e8)) 1280 | 1281 | 1282 | 1283 | ## [1.2.15](https://github.com/oclif/dev-cli/compare/v1.2.14...v1.2.15) (2018-02-17) 1284 | 1285 | 1286 | ### Bug Fixes 1287 | 1288 | * show all commands ([88f9617](https://github.com/oclif/dev-cli/commit/88f96171636a85cc139c79ac6bb4100035919caf)) 1289 | 1290 | 1291 | 1292 | ## [1.2.14](https://github.com/oclif/dev-cli/compare/v1.2.13...v1.2.14) (2018-02-17) 1293 | 1294 | 1295 | ### Bug Fixes 1296 | 1297 | * updated deps ([2478543](https://github.com/oclif/dev-cli/commit/24785434b6ba3cb52eb72928a6025834b97caacc)) 1298 | 1299 | 1300 | 1301 | ## [1.2.13](https://github.com/oclif/dev-cli/compare/v1.2.12...v1.2.13) (2018-02-17) 1302 | 1303 | 1304 | ### Bug Fixes 1305 | 1306 | * fixed uniqby ([59a1d97](https://github.com/oclif/dev-cli/commit/59a1d9723e5ec2f8630d36573cb07aac750fbcd1)) 1307 | 1308 | 1309 | 1310 | ## [1.2.12](https://github.com/oclif/dev-cli/compare/v1.2.11...v1.2.12) (2018-02-15) 1311 | 1312 | 1313 | ### Bug Fixes 1314 | 1315 | * fixed anchor links ([dfc71b8](https://github.com/oclif/dev-cli/commit/dfc71b897dad8e5026ace6b7349c9ea3c7eb123f)) 1316 | 1317 | 1318 | 1319 | ## [1.2.11](https://github.com/oclif/dev-cli/compare/v1.2.10...v1.2.11) (2018-02-15) 1320 | 1321 | 1322 | ### Bug Fixes 1323 | 1324 | * fixed slug generation with emojis ([0eb5b51](https://github.com/oclif/dev-cli/commit/0eb5b518f4262b7a51870c7fc396116d84c2578e)) 1325 | 1326 | 1327 | 1328 | ## [1.2.10](https://github.com/oclif/dev-cli/compare/v1.2.9...v1.2.10) (2018-02-15) 1329 | 1330 | 1331 | ### Bug Fixes 1332 | 1333 | * improve slug generation ([7cf7bec](https://github.com/oclif/dev-cli/commit/7cf7bec9fc2af45be1de7a61241d883b9d2deeb4)) 1334 | 1335 | 1336 | 1337 | ## [1.2.9](https://github.com/oclif/dev-cli/compare/v1.2.8...v1.2.9) (2018-02-15) 1338 | 1339 | 1340 | ### Bug Fixes 1341 | 1342 | * use OCLIF_NEXT_VERSION ([1bdf2af](https://github.com/oclif/dev-cli/commit/1bdf2af9f464fdee0868b1d6f5637b6242e769d5)) 1343 | 1344 | 1345 | 1346 | ## [1.2.8](https://github.com/oclif/dev-cli/compare/v1.2.7...v1.2.8) (2018-02-15) 1347 | 1348 | 1349 | ### Bug Fixes 1350 | 1351 | * hide OPTIONS for now ([2fb4bf3](https://github.com/oclif/dev-cli/commit/2fb4bf3eae40033f2287f5b99a78027bcb44d647)) 1352 | * hide OPTIONS for now ([f5a9af6](https://github.com/oclif/dev-cli/commit/f5a9af6d32aaba64d41b67e018712bdf5c67c4fb)) 1353 | 1354 | 1355 | 1356 | ## [1.2.7](https://github.com/oclif/dev-cli/compare/v1.2.6...v1.2.7) (2018-02-15) 1357 | 1358 | 1359 | ### Bug Fixes 1360 | 1361 | * remove [OPTIONS] ([2b1b5a7](https://github.com/oclif/dev-cli/commit/2b1b5a7b18b930148bdf44ed6fd662f3dc852798)) 1362 | 1363 | 1364 | 1365 | ## [1.2.6](https://github.com/oclif/dev-cli/compare/v1.2.5...v1.2.6) (2018-02-15) 1366 | 1367 | 1368 | ### Bug Fixes 1369 | 1370 | * updated deps ([2a23592](https://github.com/oclif/dev-cli/commit/2a235923e264d6a47e0d46e2ad43c1fa33d71669)) 1371 | 1372 | 1373 | 1374 | ## [1.2.5](https://github.com/oclif/dev-cli/compare/v1.2.4...v1.2.5) (2018-02-15) 1375 | 1376 | 1377 | ### Bug Fixes 1378 | 1379 | * replace spaces with dashes for anchors ([5abc82f](https://github.com/oclif/dev-cli/commit/5abc82f90c49d2d369497bd3519090542803b762)) 1380 | 1381 | 1382 | 1383 | ## [1.2.4](https://github.com/oclif/dev-cli/compare/v1.2.3...v1.2.4) (2018-02-14) 1384 | 1385 | 1386 | ### Bug Fixes 1387 | 1388 | * trim description ([aeedc05](https://github.com/oclif/dev-cli/commit/aeedc05ba43c07dcef7a2090681a499040aeefc1)) 1389 | 1390 | 1391 | 1392 | ## [1.2.3](https://github.com/oclif/dev-cli/compare/v1.2.2...v1.2.3) (2018-02-14) 1393 | 1394 | 1395 | ### Bug Fixes 1396 | 1397 | * improve docs ([10e6e5e](https://github.com/oclif/dev-cli/commit/10e6e5e1db71660370d97d11149ad762df10353b)) 1398 | 1399 | 1400 | 1401 | ## [1.2.2](https://github.com/oclif/dev-cli/compare/v1.2.1...v1.2.2) (2018-02-14) 1402 | 1403 | 1404 | ### Bug Fixes 1405 | 1406 | * fixed anchor links ([02ed25b](https://github.com/oclif/dev-cli/commit/02ed25bfe19585594fcf288f84949cddc5f6ba66)) 1407 | 1408 | 1409 | 1410 | ## [1.2.1](https://github.com/oclif/dev-cli/compare/v1.2.0...v1.2.1) (2018-02-14) 1411 | 1412 | 1413 | ### Bug Fixes 1414 | 1415 | * fixed label for own commands ([499f5bb](https://github.com/oclif/dev-cli/commit/499f5bb854176b8c0aabf8ae30bd9c4e71911cf2)) 1416 | 1417 | 1418 | 1419 | # [1.2.0](https://github.com/oclif/dev-cli/compare/v1.1.0...v1.2.0) (2018-02-14) 1420 | 1421 | 1422 | ### Features 1423 | 1424 | * added readme toc ([1b6f61b](https://github.com/oclif/dev-cli/commit/1b6f61b1ac2d10bad49e4dfb4ef937dd4451f242)) 1425 | 1426 | 1427 | 1428 | # [1.1.0](https://github.com/oclif/dev-cli/compare/v1.0.2...v1.1.0) (2018-02-14) 1429 | 1430 | 1431 | ### Features 1432 | 1433 | * add usage to command headers ([224679b](https://github.com/oclif/dev-cli/commit/224679be9421fb0159f51ea1c499e7f9e06012e8)) 1434 | 1435 | 1436 | 1437 | ## [1.0.2](https://github.com/oclif/dev-cli/compare/v1.0.1...v1.0.2) (2018-02-13) 1438 | 1439 | 1440 | ### Bug Fixes 1441 | 1442 | * added version script ([7fe8937](https://github.com/oclif/dev-cli/commit/7fe89373192e4d9d8c55ae6d98917d9d61fb2233)) 1443 | 1444 | 1445 | 1446 | ## [1.0.1](https://github.com/oclif/dev-cli/compare/v0.3.16...v1.0.1) (2018-02-13) 1447 | 1448 | 1449 | ### Bug Fixes 1450 | 1451 | * fixing windows readme generation ([441f1a9](https://github.com/oclif/dev-cli/commit/441f1a9d9baa0e55cc7c2ab67f14e0c4d23c5cfd)) 1452 | * updated deps ([7d3e16e](https://github.com/oclif/dev-cli/commit/7d3e16eaf7fdf85b6b30b878954825b896be3175)) 1453 | * use v1 of nyc-config ([84d3a65](https://github.com/oclif/dev-cli/commit/84d3a65e37af47996b25f67dc5dfa2affcfe5db5)) 1454 | 1455 | 1456 | 1457 | ## [0.3.16](https://github.com/oclif/dev-cli/compare/v0.3.15...v0.3.16) (2018-02-13) 1458 | 1459 | 1460 | ### Bug Fixes 1461 | 1462 | * updated legacy ([15fa7aa](https://github.com/oclif/dev-cli/commit/15fa7aa108463a3ebfc7fc781b2e155add532867)) 1463 | 1464 | 1465 | 1466 | ## [0.3.15](https://github.com/oclif/dev-cli/compare/v0.3.14...v0.3.15) (2018-02-13) 1467 | 1468 | 1469 | ### Bug Fixes 1470 | 1471 | * updated deps ([3a978f4](https://github.com/oclif/dev-cli/commit/3a978f4335ee06d88b92a4e2ef2e7c1ca7b7e8e2)) 1472 | 1473 | 1474 | 1475 | ## [0.3.14](https://github.com/oclif/dev-cli/compare/v0.3.13...v0.3.14) (2018-02-13) 1476 | 1477 | 1478 | ### Bug Fixes 1479 | 1480 | * oclif rename ([7a727af](https://github.com/oclif/dev-cli/commit/7a727affb534f28dd9e7655119e52a5eb20e3fe9)) 1481 | 1482 | 1483 | 1484 | ## [0.3.13](https://github.com/oclif/dev-cli/compare/v0.3.12...v0.3.13) (2018-02-13) 1485 | 1486 | 1487 | ### Bug Fixes 1488 | 1489 | * updated test ([179019c](https://github.com/oclif/dev-cli/commit/179019c9a80944e764714debcc06236c3f3d4fde)) 1490 | 1491 | 1492 | 1493 | ## [0.3.12](https://github.com/oclif/dev-cli/compare/v0.3.11...v0.3.12) (2018-02-13) 1494 | 1495 | 1496 | ### Bug Fixes 1497 | 1498 | * set next version ([49135a9](https://github.com/oclif/dev-cli/commit/49135a9ca2c73690f2d33d195d06f4ab0a97c501)) 1499 | 1500 | 1501 | 1502 | ## [0.3.11](https://github.com/oclif/dev-cli/compare/v0.3.10...v0.3.11) (2018-02-13) 1503 | 1504 | 1505 | ### Bug Fixes 1506 | 1507 | * oclif rename ([a598697](https://github.com/oclif/dev-cli/commit/a5986971f3e4093445198558442d17a6d79f8512)) 1508 | 1509 | 1510 | 1511 | ## [0.3.10](https://github.com/oclif/dev-cli/compare/v0.3.9...v0.3.10) (2018-02-07) 1512 | 1513 | 1514 | ### Bug Fixes 1515 | 1516 | * bump deps ([0695878](https://github.com/oclif/dev-cli/commit/0695878d56d7bcfb35feeeed7e07f45e18fd8d4e)) 1517 | * load legacy plugins ([96076bd](https://github.com/oclif/dev-cli/commit/96076bd3e4ed6f0c1d878923fa729650f2f3fb19)) 1518 | 1519 | 1520 | 1521 | ## [0.3.9](https://github.com/oclif/dev-cli/compare/v0.3.8...v0.3.9) (2018-02-07) 1522 | 1523 | 1524 | ### Bug Fixes 1525 | 1526 | * updated deps ([9d0fb57](https://github.com/oclif/dev-cli/commit/9d0fb5760e377aa26b795194a068dca1cfae22bf)) 1527 | 1528 | 1529 | 1530 | ## [0.3.8](https://github.com/oclif/dev-cli/compare/v0.3.7...v0.3.8) (2018-02-07) 1531 | 1532 | 1533 | ### Bug Fixes 1534 | 1535 | * updated command ([79b0796](https://github.com/oclif/dev-cli/commit/79b0796c62b93b3e252854b87824e6093ac6e2ae)) 1536 | 1537 | 1538 | 1539 | ## [0.3.7](https://github.com/oclif/dev-cli/compare/v0.3.6...v0.3.7) (2018-02-07) 1540 | 1541 | 1542 | ### Bug Fixes 1543 | 1544 | * bump config ([ace795c](https://github.com/oclif/dev-cli/commit/ace795c22190d9ac1967648cbb4a710767dfd544)) 1545 | * fixed topics ([077e502](https://github.com/oclif/dev-cli/commit/077e50215897dcf16de4c3b66f119cc0b7bd7370)) 1546 | * some docs ([3de5e5e](https://github.com/oclif/dev-cli/commit/3de5e5eef6c0c8ad8b8c3372e8df83dfabc9f1ef)) 1547 | 1548 | 1549 | 1550 | ## [0.3.6](https://github.com/oclif/dev-cli/compare/v0.3.5...v0.3.6) (2018-02-07) 1551 | 1552 | 1553 | ### Bug Fixes 1554 | 1555 | * fixing legacy requires ([432a5f4](https://github.com/oclif/dev-cli/commit/432a5f465376d1de0652836caa7215d5ba4e37df)) 1556 | 1557 | 1558 | 1559 | ## [0.3.5](https://github.com/oclif/dev-cli/compare/v0.3.4...v0.3.5) (2018-02-07) 1560 | 1561 | 1562 | ### Bug Fixes 1563 | 1564 | * improve finding source code path ([aaf17b5](https://github.com/oclif/dev-cli/commit/aaf17b5a133d67e61f34339a1b8e4644c77c2305)) 1565 | 1566 | 1567 | 1568 | ## [0.3.4](https://github.com/oclif/dev-cli/compare/v0.3.3...v0.3.4) (2018-02-07) 1569 | 1570 | 1571 | ### Bug Fixes 1572 | 1573 | * fixed readme output ([7525062](https://github.com/oclif/dev-cli/commit/7525062ee240be6ca830086112c25ce9613092dd)) 1574 | 1575 | 1576 | 1577 | ## [0.3.3](https://github.com/oclif/dev-cli/compare/v0.3.2...v0.3.3) (2018-02-07) 1578 | 1579 | 1580 | ### Bug Fixes 1581 | 1582 | * run build before tests ([31269cd](https://github.com/oclif/dev-cli/commit/31269cdda865fbd52e6a8cf9bf42b9f14b444430)) 1583 | * updated config ([8f1f059](https://github.com/oclif/dev-cli/commit/8f1f059a14323f459c4c4089e0955dd6e9e9ce29)) 1584 | 1585 | 1586 | 1587 | ## [0.3.2](https://github.com/oclif/dev-cli/compare/v0.3.1...v0.3.2) (2018-02-07) 1588 | 1589 | 1590 | ### Bug Fixes 1591 | 1592 | * fixed reference to self ([3163d01](https://github.com/oclif/dev-cli/commit/3163d01b3956a0ee2025b947b304f7bae310d97c)) 1593 | * unlink if linked ([3d4e1b7](https://github.com/oclif/dev-cli/commit/3d4e1b7778f9aac6dd4b7e65fbe079be1ed7ea61)) 1594 | * use local dev-cli ([7182640](https://github.com/oclif/dev-cli/commit/71826403f423a13fe8d99b7f45dfcc76bdd301c5)) 1595 | 1596 | 1597 | 1598 | ## [0.3.1](https://github.com/oclif/dev-cli/compare/v0.3.0...v0.3.1) (2018-02-07) 1599 | 1600 | 1601 | ### Bug Fixes 1602 | 1603 | * updated config ([730e2ac](https://github.com/oclif/dev-cli/commit/730e2ac221503f3207122616a1d44c8494eecc5c)) 1604 | * use git tag for command links ([09ba83e](https://github.com/oclif/dev-cli/commit/09ba83e201e14137eb6f7542325eb8ec6a0d5e52)) 1605 | * yarn link ([b3db28e](https://github.com/oclif/dev-cli/commit/b3db28e7f3cfc9e6819498004ade17d36ff1745d)) 1606 | * yarn link ([49fcca4](https://github.com/oclif/dev-cli/commit/49fcca423bc0c619b254bfabdae1b653394abb0c)) 1607 | 1608 | 1609 | 1610 | # [0.3.0](https://github.com/oclif/dev-cli/compare/v0.2.2...v0.3.0) (2018-02-06) 1611 | 1612 | 1613 | ### Bug Fixes 1614 | 1615 | * fixed test ([23fd20e](https://github.com/oclif/dev-cli/commit/23fd20e8e64bacac6eadf51e8526936ea971ad18)) 1616 | 1617 | 1618 | ### Features 1619 | 1620 | * added multi readme ([63f1385](https://github.com/oclif/dev-cli/commit/63f1385d740d8d201bbda1effd4657eb15a69e07)) 1621 | * readme generator work ([fa21751](https://github.com/oclif/dev-cli/commit/fa21751482e682896b1c3c92fcd035d3ca80d61e)) 1622 | 1623 | 1624 | 1625 | ## [0.2.2](https://github.com/oclif/dev-cli/compare/v0.2.1...v0.2.2) (2018-02-06) 1626 | 1627 | 1628 | ### Bug Fixes 1629 | 1630 | * bust cache ([9a1d6cf](https://github.com/oclif/dev-cli/commit/9a1d6cf4ec93ece7b2ad3d18b37a5a98a1b291c2)) 1631 | 1632 | 1633 | 1634 | ## [0.2.1](https://github.com/oclif/dev-cli/compare/v0.2.0...v0.2.1) (2018-02-06) 1635 | 1636 | 1637 | ### Bug Fixes 1638 | 1639 | * delete manifest if it exists ([79d6aa0](https://github.com/oclif/dev-cli/commit/79d6aa03636b02568bc9c5803c467d36721d4ec2)) 1640 | 1641 | 1642 | 1643 | # [0.2.0](https://github.com/oclif/dev-cli/compare/v0.1.7...v0.2.0) (2018-02-06) 1644 | 1645 | 1646 | ### Features 1647 | 1648 | * add legacy support ([cd64309](https://github.com/oclif/dev-cli/commit/cd643092e72139444fd8fbec50ff9e6c555019f6)) 1649 | 1650 | 1651 | 1652 | ## [0.1.7](https://github.com/oclif/dev-cli/compare/v0.1.6...v0.1.7) (2018-02-06) 1653 | 1654 | 1655 | ### Bug Fixes 1656 | 1657 | * use @anycli/errors ([feb3c0f](https://github.com/oclif/dev-cli/commit/feb3c0fc41037cd0f2810aefaf594a20bf0d0322)) 1658 | 1659 | 1660 | 1661 | ## [0.1.6](https://github.com/oclif/dev-cli/compare/v0.1.5...v0.1.6) (2018-02-05) 1662 | 1663 | 1664 | ### Bug Fixes 1665 | 1666 | * remove unneded deps ([6723525](https://github.com/oclif/dev-cli/commit/6723525df64568220de5e15ed8fd8dadc771ac0b)) 1667 | 1668 | 1669 | 1670 | ## [0.1.5](https://github.com/oclif/dev-cli/compare/v0.1.4...v0.1.5) (2018-02-03) 1671 | 1672 | 1673 | ### Bug Fixes 1674 | 1675 | * updated deps ([662f386](https://github.com/oclif/dev-cli/commit/662f3865586bd6e7d2a80bf72c9f5115b02abf89)) 1676 | 1677 | 1678 | 1679 | ## [0.1.4](https://github.com/oclif/dev-cli/compare/v0.1.3...v0.1.4) (2018-02-03) 1680 | 1681 | 1682 | ### Bug Fixes 1683 | 1684 | * updated config ([92d035f](https://github.com/oclif/dev-cli/commit/92d035f430579c2d0276d975fbad9d81f66d320f)) 1685 | * updated deps ([5ba0813](https://github.com/oclif/dev-cli/commit/5ba0813d27317e8d0a3e22c192acbef5ad36bbf1)) 1686 | 1687 | 1688 | 1689 | ## [0.1.3](https://github.com/oclif/dev-cli/compare/v0.1.2...v0.1.3) (2018-02-02) 1690 | 1691 | 1692 | ### Bug Fixes 1693 | 1694 | * fixed -o flag ([b338106](https://github.com/oclif/dev-cli/commit/b3381061be634c27bfdf504de604a467876aad51)) 1695 | 1696 | 1697 | 1698 | ## [0.1.2](https://github.com/oclif/dev-cli/compare/v0.1.1...v0.1.2) (2018-02-02) 1699 | 1700 | 1701 | ### Bug Fixes 1702 | 1703 | * set version with ANYCLI_NEXT_VERSION ([ad1c899](https://github.com/oclif/dev-cli/commit/ad1c899a6249fddb0533a4055b870b3727063f25)) 1704 | 1705 | 1706 | 1707 | ## [0.1.1](https://github.com/oclif/dev-cli/compare/v0.1.0...v0.1.1) (2018-02-02) 1708 | 1709 | 1710 | ### Bug Fixes 1711 | 1712 | * add path argument ([97e6a90](https://github.com/oclif/dev-cli/commit/97e6a90e2c51cffc0f7f2078b844ce2062d743fe)) 1713 | 1714 | 1715 | 1716 | # [0.1.0](https://github.com/oclif/dev-cli/compare/v0.0.1...v0.1.0) (2018-02-02) 1717 | 1718 | 1719 | ### Features 1720 | 1721 | * added manifest command ([97b7644](https://github.com/oclif/dev-cli/commit/97b7644228d66885d165db8479b40632985dd883)) 1722 | 1723 | 1724 | 1725 | ## [0.0.1](https://github.com/oclif/dev-cli/compare/v0.0.0...v0.0.1) (2018-02-02) 1726 | 1727 | 1728 | ### Bug Fixes 1729 | 1730 | * added bin scripts ([4e778e0](https://github.com/oclif/dev-cli/commit/4e778e0b5f9699b2f52c375e14bbb5b560fac31e)) 1731 | 1732 | 1733 | 1734 | # 0.0.0 (2018-02-02) 1735 | 1736 | 1737 | 1738 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Salesforce.com 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 | @oclif/dev-cli 2 | =============== 3 | 4 | **This library has been replaced by [oclif](https://github.com/oclif) and is now in maintenance mode. We will only consider PRs that address security concerns.** 5 | 6 | helpers for oclif CLIs 7 | 8 | [![Version](https://img.shields.io/npm/v/@oclif/dev-cli.svg)](https://npmjs.org/package/@oclif/dev-cli) 9 | [![CircleCI](https://circleci.com/gh/oclif/dev-cli/tree/master.svg?style=shield)](https://circleci.com/gh/oclif/dev-cli/tree/master) 10 | [![Appveyor CI](https://ci.appveyor.com/api/projects/status/github/oclif/dev-cli?branch=master&svg=true)](https://ci.appveyor.com/project/heroku/dev-cli/branch/master) 11 | [![Known Vulnerabilities](https://snyk.io/test/npm/@oclif/dev-cli/badge.svg)](https://snyk.io/test/npm/@oclif/dev-cli) 12 | [![Downloads/week](https://img.shields.io/npm/dw/@oclif/dev-cli.svg)](https://npmjs.org/package/@oclif/dev-cli) 13 | [![License](https://img.shields.io/npm/l/@oclif/dev-cli.svg)](https://github.com/oclif/dev-cli/blob/master/package.json) 14 | 15 | 16 | * [Usage](#usage) 17 | * [Commands](#commands) 18 | 19 | # Usage 20 | 21 | ```sh-session 22 | $ npm install -g @oclif/dev-cli 23 | $ oclif-dev COMMAND 24 | running command... 25 | $ oclif-dev (-v|--version|version) 26 | @oclif/dev-cli/1.26.10 linux-x64 node-v14.18.2 27 | $ oclif-dev --help [COMMAND] 28 | USAGE 29 | $ oclif-dev COMMAND 30 | ... 31 | ``` 32 | 33 | # Commands 34 | 35 | * [`oclif-dev help [COMMAND]`](#oclif-dev-help-command) 36 | * [`oclif-dev manifest [PATH]`](#oclif-dev-manifest-path) 37 | * [`oclif-dev pack`](#oclif-dev-pack) 38 | * [`oclif-dev pack:deb`](#oclif-dev-packdeb) 39 | * [`oclif-dev pack:macos`](#oclif-dev-packmacos) 40 | * [`oclif-dev pack:win`](#oclif-dev-packwin) 41 | * [`oclif-dev publish`](#oclif-dev-publish) 42 | * [`oclif-dev publish:deb`](#oclif-dev-publishdeb) 43 | * [`oclif-dev publish:macos`](#oclif-dev-publishmacos) 44 | * [`oclif-dev publish:win`](#oclif-dev-publishwin) 45 | * [`oclif-dev readme`](#oclif-dev-readme) 46 | 47 | ## `oclif-dev help [COMMAND]` 48 | 49 | display help for oclif-dev 50 | 51 | ``` 52 | USAGE 53 | $ oclif-dev help [COMMAND] 54 | 55 | ARGUMENTS 56 | COMMAND command to show help for 57 | 58 | OPTIONS 59 | --all see all commands in CLI 60 | ``` 61 | 62 | _See code: [@oclif/plugin-help](https://github.com/oclif/plugin-help/blob/v3.2.18/src/commands/help.ts)_ 63 | 64 | ## `oclif-dev manifest [PATH]` 65 | 66 | generates plugin manifest json 67 | 68 | ``` 69 | USAGE 70 | $ oclif-dev manifest [PATH] 71 | 72 | ARGUMENTS 73 | PATH [default: .] path to plugin 74 | ``` 75 | 76 | _See code: [src/commands/manifest.ts](https://github.com/oclif/dev-cli/blob/v1.26.10/src/commands/manifest.ts)_ 77 | 78 | ## `oclif-dev pack` 79 | 80 | packages oclif cli into tarballs 81 | 82 | ``` 83 | USAGE 84 | $ oclif-dev pack 85 | 86 | OPTIONS 87 | -r, --root=root (required) [default: .] path to oclif CLI root 88 | -t, --targets=targets comma-separated targets to pack (e.g.: linux-arm,win32-x64) 89 | --[no-]xz also build xz 90 | 91 | DESCRIPTION 92 | This can be used to create oclif CLIs that use the system node or that come preloaded with a node binary. 93 | ``` 94 | 95 | _See code: [src/commands/pack/index.ts](https://github.com/oclif/dev-cli/blob/v1.26.10/src/commands/pack/index.ts)_ 96 | 97 | ## `oclif-dev pack:deb` 98 | 99 | pack CLI into debian package 100 | 101 | ``` 102 | USAGE 103 | $ oclif-dev pack:deb 104 | 105 | OPTIONS 106 | -r, --root=root (required) [default: .] path to oclif CLI root 107 | ``` 108 | 109 | _See code: [src/commands/pack/deb.ts](https://github.com/oclif/dev-cli/blob/v1.26.10/src/commands/pack/deb.ts)_ 110 | 111 | ## `oclif-dev pack:macos` 112 | 113 | pack CLI into MacOS .pkg 114 | 115 | ``` 116 | USAGE 117 | $ oclif-dev pack:macos 118 | 119 | OPTIONS 120 | -r, --root=root (required) [default: .] path to oclif CLI root 121 | ``` 122 | 123 | _See code: [src/commands/pack/macos.ts](https://github.com/oclif/dev-cli/blob/v1.26.10/src/commands/pack/macos.ts)_ 124 | 125 | ## `oclif-dev pack:win` 126 | 127 | create windows installer from oclif CLI 128 | 129 | ``` 130 | USAGE 131 | $ oclif-dev pack:win 132 | 133 | OPTIONS 134 | -r, --root=root (required) [default: .] path to oclif CLI root 135 | ``` 136 | 137 | _See code: [src/commands/pack/win.ts](https://github.com/oclif/dev-cli/blob/v1.26.10/src/commands/pack/win.ts)_ 138 | 139 | ## `oclif-dev publish` 140 | 141 | publish an oclif CLI to S3 142 | 143 | ``` 144 | USAGE 145 | $ oclif-dev publish 146 | 147 | OPTIONS 148 | -r, --root=root (required) [default: .] path to oclif CLI root 149 | -t, --targets=targets comma-separated targets to pack (e.g.: linux-arm,win32-x64) 150 | 151 | DESCRIPTION 152 | "aws-sdk" will need to be installed as a devDependency to publish. 153 | ``` 154 | 155 | _See code: [src/commands/publish/index.ts](https://github.com/oclif/dev-cli/blob/v1.26.10/src/commands/publish/index.ts)_ 156 | 157 | ## `oclif-dev publish:deb` 158 | 159 | publish deb package built with pack:deb 160 | 161 | ``` 162 | USAGE 163 | $ oclif-dev publish:deb 164 | 165 | OPTIONS 166 | -r, --root=root (required) [default: .] path to oclif CLI root 167 | ``` 168 | 169 | _See code: [src/commands/publish/deb.ts](https://github.com/oclif/dev-cli/blob/v1.26.10/src/commands/publish/deb.ts)_ 170 | 171 | ## `oclif-dev publish:macos` 172 | 173 | publish macos installers built with pack:macos 174 | 175 | ``` 176 | USAGE 177 | $ oclif-dev publish:macos 178 | 179 | OPTIONS 180 | -r, --root=root (required) [default: .] path to oclif CLI root 181 | ``` 182 | 183 | _See code: [src/commands/publish/macos.ts](https://github.com/oclif/dev-cli/blob/v1.26.10/src/commands/publish/macos.ts)_ 184 | 185 | ## `oclif-dev publish:win` 186 | 187 | publish windows installers built with pack:win 188 | 189 | ``` 190 | USAGE 191 | $ oclif-dev publish:win 192 | 193 | OPTIONS 194 | -r, --root=root (required) [default: .] path to oclif CLI root 195 | ``` 196 | 197 | _See code: [src/commands/publish/win.ts](https://github.com/oclif/dev-cli/blob/v1.26.10/src/commands/publish/win.ts)_ 198 | 199 | ## `oclif-dev readme` 200 | 201 | adds commands to README.md in current directory 202 | 203 | ``` 204 | USAGE 205 | $ oclif-dev readme 206 | 207 | OPTIONS 208 | --dir=dir (required) [default: docs] output directory for multi docs 209 | --multi create a different markdown page for each topic 210 | 211 | DESCRIPTION 212 | The readme must have any of the following tags inside of it for it to be replaced or else it will do nothing: 213 | # Usage 214 | 215 | # Commands 216 | 217 | 218 | Customize the code URL prefix by setting oclif.repositoryPrefix in package.json. 219 | ``` 220 | 221 | _See code: [src/commands/readme.ts](https://github.com/oclif/dev-cli/blob/v1.26.10/src/commands/readme.ts)_ 222 | 223 | -------------------------------------------------------------------------------- /bin/run: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | require('@oclif/command').run() 4 | .catch(require('@oclif/errors/handle')) 5 | -------------------------------------------------------------------------------- /bin/run.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | node "%~dp0\run" %* 4 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@oclif/dev-cli", 3 | "description": "helpers for oclif CLIs", 4 | "version": "1.26.10", 5 | "author": "Jeff Dickey @jdxcode", 6 | "bin": { 7 | "oclif-dev": "./bin/run" 8 | }, 9 | "bugs": "https://github.com/oclif/dev-cli/issues", 10 | "dependencies": { 11 | "@oclif/command": "^1.8.15", 12 | "@oclif/config": "^1.18.2", 13 | "@oclif/errors": "^1.3.5", 14 | "@oclif/plugin-help": "3.2.18", 15 | "cli-ux": "5.6.7", 16 | "debug": "^4.1.1", 17 | "find-yarn-workspace-root": "^2.0.0", 18 | "fs-extra": "^8.1", 19 | "github-slugger": "^1.2.1", 20 | "lodash": "^4.17.11", 21 | "normalize-package-data": "^3.0.0", 22 | "qqjs": "^0.3.10", 23 | "tslib": "^2.0.3" 24 | }, 25 | "devDependencies": { 26 | "@oclif/plugin-legacy": "1.2.7", 27 | "@oclif/test": "1.2.9", 28 | "@types/chai": "^4.1.7", 29 | "@types/execa": "^0.9.0", 30 | "@types/fs-extra": "^9.0", 31 | "@types/lodash": "^4.14.177", 32 | "@types/mocha": "^7.0.2", 33 | "@types/node": "^14.0.14", 34 | "@types/supports-color": "^5.3.0", 35 | "@types/write-json-file": "^3.2.1", 36 | "aws-sdk": "^2.443.0", 37 | "chai": "^4.2.0", 38 | "conventional-changelog-cli": "^2.0.17", 39 | "eslint": "^7.3.1", 40 | "eslint-config-oclif": "^3.1.0", 41 | "eslint-config-oclif-typescript": "^0.2.0", 42 | "globby": "^11.0.1", 43 | "mocha": "^8.2.1", 44 | "ts-node": "^9.0.0", 45 | "typescript": "3.8.3" 46 | }, 47 | "engines": { 48 | "node": ">=8.10.0" 49 | }, 50 | "files": [ 51 | "/oclif.manifest.json", 52 | "/bin", 53 | "/lib" 54 | ], 55 | "homepage": "https://github.com/oclif/dev-cli", 56 | "keywords": [ 57 | "oclif" 58 | ], 59 | "license": "MIT", 60 | "main": "lib/index.js", 61 | "oclif": { 62 | "commands": "./lib/commands", 63 | "dirname": "oclif-dev", 64 | "bin": "oclif-dev", 65 | "macos": { 66 | "identifier": "com.oclif.devcli", 67 | "sign": "Developer ID Installer: Heroku INC" 68 | }, 69 | "update": { 70 | "autoupdate": { 71 | "rollout": 50, 72 | "debounce": 60 73 | }, 74 | "node": { 75 | "version": "12.12.0" 76 | }, 77 | "s3": { 78 | "bucket": "oclif-staging", 79 | "xz": true 80 | } 81 | }, 82 | "plugins": [ 83 | "@oclif/plugin-help" 84 | ] 85 | }, 86 | "repository": "oclif/dev-cli", 87 | "scripts": { 88 | "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0 && git add CHANGELOG.md", 89 | "lint": "eslint . --ext .ts --config .eslintrc", 90 | "postpack": "rm -f oclif.manifest.json", 91 | "posttest": "yarn lint", 92 | "prepack": "yarn build && node ./bin/run manifest", 93 | "test": "mocha --forbid-only \"test/**/*.test.ts\"", 94 | "version": "npm run changelog && node ./bin/run readme && git add README.md", 95 | "pretest": "yarn build --noEmit && echo 'Skipping test dir compile check in CI for now (3rd party type error) but you should compile it locally'", 96 | "build": "rm -rf lib && tsc" 97 | }, 98 | "types": "lib/index.d.ts" 99 | } 100 | -------------------------------------------------------------------------------- /src/aws.ts: -------------------------------------------------------------------------------- 1 | import * as CloudFront from 'aws-sdk/clients/cloudfront' 2 | import * as S3 from 'aws-sdk/clients/s3' 3 | import * as fs from 'fs-extra' 4 | import * as qq from 'qqjs' 5 | 6 | import {debug as Debug, log} from './log' 7 | 8 | const debug = Debug.new('aws') 9 | 10 | export namespace upload { 11 | export interface Options { 12 | localFile: string; 13 | s3Params: { 14 | Bucket: string; 15 | Key: string; 16 | }; 17 | } 18 | } 19 | 20 | const cache: {s3?: S3; cloudfront?: CloudFront} = {} 21 | const aws = { 22 | get creds() { 23 | const creds = { 24 | accessKeyId: process.env.AWS_ACCESS_KEY_ID, 25 | secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY, 26 | sessionToken: process.env.AWS_SESSION_TOKEN, 27 | } 28 | if (!creds.accessKeyId) throw new Error('AWS_ACCESS_KEY_ID not set') 29 | if (!creds.secretAccessKey) throw new Error('AWS_SECRET_ACCESS_KEY not set') 30 | return creds 31 | }, 32 | get s3() { 33 | try { 34 | cache.s3 = cache.s3 || new (require('aws-sdk/clients/s3') as typeof S3)({ 35 | ...this.creds, 36 | region: process.env.AWS_REGION, 37 | sslEnabled: process.env.AWS_SSL_ENABLED === undefined ? undefined : process.env.AWS_SSL_ENABLED === 'true', 38 | s3ForcePathStyle: process.env.AWS_S3_FORCE_PATH_STYLE === undefined ? undefined : process.env.AWS_S3_FORCE_PATH_STYLE === 'true', 39 | endpoint: process.env.AWS_S3_ENDPOINT, 40 | }) 41 | return cache.s3 42 | } catch (error) { 43 | if (error.code === 'MODULE_NOT_FOUND') throw new Error(`${error.message}\naws-sdk is needed to run this command.\nInstall aws-sdk as a devDependency in your CLI. \`yarn add -D aws-sdk\``) 44 | throw error 45 | } 46 | }, 47 | get cloudfront() { 48 | cache.cloudfront = cache.cloudfront || new (require('aws-sdk/clients/cloudfront') as typeof CloudFront)(this.creds) 49 | return cache.cloudfront 50 | }, 51 | } 52 | 53 | export default { 54 | get cloudfront() { 55 | return { 56 | createCloudfrontInvalidation: (options: CloudFront.Types.CreateInvalidationRequest) => new Promise((resolve, reject) => { 57 | log('createCloudfrontInvalidation', options.DistributionId, options.InvalidationBatch.Paths.Items) 58 | aws.cloudfront.createInvalidation(options, err => { 59 | if (err) reject(err) 60 | else resolve() 61 | }) 62 | }), 63 | } 64 | }, 65 | get s3() { 66 | return { 67 | uploadFile: (local: string, options: S3.Types.PutObjectRequest) => new Promise((resolve, reject) => { 68 | log('s3:uploadFile', qq.prettifyPaths(local), `s3://${options.Bucket}/${options.Key}`) 69 | options.Body = fs.createReadStream(local) 70 | aws.s3.upload(options, err => { 71 | if (err) reject(err) 72 | else resolve() 73 | }) 74 | }), 75 | headObject: (options: S3.Types.HeadObjectRequest) => new Promise((resolve, reject) => { 76 | debug('s3:headObject', `s3://${options.Bucket}/${options.Key}`) 77 | aws.s3.headObject(options, (err, data) => { 78 | if (err) reject(err) 79 | else resolve(data) 80 | }) 81 | }), 82 | } 83 | }, 84 | } 85 | 86 | // export const getObject = (options: S3.Types.GetObjectRequest) => new Promise((resolve, reject) => { 87 | // debug('getObject', `s3://${options.Bucket}/${options.Key}`) 88 | // s3().getObject(options, (err, data) => { 89 | // if (err) reject(err) 90 | // else resolve(data) 91 | // }) 92 | // }) 93 | 94 | // export const listObjects = (options: S3.Types.ListObjectsV2Request) => new Promise((resolve, reject) => { 95 | // debug('listObjects', `s3://${options.Bucket}/${options.Prefix}`) 96 | // s3().listObjectsV2(options, (err, objects) => { 97 | // if (err) reject(err) 98 | // else resolve(objects) 99 | // }) 100 | // }) 101 | -------------------------------------------------------------------------------- /src/commands/manifest.ts: -------------------------------------------------------------------------------- 1 | import {Command} from '@oclif/command' 2 | import * as Config from '@oclif/config' 3 | import * as fs from 'fs-extra' 4 | import * as path from 'path' 5 | 6 | export default class Manifest extends Command { 7 | static description = 'generates plugin manifest json' 8 | 9 | static args = [ 10 | {name: 'path', description: 'path to plugin', default: '.'}, 11 | ] 12 | 13 | async run() { 14 | try { 15 | fs.unlinkSync('oclif.manifest.json') 16 | } catch {} 17 | const {args} = this.parse(Manifest) 18 | const root = path.resolve(args.path) 19 | let plugin = new Config.Plugin({root, type: 'core', ignoreManifest: true, errorOnManifestCreate: true}) 20 | if (!plugin) throw new Error('plugin not found') 21 | await plugin.load() 22 | if (!plugin.valid) { 23 | const p = require.resolve('@oclif/plugin-legacy', {paths: [process.cwd()]}) 24 | const {PluginLegacy} = require(p) 25 | delete plugin.name 26 | plugin = new PluginLegacy(this.config, plugin) 27 | await plugin.load() 28 | } 29 | if (process.env.OCLIF_NEXT_VERSION) { 30 | plugin.manifest.version = process.env.OCLIF_NEXT_VERSION 31 | } 32 | const dotfile = plugin.pjson.files.find((f: string) => f.endsWith('.oclif.manifest.json')) 33 | const file = path.join(plugin.root, `${dotfile ? '.' : ''}oclif.manifest.json`) 34 | fs.writeFileSync(file, JSON.stringify(plugin.manifest)) 35 | this.log(`wrote manifest to ${file}`) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/commands/pack/deb.ts: -------------------------------------------------------------------------------- 1 | import {Command, flags} from '@oclif/command' 2 | import * as Config from '@oclif/config' 3 | import * as _ from 'lodash' 4 | import * as qq from 'qqjs' 5 | 6 | import * as Tarballs from '../../tarballs' 7 | 8 | function debArch(arch: Config.ArchTypes) { 9 | if (arch === 'x64') return 'amd64' 10 | if (arch === 'x86') return 'i386' 11 | if (arch === 'arm') return 'armel' 12 | throw new Error(`invalid arch: ${arch}`) 13 | } 14 | 15 | const debVersion = (buildConfig: Tarballs.IConfig) => `${buildConfig.version.split('-')[0]}-1` 16 | 17 | const scripts = { 18 | /* eslint-disable no-useless-escape */ 19 | bin: (config: Config.IConfig) => `#!/usr/bin/env bash 20 | set -e 21 | echoerr() { echo "$@" 1>&2; } 22 | get_script_dir () { 23 | SOURCE="\${BASH_SOURCE[0]}" 24 | # While \$SOURCE is a symlink, resolve it 25 | while [ -h "\$SOURCE" ]; do 26 | DIR="\$( cd -P "\$( dirname "\$SOURCE" )" && pwd )" 27 | SOURCE="\$( readlink "\$SOURCE" )" 28 | # If \$SOURCE was a relative symlink (so no "/" as prefix, need to resolve it relative to the symlink base directory 29 | [[ \$SOURCE != /* ]] && SOURCE="\$DIR/\$SOURCE" 30 | done 31 | DIR="\$( cd -P "\$( dirname "\$SOURCE" )" && pwd )" 32 | echo "\$DIR" 33 | } 34 | DIR=\$(get_script_dir) 35 | export ${config.scopedEnvVarKey('UPDATE_INSTRUCTIONS')}="update with \\"sudo apt update && sudo apt install ${config.bin}\\"" 36 | \$DIR/node \$DIR/run "\$@" 37 | `, 38 | /* eslint-enable no-useless-escape */ 39 | control: (config: Tarballs.IConfig, arch: string) => `Package: ${config.config.bin} 40 | Version: ${debVersion(config)} 41 | Section: main 42 | Priority: standard 43 | Architecture: ${arch} 44 | Maintainer: ${config.config.scopedEnvVar('AUTHOR') || config.config.pjson.author} 45 | Description: ${config.config.pjson.description} 46 | `, 47 | ftparchive: (config: Config.IConfig) => ` 48 | APT::FTPArchive::Release { 49 | Origin "${config.scopedEnvVar('AUTHOR') || config.pjson.author}"; 50 | Suite "stable"; 51 | `, 52 | } 53 | 54 | export default class PackDeb extends Command { 55 | static description = 'pack CLI into debian package' 56 | 57 | static flags = { 58 | root: flags.string({char: 'r', description: 'path to oclif CLI root', default: '.', required: true}), 59 | } 60 | 61 | async run() { 62 | if (process.platform !== 'linux') throw new Error('must be run from linux') 63 | const {flags} = this.parse(PackDeb) 64 | const buildConfig = await Tarballs.buildConfig(flags.root) 65 | const {config} = buildConfig 66 | await Tarballs.build(buildConfig, {platform: 'linux', pack: false}) 67 | const dist = buildConfig.dist('deb') 68 | await qq.emptyDir(dist) 69 | const build = async (arch: Config.ArchTypes) => { 70 | const target: {platform: 'linux'; arch: Config.ArchTypes} = {platform: 'linux', arch} 71 | const versionedDebBase = `${config.bin}_${debVersion(buildConfig)}_${debArch(arch)}` 72 | const workspace = qq.join(buildConfig.tmp, 'apt', `${versionedDebBase}.apt`) 73 | await qq.rm(workspace) 74 | await qq.mkdirp([workspace, 'DEBIAN']) 75 | await qq.mkdirp([workspace, 'usr/bin']) 76 | await qq.mkdirp([workspace, 'usr/lib']) 77 | await qq.mv(buildConfig.workspace(target), [workspace, 'usr/lib', config.dirname]) 78 | await qq.write([workspace, 'usr/lib', config.dirname, 'bin', config.bin], scripts.bin(config)) 79 | await qq.write([workspace, 'DEBIAN/control'], scripts.control(buildConfig, debArch(arch))) 80 | await qq.chmod([workspace, 'usr/lib', config.dirname, 'bin', config.bin], 0o755) 81 | await qq.x(`ln -s "../lib/${config.dirname}/bin/${config.bin}" "${workspace}/usr/bin/${config.bin}"`) 82 | await qq.x(`chown -R root "${workspace}"`) 83 | await qq.x(`chgrp -R root "${workspace}"`) 84 | await qq.x(`dpkg --build "${workspace}" "${qq.join(dist, `${versionedDebBase}.deb`)}"`) 85 | } 86 | 87 | const arches = _.uniq(buildConfig.targets 88 | .filter(t => t.platform === 'linux') 89 | .map(t => t.arch)) 90 | // eslint-disable-next-line no-await-in-loop 91 | for (const a of arches) await build(a) 92 | 93 | await qq.x('apt-ftparchive packages . > Packages', {cwd: dist}) 94 | await qq.x('gzip -c Packages > Packages.gz', {cwd: dist}) 95 | await qq.x('bzip2 -k Packages', {cwd: dist}) 96 | await qq.x('xz -k Packages', {cwd: dist}) 97 | const ftparchive = qq.join(buildConfig.tmp, 'apt', 'apt-ftparchive.conf') 98 | await qq.write(ftparchive, scripts.ftparchive(config)) 99 | await qq.x(`apt-ftparchive -c "${ftparchive}" release . > Release`, {cwd: dist}) 100 | const gpgKey = config.scopedEnvVar('DEB_KEY') 101 | if (gpgKey) { 102 | await qq.x(`gpg --digest-algo SHA512 --clearsign -u ${gpgKey} -o InRelease Release`, {cwd: dist}) 103 | await qq.x(`gpg --digest-algo SHA512 -abs -u ${gpgKey} -o Release.gpg Release`, {cwd: dist}) 104 | } 105 | } 106 | } 107 | 108 | -------------------------------------------------------------------------------- /src/commands/pack/index.ts: -------------------------------------------------------------------------------- 1 | import {Command, flags} from '@oclif/command' 2 | import * as qq from 'qqjs' 3 | 4 | import * as Tarballs from '../../tarballs' 5 | 6 | export default class Pack extends Command { 7 | static description = `packages oclif cli into tarballs 8 | 9 | This can be used to create oclif CLIs that use the system node or that come preloaded with a node binary. 10 | ` 11 | 12 | static flags: flags.Input = { 13 | root: flags.string({char: 'r', description: 'path to oclif CLI root', default: '.', required: true}), 14 | targets: flags.string({char: 't', description: 'comma-separated targets to pack (e.g.: linux-arm,win32-x64)'}), 15 | xz: flags.boolean({description: 'also build xz', allowNo: true}), 16 | } 17 | 18 | async run() { 19 | const prevCwd = qq.cwd() 20 | if (process.platform === 'win32') throw new Error('pack does not function on windows') 21 | const {flags} = this.parse(Pack) 22 | const targets = flags.targets ? flags.targets.split(',') : undefined 23 | const buildConfig = await Tarballs.buildConfig(flags.root, {xz: flags.xz, targets}) 24 | await Tarballs.build(buildConfig) 25 | qq.cd(prevCwd) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/commands/pack/macos.ts: -------------------------------------------------------------------------------- 1 | import {Command, flags} from '@oclif/command' 2 | import * as Config from '@oclif/config' 3 | import * as path from 'path' 4 | import * as qq from 'qqjs' 5 | 6 | import * as Tarballs from '../../tarballs' 7 | 8 | type OclifConfig = { 9 | macos?: { 10 | identifier?: string; 11 | sign?: string; 12 | }; 13 | } 14 | 15 | const scripts = { 16 | preinstall: (config: Config.IConfig) => `#!/usr/bin/env bash 17 | sudo rm -rf /usr/local/lib/${config.dirname} 18 | sudo rm -rf /usr/local/${config.bin} 19 | sudo rm -rf /usr/local/bin/${config.bin} 20 | `, 21 | postinstall: (config: Config.IConfig) => `#!/usr/bin/env bash 22 | set -x 23 | sudo mkdir -p /usr/local/bin 24 | sudo ln -sf /usr/local/lib/${config.dirname}/bin/${config.bin} /usr/local/bin/${config.bin} 25 | `, 26 | uninstall: (config: Config.IConfig) => { 27 | const packageIdentifier = (config.pjson.oclif as OclifConfig).macos!.identifier! 28 | return `#!/usr/bin/env bash 29 | 30 | #Parameters 31 | DATE=\`date +%Y-%m-%d\` 32 | TIME=\`date +%H:%M:%S\` 33 | LOG_PREFIX="[$DATE $TIME]" 34 | 35 | #Functions 36 | log_info() { 37 | echo "\${LOG_PREFIX}[INFO]" $1 38 | } 39 | 40 | log_warn() { 41 | echo "\${LOG_PREFIX}[WARN]" $1 42 | } 43 | 44 | log_error() { 45 | echo "\${LOG_PREFIX}[ERROR]" $1 46 | } 47 | 48 | #Check running user 49 | if (( $EUID != 0 )); then 50 | echo "Please run as root." 51 | exit 52 | fi 53 | 54 | echo "Welcome to Application Uninstaller" 55 | echo "The following packages will be REMOVED:" 56 | echo " ${config.dirname}" 57 | while [ "$1" != "-y" ]; do 58 | read -p "Do you wish to continue [Y/n]?" answer 59 | [[ $answer == "y" || $answer == "Y" || $answer == "" ]] && break 60 | [[ $answer == "n" || $answer == "N" ]] && exit 0 61 | echo "Please answer with 'y' or 'n'" 62 | done 63 | 64 | echo "Application uninstalling process started" 65 | # remove link to shorcut file 66 | find "/usr/local/bin/" -name "${config.bin}" | xargs rm 67 | if [ $? -eq 0 ] 68 | then 69 | echo "[1/3] [DONE] Successfully deleted shortcut links" 70 | else 71 | echo "[1/3] [ERROR] Could not delete shortcut links" >&2 72 | fi 73 | 74 | #forget from pkgutil 75 | pkgutil --forget "${packageIdentifier}" > /dev/null 2>&1 76 | if [ $? -eq 0 ] 77 | then 78 | echo "[2/3] [DONE] Successfully deleted application informations" 79 | else 80 | echo "[2/3] [ERROR] Could not delete application informations" >&2 81 | fi 82 | 83 | #remove application source distribution 84 | [ -e "/usr/local/lib/${config.dirname}" ] && rm -rf "/usr/local/lib/${config.dirname}" 85 | if [ $? -eq 0 ] 86 | then 87 | echo "[3/3] [DONE] Successfully deleted application" 88 | else 89 | echo "[3/3] [ERROR] Could not delete application" >&2 90 | fi 91 | 92 | echo "Application uninstall process finished" 93 | exit 0 94 | ` 95 | }, 96 | } 97 | 98 | export default class PackMacos extends Command { 99 | static description = 'pack CLI into MacOS .pkg' 100 | 101 | static flags = { 102 | root: flags.string({char: 'r', description: 'path to oclif CLI root', default: '.', required: true}), 103 | } 104 | 105 | async run() { 106 | if (process.platform !== 'darwin') this.error('must be run from macos') 107 | const {flags} = this.parse(PackMacos) 108 | const buildConfig = await Tarballs.buildConfig(flags.root) 109 | const {config} = buildConfig 110 | const c = config.pjson.oclif as OclifConfig 111 | if (!c.macos) this.error('package.json is missing an oclif.macos config') 112 | if (!c.macos.identifier) this.error('package.json must have oclif.macos.identifier set') 113 | const macos = c.macos 114 | const packageIdentifier = macos.identifier 115 | await Tarballs.build(buildConfig, {platform: 'darwin', pack: false}) 116 | const dist = buildConfig.dist(`macos/${config.bin}-v${buildConfig.version}.pkg`) 117 | await qq.emptyDir(path.dirname(dist)) 118 | const scriptsDir = qq.join(buildConfig.tmp, 'macos/scripts') 119 | const rootDir = buildConfig.workspace({platform: 'darwin', arch: 'x64'}) 120 | const writeScript = async (script: 'preinstall' | 'postinstall' | 'uninstall') => { 121 | const path = script === 'uninstall' ? [rootDir, 'bin'] : [scriptsDir] 122 | path.push(script) 123 | await qq.write(path, scripts[script](config)) 124 | await qq.chmod(path, 0o755) 125 | } 126 | await writeScript('preinstall') 127 | await writeScript('postinstall') 128 | await writeScript('uninstall') 129 | /* eslint-disable array-element-newline */ 130 | const args = [ 131 | '--root', rootDir, 132 | '--identifier', packageIdentifier, 133 | '--version', buildConfig.version, 134 | '--install-location', `/usr/local/lib/${config.dirname}`, 135 | '--scripts', scriptsDir, 136 | ] 137 | /* eslint-enable array-element-newline */ 138 | if (macos.sign) args.push('--sign', macos.sign) 139 | if (process.env.OSX_KEYCHAIN) args.push('--keychain', process.env.OSX_KEYCHAIN) 140 | args.push(dist) 141 | await qq.x('pkgbuild', args as string[]) 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /src/commands/pack/win.ts: -------------------------------------------------------------------------------- 1 | import {Command, flags} from '@oclif/command' 2 | import * as Config from '@oclif/config' 3 | import * as qq from 'qqjs' 4 | 5 | import * as Tarballs from '../../tarballs' 6 | 7 | const scripts = { 8 | /* eslint-disable no-useless-escape */ 9 | cmd: (config: Config.IConfig) => `@echo off 10 | setlocal enableextensions 11 | 12 | set ${config.scopedEnvVarKey('BINPATH')}=%~dp0\\${config.bin}.cmd 13 | if exist "%LOCALAPPDATA%\\${config.dirname}\\client\\bin\\${config.bin}.cmd" ( 14 | "%LOCALAPPDATA%\\${config.dirname}\\client\\bin\\${config.bin}.cmd" %* 15 | ) else ( 16 | "%~dp0\\..\\client\\bin\\node.exe" "%~dp0\\..\\client\\bin\\run" %* 17 | ) 18 | `, 19 | sh: (config: Config.IConfig) => `#!/bin/sh 20 | basedir=$(dirname "$(echo "$0" | sed -e 's,\\\\,/,g')") 21 | 22 | "$basedir/../client/bin/${config.bin}.cmd" "$@" 23 | ret=$? 24 | exit $ret 25 | `, 26 | nsis: (config: Config.IConfig, arch: string) => `!include MUI2.nsh 27 | 28 | !define Version '${config.version.split('-')[0]}' 29 | Name "${config.name}" 30 | CRCCheck On 31 | InstallDirRegKey HKCU "Software\\${config.name}" "" 32 | 33 | !insertmacro MUI_PAGE_COMPONENTS 34 | !insertmacro MUI_PAGE_DIRECTORY 35 | !insertmacro MUI_PAGE_INSTFILES 36 | 37 | !insertmacro MUI_UNPAGE_CONFIRM 38 | !insertmacro MUI_UNPAGE_INSTFILES 39 | 40 | !insertmacro MUI_LANGUAGE "English" 41 | 42 | OutFile "installer.exe" 43 | VIProductVersion "\${VERSION}.0" 44 | VIAddVersionKey /LANG=\${LANG_ENGLISH} "ProductName" "${config.name}" 45 | VIAddVersionKey /LANG=\${LANG_ENGLISH} "Comments" "${config.pjson.homepage}" 46 | VIAddVersionKey /LANG=\${LANG_ENGLISH} "CompanyName" "${config.scopedEnvVar('AUTHOR') || config.pjson.author}" 47 | VIAddVersionKey /LANG=\${LANG_ENGLISH} "LegalCopyright" "${new Date().getFullYear()}" 48 | VIAddVersionKey /LANG=\${LANG_ENGLISH} "FileDescription" "${config.pjson.description}" 49 | VIAddVersionKey /LANG=\${LANG_ENGLISH} "FileVersion" "\${VERSION}.0" 50 | VIAddVersionKey /LANG=\${LANG_ENGLISH} "ProductVersion" "\${VERSION}.0" 51 | 52 | InstallDir "\$PROGRAMFILES${arch === 'x64' ? '64' : ''}\\${config.dirname}" 53 | 54 | Section "${config.name} CLI \${VERSION}" 55 | SetOutPath $INSTDIR 56 | File /r bin 57 | File /r client 58 | ExpandEnvStrings $0 "%COMSPEC%" 59 | 60 | WriteRegStr HKCU "Software\\${config.dirname}" "" $INSTDIR 61 | WriteUninstaller "$INSTDIR\\Uninstall.exe" 62 | WriteRegStr HKLM "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\${config.dirname}" \\ 63 | "DisplayName" "${config.name}" 64 | WriteRegStr HKLM "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\${config.dirname}" \\ 65 | "UninstallString" "$\\"$INSTDIR\\uninstall.exe$\\"" 66 | WriteRegStr HKLM "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\${config.dirname}" \\ 67 | "Publisher" "${config.scopedEnvVar('AUTHOR') || config.pjson.author}" 68 | SectionEnd 69 | 70 | Section "Set PATH to ${config.name}" 71 | Push "$INSTDIR\\bin" 72 | Call AddToPath 73 | SectionEnd 74 | 75 | Section "Add %LOCALAPPDATA%\\${config.dirname} to Windows Defender exclusions (highly recommended for performance!)" 76 | ExecShell "" '"$0"' "/C powershell -ExecutionPolicy Bypass -Command $\\"& {Add-MpPreference -ExclusionPath $\\"$LOCALAPPDATA\\${config.dirname}$\\"}$\\" -FFFeatureOff" SW_HIDE 77 | SectionEnd 78 | 79 | Section "Uninstall" 80 | Delete "$INSTDIR\\Uninstall.exe" 81 | RMDir /r "$INSTDIR" 82 | RMDir /r "$LOCALAPPDATA\\${config.dirname}" 83 | DeleteRegKey /ifempty HKCU "Software\\${config.dirname}" 84 | DeleteRegKey HKLM "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\${config.dirname}" 85 | SectionEnd 86 | 87 | !define Environ 'HKCU "Environment"' 88 | Function AddToPath 89 | Exch $0 90 | Push $1 91 | Push $2 92 | Push $3 93 | Push $4 94 | 95 | ; NSIS ReadRegStr returns empty string on string overflow 96 | ; Native calls are used here to check actual length of PATH 97 | 98 | ; $4 = RegOpenKey(HKEY_CURRENT_USER, "Environment", &$3) 99 | System::Call "advapi32::RegOpenKey(i 0x80000001, t'Environment', *i.r3) i.r4" 100 | IntCmp $4 0 0 done done 101 | ; $4 = RegQueryValueEx($3, "PATH", (DWORD*)0, (DWORD*)0, &$1, ($2=NSIS_MAX_STRLEN, &$2)) 102 | ; RegCloseKey($3) 103 | System::Call "advapi32::RegQueryValueEx(i $3, t'PATH', i 0, i 0, t.r1, *i \${NSIS_MAX_STRLEN} r2) i.r4" 104 | System::Call "advapi32::RegCloseKey(i $3)" 105 | 106 | IntCmp $4 234 0 +4 +4 ; $4 == ERROR_MORE_DATA 107 | DetailPrint "AddToPath: original length $2 > \${NSIS_MAX_STRLEN}" 108 | MessageBox MB_OK "PATH not updated, original length $2 > \${NSIS_MAX_STRLEN}" 109 | Goto done 110 | 111 | IntCmp $4 0 +5 ; $4 != NO_ERROR 112 | IntCmp $4 2 +3 ; $4 != ERROR_FILE_NOT_FOUND 113 | DetailPrint "AddToPath: unexpected error code $4" 114 | Goto done 115 | StrCpy $1 "" 116 | 117 | ; Check if already in PATH 118 | Push "$1;" 119 | Push "$0;" 120 | Call StrStr 121 | Pop $2 122 | StrCmp $2 "" 0 done 123 | Push "$1;" 124 | Push "$0\\;" 125 | Call StrStr 126 | Pop $2 127 | StrCmp $2 "" 0 done 128 | 129 | ; Prevent NSIS string overflow 130 | StrLen $2 $0 131 | StrLen $3 $1 132 | IntOp $2 $2 + $3 133 | IntOp $2 $2 + 2 ; $2 = strlen(dir) + strlen(PATH) + sizeof(";") 134 | IntCmp $2 \${NSIS_MAX_STRLEN} +4 +4 0 135 | DetailPrint "AddToPath: new length $2 > \${NSIS_MAX_STRLEN}" 136 | MessageBox MB_OK "PATH not updated, new length $2 > \${NSIS_MAX_STRLEN}." 137 | Goto done 138 | 139 | ; Append dir to PATH 140 | DetailPrint "Add to PATH: $0" 141 | StrCpy $2 $1 1 -1 142 | StrCmp $2 ";" 0 +2 143 | StrCpy $1 $1 -1 ; remove trailing ';' 144 | StrCmp $1 "" +2 ; no leading ';' 145 | StrCpy $0 "$1;$0" 146 | WriteRegExpandStr \${Environ} "PATH" $0 147 | SendMessage \${HWND_BROADCAST} \${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000 148 | 149 | done: 150 | Pop $4 151 | Pop $3 152 | Pop $2 153 | Pop $1 154 | Pop $0 155 | FunctionEnd 156 | 157 | ; StrStr - find substring in a string 158 | ; 159 | ; Usage: 160 | ; Push "this is some string" 161 | ; Push "some" 162 | ; Call StrStr 163 | ; Pop $0 ; "some string" 164 | 165 | Function StrStr 166 | Exch $R1 ; $R1=substring, stack=[old$R1,string,...] 167 | Exch ; stack=[string,old$R1,...] 168 | Exch $R2 ; $R2=string, stack=[old$R2,old$R1,...] 169 | Push $R3 170 | Push $R4 171 | Push $R5 172 | StrLen $R3 $R1 173 | StrCpy $R4 0 174 | ; $R1=substring, $R2=string, $R3=strlen(substring) 175 | ; $R4=count, $R5=tmp 176 | loop: 177 | StrCpy $R5 $R2 $R3 $R4 178 | StrCmp $R5 $R1 done 179 | StrCmp $R5 "" done 180 | IntOp $R4 $R4 + 1 181 | Goto loop 182 | done: 183 | StrCpy $R1 $R2 "" $R4 184 | Pop $R5 185 | Pop $R4 186 | Pop $R3 187 | Pop $R2 188 | Exch $R1 ; $R1=old$R1, stack=[result,...] 189 | FunctionEnd 190 | `, 191 | /* eslint-enable no-useless-escape */ 192 | } 193 | 194 | export default class PackWin extends Command { 195 | static description = 'create windows installer from oclif CLI' 196 | 197 | static flags = { 198 | root: flags.string({char: 'r', description: 'path to oclif CLI root', default: '.', required: true}), 199 | } 200 | 201 | async run() { 202 | await this.checkForNSIS() 203 | const {flags} = this.parse(PackWin) 204 | const buildConfig = await Tarballs.buildConfig(flags.root) 205 | const {config} = buildConfig 206 | await Tarballs.build(buildConfig, {platform: 'win32', pack: false}) 207 | const arches = buildConfig.targets.filter(t => t.platform === 'win32').map(t => t.arch) 208 | for (const arch of arches) { 209 | const installerBase = qq.join(buildConfig.tmp, `windows-${arch}-installer`) 210 | // eslint-disable-next-line no-await-in-loop 211 | await qq.write([installerBase, `bin/${config.bin}.cmd`], scripts.cmd(config)) 212 | // eslint-disable-next-line no-await-in-loop 213 | await qq.write([installerBase, `bin/${config.bin}`], scripts.sh(config)) 214 | // eslint-disable-next-line no-await-in-loop 215 | await qq.write([installerBase, `${config.bin}.nsi`], scripts.nsis(config, arch)) 216 | // eslint-disable-next-line no-await-in-loop 217 | await qq.mv(buildConfig.workspace({platform: 'win32', arch}), [installerBase, 'client']) 218 | // eslint-disable-next-line no-await-in-loop 219 | await qq.x(`makensis ${installerBase}/${config.bin}.nsi | grep -v "\\[compress\\]" | grep -v "^File: Descending to"`) 220 | const o = buildConfig.dist(`win/${config.bin}-v${buildConfig.version}-${arch}.exe`) 221 | // eslint-disable-next-line no-await-in-loop 222 | await qq.mv([installerBase, 'installer.exe'], o) 223 | this.log(`built ${o}`) 224 | } 225 | } 226 | 227 | private async checkForNSIS() { 228 | try { 229 | await qq.x('makensis', {stdio: [0, null, 2]}) 230 | } catch (error) { 231 | if (error.code === 1) return 232 | if (error.code === 127) this.error('install makensis') 233 | else throw error 234 | } 235 | } 236 | } 237 | -------------------------------------------------------------------------------- /src/commands/publish/deb.ts: -------------------------------------------------------------------------------- 1 | import {Command, flags} from '@oclif/command' 2 | import * as qq from 'qqjs' 3 | 4 | import aws from '../../aws' 5 | import {log} from '../../log' 6 | import * as Tarballs from '../../tarballs' 7 | 8 | export default class PublishDeb extends Command { 9 | static description = 'publish deb package built with pack:deb' 10 | 11 | static flags = { 12 | root: flags.string({char: 'r', description: 'path to oclif CLI root', default: '.', required: true}), 13 | } 14 | 15 | async run() { 16 | const {flags} = this.parse(PublishDeb) 17 | const buildConfig = await Tarballs.buildConfig(flags.root) 18 | const {s3Config, version, config} = buildConfig 19 | const dist = (f: string) => buildConfig.dist(qq.join('deb', f)) 20 | if (!await qq.exists(dist('Release'))) this.error('run "oclif-dev pack:deb" before publishing') 21 | const S3Options = { 22 | Bucket: s3Config.bucket!, 23 | ACL: s3Config.acl || 'public-read', 24 | } 25 | 26 | const remoteBase = buildConfig.channel === 'stable' ? 'apt' : `channels/${buildConfig.channel}/apt` 27 | const upload = (file: string) => { 28 | return aws.s3.uploadFile(dist(file), {...S3Options, CacheControl: 'max-age=86400', Key: [remoteBase, file].join('/')}) 29 | } 30 | const debVersion = `${buildConfig.version.split('-')[0]}-1` 31 | const uploadDeb = async (arch: 'amd64' | 'i386') => { 32 | const deb = `${config.bin}_${debVersion}_${arch}.deb` 33 | if (await qq.exists(dist(deb))) await upload(deb) 34 | } 35 | await uploadDeb('amd64') 36 | await uploadDeb('i386') 37 | await upload('Packages.gz') 38 | await upload('Packages.xz') 39 | await upload('Packages.bz2') 40 | await upload('Release') 41 | if (await qq.exists(dist('InRelease'))) await upload('InRelease') 42 | if (await qq.exists(dist('Release.gpg'))) await upload('Release.gpg') 43 | 44 | log(`published deb ${version}`) 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/commands/publish/github.ts: -------------------------------------------------------------------------------- 1 | import {Command} from '@oclif/command' 2 | // import * as Octokit from '@octokit/rest' 3 | // import * as fs from 'fs-extra' 4 | // import * as path from 'path' 5 | // import * as qq from 'qqjs' 6 | 7 | // import * as Tarballs from '../../tarballs' 8 | // import {log as action} from '../../tarballs/log' 9 | 10 | export default class Publish extends Command { 11 | static description = 'publish an oclif CLI to GitHub Releases' 12 | 13 | static hidden = true 14 | 15 | static flags = { 16 | // root: flags.string({char: 'r', description: 'path to oclif CLI root', default: '.', required: true}), 17 | // 'node-version': flags.string({description: 'node version of binary to get', default: process.versions.node, required: true}), 18 | // xz: flags.boolean({description: 'also create xz tarballs'}), 19 | // prerelease: flags.boolean({description: 'identify as prerelease'}), 20 | // draft: flags.boolean({description: 'create an unpublished release'}), 21 | } 22 | 23 | // octokit = new Octokit() 24 | 25 | async run() { 26 | this.warn('TODO: finish this') 27 | // if (!process.env.GH_TOKEN) throw new Error('GH_TOKEN must be set') 28 | // const {flags} = this.parse(Publish) 29 | // if (process.platform === 'win32') throw new Error('pack does not function on windows') 30 | // const {'node-version': nodeVersion, prerelease, draft} = flags 31 | // const channel = flags.prerelease ? 'prerelease' : 'stable' 32 | // const root = path.resolve(flags.root) 33 | // const config = await Tarballs.config(root) 34 | // const version = config.version 35 | // const baseWorkspace = qq.join([config.root, 'tmp', 'base']) 36 | // const updateConfig = config.pjson.oclif.update || {} 37 | // const targets = updateConfig.node && updateConfig.node.targets || [] 38 | // if (!targets) throw new Error('specify oclif.targets in package.json') 39 | 40 | // // first create the generic base workspace that will be copied later 41 | // await Tarballs.build({config, channel, output: baseWorkspace, version}) 42 | 43 | // const tarballs: {target: string, tarball: string}[] = [] 44 | // for (let [platform, arch] of targets.map(t => t.split('-'))) { 45 | // const t = await Tarballs.target({config, platform, arch, channel, version, baseWorkspace, nodeVersion, xz: flags.xz}) 46 | // tarballs.push(t) 47 | // } 48 | 49 | // this.octokit.authenticate({ 50 | // type: 'token', 51 | // token: process.env.GH_TOKEN, 52 | // }) 53 | // const tag = `v${version}` 54 | // const [owner, repo] = config.pjson.repository.split('/') 55 | // const commitish = await Tarballs.gitSha(config.root) 56 | // const release = await this.findOrCreateRelease({owner, repo, tag, prerelease, draft, commitish}) 57 | 58 | // for (let {tarball} of tarballs) { 59 | // await this.addFileToRelease(release, `${tarball}.tar.gz`) 60 | // if (flags.xz) await this.addFileToRelease(release, `${tarball}.tar.xz`) 61 | // } 62 | // } 63 | 64 | // async findOrCreateRelease({owner, repo, tag, prerelease, draft, commitish}: {owner: string, repo: string, tag: string, prerelease: boolean, draft: boolean, commitish: string}) { 65 | // const findRelease = async () => { 66 | // const {data} = await this.octokit.repos.getReleaseByTag({owner, repo, tag}) 67 | // action(`found existing release ${tag}`) 68 | // return data 69 | // } 70 | // const createRelease = async () => { 71 | // action(`creating ${tag} release`) 72 | // const {data} = await this.octokit.repos.createRelease({ 73 | // owner, 74 | // repo, 75 | // target_commitish: commitish, 76 | // tag_name: tag, 77 | // prerelease, 78 | // draft, 79 | // }) 80 | // return data 81 | // } 82 | // try { 83 | // return await findRelease() 84 | // } catch (err) { 85 | // this.debug(err) 86 | // } 87 | // return createRelease() 88 | // } 89 | 90 | // async addFileToRelease(release: {upload_url: string}, file: string) { 91 | // action(`uploading ${file}`) 92 | // await this.octokit.repos.uploadAsset({ 93 | // url: release.upload_url, 94 | // file: fs.createReadStream(file), 95 | // contentType: 'application/gzip', 96 | // contentLength: fs.statSync(file).size, 97 | // name: qq.path.basename(file), 98 | // label: qq.path.basename(file), 99 | // }) 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/commands/publish/index.ts: -------------------------------------------------------------------------------- 1 | import {Command, flags} from '@oclif/command' 2 | import {ArchTypes, PlatformTypes} from '@oclif/config' 3 | import * as qq from 'qqjs' 4 | 5 | import aws from '../../aws' 6 | import {log} from '../../log' 7 | import * as Tarballs from '../../tarballs' 8 | 9 | export default class Publish extends Command { 10 | static description = `publish an oclif CLI to S3 11 | 12 | "aws-sdk" will need to be installed as a devDependency to publish. 13 | ` 14 | 15 | static flags = { 16 | root: flags.string({char: 'r', description: 'path to oclif CLI root', default: '.', required: true}), 17 | targets: flags.string({char: 't', description: 'comma-separated targets to pack (e.g.: linux-arm,win32-x64)'}), 18 | } 19 | 20 | buildConfig!: Tarballs.IConfig 21 | 22 | async run() { 23 | const {flags} = this.parse(Publish) 24 | if (process.platform === 'win32') throw new Error('publish does not function on windows') 25 | const targetOpts = flags.targets ? flags.targets.split(',') : undefined 26 | this.buildConfig = await Tarballs.buildConfig(flags.root, {targets: targetOpts}) 27 | const {s3Config, targets, dist, version, config} = this.buildConfig 28 | if (!await qq.exists(dist(config.s3Key('versioned', {ext: '.tar.gz'})))) this.error('run "oclif-dev pack" before publishing') 29 | const S3Options = { 30 | Bucket: s3Config.bucket!, 31 | ACL: s3Config.acl || 'public-read', 32 | } 33 | // for (let target of targets) await this.uploadNodeBinary(target) 34 | const ManifestS3Options = {...S3Options, CacheControl: 'max-age=86400', ContentType: 'application/json'} 35 | const uploadTarball = async (options?: {platform: PlatformTypes; arch: ArchTypes}) => { 36 | const TarballS3Options = {...S3Options, CacheControl: 'max-age=604800'} 37 | const releaseTarballs = async (ext: '.tar.gz' | '.tar.xz') => { 38 | const versioned = config.s3Key('versioned', ext, options) 39 | const unversioned = config.s3Key('unversioned', ext, options) 40 | await aws.s3.uploadFile(dist(versioned), {...TarballS3Options, ContentType: 'application/gzip', Key: versioned}) 41 | await aws.s3.uploadFile(dist(versioned), {...TarballS3Options, ContentType: 'application/gzip', Key: unversioned}) 42 | } 43 | await releaseTarballs('.tar.gz') 44 | if (this.buildConfig.xz) await releaseTarballs('.tar.xz') 45 | const manifest = config.s3Key('manifest', options) 46 | await aws.s3.uploadFile(dist(manifest), {...ManifestS3Options, Key: manifest}) 47 | } 48 | if (targets.length > 0) log('uploading targets') 49 | // eslint-disable-next-line no-await-in-loop 50 | for (const target of targets) await uploadTarball(target) 51 | log('uploading vanilla') 52 | await uploadTarball() 53 | 54 | log(`published ${version}`) 55 | } 56 | 57 | // private async uploadNodeBinary(target: Tarballs.ITarget) { 58 | // const {platform, arch} = target 59 | // log('checking for node binary %s-%s in S3', platform, arch) 60 | // const {nodeVersion, dist, tmp, s3Config} = this.buildConfig 61 | // let key = path.join('node', `node-v${nodeVersion}`, `node-v${nodeVersion}-${platform}-${arch}`) 62 | // let Key = (platform === 'win32' ? `${key}.exe` : key) + '.gz' 63 | // try { 64 | // await s3.headObject({Bucket: s3Config.bucket!, Key}) 65 | // } catch (err) { 66 | // if (err.code !== 'NotFound') throw err 67 | // log('uploading node binary %s-%s', target.platform, target.arch) 68 | // let output = dist(key) 69 | // output = await Tarballs.fetchNodeBinary({nodeVersion, platform, arch, output, tmp}) 70 | // await qq.x('gzip', ['-f', output]) 71 | // await s3.uploadFile(output + '.gz', {Bucket: s3Config.bucket!, Key}) 72 | // } 73 | // } 74 | } 75 | -------------------------------------------------------------------------------- /src/commands/publish/macos.ts: -------------------------------------------------------------------------------- 1 | import {Command, flags} from '@oclif/command' 2 | import * as qq from 'qqjs' 3 | 4 | import aws from '../../aws' 5 | import {log} from '../../log' 6 | import * as Tarballs from '../../tarballs' 7 | 8 | export default class PublishMacos extends Command { 9 | static description = 'publish macos installers built with pack:macos' 10 | 11 | static flags = { 12 | root: flags.string({char: 'r', description: 'path to oclif CLI root', default: '.', required: true}), 13 | } 14 | 15 | async run() { 16 | const {flags} = this.parse(PublishMacos) 17 | const buildConfig = await Tarballs.buildConfig(flags.root) 18 | const {s3Config, version, config} = buildConfig 19 | const S3Options = { 20 | Bucket: s3Config.bucket!, 21 | ACL: s3Config.acl || 'public-read', 22 | } 23 | 24 | const root = buildConfig.channel === 'stable' ? '' : `channels/${buildConfig.channel}/` 25 | const pkg = buildConfig.dist(`macos/${config.bin}-v${buildConfig.version}.pkg`) 26 | if (await qq.exists(pkg)) await aws.s3.uploadFile(pkg, {...S3Options, CacheControl: 'max-age=86400', Key: `${root}${config.bin}.pkg`}) 27 | 28 | log(`published macos ${version}`) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/commands/publish/win.ts: -------------------------------------------------------------------------------- 1 | import {Command, flags} from '@oclif/command' 2 | import * as qq from 'qqjs' 3 | 4 | import aws from '../../aws' 5 | import {log} from '../../log' 6 | import * as Tarballs from '../../tarballs' 7 | 8 | export default class PublishWin extends Command { 9 | static description = 'publish windows installers built with pack:win' 10 | 11 | static flags = { 12 | root: flags.string({char: 'r', description: 'path to oclif CLI root', default: '.', required: true}), 13 | } 14 | 15 | async run() { 16 | const {flags} = this.parse(PublishWin) 17 | const buildConfig = await Tarballs.buildConfig(flags.root) 18 | const {s3Config, version, config} = buildConfig 19 | const S3Options = { 20 | Bucket: s3Config.bucket!, 21 | ACL: s3Config.acl || 'public-read', 22 | } 23 | 24 | const root = buildConfig.channel === 'stable' ? '' : `channels/${buildConfig.channel}/` 25 | const uploadWin = async (arch: 'x64' | 'x86') => { 26 | const exe = buildConfig.dist(`win/${config.bin}-v${buildConfig.version}-${arch}.exe`) 27 | if (await qq.exists(exe)) await aws.s3.uploadFile(exe, {...S3Options, CacheControl: 'max-age=86400', Key: `${root}${config.bin}-${arch}.exe`}) 28 | } 29 | await uploadWin('x64') 30 | await uploadWin('x86') 31 | 32 | log(`published win ${version}`) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/commands/readme.ts: -------------------------------------------------------------------------------- 1 | // tslint:disable no-implicit-dependencies 2 | import {Command, flags} from '@oclif/command' 3 | import * as Config from '@oclif/config' 4 | import {getHelpClass} from '@oclif/plugin-help' 5 | import * as fs from 'fs-extra' 6 | import * as _ from 'lodash' 7 | import * as path from 'path' 8 | import {URL} from 'url' 9 | 10 | import {castArray, compact, sortBy, template, uniqBy} from '../util' 11 | import {HelpCompatibilityWrapper} from '../help-compatibility' 12 | 13 | const normalize = require('normalize-package-data') 14 | const columns = parseInt(process.env.COLUMNS!, 10) || 120 15 | const slugify = new (require('github-slugger') as any)() 16 | 17 | export default class Readme extends Command { 18 | static description = `adds commands to README.md in current directory 19 | The readme must have any of the following tags inside of it for it to be replaced or else it will do nothing: 20 | # Usage 21 | 22 | # Commands 23 | 24 | 25 | Customize the code URL prefix by setting oclif.repositoryPrefix in package.json. 26 | ` 27 | 28 | static flags: flags.Input = { 29 | dir: flags.string({description: 'output directory for multi docs', default: 'docs', required: true}), 30 | multi: flags.boolean({description: 'create a different markdown page for each topic'}), 31 | } 32 | 33 | async run() { 34 | const {flags} = this.parse(Readme) 35 | const cwd = process.cwd() 36 | const readmePath = path.resolve(cwd, 'README.md') 37 | const config = await Config.load({root: cwd, devPlugins: false, userPlugins: false}) 38 | 39 | try { 40 | const p = require.resolve('@oclif/plugin-legacy', {paths: [cwd]}) 41 | const plugin = new Config.Plugin({root: p, type: 'core'}) 42 | await plugin.load() 43 | config.plugins.push(plugin) 44 | } catch {} 45 | await (config as Config.Config).runHook('init', {id: 'readme', argv: this.argv}) 46 | let readme = await fs.readFile(readmePath, 'utf8') 47 | 48 | let commands = config.commands 49 | commands = commands.filter(c => !c.hidden) 50 | commands = commands.filter(c => c.pluginType === 'core') 51 | this.debug('commands:', commands.map(c => c.id).length) 52 | commands = uniqBy(commands, c => c.id) 53 | commands = sortBy(commands, c => c.id) 54 | readme = this.replaceTag(readme, 'usage', this.usage(config)) 55 | readme = this.replaceTag(readme, 'commands', flags.multi ? this.multiCommands(config, commands, flags.dir) : this.commands(config, commands)) 56 | readme = this.replaceTag(readme, 'toc', this.toc(config, readme)) 57 | 58 | readme = readme.trimRight() 59 | readme += '\n' 60 | 61 | await fs.outputFile(readmePath, readme) 62 | } 63 | 64 | replaceTag(readme: string, tag: string, body: string): string { 65 | if (readme.includes(``)) { 66 | if (readme.includes(``)) { 67 | readme = readme.replace(new RegExp(`(.|\n)*`, 'm'), ``) 68 | } 69 | this.log(`replacing in README.md`) 70 | } 71 | return readme.replace(``, `\n${body}\n`) 72 | } 73 | 74 | toc(__: Config.IConfig, readme: string): string { 75 | return readme.split('\n').filter(l => l.startsWith('# ')) 76 | .map(l => l.trim().slice(2)) 77 | .map(l => `* [${l}](#${slugify.slug(l)})`) 78 | .join('\n') 79 | } 80 | 81 | usage(config: Config.IConfig): string { 82 | return [ 83 | `\`\`\`sh-session 84 | $ npm install -g ${config.name} 85 | $ ${config.bin} COMMAND 86 | running command... 87 | $ ${config.bin} (-v|--version|version) 88 | ${config.name}/${process.env.OCLIF_NEXT_VERSION || config.version} ${process.platform}-${process.arch} node-v${process.versions.node} 89 | $ ${config.bin} --help [COMMAND] 90 | USAGE 91 | $ ${config.bin} COMMAND 92 | ... 93 | \`\`\`\n`, 94 | ].join('\n').trim() 95 | } 96 | 97 | multiCommands(config: Config.IConfig, commands: Config.Command[], dir: string): string { 98 | let topics = config.topics 99 | topics = topics.filter(t => !t.hidden && !t.name.includes(':')) 100 | topics = topics.filter(t => commands.find(c => c.id.startsWith(t.name))) 101 | topics = sortBy(topics, t => t.name) 102 | topics = uniqBy(topics, t => t.name) 103 | for (const topic of topics) { 104 | this.createTopicFile( 105 | path.join('.', dir, topic.name.replace(/:/g, '/') + '.md'), 106 | config, 107 | topic, 108 | commands.filter(c => c.id === topic.name || c.id.startsWith(topic.name + ':')), 109 | ) 110 | } 111 | 112 | return [ 113 | '# Command Topics\n', 114 | ...topics.map(t => { 115 | return compact([ 116 | `* [\`${config.bin} ${t.name}\`](${dir}/${t.name.replace(/:/g, '/')}.md)`, 117 | template({config})(t.description || '').trim().split('\n')[0], 118 | ]).join(' - ') 119 | }), 120 | ].join('\n').trim() + '\n' 121 | } 122 | 123 | createTopicFile(file: string, config: Config.IConfig, topic: Config.Topic, commands: Config.Command[]) { 124 | const bin = `\`${config.bin} ${topic.name}\`` 125 | const doc = [ 126 | bin, 127 | '='.repeat(bin.length), 128 | '', 129 | template({config})(topic.description || '').trim(), 130 | '', 131 | this.commands(config, commands), 132 | ].join('\n').trim() + '\n' 133 | fs.outputFileSync(file, doc) 134 | } 135 | 136 | commands(config: Config.IConfig, commands: Config.Command[]): string { 137 | return [ 138 | ...commands.map(c => { 139 | const usage = this.commandUsage(config, c) 140 | return `* [\`${config.bin} ${usage}\`](#${slugify.slug(`${config.bin}-${usage}`)})` 141 | }), 142 | '', 143 | ...commands.map(c => this.renderCommand(config, c)).map(s => s.trim() + '\n'), 144 | ].join('\n').trim() 145 | } 146 | 147 | renderCommand(config: Config.IConfig, c: Config.Command): string { 148 | this.debug('rendering command', c.id) 149 | const title = template({config, command: c})(c.description || '').trim().split('\n')[0] 150 | const HelpClass = getHelpClass(config) 151 | const help = new HelpClass(config, {stripAnsi: true, maxWidth: columns}) 152 | const wrapper = new HelpCompatibilityWrapper(help) 153 | 154 | const header = () => `## \`${config.bin} ${this.commandUsage(config, c)}\`` 155 | 156 | try { 157 | return compact([ 158 | header(), 159 | title, 160 | '```\n' + wrapper.formatCommand(c).trim() + '\n```', 161 | this.commandCode(config, c), 162 | ]).join('\n\n') 163 | } catch (error) { 164 | this.error(error.message) 165 | } 166 | } 167 | 168 | commandCode(config: Config.IConfig, c: Config.Command): string | undefined { 169 | const pluginName = c.pluginName 170 | if (!pluginName) return 171 | const plugin = config.plugins.find(p => p.name === c.pluginName) 172 | if (!plugin) return 173 | const repo = this.repo(plugin) 174 | if (!repo) return 175 | let label = plugin.name 176 | let version = plugin.version 177 | const commandPath = this.commandPath(plugin, c) 178 | if (!commandPath) return 179 | if (config.name === plugin.name) { 180 | label = commandPath 181 | version = process.env.OCLIF_NEXT_VERSION || version 182 | } 183 | const template = plugin.pjson.oclif.repositoryPrefix || '<%- repo %>/blob/v<%- version %>/<%- commandPath %>' 184 | return `_See code: [${label}](${_.template(template)({repo, version, commandPath, config, c})})_` 185 | } 186 | 187 | private repo(plugin: Config.IPlugin): string | undefined { 188 | const pjson = {...plugin.pjson} 189 | normalize(pjson) 190 | const repo = pjson.repository && pjson.repository.url 191 | if (!repo) return 192 | const url = new URL(repo) 193 | if (!['github.com', 'gitlab.com'].includes(url.hostname) && !pjson.oclif.repositoryPrefix) return 194 | return `https://${url.hostname}${url.pathname.replace(/\.git$/, '')}` 195 | } 196 | 197 | // eslint-disable-next-line valid-jsdoc 198 | /** 199 | * fetches the path to a command 200 | */ 201 | private commandPath(plugin: Config.IPlugin, c: Config.Command): string | undefined { 202 | const commandsDir = plugin.pjson.oclif.commands 203 | if (!commandsDir) return 204 | let p = path.join(plugin.root, commandsDir, ...c.id.split(':')) 205 | const libRegex = new RegExp('^lib' + (path.sep === '\\' ? '\\\\' : path.sep)) 206 | if (fs.pathExistsSync(path.join(p, 'index.js'))) { 207 | p = path.join(p, 'index.js') 208 | } else if (fs.pathExistsSync(p + '.js')) { 209 | p += '.js' 210 | } else if (plugin.pjson.devDependencies && plugin.pjson.devDependencies.typescript) { 211 | // check if non-compiled scripts are available 212 | const base = p.replace(plugin.root + path.sep, '') 213 | p = path.join(plugin.root, base.replace(libRegex, 'src' + path.sep)) 214 | if (fs.pathExistsSync(path.join(p, 'index.ts'))) { 215 | p = path.join(p, 'index.ts') 216 | } else if (fs.pathExistsSync(p + '.ts')) { 217 | p += '.ts' 218 | } else return 219 | } else return 220 | p = p.replace(plugin.root + path.sep, '') 221 | if (plugin.pjson.devDependencies && plugin.pjson.devDependencies.typescript) { 222 | p = p.replace(libRegex, 'src' + path.sep) 223 | p = p.replace(/\.js$/, '.ts') 224 | } 225 | p = p.replace(/\\/g, '/') // Replace windows '\' by '/' 226 | return p 227 | } 228 | 229 | private commandUsage(config: Config.IConfig, command: Config.Command): string { 230 | const arg = (arg: Config.Command.Arg) => { 231 | const name = arg.name.toUpperCase() 232 | if (arg.required) return `${name}` 233 | return `[${name}]` 234 | } 235 | const defaultUsage = () => { 236 | // const flags = Object.entries(command.flags) 237 | // .filter(([, v]) => !v.hidden) 238 | return compact([ 239 | command.id, 240 | command.args.filter(a => !a.hidden).map(a => arg(a)).join(' '), 241 | ]).join(' ') 242 | } 243 | const usages = castArray(command.usage) 244 | return template({config, command})(usages.length === 0 ? defaultUsage() : usages[0]) 245 | } 246 | } 247 | -------------------------------------------------------------------------------- /src/help-compatibility.ts: -------------------------------------------------------------------------------- 1 | import {HelpBase} from '@oclif/plugin-help' 2 | import {Command} from '@oclif/config' 3 | 4 | interface MaybeCompatibleHelp extends HelpBase { 5 | formatCommand?: (command: Command) => string; 6 | command?: (command: Command) => string; 7 | } 8 | 9 | class IncompatibleHelpError extends Error { 10 | message = 'Please implement `formatCommand` in your custom help class.\nSee https://oclif.io/docs/help_classes for more.' 11 | } 12 | 13 | export class HelpCompatibilityWrapper { 14 | inner: MaybeCompatibleHelp 15 | 16 | constructor(inner: MaybeCompatibleHelp) { 17 | this.inner = inner 18 | } 19 | 20 | formatCommand(command: Command) { 21 | if (this.inner.formatCommand) { 22 | return this.inner.formatCommand(command) 23 | } 24 | 25 | if (this.inner.command) { 26 | return command.description + '\n\n' + this.inner.command(command) 27 | } 28 | 29 | throw new IncompatibleHelpError() 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export {run} from '@oclif/command' 2 | export {IManifest} from './tarballs' 3 | -------------------------------------------------------------------------------- /src/log.ts: -------------------------------------------------------------------------------- 1 | import cli from 'cli-ux' 2 | import * as qq from 'qqjs' 3 | import * as util from 'util' 4 | 5 | export const debug = require('debug')('oclif-dev') 6 | debug.new = (name: string) => require('debug')(`oclif-dev:${name}`) 7 | 8 | export function log(format: string, ...args: any[]) { 9 | args = args.map(qq.prettifyPaths) 10 | debug.enabled ? debug(format, ...args) : cli.log(`oclif-dev: ${util.format(format, ...args)}`) 11 | } 12 | -------------------------------------------------------------------------------- /src/tarballs/bin.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-useless-escape */ 2 | import * as Config from '@oclif/config' 3 | import * as qq from 'qqjs' 4 | 5 | export async function writeBinScripts({config, baseWorkspace, nodeVersion}: {config: Config.IConfig; baseWorkspace: string; nodeVersion: string}) { 6 | const binPathEnvVar = config.scopedEnvVarKey('BINPATH') 7 | const redirectedEnvVar = config.scopedEnvVarKey('REDIRECTED') 8 | const clientHomeEnvVar = config.scopedEnvVarKey('OCLIF_CLIENT_HOME') 9 | const writeWin32 = async () => { 10 | const {bin} = config 11 | await qq.write([baseWorkspace, 'bin', `${config.bin}.cmd`], `@echo off 12 | setlocal enableextensions 13 | 14 | if not "%${redirectedEnvVar}%"=="1" if exist "%LOCALAPPDATA%\\${bin}\\client\\bin\\${bin}.cmd" ( 15 | set ${redirectedEnvVar}=1 16 | "%LOCALAPPDATA%\\${bin}\\client\\bin\\${bin}.cmd" %* 17 | goto:EOF 18 | ) 19 | 20 | if not defined ${binPathEnvVar} set ${binPathEnvVar}="%~dp0${bin}.cmd" 21 | if exist "%~dp0..\\bin\\node.exe" ( 22 | "%~dp0..\\bin\\node.exe" "%~dp0..\\bin\\run" %* 23 | ) else if exist "%LOCALAPPDATA%\\oclif\\node\\node-${nodeVersion}.exe" ( 24 | "%LOCALAPPDATA%\\oclif\\node\\node-${nodeVersion}.exe" "%~dp0..\\bin\\run" %* 25 | ) else ( 26 | node "%~dp0..\\bin\\run" %* 27 | ) 28 | `) 29 | // await qq.write([output, 'bin', config.bin], `#!/bin/sh 30 | // basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") 31 | // "$basedir/../client/bin/${config.bin}.cmd" "$@" 32 | // ret=$? 33 | // exit $ret 34 | // `) 35 | } 36 | const writeUnix = async () => { 37 | const bin = qq.join([baseWorkspace, 'bin', config.bin]) 38 | await qq.write(bin, `#!/usr/bin/env bash 39 | set -e 40 | echoerr() { echo "$@" 1>&2; } 41 | 42 | get_script_dir () { 43 | SOURCE="\${BASH_SOURCE[0]}" 44 | # While \$SOURCE is a symlink, resolve it 45 | while [ -h "\$SOURCE" ]; do 46 | DIR="\$( cd -P "\$( dirname "\$SOURCE" )" && pwd )" 47 | SOURCE="\$( readlink "\$SOURCE" )" 48 | # If \$SOURCE was a relative symlink (so no "/" as prefix, need to resolve it relative to the symlink base directory 49 | [[ \$SOURCE != /* ]] && SOURCE="\$DIR/\$SOURCE" 50 | done 51 | DIR="\$( cd -P "\$( dirname "\$SOURCE" )" && pwd )" 52 | echo "\$DIR" 53 | } 54 | DIR=\$(get_script_dir) 55 | CLI_HOME=\$(cd && pwd) 56 | XDG_DATA_HOME=\${XDG_DATA_HOME:="\$CLI_HOME/.local/share"} 57 | CLIENT_HOME=\${${clientHomeEnvVar}:=$XDG_DATA_HOME/${config.dirname}/client} 58 | BIN_PATH="\$CLIENT_HOME/bin/${config.bin}" 59 | if [ -z "\$${redirectedEnvVar}" ] && [ -x "\$BIN_PATH" ] && [[ ! "\$DIR/${config.bin}" -ef "\$BIN_PATH" ]]; then 60 | if [ "\$DEBUG" == "*" ]; then 61 | echoerr "\$BIN_PATH" "\$@" 62 | fi 63 | ${binPathEnvVar}="\$BIN_PATH" ${redirectedEnvVar}=1 "\$BIN_PATH" "\$@" 64 | else 65 | export ${binPathEnvVar}=\${${binPathEnvVar}:="\$DIR/${config.bin}"} 66 | if [ -x "$(command -v "\$XDG_DATA_HOME/oclif/node/node-custom")" ]; then 67 | NODE="\$XDG_DATA_HOME/oclif/node/node-custom" 68 | elif [ -x "$(command -v "\$DIR/node")" ]; then 69 | NODE="\$DIR/node" 70 | elif [ -x "$(command -v "\$XDG_DATA_HOME/oclif/node/node-${nodeVersion}")" ]; then 71 | NODE="\$XDG_DATA_HOME/oclif/node/node-${nodeVersion}" 72 | elif [ -x "$(command -v node)" ]; then 73 | NODE=node 74 | else 75 | echoerr 'Error: node is not installed.' >&2 76 | exit 1 77 | fi 78 | if [ "\$DEBUG" == "*" ]; then 79 | echoerr ${binPathEnvVar}="\$${binPathEnvVar}" "\$NODE" "\$DIR/run" "\$@" 80 | fi 81 | "\$NODE" "\$DIR/run" "\$@" 82 | fi 83 | `) 84 | await qq.chmod(bin, 0o755) 85 | } 86 | 87 | await writeWin32() 88 | await writeUnix() 89 | } 90 | -------------------------------------------------------------------------------- /src/tarballs/build.ts: -------------------------------------------------------------------------------- 1 | import {ArchTypes, PlatformTypes} from '@oclif/config' 2 | import * as Errors from '@oclif/errors' 3 | import * as findYarnWorkspaceRoot from 'find-yarn-workspace-root' 4 | import * as path from 'path' 5 | import * as qq from 'qqjs' 6 | 7 | import {log} from '../log' 8 | 9 | import {writeBinScripts} from './bin' 10 | import {IConfig, IManifest} from './config' 11 | import {fetchNodeBinary} from './node' 12 | 13 | const pack = async (from: string, to: string) => { 14 | const prevCwd = qq.cwd() 15 | qq.cd(path.dirname(from)) 16 | await qq.mkdirp(path.dirname(to)) 17 | log(`packing tarball from ${qq.prettifyPaths(from)} to ${qq.prettifyPaths(to)}`) 18 | await (to.endsWith('gz') ? 19 | qq.x('tar', ['czf', to, path.basename(from)]) : 20 | qq.x(`tar c ${path.basename(from)} | xz > ${to}`)) 21 | qq.cd(prevCwd) 22 | } 23 | 24 | export async function build(c: IConfig, options: { 25 | platform?: string; 26 | pack?: boolean; 27 | } = {}) { 28 | const {xz, config} = c 29 | const prevCwd = qq.cwd() 30 | const packCLI = async () => { 31 | const stdout = await qq.x.stdout('npm', ['pack', '--unsafe-perm'], {cwd: c.root}) 32 | return path.join(c.root, stdout.split('\n').pop()!) 33 | } 34 | const extractCLI = async (tarball: string) => { 35 | await qq.emptyDir(c.workspace()) 36 | await qq.mv(tarball, c.workspace()) 37 | tarball = path.basename(tarball) 38 | tarball = qq.join([c.workspace(), tarball]) 39 | qq.cd(c.workspace()) 40 | await qq.x(`tar -xzf ${tarball}`) 41 | // eslint-disable-next-line no-await-in-loop 42 | for (const f of await qq.ls('package', {fullpath: true})) await qq.mv(f, '.') 43 | await qq.rm('package', tarball, 'bin/run.cmd') 44 | } 45 | const updatePJSON = async () => { 46 | qq.cd(c.workspace()) 47 | const pjson = await qq.readJSON('package.json') 48 | pjson.version = c.version 49 | pjson.oclif.update = pjson.oclif.update || {} 50 | pjson.oclif.update.s3 = pjson.oclif.update.s3 || {} 51 | pjson.oclif.update.s3.bucket = c.s3Config.bucket 52 | await qq.writeJSON('package.json', pjson) 53 | } 54 | const addDependencies = async () => { 55 | qq.cd(c.workspace()) 56 | const yarnRoot = findYarnWorkspaceRoot(c.root) || c.root 57 | const yarn = await qq.exists([yarnRoot, 'yarn.lock']) 58 | if (yarn) { 59 | await qq.cp([yarnRoot, 'yarn.lock'], '.') 60 | await qq.x('yarn --no-progress --production --non-interactive') 61 | } else { 62 | let lockpath = qq.join(c.root, 'package-lock.json') 63 | if (!await qq.exists(lockpath)) { 64 | lockpath = qq.join(c.root, 'npm-shrinkwrap.json') 65 | } 66 | await qq.cp(lockpath, '.') 67 | await qq.x('npm install --production') 68 | } 69 | } 70 | const buildTarget = async (target: {platform: PlatformTypes; arch: ArchTypes}) => { 71 | const workspace = c.workspace(target) 72 | const key = config.s3Key('versioned', '.tar.gz', target) 73 | const base = path.basename(key) 74 | log(`building target ${base}`) 75 | await qq.rm(workspace) 76 | await qq.cp(c.workspace(), workspace) 77 | await fetchNodeBinary({ 78 | nodeVersion: c.nodeVersion, 79 | output: path.join(workspace, 'bin', 'node'), 80 | platform: target.platform, 81 | arch: target.arch, 82 | tmp: qq.join(config.root, 'tmp'), 83 | }) 84 | if (options.pack === false) return 85 | await pack(workspace, c.dist(key)) 86 | if (xz) await pack(workspace, c.dist(config.s3Key('versioned', '.tar.xz', target))) 87 | if (!c.updateConfig.s3.host) return 88 | const rollout = (typeof c.updateConfig.autoupdate === 'object' && c.updateConfig.autoupdate.rollout) 89 | const manifest: IManifest = { 90 | rollout: rollout === false ? undefined : rollout, 91 | version: c.version, 92 | channel: c.channel, 93 | baseDir: config.s3Key('baseDir', target), 94 | gz: config.s3Url(config.s3Key('versioned', '.tar.gz', target)), 95 | xz: xz ? config.s3Url(config.s3Key('versioned', '.tar.xz', target)) : undefined, 96 | sha256gz: await qq.hash('sha256', c.dist(config.s3Key('versioned', '.tar.gz', target))), 97 | sha256xz: xz ? await qq.hash('sha256', c.dist(config.s3Key('versioned', '.tar.xz', target))) : undefined, 98 | node: { 99 | compatible: config.pjson.engines.node, 100 | recommended: c.nodeVersion, 101 | }, 102 | } 103 | await qq.writeJSON(c.dist(config.s3Key('manifest', target)), manifest) 104 | } 105 | const buildBaseTarball = async () => { 106 | if (options.pack === false) return 107 | await pack(c.workspace(), c.dist(config.s3Key('versioned', '.tar.gz'))) 108 | if (xz) await pack(c.workspace(), c.dist(config.s3Key('versioned', '.tar.xz'))) 109 | if (!c.updateConfig.s3.host) { 110 | Errors.warn('No S3 bucket or host configured. CLI will not be able to update.') 111 | return 112 | } 113 | const manifest: IManifest = { 114 | version: c.version, 115 | baseDir: config.s3Key('baseDir'), 116 | channel: config.channel, 117 | gz: config.s3Url(config.s3Key('versioned', '.tar.gz')), 118 | xz: config.s3Url(config.s3Key('versioned', '.tar.xz')), 119 | sha256gz: await qq.hash('sha256', c.dist(config.s3Key('versioned', '.tar.gz'))), 120 | sha256xz: xz ? await qq.hash('sha256', c.dist(config.s3Key('versioned', '.tar.xz'))) : undefined, 121 | rollout: (typeof c.updateConfig.autoupdate === 'object' && c.updateConfig.autoupdate.rollout) as number, 122 | node: { 123 | compatible: config.pjson.engines.node, 124 | recommended: c.nodeVersion, 125 | }, 126 | } 127 | await qq.writeJSON(c.dist(config.s3Key('manifest')), manifest) 128 | } 129 | log(`gathering workspace for ${config.bin} to ${c.workspace()}`) 130 | await extractCLI(await packCLI()) 131 | await updatePJSON() 132 | await addDependencies() 133 | await writeBinScripts({config, baseWorkspace: c.workspace(), nodeVersion: c.nodeVersion}) 134 | await buildBaseTarball() 135 | for (const target of c.targets) { 136 | if (!options.platform || options.platform === target.platform) { 137 | // eslint-disable-next-line no-await-in-loop 138 | await buildTarget(target) 139 | } 140 | } 141 | qq.cd(prevCwd) 142 | } 143 | -------------------------------------------------------------------------------- /src/tarballs/config.ts: -------------------------------------------------------------------------------- 1 | import * as Config from '@oclif/config' 2 | import * as path from 'path' 3 | import * as qq from 'qqjs' 4 | 5 | import {compact} from '../util' 6 | 7 | const TARGETS = [ 8 | 'linux-x64', 9 | 'linux-arm', 10 | 'win32-x64', 11 | 'win32-x86', 12 | 'darwin-x64', 13 | ] 14 | 15 | // eslint-disable-next-line @typescript-eslint/interface-name-prefix 16 | export interface IConfig { 17 | root: string; 18 | gitSha: string; 19 | config: Config.IConfig; 20 | nodeVersion: string; 21 | version: string; 22 | tmp: string; 23 | updateConfig: IConfig['config']['pjson']['oclif']['update']; 24 | s3Config: IConfig['updateConfig']['s3']; 25 | channel: string; 26 | xz: boolean; 27 | targets: {platform: Config.PlatformTypes; arch: Config.ArchTypes}[]; 28 | workspace(target?: {platform: Config.PlatformTypes; arch: Config.ArchTypes}): string; 29 | dist(input: string): string; 30 | } 31 | 32 | // eslint-disable-next-line @typescript-eslint/interface-name-prefix 33 | export interface IManifest { 34 | version: string; 35 | channel: string; 36 | gz: string; 37 | xz?: string; 38 | sha256gz: string; 39 | sha256xz?: string; 40 | baseDir: string; 41 | rollout?: number; 42 | node: { 43 | compatible: string; 44 | recommended: string; 45 | }; 46 | } 47 | 48 | export function gitSha(cwd: string, options: {short?: boolean} = {}) { 49 | const args = options.short ? ['rev-parse', '--short', 'HEAD'] : ['rev-parse', 'HEAD'] 50 | return qq.x.stdout('git', args, {cwd}) 51 | } 52 | 53 | async function Tmp(config: Config.IConfig) { 54 | const tmp = path.join(config.root, 'tmp') 55 | await qq.mkdirp(tmp) 56 | return tmp 57 | } 58 | 59 | export async function buildConfig(root: string, options: {xz?: boolean; targets?: string[]} = {}): Promise { 60 | const config = await Config.load({root: path.resolve(root), devPlugins: false, userPlugins: false}) 61 | const channel = config.channel 62 | root = config.root 63 | const _gitSha = await gitSha(root, {short: true}) 64 | const version = config.version.includes('-') ? `${config.version}.${_gitSha}` : config.version 65 | // eslint-disable-next-line new-cap 66 | const tmp = await Tmp(config) 67 | const updateConfig = config.pjson.oclif.update || {} 68 | updateConfig.s3 = updateConfig.s3 || {} 69 | return { 70 | root, 71 | gitSha: _gitSha, 72 | config, 73 | tmp, 74 | updateConfig, 75 | version, 76 | channel, 77 | xz: typeof options.xz === 'boolean' ? options.xz : Boolean(updateConfig.s3.xz), 78 | dist: (...args: string[]) => path.join(config.root, 'dist', ...args), 79 | s3Config: updateConfig.s3, 80 | nodeVersion: updateConfig.node.version || process.versions.node, 81 | workspace(target) { 82 | const base = qq.join(config.root, 'tmp') 83 | if (target && target.platform) return qq.join(base, [target.platform, target.arch].join('-'), config.s3Key('baseDir', target)) 84 | return qq.join(base, config.s3Key('baseDir', target)) 85 | }, 86 | targets: compact(options.targets || updateConfig.node.targets || TARGETS).map(t => { 87 | const [platform, arch] = t.split('-') as [Config.PlatformTypes, Config.ArchTypes] 88 | return {platform, arch} 89 | }), 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/tarballs/index.ts: -------------------------------------------------------------------------------- 1 | export * from './bin' 2 | export * from './build' 3 | export * from './config' 4 | export * from './node' 5 | -------------------------------------------------------------------------------- /src/tarballs/node.ts: -------------------------------------------------------------------------------- 1 | import {error as oclifError} from '@oclif/errors' 2 | import * as path from 'path' 3 | import * as qq from 'qqjs' 4 | 5 | import {log} from '../log' 6 | 7 | async function checkFor7Zip() { 8 | try { 9 | await qq.x('7z', {stdio: [0, null, 2]}) 10 | } catch (error) { 11 | if (error.code === 127) oclifError('install 7-zip to package windows tarball') 12 | else throw error 13 | } 14 | } 15 | 16 | export async function fetchNodeBinary({nodeVersion, output, platform, arch, tmp}: {nodeVersion: string; output: string; platform: string; arch: string; tmp: string}) { 17 | if (arch === 'arm') arch = 'armv7l' 18 | let nodeBase = `node-v${nodeVersion}-${platform}-${arch}` 19 | let tarball = path.join(tmp, 'node', `${nodeBase}.tar.xz`) 20 | let url = `https://nodejs.org/dist/v${nodeVersion}/${nodeBase}.tar.xz` 21 | if (platform === 'win32') { 22 | await checkFor7Zip() 23 | // eslint-disable-next-line require-atomic-updates 24 | nodeBase = `node-v${nodeVersion}-win-${arch}` 25 | tarball = path.join(tmp, 'node', `${nodeBase}.7z`) 26 | url = `https://nodejs.org/dist/v${nodeVersion}/${nodeBase}.7z` 27 | output += '.exe' 28 | } 29 | 30 | let cache = path.join(tmp, 'cache', `node-v${nodeVersion}-${platform}-${arch}`) 31 | if (platform === 'win32') cache += '.exe' 32 | 33 | const download = async () => { 34 | log(`downloading ${nodeBase}`) 35 | const shasums = path.join(tmp, 'cache', nodeVersion, 'SHASUMS256.txt.asc') 36 | if (!await qq.exists(shasums)) { 37 | await qq.download(`https://nodejs.org/dist/v${nodeVersion}/SHASUMS256.txt.asc`, shasums) 38 | } 39 | const basedir = path.dirname(tarball) 40 | await qq.mkdirp(basedir) 41 | await qq.download(url, tarball) 42 | await qq.x(`grep ${path.basename(tarball)} ${shasums} | shasum -a 256 -c -`, {cwd: basedir}) 43 | } 44 | const extract = async () => { 45 | log(`extracting ${nodeBase}`) 46 | const nodeTmp = path.join(tmp, 'node') 47 | await qq.rm([nodeTmp, nodeBase]) 48 | await qq.mkdirp(nodeTmp) 49 | await qq.mkdirp(path.dirname(cache)) 50 | if (platform === 'win32') { 51 | qq.pushd(nodeTmp) 52 | await qq.x(`7z x -bd -y ${tarball} > /dev/null`) 53 | await qq.mv([nodeBase, 'node.exe'], cache) 54 | qq.popd() 55 | } else { 56 | await qq.x(`tar -C ${tmp}/node -xJf ${tarball}`) 57 | await qq.mv([nodeTmp, nodeBase, 'bin/node'], cache) 58 | } 59 | } 60 | if (await qq.exists(cache)) { 61 | await qq.cp(cache, output) 62 | } else { 63 | await download() 64 | await extract() 65 | await qq.cp(cache, output) 66 | } 67 | return output 68 | } 69 | -------------------------------------------------------------------------------- /src/util.ts: -------------------------------------------------------------------------------- 1 | import _ = require('lodash') 2 | 3 | export function castArray(input?: T | T[]): T[] { 4 | if (input === undefined) return [] 5 | return Array.isArray(input) ? input : [input] 6 | } 7 | 8 | export function uniqBy(arr: T[], fn: (cur: T) => any): T[] { 9 | return arr.filter((a, i) => { 10 | const aVal = fn(a) 11 | return !arr.find((b, j) => j > i && fn(b) === aVal) 12 | }) 13 | } 14 | 15 | export function compact(a: (T | undefined)[]): T[] { 16 | return a.filter((a): a is T => Boolean(a)) 17 | } 18 | 19 | export function sortBy(arr: T[], fn: (i: T) => sort.Types | sort.Types[]): T[] { 20 | function compare(a: sort.Types | sort.Types[], b: sort.Types | sort.Types[]): number { 21 | a = a === undefined ? 0 : a 22 | b = b === undefined ? 0 : b 23 | 24 | if (Array.isArray(a) && Array.isArray(b)) { 25 | if (a.length === 0 && b.length === 0) return 0 26 | const diff = compare(a[0], b[0]) 27 | if (diff !== 0) return diff 28 | return compare(a.slice(1), b.slice(1)) 29 | } 30 | 31 | if (a < b) return -1 32 | if (a > b) return 1 33 | return 0 34 | } 35 | 36 | return arr.sort((a, b) => compare(fn(a), fn(b))) 37 | } 38 | 39 | export namespace sort { 40 | export type Types = string | number | undefined | boolean 41 | } 42 | 43 | export const template = (context: any) => (t: string | undefined): string => _.template(t || '')(context) 44 | -------------------------------------------------------------------------------- /test/deb.test.ts: -------------------------------------------------------------------------------- 1 | import {expect, test} from '@oclif/test' 2 | import * as qq from 'qqjs' 3 | 4 | import {gitSha} from '../src/tarballs' 5 | 6 | const pjson = require('../package.json') 7 | const pjsonPath = require.resolve('../package.json') 8 | const originalVersion = pjson.version 9 | const target = [process.platform, process.arch].join('-') 10 | 11 | const onlyLinux = process.platform === 'linux' ? test : test.skip() 12 | const testRun = `test-${Math.random().toString().split('.')[1].slice(0, 4)}` 13 | 14 | describe('publish:deb', () => { 15 | beforeEach(async () => { 16 | await qq.x(`aws s3 rm --recursive s3://oclif-staging/channels/${testRun}`) 17 | pjson.version = `${pjson.version}-${testRun}` 18 | await qq.writeJSON(pjsonPath, pjson) 19 | const root = qq.join(__dirname, '../tmp/test/publish') 20 | await qq.emptyDir(root) 21 | qq.cd(root) 22 | }) 23 | afterEach(async () => { 24 | await qq.x(`aws s3 rm --recursive s3://oclif/dev-cli/channels/${testRun}`) 25 | qq.cd([__dirname, '..']) 26 | pjson.version = originalVersion 27 | await qq.writeJSON(pjsonPath, pjson) 28 | }) 29 | 30 | onlyLinux 31 | .command(['pack:deb']) 32 | .command(['publish:deb']) 33 | .it('publishes valid releases', async () => { 34 | const sha = await gitSha(process.cwd(), {short: true}) 35 | qq.cd([__dirname, '..']) 36 | await qq.x('cat test/release.key | apt-key add -') 37 | await qq.x(`echo "deb https://oclif-staging.s3.amazonaws.com/channels/${testRun}/apt ./" > /etc/apt/sources.list.d/oclif-dev.list`) 38 | await qq.x('apt-get update') 39 | await qq.x('apt-get install -y oclif-dev') 40 | await qq.x('oclif-dev --version') 41 | const stdout = await qq.x.stdout('oclif-dev', ['--version']) 42 | expect(stdout).to.contain(`@oclif/dev-cli/${pjson.version}.${sha} ${target} node-v${pjson.oclif.update.node.version}`) 43 | }) 44 | }) 45 | -------------------------------------------------------------------------------- /test/fixtures/cli-with-custom-help-no-format-command/README.md: -------------------------------------------------------------------------------- 1 | # cli-with-custom-help 2 | 3 | This file is a test for running `oclif-dev readme` in the presence of 4 | a custom help class. It should use the custom help class to generate 5 | the command documentation below. The test suite resets this file after 6 | each test. 7 | 8 | 9 | 10 | 11 | # Usage 12 | 13 | 14 | 15 | 16 | # Commands 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /test/fixtures/cli-with-custom-help-no-format-command/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cli-with-custom-help-no-format-command", 3 | "files": [ 4 | "/lib" 5 | ], 6 | "oclif": { 7 | "commands": "./lib/commands", 8 | "bin": "cli-with-custom-help", 9 | "helpClass": "./lib/help" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /test/fixtures/cli-with-custom-help-no-format-command/src/commands/hello.ts: -------------------------------------------------------------------------------- 1 | import {Command, flags} from '@oclif/command' 2 | 3 | export default class Hello extends Command { 4 | static description = 'describe the command here' 5 | 6 | static examples = [ 7 | `$ cli-with-custom-help hello 8 | hello world from ./src/hello.ts! 9 | `, 10 | ] 11 | 12 | static flags = { 13 | help: flags.help({char: 'h'}), 14 | // flag with a value (-n, --name=VALUE) 15 | name: flags.string({char: 'n', description: 'name to print'}), 16 | // flag with no value (-f, --force) 17 | force: flags.boolean({char: 'f'}), 18 | } 19 | 20 | static args = [{name: 'file'}] 21 | 22 | async run() { 23 | const {args, flags} = this.parse(Hello) 24 | 25 | const name = flags.name ?? 'world' 26 | this.log(`hello ${name} from ./src/commands/hello.ts`) 27 | if (args.file && flags.force) { 28 | this.log(`you input --force and --file: ${args.file}`) 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /test/fixtures/cli-with-custom-help-no-format-command/src/help.ts: -------------------------------------------------------------------------------- 1 | import {HelpBase} from '@oclif/plugin-help' 2 | import {Command} from '@oclif/config' 3 | 4 | export default class CustomHelp extends HelpBase { 5 | showHelp() { 6 | console.log('TODO: showHelp') 7 | } 8 | 9 | showCommandHelp(command: Command) { 10 | console.log(`Custom help for ${command.id}`) 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /test/fixtures/cli-with-custom-help-no-format-command/src/index.ts: -------------------------------------------------------------------------------- 1 | export {run} from '@oclif/command' 2 | -------------------------------------------------------------------------------- /test/fixtures/cli-with-custom-help-no-format-command/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "declaration": true, 4 | "importHelpers": true, 5 | "module": "commonjs", 6 | "outDir": "lib", 7 | "rootDir": "src", 8 | "strict": true, 9 | "target": "es2017" 10 | }, 11 | "include": [ 12 | "src/**/*" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /test/fixtures/cli-with-custom-help/README.md: -------------------------------------------------------------------------------- 1 | # cli-with-custom-help 2 | 3 | This file is a test for running `oclif-dev readme` in the presence of 4 | a custom help class. It should use the custom help class to generate 5 | the command documentation below. The test suite resets this file after 6 | each test. 7 | 8 | 9 | 10 | 11 | # Usage 12 | 13 | 14 | 15 | 16 | # Commands 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /test/fixtures/cli-with-custom-help/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cli-with-custom-help", 3 | "files": [ 4 | "/lib" 5 | ], 6 | "oclif": { 7 | "commands": "./lib/commands", 8 | "bin": "cli-with-custom-help", 9 | "helpClass": "./lib/help" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /test/fixtures/cli-with-custom-help/src/commands/hello.ts: -------------------------------------------------------------------------------- 1 | import {Command, flags} from '@oclif/command' 2 | 3 | export default class Hello extends Command { 4 | static description = 'describe the command here' 5 | 6 | static examples = [ 7 | `$ cli-with-custom-help hello 8 | hello world from ./src/hello.ts! 9 | `, 10 | ] 11 | 12 | static flags = { 13 | help: flags.help({char: 'h'}), 14 | // flag with a value (-n, --name=VALUE) 15 | name: flags.string({char: 'n', description: 'name to print'}), 16 | // flag with no value (-f, --force) 17 | force: flags.boolean({char: 'f'}), 18 | } 19 | 20 | static args = [{name: 'file'}] 21 | 22 | async run() { 23 | const {args, flags} = this.parse(Hello) 24 | 25 | const name = flags.name ?? 'world' 26 | this.log(`hello ${name} from ./src/commands/hello.ts`) 27 | if (args.file && flags.force) { 28 | this.log(`you input --force and --file: ${args.file}`) 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /test/fixtures/cli-with-custom-help/src/help.ts: -------------------------------------------------------------------------------- 1 | import {Help} from '@oclif/plugin-help' 2 | import {Command} from '@oclif/config' 3 | 4 | export default class CustomHelp extends Help { 5 | formatCommand(command: Command) { 6 | return `Custom help for ${command.id}` 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /test/fixtures/cli-with-custom-help/src/index.ts: -------------------------------------------------------------------------------- 1 | export {run} from '@oclif/command' 2 | -------------------------------------------------------------------------------- /test/fixtures/cli-with-custom-help/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "declaration": true, 4 | "importHelpers": true, 5 | "module": "commonjs", 6 | "outDir": "lib", 7 | "rootDir": "src", 8 | "strict": true, 9 | "target": "es2017" 10 | }, 11 | "include": [ 12 | "src/**/*" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /test/fixtures/cli-with-old-school-custom-help/README.md: -------------------------------------------------------------------------------- 1 | # cli-with-custom-help 2 | 3 | This file is a test for running `oclif-dev readme` in the presence of 4 | a custom help class. It should use the custom help class to generate 5 | the command documentation below. The test suite resets this file after 6 | each test. 7 | 8 | 9 | 10 | 11 | # Usage 12 | 13 | 14 | 15 | 16 | # Commands 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /test/fixtures/cli-with-old-school-custom-help/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cli-with-old-school-custom-help", 3 | "files": [ 4 | "/lib" 5 | ], 6 | "oclif": { 7 | "commands": "./lib/commands", 8 | "bin": "cli-with-custom-help", 9 | "helpClass": "./lib/help" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /test/fixtures/cli-with-old-school-custom-help/src/commands/hello.ts: -------------------------------------------------------------------------------- 1 | import {Command, flags} from '@oclif/command' 2 | 3 | export default class Hello extends Command { 4 | static description = 'describe the command here' 5 | 6 | static examples = [ 7 | `$ cli-with-custom-help hello 8 | hello world from ./src/hello.ts! 9 | `, 10 | ] 11 | 12 | static flags = { 13 | help: flags.help({char: 'h'}), 14 | // flag with a value (-n, --name=VALUE) 15 | name: flags.string({char: 'n', description: 'name to print'}), 16 | // flag with no value (-f, --force) 17 | force: flags.boolean({char: 'f'}), 18 | } 19 | 20 | static args = [{name: 'file'}] 21 | 22 | async run() { 23 | const {args, flags} = this.parse(Hello) 24 | 25 | const name = flags.name ?? 'world' 26 | this.log(`hello ${name} from ./src/commands/hello.ts`) 27 | if (args.file && flags.force) { 28 | this.log(`you input --force and --file: ${args.file}`) 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /test/fixtures/cli-with-old-school-custom-help/src/help.ts: -------------------------------------------------------------------------------- 1 | import {HelpBase} from '@oclif/plugin-help' 2 | import {Command} from '@oclif/config' 3 | 4 | export default class CustomHelp extends HelpBase { 5 | showHelp() { 6 | console.log('TODO: showHelp') 7 | } 8 | 9 | showCommandHelp(command: Command) { 10 | console.log(`Custom help for ${command.id}`) 11 | } 12 | 13 | command(command: Command) { 14 | return `Custom help for ${command.id}` 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test/fixtures/cli-with-old-school-custom-help/src/index.ts: -------------------------------------------------------------------------------- 1 | export {run} from '@oclif/command' 2 | -------------------------------------------------------------------------------- /test/fixtures/cli-with-old-school-custom-help/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "declaration": true, 4 | "importHelpers": true, 5 | "module": "commonjs", 6 | "outDir": "lib", 7 | "rootDir": "src", 8 | "strict": true, 9 | "target": "es2017" 10 | }, 11 | "include": [ 12 | "src/**/*" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /test/helpers/init.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | process.env.TS_NODE_PROJECT = path.resolve('test/tsconfig.json') 3 | -------------------------------------------------------------------------------- /test/macos.test.ts: -------------------------------------------------------------------------------- 1 | import {test} from '@oclif/test' 2 | import * as qq from 'qqjs' 3 | 4 | const pjson = require('../package.json') 5 | const pjsonPath = require.resolve('../package.json') 6 | const originalVersion = pjson.version 7 | 8 | const onlyMacos = process.platform === 'darwin' ? test : test.skip() 9 | const testRun = `test-${Math.random().toString().split('.')[1].slice(0, 4)}` 10 | 11 | describe('publish:macos', () => { 12 | beforeEach(async () => { 13 | await qq.x(`aws s3 rm --recursive s3://oclif-staging/channels/${testRun}`) 14 | pjson.version = `${pjson.version}-${testRun}` 15 | await qq.writeJSON(pjsonPath, pjson) 16 | const root = qq.join(__dirname, '../tmp/test/publish') 17 | await qq.emptyDir(root) 18 | qq.cd(root) 19 | }) 20 | afterEach(async () => { 21 | await qq.x(`aws s3 rm --recursive s3://oclif/dev-cli/channels/${testRun}`) 22 | qq.cd([__dirname, '..']) 23 | pjson.version = originalVersion 24 | await qq.writeJSON(pjsonPath, pjson) 25 | }) 26 | 27 | onlyMacos 28 | .command(['pack:macos']) 29 | .command(['publish:macos']) 30 | .it('publishes valid releases', async () => { 31 | await qq.download(`https://oclif-staging.s3.amazonaws.com/channels/${testRun}/oclif-dev.pkg`) 32 | }) 33 | }) 34 | -------------------------------------------------------------------------------- /test/manifest.test.ts: -------------------------------------------------------------------------------- 1 | import * as Config from '@oclif/config' 2 | import {expect, test} from '@oclif/test' 3 | import * as fs from 'fs-extra' 4 | 5 | describe('manifest', () => { 6 | test 7 | .stdout() 8 | .do(() => fs.remove('oclif.manifest.json')) 9 | .finally(() => fs.remove('oclif.manifest.json')) 10 | .command(['manifest']) 11 | .it('outputs plugins', ctx => { 12 | const {commands} = fs.readJSONSync('oclif.manifest.json') as Config.Manifest 13 | expect(commands.manifest).to.include({ 14 | description: 'generates plugin manifest json', 15 | }) 16 | expect(ctx.stdout).to.match(/wrote manifest to .*oclif.manifest.json/) 17 | }) 18 | }) 19 | -------------------------------------------------------------------------------- /test/publish.test.ts: -------------------------------------------------------------------------------- 1 | import {expect, test} from '@oclif/test' 2 | import * as qq from 'qqjs' 3 | 4 | import aws from '../src/aws' 5 | import {gitSha} from '../src/tarballs' 6 | 7 | const pjson = require('../package.json') 8 | const pjsonPath = require.resolve('../package.json') 9 | const originalVersion = pjson.version 10 | const target = [process.platform, process.arch].join('-') 11 | 12 | const skipIfWindows = process.platform === 'win32' ? test.skip() : test 13 | const testRun = `test-${Math.random().toString().split('.')[1].slice(0, 4)}` 14 | const s3UploadedFiles: string[] = [] 15 | 16 | describe('publish', () => { 17 | beforeEach(async () => { 18 | await qq.x(`aws s3 rm --recursive s3://oclif-staging/channels/${testRun}`) 19 | pjson.version = `${pjson.version}-${testRun}` 20 | await qq.writeJSON(pjsonPath, pjson) 21 | const root = qq.join(__dirname, '../tmp/test/publish') 22 | await qq.emptyDir(root) 23 | qq.cd(root) 24 | }) 25 | afterEach(async () => { 26 | await qq.x(`aws s3 rm --recursive s3://oclif/dev-cli/channels/${testRun}`) 27 | qq.cd([__dirname, '..']) 28 | pjson.version = originalVersion 29 | await qq.writeJSON(pjsonPath, pjson) 30 | }) 31 | 32 | skipIfWindows 33 | .command(['pack']) 34 | .command(['publish']) 35 | .it('publishes valid releases', async () => { 36 | const manifest = async (url: string, nodeVersion: string) => { 37 | const manifest = await qq.readJSON(url) 38 | const test = async (url: string, expectedSha: string, nodeVersion: string) => { 39 | const xz = url.endsWith('.tar.xz') 40 | const ext = xz ? '.tar.xz' : '.tar.gz' 41 | await qq.download(url, `oclif-dev${ext}`) 42 | const receivedSha = await qq.hash('sha256', `oclif-dev${ext}`) 43 | expect(receivedSha).to.equal(expectedSha) 44 | if (xz) { 45 | await qq.x('tar xJf oclif-dev.tar.xz') 46 | } else { 47 | await qq.x('tar xzf oclif-dev.tar.gz') 48 | } 49 | const stdout = await qq.x.stdout('./oclif-dev/bin/oclif-dev', ['--version']) 50 | const sha = await gitSha(process.cwd(), {short: true}) 51 | expect(stdout).to.contain(`@oclif/dev-cli/${pjson.version}.${sha} ${target} node-v${nodeVersion}`) 52 | await qq.rm('oclif-dev') 53 | } 54 | 55 | await test(manifest.gz, manifest.sha256gz, nodeVersion) 56 | await test(manifest.xz, manifest.sha256xz, nodeVersion) 57 | } 58 | await manifest(`https://oclif-staging.s3.amazonaws.com/channels/${testRun}/version`, process.versions.node) 59 | await manifest(`https://oclif-staging.s3.amazonaws.com/channels/${testRun}/${target}`, pjson.oclif.update.node.version) 60 | }) 61 | 62 | describe('with filter', () => { 63 | skipIfWindows 64 | .stub(aws, 's3', () => ({ 65 | uploadFile: (file: string) => { 66 | s3UploadedFiles.push(file) 67 | }, 68 | })) 69 | .command(['publish', '-t', 'linux-x64']) 70 | .it('publishes only the specified target', async () => { 71 | expect(s3UploadedFiles.join()).to.contain('linux-x64') 72 | expect(s3UploadedFiles.join()).to.not.contain('win32-x64') 73 | expect(s3UploadedFiles.join()).to.not.contain('darwin-x64') 74 | }) 75 | }) 76 | 77 | describe('without filter', () => { 78 | skipIfWindows 79 | .stub(aws, 's3', () => ({ 80 | uploadFile: (file: string) => { 81 | s3UploadedFiles.push(file) 82 | }, 83 | })) 84 | .command(['publish']) 85 | .it('publishes all', async () => { 86 | expect(s3UploadedFiles.join()).to.contain('linux-x64') 87 | expect(s3UploadedFiles.join()).to.contain('win32-x64') 88 | expect(s3UploadedFiles.join()).to.contain('darwin-x64') 89 | }) 90 | }) 91 | }) 92 | -------------------------------------------------------------------------------- /test/readme.test.ts: -------------------------------------------------------------------------------- 1 | import {expect, test} from '@oclif/test' 2 | import * as fs from 'fs-extra' 3 | import * as path from 'path' 4 | 5 | const readme = fs.readFileSync('README.md', 'utf8') 6 | 7 | describe('readme', () => { 8 | test 9 | .stdout() 10 | .finally(() => fs.writeFile('README.md', readme)) 11 | .command(['readme']) 12 | .it('runs readme', () => { 13 | expect(fs.readFileSync('README.md', 'utf8')).to.contain('manifest') 14 | }) 15 | 16 | test 17 | .stdout() 18 | .finally(() => fs.writeFile('README.md', readme)) 19 | .finally(() => fs.remove('docs')) 20 | .command(['readme', '--multi']) 21 | .it('runs readme --multi', () => { 22 | expect(fs.readFileSync('README.md', 'utf8')).to.contain('manifest') 23 | }) 24 | 25 | describe('with custom help that implements formatCommand', () => { 26 | const rootPath = path.join(__dirname, 'fixtures/cli-with-custom-help') 27 | const readmePath = path.join(rootPath, 'README.md') 28 | const originalReadme = fs.readFileSync(readmePath, 'utf8') 29 | 30 | test 31 | .stdout() 32 | .finally(() => fs.writeFileSync(readmePath, originalReadme)) 33 | .stub(process, 'cwd', () => rootPath) 34 | .command(['readme']) 35 | .it('writes custom help to the readme', () => { 36 | const newReadme = fs.readFileSync(readmePath, 'utf8') 37 | 38 | expect(newReadme).to.contain('Custom help for hello') 39 | }) 40 | }) 41 | 42 | describe('with custom help that implements command', () => { 43 | const rootPath = path.join(__dirname, 'fixtures/cli-with-old-school-custom-help') 44 | const readmePath = path.join(rootPath, 'README.md') 45 | const originalReadme = fs.readFileSync(readmePath, 'utf8') 46 | 47 | test 48 | .stdout() 49 | .finally(() => fs.writeFileSync(readmePath, originalReadme)) 50 | .stub(process, 'cwd', () => rootPath) 51 | .command(['readme']) 52 | .it('writes custom help to the readme', () => { 53 | const newReadme = fs.readFileSync(readmePath, 'utf8') 54 | 55 | expect(newReadme).to.contain('Custom help for hello') 56 | }) 57 | }) 58 | 59 | describe('with custom help that does not implement formatCommand', () => { 60 | const rootPath = path.join(__dirname, 'fixtures/cli-with-custom-help-no-format-command') 61 | const readmePath = path.join(rootPath, 'README.md') 62 | const originalReadme = fs.readFileSync(readmePath, 'utf8') 63 | 64 | test 65 | .stdout() 66 | .finally(() => fs.writeFileSync(readmePath, originalReadme)) 67 | .stub(process, 'cwd', () => rootPath) 68 | .command(['readme']) 69 | .catch(error => { 70 | expect(error.message).to.contain('Please implement `formatCommand`') 71 | }) 72 | .it('prints a helpful error message') 73 | }) 74 | }) 75 | -------------------------------------------------------------------------------- /test/release.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PGP PUBLIC KEY BLOCK----- 2 | 3 | mQENBFrMe8gBCADUuDPKDBwneHVs1lUQ4losjkwH5siY9Y2/w2fUqUhiwssuFVBb 4 | aOLzffEMYtdc+rW9zUSBaftovzpnDKgI/bleIxDC/5VdkC4FuxPQYPXfV4gIrTT1 5 | r7JoPMm9mwHxKMga4QmOFPeIHS+fZ11KMawANA2zvtv0CMrLTBRvHdGkbdO2u7XL 6 | Plp++G6ifFuTLy9DQcRaFUwa2vBuM5Uxxaf6TIlnQndFSib9BHRCFp6cXNJU0VNI 7 | RvD4O9BxioFMuhy+jWKR4tM65Btx7H9ydhqkS0PKMMi4BJOfeCRgBJ7g/tl3uXnH 8 | VwIUb2qsOZ7+jCen7d36nrsZkOSWqhMtBqnBABEBAAG0CW9jbGlmLWRldokBTgQT 9 | AQgAOBYhBFkKfMcUiWgcatzwkzXMdhxCULWABQJazHvIAhsDBQsJCAcCBhUICQoL 10 | AgQWAgMBAh4BAheAAAoJEDXMdhxCULWASjUIAJqvLYuhuO+bLP7F2a5a5lGktG65 11 | G/U4qjfUo5GasiZsM8RjYfzx8WxSMvrvhH8BobAbr0swtPLfFpl64YZpQpS1M1ES 12 | JxrCiXWHqPV7X3SQkBRZBJn8oG7p18Bjt5xXzcmM5H1uUwDEyF1d6uuokVI0Lk5u 13 | a6fZukKRfOocoVL55Krv1Ted0R0oBvxqQnmVOyly9YUZD3PfF26EZgDek/+X4QWy 14 | qsWJHtGDSHqJkuUv0PrvRhzNmaFs9KX0a/VfaVrvnXzjIW5A/34SsO+OYtDX0nQE 15 | qsA/s+SC+uFr+9YYpVR+E+SizjM1LcP+pWMZ1Add5X/UK6O0dd165FPzg2K5AQ0E 16 | Wsx7yAEIAM3aJIrrRM5NUAaYfes9NX+pk9WQDFywqFRa6/LZ+Baap6Qo67T3C+ib 17 | pcLv6Gj7/wChNX3D9OrRdaNlV8ePfQftJmI2oGJ5ybCgEzRB4ynt782x/+Md/CHm 18 | U8+B12wzWwCSPEPPjijbeHICiW0swhzGY3zt7UDSCiIgGfz8D6espbdnlnrxmnSu 19 | Q6JTONVkmovBBVg3GDTfa07qlgfxRDYHVm0EL18WvkIHqZHASm96uNKdfEMI2C9e 20 | EHV56t2SNW4nJlBXHmI5Tqit5idMR5pyGcJ616g8Y3DghYuikaq0a2edpOQpDDmo 21 | uh9WulS6nHyQxbC73OS2ViPjEB11XHsAEQEAAYkBNgQYAQgAIBYhBFkKfMcUiWgc 22 | atzwkzXMdhxCULWABQJazHvIAhsMAAoJEDXMdhxCULWA1dgIALCwfa+hD7vEmKJG 23 | DRJwrRoynRHerugC+Ntz53VdzfeQuyLwPBN2qT6UawVqGbXLyOfA2egGuKhqqQQl 24 | x/c8aa5LGPEbVAZOCL9Q+nVaaPdUNAV3UdBPP2DWZSzVKvvCBBliUoa7gLgwnC3e 25 | x4G0y02qKndt97H9holbFa6UtGRiEXo+GfVPDCe0B33M6hCnDrvqKC8NwQPI9ZSy 26 | uLBjwbwTovafoZbhoPfHKS5defa3JQ3dHqGBg+GJUeyK/t0vUoMm8MM/LTuRXb5O 27 | SFraQVYholUUPMe5VT0dXAhibxXpcSTf82bl0iuqQndB+E0eq1gu+98D7CWzDDS7 28 | uUAn/24= 29 | =5Z6m 30 | -----END PGP PUBLIC KEY BLOCK----- 31 | -------------------------------------------------------------------------------- /test/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "declaration": false, 3 | "extends": "../tsconfig", 4 | "compilerOptions": { 5 | "sourceMap": true 6 | }, 7 | "include": [ 8 | "./**/*", 9 | "../src/**/*" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /test/win.test.ts: -------------------------------------------------------------------------------- 1 | import {test} from '@oclif/test' 2 | import * as qq from 'qqjs' 3 | 4 | const pjson = require('../package.json') 5 | const pjsonPath = require.resolve('../package.json') 6 | const originalVersion = pjson.version 7 | 8 | const skipIfWindows = process.platform === 'win32' ? test.skip() : test 9 | const testRun = `test-${Math.random().toString().split('.')[1].slice(0, 4)}` 10 | 11 | describe('publish:win', () => { 12 | beforeEach(async () => { 13 | await qq.x(`aws s3 rm --recursive s3://oclif-staging/channels/${testRun}`) 14 | pjson.version = `${pjson.version}-${testRun}` 15 | await qq.writeJSON(pjsonPath, pjson) 16 | const root = qq.join(__dirname, '../tmp/test/publish') 17 | await qq.emptyDir(root) 18 | qq.cd(root) 19 | }) 20 | afterEach(async () => { 21 | await qq.x(`aws s3 rm --recursive s3://oclif/dev-cli/channels/${testRun}`) 22 | qq.cd([__dirname, '..']) 23 | pjson.version = originalVersion 24 | await qq.writeJSON(pjsonPath, pjson) 25 | }) 26 | 27 | skipIfWindows 28 | .command(['pack:win']) 29 | .command(['publish:win']) 30 | .it('publishes valid releases', async () => { 31 | await qq.download(`https://oclif-staging.s3.amazonaws.com/channels/${testRun}/oclif-dev-x64.exe`) 32 | await qq.download(`https://oclif-staging.s3.amazonaws.com/channels/${testRun}/oclif-dev-x86.exe`) 33 | }) 34 | }) 35 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "declaration": true, 4 | "forceConsistentCasingInFileNames": true, 5 | "importHelpers": true, 6 | "module": "commonjs", 7 | "outDir": "./lib", 8 | "pretty": true, 9 | "rootDirs": [ 10 | "./src" 11 | ], 12 | "strict": true, 13 | "target": "es2017" 14 | }, 15 | "include": [ 16 | "./src/**/*" 17 | ] 18 | } 19 | --------------------------------------------------------------------------------