From c970fed7c76ee613b935a0b7930ed327068bf627 Mon Sep 17 00:00:00 2001 From: Katy Bowman Date: Wed, 15 Mar 2023 09:39:16 -0400 Subject: [PATCH] Revert "refactor: revert oclif upgrade (#2256)" This reverts commit f6cb67bd59dd363123d27411dbfa9ffe3217c5af. --- .eslintignore | 3 + .github/workflows/ci.yml | 19 +- .gitignore | 4 +- .tool-versions | 1 + package.json | 9 +- packages/addons-v5/package.json | 9 +- .../addons-v5/test/commands/addons/create.js | 2 +- packages/apps-v5/package.json | 11 +- packages/apps-v5/test/commands/apps/create.js | 2 +- packages/apps-v5/test/commands/config/set.js | 2 +- packages/apps/.eslintrc | 1 + packages/apps/bin/run | 5 +- packages/apps/package.json | 33 +- packages/apps/src/commands/domains/add.ts | 18 +- packages/apps/src/commands/domains/clear.ts | 10 +- packages/apps/src/commands/domains/index.ts | 6 +- packages/apps/src/commands/domains/info.ts | 6 +- packages/apps/src/commands/domains/remove.ts | 10 +- packages/apps/src/commands/domains/update.ts | 15 +- packages/apps/src/commands/domains/wait.ts | 2 +- packages/apps/src/lib/wait-for-domain.ts | 11 +- .../apps/test/commands/domains/add.test.ts | 2 +- .../apps/test/commands/domains/clear.test.ts | 2 +- .../apps/test/commands/domains/index.test.ts | 6 +- .../apps/test/commands/domains/info.test.ts | 2 +- .../apps/test/commands/domains/remove.test.ts | 2 +- .../apps/test/commands/domains/update.test.ts | 2 +- .../apps/test/commands/domains/wait.test.ts | 2 +- packages/apps/test/test.ts | 6 - packages/apps/tsconfig.json | 1 + packages/auth/.eslintrc | 4 +- packages/auth/bin/run | 5 +- packages/auth/package.json | 34 +- .../auth/src/commands/auth/2fa/disable.ts | 6 +- packages/auth/src/commands/auth/login.ts | 3 +- packages/auth/src/commands/auth/logout.ts | 4 +- packages/auth/src/commands/auth/token.ts | 7 +- packages/auth/src/commands/auth/whoami.ts | 2 +- packages/auth/src/commands/labs/disable.ts | 16 +- packages/auth/test/commands/2fa/index.test.ts | 2 +- .../auth/test/commands/auth/token.test.ts | 2 +- .../auth/test/commands/auth/whoami.test.ts | 2 +- .../auth/test/commands/labs/disable.test.ts | 2 +- packages/auth/test/test.ts | 6 - packages/auth/tsconfig.json | 2 + packages/autocomplete/.eslintrc | 3 +- packages/autocomplete/bin/run | 5 +- packages/autocomplete/package.json | 33 +- packages/autocomplete/src/base.ts | 5 +- .../src/commands/autocomplete/create.ts | 22 +- .../src/commands/autocomplete/doctor.ts | 18 +- .../src/commands/autocomplete/index.ts | 10 +- .../src/commands/autocomplete/options.ts | 22 +- .../src/commands/autocomplete/script.ts | 2 +- packages/autocomplete/src/completions.ts | 52 +- packages/autocomplete/src/hooks/recache.ts | 13 +- packages/autocomplete/test/base.test.ts | 4 +- .../test/commands/autocomplete/create.test.ts | 9 +- .../commands/autocomplete/options.test.ts | 2 +- packages/autocomplete/tsconfig.json | 1 + packages/buildpacks/.eslintrc | 3 +- packages/buildpacks/bin/run | 5 +- packages/buildpacks/package.json | 30 +- packages/buildpacks/src/buildpacks.ts | 42 +- .../buildpacks/src/commands/buildpacks/add.ts | 2 +- .../src/commands/buildpacks/clear.ts | 2 +- .../src/commands/buildpacks/index.ts | 6 +- .../src/commands/buildpacks/info.ts | 12 +- .../src/commands/buildpacks/remove.ts | 12 +- .../src/commands/buildpacks/search.ts | 28 +- .../buildpacks/src/commands/buildpacks/set.ts | 2 +- .../src/commands/buildpacks/versions.ts | 20 +- .../test/commands/buildpacks/add.test.ts | 32 +- .../test/commands/buildpacks/clear.test.ts | 10 +- .../test/commands/buildpacks/index.test.ts | 21 +- .../test/commands/buildpacks/info.test.ts | 10 +- .../test/commands/buildpacks/remove.test.ts | 38 +- .../test/commands/buildpacks/search.test.ts | 8 +- .../test/commands/buildpacks/set.test.ts | 31 +- .../test/commands/buildpacks/versions.test.ts | 10 +- packages/buildpacks/tsconfig.json | 1 + packages/certs-v5/package.json | 8 +- packages/certs/.eslintrc | 3 +- packages/certs/bin/run | 5 +- packages/certs/package.json | 27 +- .../certs/src/commands/certs/auto/wait.ts | 4 +- packages/certs/tsconfig.json | 1 + packages/ci-v5/package.json | 12 +- packages/ci/.eslintignore | 1 + packages/ci/.eslintrc | 3 +- packages/ci/bin/run | 5 +- packages/ci/package.json | 31 +- packages/ci/src/commands/ci/index.ts | 2 +- packages/ci/src/commands/ci/info.ts | 2 +- packages/ci/src/commands/ci/last.ts | 6 +- packages/ci/src/commands/ci/rerun.ts | 6 +- packages/ci/src/commands/ci/run.ts | 7 +- packages/ci/src/utils/source.ts | 4 +- packages/ci/src/utils/test-run.ts | 30 +- packages/ci/test/commands/ci/index.test.ts | 10 +- packages/ci/test/commands/ci/info.test.ts | 7 +- packages/ci/test/commands/ci/last.test.ts | 7 +- packages/ci/test/commands/ci/rerun.test.ts | 7 +- packages/ci/test/commands/ci/run.test.ts | 16 +- packages/ci/tsconfig.json | 1 + packages/cli/.eslintignore | 2 + packages/cli/.eslintrc | 1 + packages/cli/bin/run | 6 +- packages/cli/package.json | 48 +- packages/cli/src/analytics.ts | 8 +- packages/cli/src/file.ts | 2 +- .../cli/src/hooks/init/terms-of-service.ts | 5 +- packages/cli/src/hooks/init/version.ts | 2 +- packages/cli/src/hooks/prerun/analytics.ts | 2 +- packages/cli/src/hooks/update/b.ts | 4 +- packages/cli/src/hooks/update/brew.ts | 4 +- packages/cli/src/hooks/update/completions.ts | 2 +- .../cli/src/hooks/update/plugin-migrate.ts | 6 +- packages/cli/src/hooks/update/tidy.ts | 6 +- packages/cli/src/index.ts | 2 +- packages/cli/src/user-config.ts | 8 +- packages/cli/test/analytics.test.ts | 19 +- packages/cli/tsconfig.json | 1 + packages/config/.eslintrc | 3 +- packages/config/bin/run | 5 +- packages/config/package.json | 31 +- packages/config/src/commands/config/edit.ts | 5 +- packages/config/src/commands/config/get.ts | 2 +- packages/config/src/commands/config/index.ts | 5 +- packages/config/src/commands/config/unset.ts | 6 +- .../config/test/commands/config/edit.test.ts | 12 +- .../config/test/commands/config/get.test.ts | 2 +- .../config/test/commands/config/index.test.ts | 4 +- .../config/test/commands/config/unset.test.ts | 2 +- packages/config/test/test.ts | 6 - packages/config/tsconfig.json | 1 + packages/container-registry-v5/package.json | 8 +- packages/git/.eslintrc | 4 +- packages/git/bin/run | 5 +- packages/git/package.json | 30 +- packages/git/src/commands/git/clone.ts | 2 +- packages/git/src/commands/git/credentials.ts | 2 +- packages/git/src/commands/git/remote.ts | 2 +- packages/git/src/git.ts | 8 +- packages/git/tsconfig.json | 1 + packages/local/.eslintrc | 2 + packages/local/bin/run | 5 +- packages/local/package.json | 36 +- packages/local/src/commands/local/index.ts | 14 +- packages/local/src/commands/local/run.ts | 8 +- packages/local/src/commands/local/version.ts | 4 +- .../local/test/commands/local/index.test.ts | 41 +- .../local/test/commands/local/run.test.ts | 24 +- .../local/test/commands/local/version.test.ts | 4 +- packages/local/tsconfig.json | 1 + .../lib/commands/authorizations/revoke.js | 2 +- packages/oauth-v5/package.json | 10 +- packages/oauth/.eslintrc | 1 + packages/oauth/bin/run | 6 +- packages/oauth/package.json | 31 +- .../src/commands/authorizations/create.ts | 12 +- .../src/commands/authorizations/index.ts | 13 +- .../oauth/src/commands/authorizations/info.ts | 6 +- .../src/commands/authorizations/revoke.ts | 8 +- .../src/commands/authorizations/rotate.ts | 8 +- .../src/commands/authorizations/update.ts | 8 +- packages/oauth/src/commands/clients/create.ts | 14 +- .../oauth/src/commands/clients/destroy.ts | 8 +- packages/oauth/src/commands/clients/index.ts | 13 +- packages/oauth/src/commands/clients/info.ts | 14 +- packages/oauth/src/commands/clients/rotate.ts | 18 +- packages/oauth/src/commands/clients/update.ts | 8 +- .../oauth/src/commands/sessions/destroy.ts | 8 +- packages/oauth/src/commands/sessions/index.ts | 13 +- packages/oauth/src/lib/authorizations.ts | 4 +- .../commands/authorizations/create.test.ts | 5 +- .../commands/authorizations/index.test.ts | 4 +- .../test/commands/sessions/index.test.ts | 4 +- packages/oauth/tsconfig.json | 1 + packages/orgs-v5/package.json | 10 +- packages/pg-v5/package.json | 8 +- packages/pipelines/.eslintrc | 3 +- packages/pipelines/bin/run | 5 +- packages/pipelines/package.json | 48 +- .../pipelines/src/commands/pipelines/add.ts | 6 +- .../src/commands/pipelines/connect.ts | 6 +- .../src/commands/pipelines/create.ts | 6 +- .../src/commands/pipelines/destroy.ts | 6 +- .../pipelines/src/commands/pipelines/diff.ts | 18 +- .../pipelines/src/commands/pipelines/index.ts | 6 +- .../pipelines/src/commands/pipelines/info.ts | 6 +- .../pipelines/src/commands/pipelines/open.ts | 6 +- .../src/commands/pipelines/promote.ts | 12 +- .../src/commands/pipelines/remove.ts | 6 +- .../src/commands/pipelines/rename.ts | 6 +- .../pipelines/src/commands/pipelines/setup.ts | 9 +- .../src/commands/pipelines/transfer.ts | 6 +- .../src/commands/pipelines/update.ts | 6 +- .../src/commands/reviewapps/disable.ts | 8 +- .../src/commands/reviewapps/enable.ts | 8 +- packages/pipelines/src/ownership.ts | 4 +- packages/pipelines/src/render-pipeline.ts | 6 +- packages/pipelines/src/setup/create-apps.ts | 4 +- .../pipelines/src/setup/get-ci-settings.ts | 4 +- .../pipelines/src/setup/get-name-and-repo.ts | 4 +- packages/pipelines/src/setup/get-settings.ts | 4 +- .../pipelines/src/setup/setup-pipeline.ts | 4 +- packages/pipelines/src/setup/validate.ts | 3 +- .../test/commands/pipelines/add.test.ts | 9 +- .../test/commands/pipelines/info.test.ts | 27 +- .../test/commands/pipelines/open.test.ts | 4 +- .../test/commands/pipelines/promote.test.ts | 1 + .../test/commands/pipelines/setup.test.ts | 4 +- packages/pipelines/test/helpers/init.js | 2 +- packages/pipelines/test/tsconfig.json | 3 +- packages/pipelines/tsconfig.json | 1 + packages/ps/.eslintrc | 3 +- packages/ps/bin/run | 6 +- packages/ps/package.json | 29 +- .../ps/src/commands/ps/autoscale/disable.ts | 8 +- .../ps/src/commands/ps/autoscale/enable.ts | 8 +- packages/ps/src/commands/ps/wait.ts | 16 +- packages/ps/src/commands/regions.ts | 24 +- packages/ps/test/commands/enable.test.ts | 6 +- packages/ps/test/commands/regions.test.ts | 20 +- packages/ps/test/commands/wait.test.ts | 6 +- packages/ps/test/test.ts | 4 - packages/ps/tsconfig.json | 1 + packages/redis-v5/package.json | 8 +- packages/run-v5/lib/colorize.js | 8 +- packages/run-v5/package.json | 19 +- packages/run/.eslintignore | 1 + packages/run/.eslintrc | 3 +- packages/run/bin/run | 4 +- packages/run/package.json | 29 +- packages/run/src/commands/console.ts | 2 +- packages/run/src/commands/logs.ts | 2 +- packages/run/src/commands/rake.ts | 6 +- packages/run/src/commands/run/detached.ts | 6 +- packages/run/src/commands/run/index.ts | 6 +- packages/run/src/commands/run/inside.ts | 6 +- packages/run/src/lib/colorize.ts | 8 +- packages/run/src/lib/dyno.ts | 26 +- packages/run/src/lib/helpers.ts | 4 +- packages/run/src/lib/log-displayer.ts | 10 +- packages/run/test/commands/run.test.ts | 8 +- packages/run/tsconfig.json | 1 + packages/spaces/package.json | 10 +- packages/status/.eslintignore | 1 + packages/status/.eslintrc | 1 + packages/status/bin/run | 6 + packages/{run => status}/bin/run.cmd | 0 packages/status/package.json | 33 +- packages/status/src/commands/status.ts | 17 +- packages/status/test/status.test.ts | 1 + packages/status/tsconfig.json | 1 + packages/webhooks/.eslintrc | 1 + packages/webhooks/bin/run | 5 +- packages/webhooks/package.json | 31 +- packages/webhooks/src/base.ts | 4 +- .../webhooks/src/commands/webhooks/add.ts | 16 +- .../src/commands/webhooks/deliveries/index.ts | 11 +- .../src/commands/webhooks/deliveries/info.ts | 16 +- .../src/commands/webhooks/events/index.ts | 14 +- .../src/commands/webhooks/events/info.ts | 12 +- .../webhooks/src/commands/webhooks/index.ts | 12 +- .../webhooks/src/commands/webhooks/info.ts | 10 +- .../webhooks/src/commands/webhooks/remove.ts | 9 +- .../webhooks/src/commands/webhooks/update.ts | 9 +- packages/webhooks/test/commands/base.test.ts | 4 +- .../test/commands/webhooks/add.test.ts | 9 +- .../webhooks/deliveries/index.test.ts | 30 +- .../commands/webhooks/deliveries/info.test.ts | 50 +- .../commands/webhooks/events/index.test.ts | 38 +- .../commands/webhooks/events/info.test.ts | 39 +- .../test/commands/webhooks/index.test.ts | 27 +- .../test/commands/webhooks/info.test.ts | 22 +- packages/webhooks/test/tsconfig.json | 3 +- packages/webhooks/tsconfig.json | 1 + scripts/pack/deb | 2 +- scripts/pack/tarballs | 4 +- scripts/pack/win | 4 +- scripts/postrelease/dev_center_docs | 2 +- scripts/release/deb | 2 +- scripts/release/tarballs | 2 +- scripts/release/win | 4 +- scripts/run-acceptance | 24 - scripts/sign/deb | 2 +- tslint.json | 2 +- yarn.lock | 6861 ++++++++++------- 290 files changed, 5574 insertions(+), 4009 deletions(-) create mode 100644 .tool-versions delete mode 100644 packages/apps/test/test.ts delete mode 100644 packages/auth/test/test.ts delete mode 100644 packages/config/test/test.ts delete mode 100644 packages/ps/test/test.ts create mode 100644 packages/run/.eslintignore create mode 100644 packages/status/.eslintignore create mode 100755 packages/status/bin/run rename packages/{run => status}/bin/run.cmd (100%) delete mode 100755 scripts/run-acceptance diff --git a/.eslintignore b/.eslintignore index 3c07905cbf..8af4e8f181 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,2 +1,5 @@ node_modules packages/*/lib +packages/*/tmp +tmp +dst diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7c0d41623d..e00f9619d0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,7 +16,7 @@ jobs: uses: actions/setup-node@v3 with: node-version: ${{ matrix.node-version }} - yarn: cache + cache: yarn - run: yarn --frozen-lockfile --network-timeout 1000000 - run: yarn test @@ -36,9 +36,12 @@ jobs: uses: actions/setup-node@v3 with: node-version: ${{ matrix.node-version }} - - run: yarn --frozen-lockfile + cache: yarn + - run: yarn --frozen-lockfile --network-timeout 1000000 + - name: Build packages + run: yarn lerna run prepack - run: ./bin/run whoami - - run: ./scripts/run-acceptance + - run: yarn lerna run test:acceptance # dummy job needed to pass changeling compliance because it only watches one build done: @@ -66,7 +69,7 @@ jobs: run: | cp yarn.lock packages/cli cd packages/cli - yarn --frozen-lockfile + yarn --frozen-lockfile --network-timeout 1000000 - name: Building deb run: ./scripts/pack/deb - uses: actions/upload-artifact@v3 @@ -88,7 +91,7 @@ jobs: run: | cp yarn.lock packages/cli cd packages/cli - yarn --frozen-lockfile + yarn --frozen-lockfile --network-timeout 1000000 - name: Building tarballs run: ./scripts/pack/tarballs - uses: actions/upload-artifact@v3 @@ -156,7 +159,7 @@ jobs: run: | cp yarn.lock packages/cli cd packages/cli - yarn --frozen-lockfile --prefer-offline + yarn --frozen-lockfile --prefer-offline --network-timeout 1000000 - name: Upload production artifacts run: | cd packages/cli @@ -208,7 +211,7 @@ jobs: - run: | cp yarn.lock packages/cli cd packages/cli - yarn --frozen-lockfile + yarn --frozen-lockfile --network-timeout 1000000 ./scripts/release/homebrew.js change-management: @@ -225,5 +228,5 @@ jobs: steps: - uses: actions/checkout@v3 - run: | - yarn --frozen-lockfile + yarn --frozen-lockfile --network-timeout 1000000 ./scripts/postrelease/change_management diff --git a/.gitignore b/.gitignore index 2768c64c68..688b47e1b3 100644 --- a/.gitignore +++ b/.gitignore @@ -10,8 +10,8 @@ node_modules /tmp /packages/cli/docs/* -.vscode - **/.DS_Store ./idea +.vscode + diff --git a/.tool-versions b/.tool-versions new file mode 100644 index 0000000000..d82b78e38c --- /dev/null +++ b/.tool-versions @@ -0,0 +1 @@ +nodejs 16.19.0 diff --git a/package.json b/package.json index 0c1dc94589..b93e42ced0 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,13 @@ { "devDependencies": { + "@oclif/tslint": "^3.1.1", "eslint": "5.13.0", "eslint-config-standard": "12.0.0", "eslint-plugin-import": "^2.16.0", "eslint-plugin-node": "^8.0.1", "eslint-plugin-promise": "^4.0.1", "eslint-plugin-standard": "^4.0.0", - "lerna": "^3.22.1", + "lerna": "^6.4.1", "promise-request-retry": "^1.0.2", "standard": "12.0.1", "tmp": "^0.2.1" @@ -19,12 +20,14 @@ ] }, "engines": { - "node": ">=10.0.0" + "node": ">=14" }, "private": true, "scripts": { + "build": "lerna run prepack", "test": "lerna run test --concurrency 4", - "version": "cp packages/cli/CHANGELOG.md CHANGELOG.md && git add CHANGELOG.md" + "version": "cp packages/cli/CHANGELOG.md CHANGELOG.md && git add CHANGELOG.md", + "cleanNodeModules": "rm -rf ./packages/*/node_modules && rm -rf ./node_modules" }, "workspaces": [ "packages/*" diff --git a/packages/addons-v5/package.json b/packages/addons-v5/package.json index 36068076e1..c4a2516d58 100644 --- a/packages/addons-v5/package.json +++ b/packages/addons-v5/package.json @@ -19,14 +19,15 @@ "printf": "0.6.1" }, "devDependencies": { - "@heroku-cli/dev-cli": "^1.26.13", - "@oclif/plugin-legacy": "^1.2.0", + "@oclif/core": "^1.26.2", + "@oclif/plugin-legacy": "^1.3.0", "chai": "^4.2.0", "chai-as-promised": "^7.1.1", "lolex": "^3.1.0", "mocha": "^5.2.0", "nock": "9.0.13", "nyc": "^15.1.0", + "oclif": "3.6.4", "sinon": "^6.3.5" }, "files": [ @@ -44,9 +45,9 @@ "repository": "heroku/cli", "scripts": { "postpublish": "rm oclif.manifest.json", - "prepack": "oclif-dev manifest", + "prepack": "oclif manifest", "release": "np", "test": "nyc mocha", - "version": "oclif-dev readme && git add README.md" + "version": "oclif readme && git add README.md" } } diff --git a/packages/addons-v5/test/commands/addons/create.js b/packages/addons-v5/test/commands/addons/create.js index 8b0bde4f94..5808c1d515 100644 --- a/packages/addons-v5/test/commands/addons/create.js +++ b/packages/addons-v5/test/commands/addons/create.js @@ -5,7 +5,7 @@ const cmd = commands.find(c => c.topic === 'addons' && c.command === 'create') const { expect } = require('chai') const lolex = require('lolex') const _ = require('lodash') -const Config = require('@oclif/config') +const { Config } = require('@oclif/core') const sinon = require('sinon') let config diff --git a/packages/apps-v5/package.json b/packages/apps-v5/package.json index 0df846f1b1..e54effbc41 100644 --- a/packages/apps-v5/package.json +++ b/packages/apps-v5/package.json @@ -15,7 +15,8 @@ "repositoryPrefix": "<%- repo %>/blob/v<%- version %>/packages/apps-v5/<%- commandPath %>" }, "dependencies": { - "@heroku-cli/command": "^8.4.1", + "@heroku-cli/command": "^9.0.2", + "@oclif/core": "^1.26.2", "filesize": "^4.0.0", "fs-extra": "^7.0.1", "heroku-cli-util": "^8.0.11", @@ -29,8 +30,7 @@ "urijs": "1.19.11" }, "devDependencies": { - "@heroku-cli/dev-cli": "^1.26.13", - "@oclif/plugin-legacy": "^1.2.0", + "@oclif/plugin-legacy": "^1.3.0", "chai": "^4.2.0", "chai-as-promised": "^7.1.1", "lolex": "^3.1.0", @@ -38,6 +38,7 @@ "mockdate": "^2.0.2", "netrc-parser": "^3.1.6", "nock": "^10.0.6", + "oclif": "3.6.4", "proxyquire": "^2.1.0", "set-tz": "^0.1.0", "std-mocks": "1.0.1", @@ -61,8 +62,8 @@ "repository": "heroku/cli", "scripts": { "postpublish": "rm oclif.manifest.json", - "prepack": "oclif-dev manifest && oclif-dev readme", + "prepack": "oclif manifest", "test": "mocha", - "version": "oclif-dev readme && git add README.md" + "version": "oclif readme && git add README.md" } } diff --git a/packages/apps-v5/test/commands/apps/create.js b/packages/apps-v5/test/commands/apps/create.js index de41702172..ec39fe5091 100644 --- a/packages/apps-v5/test/commands/apps/create.js +++ b/packages/apps-v5/test/commands/apps/create.js @@ -5,7 +5,7 @@ const cli = require('heroku-cli-util') const nock = require('nock') const expect = require('chai').expect const apps = commands.find(c => c.topic === 'apps' && c.command === 'create') -const Config = require('@oclif/config') +const { Config } = require('@oclif/core') let config describe('apps:create', function () { diff --git a/packages/apps-v5/test/commands/config/set.js b/packages/apps-v5/test/commands/config/set.js index dd051347b3..092b13b56b 100644 --- a/packages/apps-v5/test/commands/config/set.js +++ b/packages/apps-v5/test/commands/config/set.js @@ -12,7 +12,7 @@ const assertExit = require('../../assert_exit.js') describe('config:set', () => { beforeEach(async () => { - config = await require('@oclif/config').load() + config = await require('@oclif/core').Config.load() cli.mockConsole() cli.exit.mock() }) diff --git a/packages/apps/.eslintrc b/packages/apps/.eslintrc index 68c6a917b5..ee72301381 100644 --- a/packages/apps/.eslintrc +++ b/packages/apps/.eslintrc @@ -4,5 +4,6 @@ "oclif-typescript" ], "rules": { + "camelcase": "off" } } diff --git a/packages/apps/bin/run b/packages/apps/bin/run index 3c4ae3ac07..a371425871 100755 --- a/packages/apps/bin/run +++ b/packages/apps/bin/run @@ -1,4 +1,5 @@ #!/usr/bin/env node -require('@oclif/command').run() -.catch(require('@oclif/errors/handle')) +const oclif = require('@oclif/core') + +oclif.run().catch(require('@oclif/core/handle')) diff --git a/packages/apps/package.json b/packages/apps/package.json index 280e857dca..fbbff8d4bf 100644 --- a/packages/apps/package.json +++ b/packages/apps/package.json @@ -5,24 +5,18 @@ "bugs": "https://github.com/heroku/heroku-cli-plugin-apps/issues", "dependencies": { "@heroku-cli/color": "^1.1.14", - "@heroku-cli/command": "^8.4.1", + "@heroku-cli/command": "^9.0.2", "@heroku-cli/schema": "^1.0.25", - "@oclif/command": "^1", - "@oclif/config": "^1", - "cli-ux": "^5.3.2", + "@oclif/core": "^1.26.2", "inquirer": "^7.0.1", "shell-escape": "^0.2.0", "tslib": "^1", "urijs": "^1.19.11" }, "devDependencies": { - "@fancy-test/nock": "^0.1.1", - "@heroku-cli/dev-cli": "^1.26.13", - "@oclif/plugin-help": "^2", - "@oclif/test": "^1", + "@oclif/test": "^2.2.20", "@types/chai": "^4", "@types/mocha": "^5", - "@types/node": "^10", "@types/shell-escape": "^0.2.0", "@types/supports-color": "^5.3.0", "@types/urijs": "^1.19.4", @@ -32,12 +26,14 @@ "eslint-config-oclif-typescript": "^0.1.0", "globby": "^10", "mocha": "^5", + "nock": "^13.0.1", "nyc": "^15.1.0", + "oclif": "3.6.4", "ts-node": "^10", - "typescript": "3.7.5" + "typescript": "4.8.4" }, "engines": { - "node": ">=10.0.0" + "node": ">=14" }, "files": [ "/lib", @@ -51,11 +47,14 @@ ], "license": "MIT", "oclif": { - "commands": "./lib/commands", + "additionalHelpFlags": [ + "-h" + ], + "additionalVersionFlags": [ + "-v" + ], "bin": "heroku", - "devPlugins": [ - "@oclif/plugin-help" - ] + "commands": "./lib/commands" }, "repository": "heroku/heroku-cli-plugin-apps", "scripts": { @@ -63,8 +62,8 @@ "lint": "eslint . --ext .ts --config .eslintrc", "pretest": "tsc -p test --noEmit", "posttest": "yarn lint", - "prepack": "rm -rf lib && tsc -b && oclif-dev manifest && oclif-dev readme", + "prepack": "rm -rf lib && tsc -b && oclif manifest", "test": "nyc --extension .ts mocha --forbid-only \"test/**/*.test.ts\"", - "version": "oclif-dev readme && git add README.md" + "version": "oclif readme && git add README.md" } } diff --git a/packages/apps/src/commands/domains/add.ts b/packages/apps/src/commands/domains/add.ts index 109c8acdad..a003a761b7 100644 --- a/packages/apps/src/commands/domains/add.ts +++ b/packages/apps/src/commands/domains/add.ts @@ -1,11 +1,14 @@ import {color} from '@heroku-cli/color' import {Command, flags} from '@heroku-cli/command' import * as Heroku from '@heroku-cli/schema' -import cli from 'cli-ux' +import {CliUx} from '@oclif/core' +import Spinner from '@oclif/core/lib/cli-ux/action/spinner' import {prompt} from 'inquirer' import * as shellescape from 'shell-escape' import waitForDomain from '../../lib/wait-for-domain' +const cli = CliUx.ux + interface DomainCreatePayload { hostname: string; sni_endpoint: string | null; @@ -71,8 +74,9 @@ export default class DomainsAdd extends Command { } async run() { - const {args, flags} = this.parse(DomainsAdd) + const {args, flags} = await this.parse(DomainsAdd) const {hostname} = args + const action = new Spinner() const domainCreatePayload: DomainCreatePayload = { hostname, @@ -81,7 +85,7 @@ export default class DomainsAdd extends Command { let certs: Array = [] - cli.action.start(`Adding ${color.green(domainCreatePayload.hostname)} to ${color.app(flags.app)}`) + action.start(`Adding ${color.green(domainCreatePayload.hostname)} to ${color.app(flags.app)}`) if (flags.cert) { domainCreatePayload.sni_endpoint = flags.cert } else { @@ -91,14 +95,14 @@ export default class DomainsAdd extends Command { } if (certs.length > 1) { - cli.action.stop('resolving SNI endpoint') + action.stop('resolving SNI endpoint') const certSelection = await this.certSelect(certs) if (certSelection) { domainCreatePayload.sni_endpoint = certSelection } - cli.action.start(`Adding ${color.green(domainCreatePayload.hostname)} to ${color.app(flags.app)}`) + action.start(`Adding ${color.green(domainCreatePayload.hostname)} to ${color.app(flags.app)}`) } try { @@ -122,10 +126,10 @@ export default class DomainsAdd extends Command { } } } - } catch (error) { + } catch (error: any) { cli.error(error) } finally { - cli.action.stop() + action.stop() } } } diff --git a/packages/apps/src/commands/domains/clear.ts b/packages/apps/src/commands/domains/clear.ts index d5a04dd953..3cffe9346c 100644 --- a/packages/apps/src/commands/domains/clear.ts +++ b/packages/apps/src/commands/domains/clear.ts @@ -1,7 +1,7 @@ import {color} from '@heroku-cli/color' import {Command, flags} from '@heroku-cli/command' import * as Heroku from '@heroku-cli/schema' -import cli from 'cli-ux' +import Spinner from '@oclif/core/lib/cli-ux/action/spinner' export default class DomainsClear extends Command { static description = 'remove all domains from an app' @@ -15,14 +15,16 @@ export default class DomainsClear extends Command { } async run() { - const {flags} = this.parse(DomainsClear) - cli.action.start(`Removing all domains from ${color.app(flags.app)}`) + const {flags} = await this.parse(DomainsClear) + const action = new Spinner() + + action.start(`Removing all domains from ${color.app(flags.app)}`) let {body: domains} = await this.heroku.get>(`/apps/${flags.app}/domains`) domains = domains.filter((d: Heroku.Domain) => d.kind === 'custom') for (const domain of domains) { // eslint-disable-next-line no-await-in-loop await this.heroku.delete(`/apps/${flags.app}/domains/${domain.hostname}`) } - cli.action.stop() + action.stop() } } diff --git a/packages/apps/src/commands/domains/index.ts b/packages/apps/src/commands/domains/index.ts index 282991f20f..b1e52300eb 100644 --- a/packages/apps/src/commands/domains/index.ts +++ b/packages/apps/src/commands/domains/index.ts @@ -1,8 +1,10 @@ import {Command, flags} from '@heroku-cli/command' import * as Heroku from '@heroku-cli/schema' -import cli from 'cli-ux' +import {CliUx} from '@oclif/core' import * as Uri from 'urijs' +const cli = CliUx.ux + function isApexDomain(hostname: string) { if (hostname.includes('*')) return false const a = new Uri({protocol: 'http', hostname}) @@ -71,7 +73,7 @@ www.example.com CNAME www.example.herokudns.com } async run() { - const {flags} = this.parse(DomainsIndex) + const {flags} = await this.parse(DomainsIndex) const {body: domains} = await this.heroku.get>(`/apps/${flags.app}/domains`) const herokuDomain = domains.find(domain => domain.kind === 'heroku') const customDomains = domains.filter(domain => domain.kind === 'custom') diff --git a/packages/apps/src/commands/domains/info.ts b/packages/apps/src/commands/domains/info.ts index 216fc55f70..f0c33bd479 100644 --- a/packages/apps/src/commands/domains/info.ts +++ b/packages/apps/src/commands/domains/info.ts @@ -1,6 +1,8 @@ import {Command, flags} from '@heroku-cli/command' import * as Heroku from '@heroku-cli/schema' -import cli from 'cli-ux' +import {CliUx} from '@oclif/core' + +const cli = CliUx.ux export default class DomainsInfo extends Command { static description = 'show detailed information for a domain on an app' @@ -18,7 +20,7 @@ export default class DomainsInfo extends Command { static args = [{name: 'hostname', required: true}] async run() { - const {args, flags} = this.parse(DomainsInfo) + const {args, flags} = await this.parse(DomainsInfo) const {body: res} = await this.heroku.get(`/apps/${flags.app}/domains/${args.hostname}`) const domain = { ...res, diff --git a/packages/apps/src/commands/domains/remove.ts b/packages/apps/src/commands/domains/remove.ts index a73828868d..58f973d0d5 100644 --- a/packages/apps/src/commands/domains/remove.ts +++ b/packages/apps/src/commands/domains/remove.ts @@ -1,6 +1,6 @@ import {color} from '@heroku-cli/color' import {Command, flags} from '@heroku-cli/command' -import cli from 'cli-ux' +import Spinner from '@oclif/core/lib/cli-ux/action/spinner' export default class DomainsRemove extends Command { static description = 'remove a domain from an app' @@ -16,9 +16,11 @@ export default class DomainsRemove extends Command { static args = [{name: 'hostname', required: true}] async run() { - const {args, flags} = this.parse(DomainsRemove) - cli.action.start(`Removing ${color.green(args.hostname)} from ${color.app(flags.app)}`) + const {args, flags} = await this.parse(DomainsRemove) + const action = new Spinner() + + action.start(`Removing ${color.green(args.hostname)} from ${color.app(flags.app)}`) await this.heroku.delete(`/apps/${flags.app}/domains/${args.hostname}`) - cli.action.stop() + action.stop() } } diff --git a/packages/apps/src/commands/domains/update.ts b/packages/apps/src/commands/domains/update.ts index 44bb8e0c02..f62fe6af11 100644 --- a/packages/apps/src/commands/domains/update.ts +++ b/packages/apps/src/commands/domains/update.ts @@ -1,6 +1,7 @@ import {color} from '@heroku-cli/color' import {Command, flags} from '@heroku-cli/command' -import cli from 'cli-ux' +import {CliUx} from '@oclif/core' +import Spinner from '@oclif/core/lib/cli-ux/action/spinner' export default class DomainsUpdate extends Command { static description = 'update a domain to use a different SSL certificate on an app' @@ -20,17 +21,19 @@ export default class DomainsUpdate extends Command { static args = [{name: 'hostname'}] async run() { - const {args, flags} = this.parse(DomainsUpdate) + const {args, flags} = await this.parse(DomainsUpdate) const {hostname} = args + const action = new Spinner() + try { - cli.action.start(`Updating ${color.cyan(hostname)} to use ${color.cyan(flags.cert)} certificate`) + action.start(`Updating ${color.cyan(hostname)} to use ${color.cyan(flags.cert)} certificate`) await this.heroku.patch(`/apps/${flags.app}/domains/${hostname}`, { body: {sni_endpoint: flags.cert}, }) - } catch (error) { - cli.error(error) + } catch (error: any) { + CliUx.ux.error(error) } finally { - cli.action.stop() + action.stop() } } } diff --git a/packages/apps/src/commands/domains/wait.ts b/packages/apps/src/commands/domains/wait.ts index f06f492467..7335b8c71d 100644 --- a/packages/apps/src/commands/domains/wait.ts +++ b/packages/apps/src/commands/domains/wait.ts @@ -15,7 +15,7 @@ export default class DomainsWait extends Command { static args = [{name: 'hostname'}] async run() { - const {args, flags} = this.parse(DomainsWait) + const {args, flags} = await this.parse(DomainsWait) let domains if (args.hostname) { diff --git a/packages/apps/src/lib/wait-for-domain.ts b/packages/apps/src/lib/wait-for-domain.ts index 208d301a9f..de35dd2fa8 100644 --- a/packages/apps/src/lib/wait-for-domain.ts +++ b/packages/apps/src/lib/wait-for-domain.ts @@ -1,18 +1,21 @@ import {color} from '@heroku-cli/color' import {APIClient} from '@heroku-cli/command' import * as Heroku from '@heroku-cli/schema' -import cli from 'cli-ux' +import {CliUx} from '@oclif/core' +import Spinner from '@oclif/core/lib/cli-ux/action/spinner' export default async function waitForDomain(app: string, heroku: APIClient, domain: Heroku.Domain) { - cli.action.start(`Waiting for ${color.green(domain.hostname || 'domain')}`) + const action = new Spinner() + + action.start(`Waiting for ${color.green(domain.hostname || 'domain')}`) while (domain.status === 'pending') { // eslint-disable-next-line no-await-in-loop - await cli.wait(5000) + await CliUx.ux.wait(5000) // eslint-disable-next-line no-await-in-loop const {body: updatedDomain} = await heroku.get(`/apps/${app}/domains/${domain.id}`) domain = updatedDomain } - cli.action.stop() + action.stop() if (domain.status === 'succeeded' || domain.status === 'none') return throw new Error(`The domain creation finished with status ${domain.status}`) } diff --git a/packages/apps/test/commands/domains/add.test.ts b/packages/apps/test/commands/domains/add.test.ts index 3311b6ec65..467ceb6fa9 100644 --- a/packages/apps/test/commands/domains/add.test.ts +++ b/packages/apps/test/commands/domains/add.test.ts @@ -1,6 +1,6 @@ import * as inquirer from 'inquirer' -import {expect, test} from '../../test' +import {expect, test} from '@oclif/test' describe('domains:add', () => { const domainsResponse = { diff --git a/packages/apps/test/commands/domains/clear.test.ts b/packages/apps/test/commands/domains/clear.test.ts index 5f01538462..d69ec860d2 100644 --- a/packages/apps/test/commands/domains/clear.test.ts +++ b/packages/apps/test/commands/domains/clear.test.ts @@ -1,4 +1,4 @@ -import {expect, test} from '../../test' +import {expect, test} from '@oclif/test' describe('domains:clear', () => { test diff --git a/packages/apps/test/commands/domains/index.test.ts b/packages/apps/test/commands/domains/index.test.ts index 4c2b0c790b..805318bb86 100644 --- a/packages/apps/test/commands/domains/index.test.ts +++ b/packages/apps/test/commands/domains/index.test.ts @@ -1,4 +1,4 @@ -import {expect, test} from '../../test' +import {expect, test} from '@oclif/test' describe('domains', () => { const herokuOnlyDomainsResponse = [{ @@ -96,7 +96,7 @@ describe('domains', () => { .stdout() .command(['domains', '--app', 'myapp']) .it('does not show the custom domain header if there are no custom domains', ctx => { - expect(ctx.stdout).to.contain('=== myapp Heroku Domain\nmyapp.herokuapp.com') + expect(ctx.stdout).to.contain('=== myapp Heroku Domain\n\nmyapp.herokuapp.com') expect(ctx.stdout).to.contain('myapp.herokuapp.com') expect(ctx.stdout).to.not.contain('=== myapp Custom Domains') }) @@ -109,7 +109,7 @@ describe('domains', () => { .stdout() .command(['domains', '--app', 'myapp']) .it('shows a list of domains and their DNS targets when there are custom domains', ctx => { - expect(ctx.stdout).to.contain('=== myapp Heroku Domain\nmyapp.herokuapp.com') + expect(ctx.stdout).to.contain('=== myapp Heroku Domain\n\nmyapp.herokuapp.com') expect(ctx.stdout).to.contain('myapp.herokuapp.com') expect(ctx.stdout).to.contain('=== myapp Custom Domains') expect(ctx.stdout).to.contain('Domain Name DNS Record Type DNS Target') diff --git a/packages/apps/test/commands/domains/info.test.ts b/packages/apps/test/commands/domains/info.test.ts index 38c31ecbde..a88ac76577 100644 --- a/packages/apps/test/commands/domains/info.test.ts +++ b/packages/apps/test/commands/domains/info.test.ts @@ -1,4 +1,4 @@ -import {expect, test} from '../../test' +import {expect, test} from '@oclif/test' describe('domains:info', () => { const domainInfoResponse = { diff --git a/packages/apps/test/commands/domains/remove.test.ts b/packages/apps/test/commands/domains/remove.test.ts index d9332da729..c01b9009a6 100644 --- a/packages/apps/test/commands/domains/remove.test.ts +++ b/packages/apps/test/commands/domains/remove.test.ts @@ -1,4 +1,4 @@ -import {expect, test} from '../../test' +import {expect, test} from '@oclif/test' describe('domains:remove', () => { test diff --git a/packages/apps/test/commands/domains/update.test.ts b/packages/apps/test/commands/domains/update.test.ts index e1a2943d3a..14b9a2fe08 100644 --- a/packages/apps/test/commands/domains/update.test.ts +++ b/packages/apps/test/commands/domains/update.test.ts @@ -1,4 +1,4 @@ -import {expect, test} from '../../test' +import {expect, test} from '@oclif/test' describe('domains:update', () => { const responseBody = { diff --git a/packages/apps/test/commands/domains/wait.test.ts b/packages/apps/test/commands/domains/wait.test.ts index 4d9592b9ae..2e5cbe7e6b 100644 --- a/packages/apps/test/commands/domains/wait.test.ts +++ b/packages/apps/test/commands/domains/wait.test.ts @@ -1,4 +1,4 @@ -import {expect, test} from '../../test' +import {expect, test} from '@oclif/test' describe('domains:wait', () => { test diff --git a/packages/apps/test/test.ts b/packages/apps/test/test.ts deleted file mode 100644 index 0e5c0d12de..0000000000 --- a/packages/apps/test/test.ts +++ /dev/null @@ -1,6 +0,0 @@ -import Nock from '@fancy-test/nock' -import * as Test from '@oclif/test' -export {expect} from '@oclif/test' - -export const test = Test.test -.register('nock', Nock) diff --git a/packages/apps/tsconfig.json b/packages/apps/tsconfig.json index b4c5d7686b..41f29f4536 100644 --- a/packages/apps/tsconfig.json +++ b/packages/apps/tsconfig.json @@ -5,6 +5,7 @@ "module": "commonjs", "outDir": "lib", "rootDir": "src", + "skipLibCheck": true, "strict": true, "target": "es2017" }, diff --git a/packages/auth/.eslintrc b/packages/auth/.eslintrc index 1177069b62..ee72301381 100644 --- a/packages/auth/.eslintrc +++ b/packages/auth/.eslintrc @@ -3,5 +3,7 @@ "oclif", "oclif-typescript" ], - "rules": {} + "rules": { + "camelcase": "off" + } } diff --git a/packages/auth/bin/run b/packages/auth/bin/run index 3c4ae3ac07..a371425871 100755 --- a/packages/auth/bin/run +++ b/packages/auth/bin/run @@ -1,4 +1,5 @@ #!/usr/bin/env node -require('@oclif/command').run() -.catch(require('@oclif/errors/handle')) +const oclif = require('@oclif/core') + +oclif.run().catch(require('@oclif/core/handle')) diff --git a/packages/auth/package.json b/packages/auth/package.json index e6995fd3be..2f64616142 100644 --- a/packages/auth/package.json +++ b/packages/auth/package.json @@ -6,37 +6,32 @@ "bugs": "https://github.com/heroku/cli/issues", "dependencies": { "@heroku-cli/color": "^1.1.14", - "@heroku-cli/command": "^8.5.0", - "@oclif/command": "^1.5.11", - "@oclif/config": "^1.12.10", - "cli-ux": "^4.9.3", + "@heroku-cli/command": "^9.0.2", + "@oclif/core": "^1.26.2", "date-fns": "^2.0.0-alpha.8" }, "devDependencies": { - "@fancy-test/nock": "^0.1.1", - "@heroku-cli/dev-cli": "^1.26.13", "@heroku-cli/schema": "^1.0.25", - "@oclif/plugin-help": "^2.1.6", - "@oclif/test": "^1.2.4", + "@oclif/test": "^2.2.20", "@types/chai": "^4.1.7", "@types/mocha": "^5.2.6", "@types/nock": "^9.3.1", - "@types/node": "^10.12.24", "@types/supports-color": "^5.3.0", "chai": "^4.2.0", "eslint": "^6.7.2", "eslint-config-oclif": "^3.1.0", "eslint-config-oclif-typescript": "^0.1.0", - "globby": "^9.0.0", + "globby": "^10.0.1", "mocha": "^5.2.0", "nock": "^10.0.6", "nyc": "^15.1.0", + "oclif": "3.6.4", "ts-node": "^10.9.1", "tslib": "^1.9.3", - "typescript": "3.7.5" + "typescript": "4.8.4" }, "engines": { - "node": ">=10.0.0" + "node": ">=14" }, "files": [ "oclif.manifest.json", @@ -48,11 +43,14 @@ ], "license": "MIT", "oclif": { + "additionalHelpFlags": [ + "-h" + ], + "additionalVersionFlags": [ + "-v" + ], "commands": "./lib/commands", "bin": "heroku", - "devPlugins": [ - "@oclif/plugin-help" - ], "repositoryPrefix": "<%- repo %>/blob/v<%- version %>/packages/auth/<%- commandPath %>" }, "repository": "heroku/cli", @@ -61,9 +59,9 @@ "pretest": "tsc -p test --noEmit", "posttest": "yarn lint", "lint": "eslint . --ext .ts --config .eslintrc", - "prepack": "rm -rf lib && tsc && oclif-dev manifest && oclif-dev readme", - "prepare": "rm -rf lib && tsc && oclif-dev manifest && oclif-dev readme", + "prepack": "rm -rf lib && tsc && oclif manifest", + "prepare": "rm -rf lib && tsc && oclif manifest", "test": "nyc mocha --forbid-only \"test/**/*.test.ts\"", - "version": "oclif-dev readme && git add README.md" + "version": "oclif readme && git add README.md" } } diff --git a/packages/auth/src/commands/auth/2fa/disable.ts b/packages/auth/src/commands/auth/2fa/disable.ts index f1a90e02fb..8856bbe4cd 100644 --- a/packages/auth/src/commands/auth/2fa/disable.ts +++ b/packages/auth/src/commands/auth/2fa/disable.ts @@ -1,5 +1,5 @@ import {Command} from '@heroku-cli/command' -import cli from 'cli-ux' +import {CliUx} from '@oclif/core' export default class Auth2faGenerate extends Command { static description = 'disables 2fa on account' @@ -12,7 +12,7 @@ export default class Auth2faGenerate extends Command { ] async run() { - cli.error('this command has been removed, in favor of disabling MFA in your Account Settings in a browser: https://dashboard.heroku.com/account') - cli.exit(1) + CliUx.ux.error('this command has been removed, in favor of disabling MFA in your Account Settings in a browser: https://dashboard.heroku.com/account') + CliUx.ux.exit(1) } } diff --git a/packages/auth/src/commands/auth/login.ts b/packages/auth/src/commands/auth/login.ts index 00d8c45fa7..2359d7a55a 100644 --- a/packages/auth/src/commands/auth/login.ts +++ b/packages/auth/src/commands/auth/login.ts @@ -1,13 +1,14 @@ import color from '@heroku-cli/color' import {Command, flags} from '@heroku-cli/command' import * as Heroku from '@heroku-cli/schema' +import {Interfaces} from '@oclif/core' export default class Login extends Command { static description = 'login with your Heroku credentials' static aliases = ['login'] - static flags = { + static flags: Interfaces.FlagInput = { browser: flags.string({description: 'browser to open SSO with (example: "firefox", "safari")'}), sso: flags.boolean({hidden: true, char: 's', description: 'login for enterprise users under SSO'}), interactive: flags.boolean({char: 'i', description: 'login with username/password'}), diff --git a/packages/auth/src/commands/auth/logout.ts b/packages/auth/src/commands/auth/logout.ts index 8c1f33f862..a6d9bd37f4 100644 --- a/packages/auth/src/commands/auth/logout.ts +++ b/packages/auth/src/commands/auth/logout.ts @@ -1,5 +1,5 @@ import {Command} from '@heroku-cli/command' -import ux from 'cli-ux' +import {CliUx} from '@oclif/core' export default class Logout extends Command { static description = 'clears local login credentials and invalidates API session' @@ -7,7 +7,7 @@ export default class Logout extends Command { static aliases = ['logout'] async run() { - ux.action.start('Logging out') + CliUx.ux.action.start('Logging out') await this.heroku.logout() await this.config.runHook('recache', {type: 'logout'}) } diff --git a/packages/auth/src/commands/auth/token.ts b/packages/auth/src/commands/auth/token.ts index 429c069253..49922b953d 100644 --- a/packages/auth/src/commands/auth/token.ts +++ b/packages/auth/src/commands/auth/token.ts @@ -1,13 +1,14 @@ import color from '@heroku-cli/color' import {Command, flags} from '@heroku-cli/command' import * as Heroku from '@heroku-cli/schema' -import * as formatRelative from 'date-fns/formatRelative' +import {Interfaces} from '@oclif/core' +import formatRelative from 'date-fns/formatRelative' export default class AuthToken extends Command { static description = `outputs current CLI authentication token. By default, the CLI auth token is only valid for 1 year. To generate a long-lived token, use heroku authorizations:create` - static flags = { + static flags: Interfaces.FlagInput = { help: flags.help({char: 'h'}), } @@ -22,7 +23,7 @@ By default, the CLI auth token is only valid for 1 year. To generate a long-live d.setSeconds(d.getSeconds() + token.access_token.expires_in) this.warn(`token will expire ${formatRelative(d, new Date())}\nUse ${color.cmd('heroku authorizations:create')} to generate a long-term token`) } - } catch (error) { + } catch (error: any) { this.warn(error) } this.log(this.heroku.auth) diff --git a/packages/auth/src/commands/auth/whoami.ts b/packages/auth/src/commands/auth/whoami.ts index 831fe5eeb5..1f8bc5162c 100644 --- a/packages/auth/src/commands/auth/whoami.ts +++ b/packages/auth/src/commands/auth/whoami.ts @@ -12,7 +12,7 @@ export default class AuthWhoami extends Command { try { const {body: account} = await this.heroku.get('/account', {retryAuth: false}) this.log(account.email) - } catch (error) { + } catch (error: any) { if (error.statusCode === 401) this.notloggedin() throw error } diff --git a/packages/auth/src/commands/labs/disable.ts b/packages/auth/src/commands/labs/disable.ts index 5aee15548f..30e8e49c69 100644 --- a/packages/auth/src/commands/labs/disable.ts +++ b/packages/auth/src/commands/labs/disable.ts @@ -1,13 +1,13 @@ import color from '@heroku-cli/color' import {Command, flags} from '@heroku-cli/command' import * as Heroku from '@heroku-cli/schema' -import {cli} from 'cli-ux' +import {CliUx, Interfaces} from '@oclif/core' const SecurityExceptionFeatures: any = { 'spaces-strict-tls': { async prompt(out: any, app: string): Promise { out.warn('Insecure Action') - const name = await cli.prompt(`You are enabling an older security protocol, TLS 1.0, which some organizations may not deem secure. + const name = await CliUx.ux.prompt(`You are enabling an older security protocol, TLS 1.0, which some organizations may not deem secure. To proceed, type ${app} or re-run this command with --confirm ${app}`) return name }, @@ -19,14 +19,14 @@ export default class LabsDisable extends Command { static args = [{name: 'feature'}] - static flags = { + static flags: Interfaces.FlagInput = { app: flags.app(), remote: flags.remote(), confirm: flags.string({required: false}), } async run() { - const {args, flags} = this.parse(LabsDisable) + const {args, flags} = await this.parse(LabsDisable) const feature = args.feature let request let target @@ -34,7 +34,7 @@ export default class LabsDisable extends Command { if (SecurityExceptionFeatures[feature]) { if (flags.confirm !== flags.app) { const prompt = SecurityExceptionFeatures[feature].prompt - const confirm = await prompt(cli, flags.app) + const confirm = await prompt(CliUx, flags.app) if (confirm !== flags.app) { this.error('Confirmation name did not match app name. Try again.') } @@ -45,7 +45,7 @@ export default class LabsDisable extends Command { await this.heroku.get(`/account/features/${feature}`) request = this.disableFeature(feature) target = (await this.heroku.get('/account')).body.email - } catch (error) { + } catch (error: any) { if (error.http.statusCode !== 404) throw error // might be an app feature if (!flags.app) throw error @@ -54,9 +54,9 @@ export default class LabsDisable extends Command { target = flags.app } - cli.action.start(`Disabling ${color.green(feature)} for ${color.cyan(target!)}`) + CliUx.ux.action.start(`Disabling ${color.green(feature)} for ${color.cyan(target!)}`) await request - cli.action.stop() + CliUx.ux.action.stop() } disableFeature(feature: string, app?: string): Promise { diff --git a/packages/auth/test/commands/2fa/index.test.ts b/packages/auth/test/commands/2fa/index.test.ts index edda81248e..5458e866a5 100644 --- a/packages/auth/test/commands/2fa/index.test.ts +++ b/packages/auth/test/commands/2fa/index.test.ts @@ -1,4 +1,4 @@ -import {expect, test} from '../../test' +import {expect, test} from '@oclif/test' describe('2fa', () => { test diff --git a/packages/auth/test/commands/auth/token.test.ts b/packages/auth/test/commands/auth/token.test.ts index 99e0546ca7..097d82ecb7 100644 --- a/packages/auth/test/commands/auth/token.test.ts +++ b/packages/auth/test/commands/auth/token.test.ts @@ -1,4 +1,4 @@ -import {expect, test} from '../../test' +import {expect, test} from '@oclif/test' describe('auth:token', () => { test diff --git a/packages/auth/test/commands/auth/whoami.test.ts b/packages/auth/test/commands/auth/whoami.test.ts index b8897647c3..daf3c6e1df 100644 --- a/packages/auth/test/commands/auth/whoami.test.ts +++ b/packages/auth/test/commands/auth/whoami.test.ts @@ -1,4 +1,4 @@ -import {expect, test} from '../../test' +import {expect, test} from '@oclif/test' describe('auth:whoami', () => { test diff --git a/packages/auth/test/commands/labs/disable.test.ts b/packages/auth/test/commands/labs/disable.test.ts index afc31f7911..c10d6d3a91 100644 --- a/packages/auth/test/commands/labs/disable.test.ts +++ b/packages/auth/test/commands/labs/disable.test.ts @@ -1,4 +1,4 @@ -import {expect, test} from '../../test' +import {expect, test} from '@oclif/test' describe('labs:disable', () => { test diff --git a/packages/auth/test/test.ts b/packages/auth/test/test.ts deleted file mode 100644 index 0e5c0d12de..0000000000 --- a/packages/auth/test/test.ts +++ /dev/null @@ -1,6 +0,0 @@ -import Nock from '@fancy-test/nock' -import * as Test from '@oclif/test' -export {expect} from '@oclif/test' - -export const test = Test.test -.register('nock', Nock) diff --git a/packages/auth/tsconfig.json b/packages/auth/tsconfig.json index c6454f7a5f..9dc46276e2 100644 --- a/packages/auth/tsconfig.json +++ b/packages/auth/tsconfig.json @@ -1,6 +1,7 @@ { "compilerOptions": { "declaration": true, + "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "importHelpers": true, "module": "commonjs", @@ -9,6 +10,7 @@ "rootDirs": [ "./src" ], + "skipLibCheck": true, "strict": true, "target": "es2017" }, diff --git a/packages/autocomplete/.eslintrc b/packages/autocomplete/.eslintrc index 7c4a11dc71..2b45bde115 100644 --- a/packages/autocomplete/.eslintrc +++ b/packages/autocomplete/.eslintrc @@ -4,6 +4,7 @@ "oclif-typescript" ], "rules": { - "unicorn/no-abusive-eslint-disable": "off" + "unicorn/no-abusive-eslint-disable": "off", + "camelcase": "off" } } diff --git a/packages/autocomplete/bin/run b/packages/autocomplete/bin/run index 3c4ae3ac07..a371425871 100755 --- a/packages/autocomplete/bin/run +++ b/packages/autocomplete/bin/run @@ -1,4 +1,5 @@ #!/usr/bin/env node -require('@oclif/command').run() -.catch(require('@oclif/errors/handle')) +const oclif = require('@oclif/core') + +oclif.run().catch(require('@oclif/core/handle')) diff --git a/packages/autocomplete/package.json b/packages/autocomplete/package.json index a6215b3fab..858970cdff 100644 --- a/packages/autocomplete/package.json +++ b/packages/autocomplete/package.json @@ -4,27 +4,23 @@ "author": "Philipe Navarro @RasPhilCo", "bugs": "https://github.com/heroku/cli/issues", "dependencies": { - "@heroku-cli/command": "^8.4.1", - "@oclif/command": "^1.5.11", - "@oclif/config": "^1.12.10", + "@heroku-cli/command": "^9.0.2", + "@oclif/core": "^1.26.2", "chalk": "^2.4.2", - "cli-ux": "^4.9.3", "debug": "^4.1.1", "fs-extra": "^7.0.1", "lodash.flatten": "^4.4.0", "tslib": "1.9.3" }, "devDependencies": { - "@fancy-test/nock": "^0.1.1", - "@heroku-cli/dev-cli": "^1.26.13", - "@oclif/plugin-help": "2.1.6", - "@oclif/test": "1.2.4", + "@oclif/test": "2.2.20", "@types/chai": "4.1.7", "@types/fs-extra": "^5.0.5", "@types/lodash.flatten": "^4.4.6", "@types/mocha": "5.2.6", "@types/nock": "^9.3.1", - "@types/node": "10.12.24", + "@typescript-eslint/eslint-plugin": "4.18.0", + "@typescript-eslint/parser": "4.18.0", "chai": "4.2.0", "eslint": "^6.7.2", "eslint-config-oclif": "^3.1.0", @@ -33,11 +29,12 @@ "mocha": "5.2.0", "nock": "^10.0.6", "nyc": "15.1.0", + "oclif": "3.6.4", "ts-node": "10.9.1", - "typescript": "3.7.5" + "typescript": "4.8.4" }, "engines": { - "node": ">=10.0.0" + "node": ">=14" }, "files": [ "/oclif.manifest.json", @@ -51,15 +48,18 @@ ], "license": "MIT", "oclif": { + "additionalHelpFlags": [ + "-h" + ], + "additionalVersionFlags": [ + "-v" + ], "commands": "./lib/commands", "bin": "heroku", "hooks": { "update": "./lib/hooks/recache", "recache": "./lib/hooks/recache" }, - "devPlugins": [ - "@oclif/plugin-help" - ], "repositoryPrefix": "<%- repo %>/blob/v<%- version %>/packages/autocomplete/<%- commandPath %>" }, "repository": "heroku/cli", @@ -68,7 +68,8 @@ "pretest": "tsc -p test --noEmit", "posttest": "yarn lint", "lint": "eslint . --ext .ts --config .eslintrc", - "prepack": "rm -rf lib && tsc && oclif-dev manifest", - "test": "nyc mocha --forbid-only \"test/**/*.test.ts\"" + "prepack": "rm -rf lib && tsc && oclif manifest", + "test": "nyc mocha --forbid-only \"test/**/*.test.ts\"", + "version": "oclif readme && git add README.md" } } diff --git a/packages/autocomplete/src/base.ts b/packages/autocomplete/src/base.ts index 7b6a794e5c..acf5d13c8f 100644 --- a/packages/autocomplete/src/base.ts +++ b/packages/autocomplete/src/base.ts @@ -1,8 +1,9 @@ -import Command, {flags} from '@heroku-cli/command' +import Command from '@heroku-cli/command' import * as fs from 'fs-extra' import * as path from 'path' import {CompletionLookup} from './completions' +import {Interfaces} from '@oclif/core' export abstract class AutocompleteBase extends Command { public errorIfWindows() { @@ -42,7 +43,7 @@ export abstract class AutocompleteBase extends Command { fs.write(fd, entry) } - protected findCompletion(cmdId: string, name: string, description = ''): flags.ICompletion | undefined { + protected findCompletion(cmdId: string, name: string, description = ''): Interfaces.Completion | undefined { return new CompletionLookup(cmdId, name, description).run() } } diff --git a/packages/autocomplete/src/commands/autocomplete/create.ts b/packages/autocomplete/src/commands/autocomplete/create.ts index de916ddcbc..233e6e8278 100644 --- a/packages/autocomplete/src/commands/autocomplete/create.ts +++ b/packages/autocomplete/src/commands/autocomplete/create.ts @@ -1,4 +1,4 @@ -import {Command} from '@oclif/config' +import {Interfaces} from '@oclif/core' import * as fs from 'fs-extra' import * as path from 'path' @@ -11,7 +11,7 @@ export default class Create extends AutocompleteBase { static description = 'create autocomplete setup scripts and completion functions' - private _commands?: Command[] + private _commands?: Interfaces.Command[] async run() { this.errorIfWindows() @@ -59,18 +59,18 @@ export default class Create extends AutocompleteBase { return process.env.HEROKU_AC_ZSH_SKIP_ELLIPSIS === '1' } - private get commands(): Command[] { + private get commands(): Interfaces.Command[] { if (this._commands) return this._commands const plugins = this.config.plugins - const commands: Command[] = [] + const commands: Interfaces.Command[] = [] plugins.forEach(p => { p.commands.forEach(c => { if (c.hidden) return try { commands.push(c) - } catch (error) { + } catch (error: any) { debug(`Error creating completions for command ${c.id}`) debug(error.message) this.writeLogFile(error.message) @@ -87,7 +87,7 @@ export default class Create extends AutocompleteBase { try { const publicFlags = this.genCmdPublicFlags(c).trim() return `${c.id} ${publicFlags}` - } catch (error) { + } catch (error: any) { debug(`Error creating bash completion for command ${c.id}, moving on...`) debug(error.message) this.writeLogFile(error.message) @@ -106,7 +106,7 @@ export default class Create extends AutocompleteBase { const cmdsWithDescriptions = this.commands.map(c => { try { return this.genCmdWithDescription(c) - } catch (error) { + } catch (error: any) { debug(`Error creating zsh autocomplete for command ${c.id}, moving on...`) debug(error.message) this.writeLogFile(error.message) @@ -121,7 +121,7 @@ export default class Create extends AutocompleteBase { return this.commands.map(c => { try { return this.genZshCmdFlagsSetter(c) - } catch (error) { + } catch (error: any) { debug(`Error creating zsh autocomplete for command ${c.id}, moving on...`) debug(error.message) this.writeLogFile(error.message) @@ -130,7 +130,7 @@ export default class Create extends AutocompleteBase { }).join('\n') } - private genCmdPublicFlags(Command: Command): string { + private genCmdPublicFlags(Command: Interfaces.Command): string { const Flags = Command.flags || {} return Object.keys(Flags) .filter(flag => !Flags[flag].hidden) @@ -138,7 +138,7 @@ export default class Create extends AutocompleteBase { .join(' ') } - private genCmdWithDescription(Command: Command): string { + private genCmdWithDescription(Command: Interfaces.Command): string { let description = '' if (Command.description) { const text = Command.description.split('\n')[0] @@ -147,7 +147,7 @@ export default class Create extends AutocompleteBase { return `"${Command.id.replace(/:/g, '\\:')}"${description}` } - private genZshCmdFlagsSetter(Command: Command): string { + private genZshCmdFlagsSetter(Command: Interfaces.Command): string { const id = Command.id const flagscompletions = Object.keys(Command.flags || {}) .filter(flag => Command.flags && !Command.flags[flag].hidden) diff --git a/packages/autocomplete/src/commands/autocomplete/doctor.ts b/packages/autocomplete/src/commands/autocomplete/doctor.ts index 1e0ca48615..83de328746 100644 --- a/packages/autocomplete/src/commands/autocomplete/doctor.ts +++ b/packages/autocomplete/src/commands/autocomplete/doctor.ts @@ -1,5 +1,5 @@ import {flags} from '@heroku-cli/command' -import {ux} from 'cli-ux' +import {CliUx, Interfaces} from '@oclif/core' import * as fs from 'fs-extra' import * as path from 'path' @@ -14,13 +14,14 @@ export default class Doctor extends AutocompleteBase { {name: 'shell', description: 'shell type', required: false}, ] - static flags = { + static flags: Interfaces.FlagInput = { verbose: flags.boolean({description: 'list completable commands'}), } async run() { - const {args, flags} = this.parse(Doctor) + const {args, flags} = await this.parse(Doctor) const shell = args.shell || this.config.shell + const printLine: typeof this.log = (...args) => this.log(...args) this.errorIfNotSupportedShell(shell) const data = [] @@ -62,13 +63,10 @@ export default class Doctor extends AutocompleteBase { data.push({name: 'apps completion cache', value: appsCacheValue}) - ux.table(data, { - printHeader: undefined, - columns: [ - {key: 'name'}, - {key: 'value'}, - ], - }) + CliUx.ux.table(data, { + name: {}, + value: {}, + }, {'no-header': true, printLine}) if (flags.verbose) this.printList() } diff --git a/packages/autocomplete/src/commands/autocomplete/index.ts b/packages/autocomplete/src/commands/autocomplete/index.ts index 6afbfd2e4c..19298e027f 100644 --- a/packages/autocomplete/src/commands/autocomplete/index.ts +++ b/packages/autocomplete/src/commands/autocomplete/index.ts @@ -1,7 +1,7 @@ import {flags} from '@heroku-cli/command' import {AppCompletion, PipelineCompletion, SpaceCompletion, TeamCompletion} from '@heroku-cli/command/lib/completions' import chalk from 'chalk' -import {cli} from 'cli-ux' +import {Interfaces, CliUx} from '@oclif/core' import * as path from 'path' import {AutocompleteBase} from '../../base' @@ -14,7 +14,7 @@ export default class Index extends AutocompleteBase { static args = [{name: 'shell', description: 'shell type', required: false}] - static flags = { + static flags: Interfaces.FlagInput = { 'refresh-cache': flags.boolean({description: 'refresh cache only (ignores displaying instructions)', char: 'r'}), } @@ -26,17 +26,17 @@ export default class Index extends AutocompleteBase { ] async run() { - const {args, flags} = this.parse(Index) + const {args, flags} = await this.parse(Index) const shell = args.shell || this.config.shell this.errorIfNotSupportedShell(shell) - cli.action.start(`${chalk.bold('Building the autocomplete cache')}`) + CliUx.ux.action.start(`${chalk.bold('Building the autocomplete cache')}`) await Create.run([], this.config) await this.updateCache(AppCompletion, 'app') await this.updateCache(PipelineCompletion, 'pipeline') await this.updateCache(SpaceCompletion, 'space') await this.updateCache(TeamCompletion, 'team') - cli.action.stop() + CliUx.ux.action.stop() if (!flags['refresh-cache']) { const bin = this.config.bin diff --git a/packages/autocomplete/src/commands/autocomplete/options.ts b/packages/autocomplete/src/commands/autocomplete/options.ts index 142659a962..f3f57a2fcd 100644 --- a/packages/autocomplete/src/commands/autocomplete/options.ts +++ b/packages/autocomplete/src/commands/autocomplete/options.ts @@ -1,5 +1,5 @@ import {flags} from '@heroku-cli/command' -import {Command} from '@oclif/config' +import {Interfaces} from '@oclif/core' import * as path from 'path' import {AutocompleteBase} from '../../base' @@ -8,7 +8,7 @@ import {fetchCache} from '../../cache' export default class Options extends AutocompleteBase { static hidden = true - static description = 'display arg or flag completion options (used internally by completion fuctions)' + static description = 'display arg or flag completion options (used internally by completion functions)' static flags = { app: flags.app({required: false, hidden: true}), @@ -40,7 +40,7 @@ export default class Options extends AutocompleteBase { const completion = this.determineCompletion(commandStateVars) const options = await this.fetchOptions(completion) if (options) this.log(options) - } catch (error) { + } catch (error: any) { // write to ac log this.writeLogFile(error.message) } @@ -54,10 +54,10 @@ export default class Options extends AutocompleteBase { const C = this.config.findCommand(id) let Klass if (C) { - Klass = C.load() + Klass = await C.load() // process Command state from command line data const slicedArgv = commandLineToComplete.slice(2) - const [argsIndex, curPositionIsFlag, curPositionIsFlagValue] = this.determineCmdState(slicedArgv, (Klass as Command)) + const [argsIndex, curPositionIsFlag, curPositionIsFlagValue] = this.determineCmdState(slicedArgv, Klass) return {id, Klass, argsIndex, curPositionIsFlag, curPositionIsFlagValue, slicedArgv} } this.throwError(`Command ${id} not found`) @@ -103,12 +103,14 @@ export default class Options extends AutocompleteBase { private async fetchOptions(cache: any) { const {cacheCompletion, cacheKey} = cache + const flags = await this.parsedFlagsWithEnvVars() + // build/retrieve & return options cache if (cacheCompletion && cacheCompletion.options) { const ctx = { args: this.parsedArgs, // special case for app & team env vars - flags: this.parsedFlagsWithEnvVars, + flags, argv: this.argv, config: this.config, } @@ -127,8 +129,8 @@ export default class Options extends AutocompleteBase { } } - private get parsedFlagsWithEnvVars() { - const {flags} = this.parse(Options) + private async parsedFlagsWithEnvVars() { + const {flags} = await this.parse(Options) return { app: process.env.HEROKU_APP || flags.app, team: process.env.HEROKU_TEAM || process.env.HEROKU_ORG, @@ -140,7 +142,7 @@ export default class Options extends AutocompleteBase { throw new Error(msg) } - private findFlagFromWildArg(wild: string, Klass: Command): { flag: any; name: any } { + private findFlagFromWildArg(wild: string, Klass: Interfaces.Command.Class): { flag: any; name: any } { let name = wild.replace(/^-+/, '') name = name.replace(/[=](.+)?$/, '') @@ -157,7 +159,7 @@ export default class Options extends AutocompleteBase { return unknown } - private determineCmdState(argv: string[], Klass: Command): [number, boolean, boolean] { + private determineCmdState(argv: string[], Klass: Interfaces.Command.Class): [number, boolean, boolean] { const Args = Klass.args || [] let needFlagValueSatisfied = false let argIsFlag = false diff --git a/packages/autocomplete/src/commands/autocomplete/script.ts b/packages/autocomplete/src/commands/autocomplete/script.ts index 6222675a81..e0ce042366 100644 --- a/packages/autocomplete/src/commands/autocomplete/script.ts +++ b/packages/autocomplete/src/commands/autocomplete/script.ts @@ -10,7 +10,7 @@ export default class Script extends AutocompleteBase { static args = [{name: 'shell', description: 'shell type', required: true}] async run() { - const {args} = this.parse(Script) + const {args} = await this.parse(Script) const shell = args.shell || this.config.shell this.errorIfNotSupportedShell(shell) diff --git a/packages/autocomplete/src/completions.ts b/packages/autocomplete/src/completions.ts index fdec2fc1f9..0ff0b5c8df 100644 --- a/packages/autocomplete/src/completions.ts +++ b/packages/autocomplete/src/completions.ts @@ -1,20 +1,20 @@ -import {APIClient, flags} from '@heroku-cli/command' +import {APIClient} from '@heroku-cli/command' import {deps} from '@heroku-cli/command/lib/deps' import {configRemote, getGitRemotes} from '@heroku-cli/command/lib/git' -import * as Config from '@oclif/config' +import {Interfaces} from '@oclif/core' import * as path from 'path' import flatten = require('lodash.flatten') export const oneDay = 60 * 60 * 24 -export const herokuGet = async (resource: string, ctx: { config: Config.IConfig }): Promise => { +export const herokuGet = async (resource: string, ctx: Interfaces.CompletionContext): Promise => { const heroku = new APIClient(ctx.config) let {body} = await heroku.get(`/${resource}`, {retryAuth: false}) if (typeof body === 'string') body = JSON.parse(body) return (body as any[]).map((a: any) => a.name).sort() } -export const AppCompletion: flags.ICompletion = { +export const AppCompletion: Interfaces.Completion = { cacheDuration: oneDay, options: async ctx => { const teams = await herokuGet('teams', ctx) @@ -26,7 +26,7 @@ export const AppCompletion: flags.ICompletion = { }, } -export const AppAddonCompletion: flags.ICompletion = { +export const AppAddonCompletion: Interfaces.Completion = { cacheDuration: oneDay, cacheKey: async ctx => { return ctx.flags && ctx.flags.app ? `${ctx.flags.app}_addons` : '' @@ -37,7 +37,7 @@ export const AppAddonCompletion: flags.ICompletion = { }, } -export const AppDynoCompletion: flags.ICompletion = { +export const AppDynoCompletion: Interfaces.Completion = { cacheDuration: oneDay, cacheKey: async ctx => { return ctx.flags && ctx.flags.app ? `${ctx.flags.app}_dynos` : '' @@ -48,7 +48,7 @@ export const AppDynoCompletion: flags.ICompletion = { }, } -export const BuildpackCompletion: flags.ICompletion = { +export const BuildpackCompletion: Interfaces.Completion = { skipCache: true, options: async () => { @@ -66,7 +66,7 @@ export const BuildpackCompletion: flags.ICompletion = { }, } -const ConfigCompletion: flags.ICompletion = { +const ConfigCompletion: Interfaces.Completion = { cacheDuration: 60 * 60 * 24 * 7, cacheKey: async (ctx: any) => { return ctx.flags && ctx.flags.app ? `${ctx.flags.app}_config_vars` : '' @@ -74,14 +74,14 @@ const ConfigCompletion: flags.ICompletion = { options: async (ctx: any) => { const heroku = new APIClient(ctx.config) if (ctx.flags && ctx.flags.app) { - const {body: configs} = await heroku.get(`/apps/${ctx.flags.app}/config-vars`, {retryAuth: false}) + const {body: configs} = await heroku.get<{body: Record}>(`/apps/${ctx.flags.app}/config-vars`, {retryAuth: false}) return Object.keys(configs) } return [] }, } -const ConfigSetCompletion: flags.ICompletion = { +const ConfigSetCompletion: Interfaces.Completion = { cacheDuration: 60 * 60 * 24 * 7, cacheKey: async (ctx: any) => { return ctx.flags && ctx.flags.app ? `${ctx.flags.app}_config_set_vars` : '' @@ -89,14 +89,14 @@ const ConfigSetCompletion: flags.ICompletion = { options: async (ctx: any) => { const heroku = new APIClient(ctx.config) if (ctx.flags && ctx.flags.app) { - const {body: configs} = await heroku.get(`/apps/${ctx.flags.app}/config-vars`, {retryAuth: false}) + const {body: configs} = await heroku.get<{body: Record}>(`/apps/${ctx.flags.app}/config-vars`, {retryAuth: false}) return Object.keys(configs).map(k => `${k}=`) } return [] }, } -export const DynoSizeCompletion: flags.ICompletion = { +export const DynoSizeCompletion: Interfaces.Completion = { cacheDuration: oneDay * 90, options: async ctx => { let sizes = await herokuGet('dyno-sizes', ctx) @@ -105,7 +105,7 @@ export const DynoSizeCompletion: flags.ICompletion = { }, } -export const FileCompletion: flags.ICompletion = { +export const FileCompletion: Interfaces.Completion = { skipCache: true, options: async () => { @@ -114,7 +114,7 @@ export const FileCompletion: flags.ICompletion = { }, } -export const PipelineCompletion: flags.ICompletion = { +export const PipelineCompletion: Interfaces.Completion = { cacheDuration: oneDay, options: async ctx => { const pipelines = await herokuGet('pipelines', ctx) @@ -122,7 +122,7 @@ export const PipelineCompletion: flags.ICompletion = { }, } -export const ProcessTypeCompletion: flags.ICompletion = { +export const ProcessTypeCompletion: Interfaces.Completion = { skipCache: true, options: async () => { @@ -139,14 +139,14 @@ export const ProcessTypeCompletion: flags.ICompletion = { return m ? m[0] : false }) .filter(t => t) as string[] - } catch (error) { + } catch (error: any) { if (error.code !== 'ENOENT') throw error } return types }, } -export const RegionCompletion: flags.ICompletion = { +export const RegionCompletion: Interfaces.Completion = { cacheDuration: oneDay * 7, options: async ctx => { const regions = await herokuGet('regions', ctx) @@ -154,7 +154,7 @@ export const RegionCompletion: flags.ICompletion = { }, } -export const RemoteCompletion: flags.ICompletion = { +export const RemoteCompletion: Interfaces.Completion = { skipCache: true, options: async () => { @@ -163,7 +163,7 @@ export const RemoteCompletion: flags.ICompletion = { }, } -export const RoleCompletion: flags.ICompletion = { +export const RoleCompletion: Interfaces.Completion = { skipCache: true, options: async () => { @@ -171,7 +171,7 @@ export const RoleCompletion: flags.ICompletion = { }, } -export const ScopeCompletion: flags.ICompletion = { +export const ScopeCompletion: Interfaces.Completion = { skipCache: true, options: async () => { @@ -179,7 +179,7 @@ export const ScopeCompletion: flags.ICompletion = { }, } -export const SpaceCompletion: flags.ICompletion = { +export const SpaceCompletion: Interfaces.Completion = { cacheDuration: oneDay, options: async ctx => { const spaces = await herokuGet('spaces', ctx) @@ -187,7 +187,7 @@ export const SpaceCompletion: flags.ICompletion = { }, } -export const StackCompletion: flags.ICompletion = { +export const StackCompletion: Interfaces.Completion = { cacheDuration: oneDay, options: async ctx => { const stacks = await herokuGet('stacks', ctx) @@ -195,7 +195,7 @@ export const StackCompletion: flags.ICompletion = { }, } -export const StageCompletion: flags.ICompletion = { +export const StageCompletion: Interfaces.Completion = { skipCache: true, options: async () => { @@ -203,7 +203,7 @@ export const StageCompletion: flags.ICompletion = { }, } -export const TeamCompletion: flags.ICompletion = { +export const TeamCompletion: Interfaces.Completion = { cacheDuration: oneDay, options: async ctx => { const teams = await herokuGet('teams', ctx) @@ -211,7 +211,7 @@ export const TeamCompletion: flags.ICompletion = { }, } -export const CompletionMapping: { [key: string]: flags.ICompletion } = { +export const CompletionMapping: { [key: string]: Interfaces.Completion } = { app: AppCompletion, addon: AppAddonCompletion, dyno: AppDynoCompletion, @@ -257,7 +257,7 @@ export class CompletionLookup { constructor(private readonly cmdId: string, private readonly name: string, private readonly description?: string) { } - run(): flags.ICompletion | undefined { + run(): Interfaces.Completion | undefined { if (this.blocklisted()) return return CompletionMapping[this.key] } diff --git a/packages/autocomplete/src/hooks/recache.ts b/packages/autocomplete/src/hooks/recache.ts index 35a4b67541..d77d0cc0f7 100644 --- a/packages/autocomplete/src/hooks/recache.ts +++ b/packages/autocomplete/src/hooks/recache.ts @@ -1,14 +1,13 @@ import {APIClient} from '@heroku-cli/command' import {AppCompletion, PipelineCompletion, SpaceCompletion, TeamCompletion} from '@heroku-cli/command/lib/completions' -import {Hook} from '@oclif/config' -import cli from 'cli-ux' +import {Interfaces, CliUx} from '@oclif/core' import * as fs from 'fs-extra' import * as path from 'path' import {updateCache} from '../cache' import acCreate from '../commands/autocomplete/create' -export const completions: Hook = async function ({type, app}: {type?: 'app' | 'addon' | 'config' | 'login' | 'logout'; app?: string}) { +export const completions: Interfaces.Hook<'app' | 'addon' | 'config' | 'login' | 'logout'> = async function ({type, app}) { // autocomplete is now in core, skip windows if (this.config.windows) return const logInOut = type === 'login' || type === 'logout' @@ -32,12 +31,12 @@ export const completions: Hook = async function ({type, app}: {type?: 'app' const heroku = new APIClient(this.config) if (!heroku.auth) return await heroku.get('/account', {retryAuth: false}) - } catch (error) { + } catch (error: any) { this.debug(error.message) return } - cli.action.start('Updating completions') + CliUx.ux.action.start('Updating completions') await rm() await acCreate.run([], this.config) @@ -46,8 +45,8 @@ export const completions: Hook = async function ({type, app}: {type?: 'app' await update(PipelineCompletion, 'pipeline') await update(SpaceCompletion, 'space') await update(TeamCompletion, 'team') - } catch (error) { + } catch (error: any) { this.debug(error.message) } - cli.action.stop() + CliUx.ux.action.stop() } diff --git a/packages/autocomplete/test/base.test.ts b/packages/autocomplete/test/base.test.ts index 561012f458..78ba5250fa 100644 --- a/packages/autocomplete/test/base.test.ts +++ b/packages/autocomplete/test/base.test.ts @@ -1,5 +1,5 @@ import {flags} from '@heroku-cli/command' -import {Config} from '@oclif/config' +import {Config} from '@oclif/core' import {expect} from 'chai' import * as path from 'path' @@ -34,7 +34,7 @@ runtest('AutocompleteBase', () => { it('#errorIfWindows', async () => { try { new AutocompleteTest([], config).errorIfWindows() - } catch (error) { + } catch (error: any) { expect(error.message).to.eq('Autocomplete is not currently supported in Windows') } }) diff --git a/packages/autocomplete/test/commands/autocomplete/create.test.ts b/packages/autocomplete/test/commands/autocomplete/create.test.ts index 1c1ea6c228..5232b42944 100644 --- a/packages/autocomplete/test/commands/autocomplete/create.test.ts +++ b/packages/autocomplete/test/commands/autocomplete/create.test.ts @@ -1,5 +1,5 @@ -import {Config, Plugin} from '@oclif/config' -import {loadJSON} from '@oclif/config/lib/util' +import {Config, Plugin} from '@oclif/core' +import {loadJSON} from '@oclif/core/lib/config/util' import {expect} from 'chai' import * as path from 'path' @@ -38,7 +38,10 @@ runtest('Create', () => { // eslint-disable-next-line require-atomic-updates plugin.manifest = await loadJSON(path.resolve(__dirname, '../../test.oclif.manifest.json')) // eslint-disable-next-line require-atomic-updates - plugin.commands = Object.entries(plugin.manifest.commands).map(([id, c]) => ({...c as object, load: () => plugin.findCommand(id, {must: true})})) + plugin.commands = Object.entries(plugin.manifest.commands).map(([id, c]) => ({ + ...c as Record, + load: () => plugin.findCommand(id, {must: true})} + )) Klass = plugin.commands[1] }) diff --git a/packages/autocomplete/test/commands/autocomplete/options.test.ts b/packages/autocomplete/test/commands/autocomplete/options.test.ts index 165272eb72..d6ce140f59 100644 --- a/packages/autocomplete/test/commands/autocomplete/options.test.ts +++ b/packages/autocomplete/test/commands/autocomplete/options.test.ts @@ -1,5 +1,5 @@ import {Command, flags} from '@heroku-cli/command' -import {Config} from '@oclif/config' +import {Config} from '@oclif/core' import {expect} from 'chai' import * as path from 'path' diff --git a/packages/autocomplete/tsconfig.json b/packages/autocomplete/tsconfig.json index c6454f7a5f..7069ac7c9c 100644 --- a/packages/autocomplete/tsconfig.json +++ b/packages/autocomplete/tsconfig.json @@ -9,6 +9,7 @@ "rootDirs": [ "./src" ], + "skipLibCheck": true, "strict": true, "target": "es2017" }, diff --git a/packages/buildpacks/.eslintrc b/packages/buildpacks/.eslintrc index 7c4a11dc71..2b45bde115 100644 --- a/packages/buildpacks/.eslintrc +++ b/packages/buildpacks/.eslintrc @@ -4,6 +4,7 @@ "oclif-typescript" ], "rules": { - "unicorn/no-abusive-eslint-disable": "off" + "unicorn/no-abusive-eslint-disable": "off", + "camelcase": "off" } } diff --git a/packages/buildpacks/bin/run b/packages/buildpacks/bin/run index 3c4ae3ac07..a371425871 100755 --- a/packages/buildpacks/bin/run +++ b/packages/buildpacks/bin/run @@ -1,4 +1,5 @@ #!/usr/bin/env node -require('@oclif/command').run() -.catch(require('@oclif/errors/handle')) +const oclif = require('@oclif/core') + +oclif.run().catch(require('@oclif/core/handle')) diff --git a/packages/buildpacks/package.json b/packages/buildpacks/package.json index 2241bcd5f8..5e4be2f7a4 100644 --- a/packages/buildpacks/package.json +++ b/packages/buildpacks/package.json @@ -5,11 +5,9 @@ "bugs": "https://github.com/heroku/cli/issues", "dependencies": { "@heroku-cli/color": "^1.1.14", - "@heroku-cli/command": "^8.4.1", + "@heroku-cli/command": "^9.0.2", "@heroku/buildpack-registry": "^1.0.1", - "@oclif/config": "^1.12.10", - "@oclif/plugin-legacy": "^1.2.0", - "cli-ux": "^4.9.3", + "@oclif/core": "^1.21.0", "heroku-cli-util": "^8.0.11", "http-call": "^5.2.3", "lodash": "^4.17.11", @@ -17,16 +15,12 @@ "valid-url": "^1.0.9" }, "devDependencies": { - "@fancy-test/nock": "^0.1.1", - "@heroku-cli/dev-cli": "^1.26.13", - "@oclif/plugin-help": "^2.1.6", - "@oclif/test": "^1.2.4", + "@oclif/test": "^2.2.20", "@types/ansi-styles": "^3.2.1", "@types/chai": "^4.1.7", "@types/lodash": "^4.14.123", "@types/mocha": "^5.2.6", "@types/nock": "^9.3.1", - "@types/node": "^10.12.24", "@types/node-fetch": "^2.1.6", "@types/supports-color": "^5.3.0", "chai": "^4.2.0", @@ -37,13 +31,14 @@ "mocha": "^5", "nock": "^10.0.6", "nyc": "^15.1.0", + "oclif": "3.6.4", "tmp": "^0.0.33", "ts-node": "^10.9.1", "tslib": "^1", - "typescript": "3.7.5" + "typescript": "4.8.4" }, "engines": { - "node": ">=10.0.0" + "node": ">=14" }, "files": [ "/lib", @@ -57,22 +52,25 @@ ], "license": "MIT", "oclif": { + "additionalHelpFlags": [ + "-h" + ], + "additionalVersionFlags": [ + "-v" + ], "commands": "./lib/commands", "bin": "heroku", - "devPlugins": [ - "@oclif/plugin-help" - ], "repositoryPrefix": "<%- repo %>/blob/v<%- version %>/packages/buildpacks/<%- commandPath %>" }, "repository": "heroku/cli", "scripts": { "lint": "eslint . --ext .ts --config .eslintrc", "postpack": "rm -f oclif.manifest.json npm-shrinkwrap.json", - "prepack": "rm -rf lib && tsc && oclif-dev manifest && oclif-dev readme", + "prepack": "rm -rf lib && tsc && oclif manifest", "prepare": "rm -rf lib && tsc", "pretest": "tsc -p test --noEmit", "test": "nyc mocha --forbid-only \"test/**/*.test.ts\"", "posttest": "yarn lint", - "version": "oclif-dev readme && git add README.md" + "version": "oclif readme && git add README.md" } } diff --git a/packages/buildpacks/src/buildpacks.ts b/packages/buildpacks/src/buildpacks.ts index 8ea93bc26a..d9230caf85 100644 --- a/packages/buildpacks/src/buildpacks.ts +++ b/packages/buildpacks/src/buildpacks.ts @@ -1,7 +1,7 @@ import color from '@heroku-cli/color' import {APIClient} from '@heroku-cli/command' import {BuildpackRegistry} from '@heroku/buildpack-registry' -import {cli} from 'cli-ux' +import {CliUx} from '@oclif/core' import {findIndex as lodashFindIndex} from 'lodash' import {Result} from 'true-myth' @@ -42,10 +42,10 @@ export class BuildpackCommand { display(buildpacks: BuildpackResponse[], indent: string) { if (buildpacks.length === 1) { - cli.log(this.registryUrlToName(buildpacks[0].buildpack.url, true)) + CliUx.ux.log(this.registryUrlToName(buildpacks[0].buildpack.url, true)) } else { buildpacks.forEach((b, i) => { - cli.log(`${indent}${i + 1}. ${this.registryUrlToName(b.buildpack.url, true)}`) + CliUx.ux.log(`${indent}${i + 1}. ${this.registryUrlToName(b.buildpack.url, true)}`) }) } } @@ -59,7 +59,7 @@ export class BuildpackCommand { // eslint-disable-next-line @typescript-eslint/no-empty-function Ok: _ => {}, Err: err => { - cli.error(`Could not find the buildpack: ${buildpack}. ${err}`, {exit: 1}) + CliUx.ux.error(`Could not find the buildpack: ${buildpack}. ${err}`, {exit: 1}) }, }, BuildpackRegistry.isValidBuildpackSlug(buildpack)) @@ -67,13 +67,13 @@ export class BuildpackCommand { const response = await this.registry.buildpackExists(buildpack) const body = await response.json() return body.blob_url - } catch (error) { + } catch (error: any) { if (error.statusCode === 404) { - cli.error(`${buildpack} is not in the buildpack registry.`, {exit: 1}) + CliUx.ux.error(`${buildpack} is not in the buildpack registry.`, {exit: 1}) } else if (error.statusCode) { - cli.error(`${error.statusCode}: ${error.message}`, {exit: 1}) + CliUx.ux.error(`${error.statusCode}: ${error.message}`, {exit: 1}) } else { - cli.error(error.message, {exit: 1}) + CliUx.ux.error(error.message, {exit: 1}) } } @@ -89,7 +89,7 @@ export class BuildpackCommand { async validateUrlNotSet(buildpacks: BuildpackResponse[], buildpack: string) { if (await this.findUrl(buildpacks, buildpack) !== -1) { - cli.error(`The buildpack ${buildpack} is already set on your app.`, {exit: 1}) + CliUx.ux.error(`The buildpack ${buildpack} is already set on your app.`, {exit: 1}) } } @@ -128,12 +128,12 @@ export class BuildpackCommand { displayUpdate(app: string, remote: string, buildpacks: BuildpackResponse[], action: 'added' | 'set' | 'removed') { if (buildpacks.length === 1) { - cli.log(`Buildpack ${action}. Next release on ${app} will use ${this.registryUrlToName(buildpacks[0].buildpack.url)}.`) - cli.log(`Run ${color.magenta(push(remote))} to create a new release using this buildpack.`) + CliUx.ux.log(`Buildpack ${action}. Next release on ${app} will use ${this.registryUrlToName(buildpacks[0].buildpack.url)}.`) + CliUx.ux.log(`Run ${color.magenta(push(remote))} to create a new release using this buildpack.`) } else { - cli.log(`Buildpack ${action}. Next release on ${app} will use:`) + CliUx.ux.log(`Buildpack ${action}. Next release on ${app} will use:`) this.display(buildpacks, ' ') - cli.log(`Run ${color.magenta(push(remote))} to create a new release using these buildpacks.`) + CliUx.ux.log(`Run ${color.magenta(push(remote))} to create a new release using these buildpacks.`) } } @@ -161,29 +161,29 @@ export class BuildpackCommand { const configVars: any = await this.heroku.get(`/apps/${app}/config-vars`) const message = `Buildpack${command === 'clear' ? 's' : ''} ${action}.` if (configVars.body.BUILDPACK_URL) { - cli.log(message) - cli.warn('The BUILDPACK_URL config var is still set and will be used for the next release') + CliUx.ux.log(message) + CliUx.ux.warn('The BUILDPACK_URL config var is still set and will be used for the next release') } else if (configVars.body.LANGUAGE_PACK_URL) { - cli.log(message) - cli.warn('The LANGUAGE_PACK_URL config var is still set and will be used for the next release') + CliUx.ux.log(message) + CliUx.ux.warn('The LANGUAGE_PACK_URL config var is still set and will be used for the next release') } else { - cli.log(`${message} Next release on ${app} will detect buildpacks normally.`) + CliUx.ux.log(`${message} Next release on ${app} will detect buildpacks normally.`) } } validateIndexInRange(buildpacks: BuildpackResponse[], index: number) { if (index < 0 || index > buildpacks.length) { if (buildpacks.length === 1) { - cli.error('Invalid index. Only valid value is 1.', {exit: 1}) + CliUx.ux.error('Invalid index. Only valid value is 1.', {exit: 1}) } else { - cli.error(`Invalid index. Please choose a value between 1 and ${buildpacks.length}`, {exit: 1}) + CliUx.ux.error(`Invalid index. Please choose a value between 1 and ${buildpacks.length}`, {exit: 1}) } } } validateIndex(index: number) { if (Number.isNaN(index) || index <= 0) { - cli.error('Invalid index. Must be greater than 0.', {exit: 1}) + CliUx.ux.error('Invalid index. Must be greater than 0.', {exit: 1}) } } } diff --git a/packages/buildpacks/src/commands/buildpacks/add.ts b/packages/buildpacks/src/commands/buildpacks/add.ts index dc114e623d..b4d781c04a 100644 --- a/packages/buildpacks/src/commands/buildpacks/add.ts +++ b/packages/buildpacks/src/commands/buildpacks/add.ts @@ -23,7 +23,7 @@ export default class Add extends Command { ] async run() { - const {args, flags} = this.parse(Add) + const {args, flags} = await this.parse(Add) const buildpackCommand = new BuildpackCommand(this.heroku) if (flags.index !== undefined) { diff --git a/packages/buildpacks/src/commands/buildpacks/clear.ts b/packages/buildpacks/src/commands/buildpacks/clear.ts index 75e598a7ad..7849b8560e 100644 --- a/packages/buildpacks/src/commands/buildpacks/clear.ts +++ b/packages/buildpacks/src/commands/buildpacks/clear.ts @@ -11,7 +11,7 @@ export default class Clear extends Command { } async run() { - const {flags} = this.parse(Clear) + const {flags} = await this.parse(Clear) const buildpackCommand = new BuildpackCommand(this.heroku) await buildpackCommand.clear(flags.app, 'clear', 'cleared') } diff --git a/packages/buildpacks/src/commands/buildpacks/index.ts b/packages/buildpacks/src/commands/buildpacks/index.ts index 5ee4f175c4..789661df9d 100644 --- a/packages/buildpacks/src/commands/buildpacks/index.ts +++ b/packages/buildpacks/src/commands/buildpacks/index.ts @@ -1,5 +1,5 @@ import {Command, flags as Flags} from '@heroku-cli/command' -import {cli} from 'cli-ux' +import {CliUx} from '@oclif/core' import {BuildpackCommand} from '../../buildpacks' @@ -12,14 +12,14 @@ export default class Index extends Command { } async run() { - const {flags} = this.parse(Index) + const {flags} = await this.parse(Index) const buildpacksCommand = new BuildpackCommand(this.heroku) const buildpacks = await buildpacksCommand.fetch(flags.app) if (buildpacks.length === 0) { this.log(`${flags.app} has no Buildpack URL set.`) } else { - cli.styledHeader(`${flags.app} Buildpack URL${buildpacks.length > 1 ? 's' : ''}`) + CliUx.ux.styledHeader(`${flags.app} Buildpack URL${buildpacks.length > 1 ? 's' : ''}`) buildpacksCommand.display(buildpacks, '') } } diff --git a/packages/buildpacks/src/commands/buildpacks/info.ts b/packages/buildpacks/src/commands/buildpacks/info.ts index 5b104ab92e..c2036ec75c 100644 --- a/packages/buildpacks/src/commands/buildpacks/info.ts +++ b/packages/buildpacks/src/commands/buildpacks/info.ts @@ -1,5 +1,5 @@ import {Command} from '@heroku-cli/command' -import {cli} from 'cli-ux' +import {CliUx} from '@oclif/core' import {Result} from 'true-myth' import {BuildpackRegistry} from '@heroku/buildpack-registry' @@ -16,7 +16,7 @@ export default class Info extends Command { ] async run() { - const {args} = this.parse(Info) + const {args} = await this.parse(Info) const registry = new BuildpackRegistry() Result.match({ @@ -30,14 +30,14 @@ export default class Info extends Command { const result = await registry.info(args.buildpack) Result.match({ Ok: buildpack => { - cli.styledHeader(args.buildpack) - cli.styledObject(buildpack, ['description', 'category', 'license', 'support', 'source', 'readme']) + CliUx.ux.styledHeader(args.buildpack) + CliUx.ux.styledObject(buildpack, ['description', 'category', 'license', 'support', 'source', 'readme']) }, Err: err => { if (err.status === 404) { - cli.error(`Could not find the buildpack '${args.buildpack}'`) + CliUx.ux.error(`Could not find the buildpack '${args.buildpack}'`) } else { - cli.error(`Problems finding buildpack info: ${err.description}`) + CliUx.ux.error(`Problems finding buildpack info: ${err.description}`) } }, }, result) diff --git a/packages/buildpacks/src/commands/buildpacks/remove.ts b/packages/buildpacks/src/commands/buildpacks/remove.ts index 32069c3007..0b13f9ab0f 100644 --- a/packages/buildpacks/src/commands/buildpacks/remove.ts +++ b/packages/buildpacks/src/commands/buildpacks/remove.ts @@ -1,5 +1,5 @@ import {Command, flags as Flags} from '@heroku-cli/command' -import {cli} from 'cli-ux' +import {CliUx} from '@oclif/core' import {BuildpackCommand} from '../../buildpacks' @@ -23,19 +23,19 @@ export default class Remove extends Command { ] async run() { - const {args, flags} = this.parse(Remove) + const {args, flags} = await this.parse(Remove) const buildpackCommand = new BuildpackCommand(this.heroku) if (flags.index && args.buildpack) { - cli.error('Please choose either index or Buildpack, but not both.', {exit: 1}) + CliUx.ux.error('Please choose either index or Buildpack, but not both.', {exit: 1}) } if (!flags.index && !args.buildpack) { - cli.error('Usage: heroku buildpacks:remove [BUILDPACK_URL]. Must specify a buildpack to remove, either by index or URL.') + CliUx.ux.error('Usage: heroku buildpacks:remove [BUILDPACK_URL]. Must specify a buildpack to remove, either by index or URL.') } const buildpacks = await buildpackCommand.fetch(flags.app) if (buildpacks.length === 0) { - cli.error(`No buildpacks were found. Next release on ${flags.app} will detect buildpack normally.`, {exit: 1}) + CliUx.ux.error(`No buildpacks were found. Next release on ${flags.app} will detect buildpack normally.`, {exit: 1}) } let spliceIndex: number @@ -47,7 +47,7 @@ export default class Remove extends Command { } if (spliceIndex === -1) { - cli.error('Buildpack not found. Nothing was removed.', {exit: 1}) + CliUx.ux.error('Buildpack not found. Nothing was removed.', {exit: 1}) } if (buildpacks.length === 1) { diff --git a/packages/buildpacks/src/commands/buildpacks/search.ts b/packages/buildpacks/src/commands/buildpacks/search.ts index 579af48a45..bde7a9cd8b 100644 --- a/packages/buildpacks/src/commands/buildpacks/search.ts +++ b/packages/buildpacks/src/commands/buildpacks/search.ts @@ -1,6 +1,5 @@ import {Command, flags as Flags} from '@heroku-cli/command' -import {cli} from 'cli-ux' -import {truncate} from 'lodash' +import {CliUx} from '@oclif/core' import {BuildpackBody, BuildpackRegistry, Category} from '@heroku/buildpack-registry' @@ -21,7 +20,7 @@ export default class Search extends Command { ] async run() { - const {args, flags} = this.parse(Search) + const {args, flags} = await this.parse(Search) let searchResults: BuildpackBody[] const registry = new BuildpackRegistry() @@ -52,25 +51,28 @@ export default class Search extends Command { description: buildpack.description, } }) - const trunc = (value: string, _: string) => truncate(value, {length: 35, omission: '…'}) const displayTable = (buildpacks: TableRow[]) => { - cli.table(buildpacks, { - columns: [ - {key: 'buildpack', label: 'Buildpack'}, - {key: 'category', label: 'Category'}, - {key: 'description', label: 'Description', format: trunc}, - ], + CliUx.ux.table(buildpacks, { + buildpack: { + header: 'Buildpack', + }, + category: { + header: 'Category', + }, + description: { + header: 'Description', + }, }) } if (buildpacks.length === 0) { - cli.log('No buildpacks found') + CliUx.ux.log('No buildpacks found') } else if (buildpacks.length === 1) { displayTable(buildpacks) - cli.log('\n1 buildpack found') + CliUx.ux.log('\n1 buildpack found') } else { displayTable(buildpacks) - cli.log(`\n${buildpacks.length} buildpacks found`) + CliUx.ux.log(`\n${buildpacks.length} buildpacks found`) } } } diff --git a/packages/buildpacks/src/commands/buildpacks/set.ts b/packages/buildpacks/src/commands/buildpacks/set.ts index ea2c398a80..a654cf9cae 100644 --- a/packages/buildpacks/src/commands/buildpacks/set.ts +++ b/packages/buildpacks/src/commands/buildpacks/set.ts @@ -23,7 +23,7 @@ export default class Set extends Command { ] async run() { - const {args, flags} = this.parse(Set) + const {args, flags} = await this.parse(Set) if (flags.index && flags.index < 0) { this.error('Invalid index. Must be greater than 0.') diff --git a/packages/buildpacks/src/commands/buildpacks/versions.ts b/packages/buildpacks/src/commands/buildpacks/versions.ts index 1d10fd5e86..7eeede137b 100644 --- a/packages/buildpacks/src/commands/buildpacks/versions.ts +++ b/packages/buildpacks/src/commands/buildpacks/versions.ts @@ -1,5 +1,5 @@ import {Command} from '@heroku-cli/command' -import {cli} from 'cli-ux' +import {CliUx} from '@oclif/core' import {Result} from 'true-myth' import {BuildpackRegistry, RevisionBody} from '@heroku/buildpack-registry' @@ -16,7 +16,7 @@ export default class Versions extends Command { ] async run() { - const {args} = this.parse(Versions) + const {args} = await this.parse(Versions) const herokuAuth = this.heroku.auth || '' if (herokuAuth === '') { this.error('You need to be logged in to run this command.') @@ -34,14 +34,18 @@ export default class Versions extends Command { const result = await registry.listVersions(args.buildpack) Result.match({ Ok: versions => { - cli.table(versions.sort((a: RevisionBody, b: RevisionBody) => { + CliUx.ux.table(versions.sort((a: RevisionBody, b: RevisionBody) => { return a.release > b.release ? -1 : 1 }), { - columns: [ - {key: 'release', label: 'Version'}, - {key: 'created_at', label: 'Released At'}, - {key: 'status', label: 'Status'}, - ], + release: { + header: 'Version', + }, + created_at: { + header: 'Released At', + }, + status: { + header: 'Status', + }, }) }, Err: err => { diff --git a/packages/buildpacks/test/commands/buildpacks/add.test.ts b/packages/buildpacks/test/commands/buildpacks/add.test.ts index 758a58e6f9..f6b70ea5e8 100644 --- a/packages/buildpacks/test/commands/buildpacks/add.test.ts +++ b/packages/buildpacks/test/commands/buildpacks/add.test.ts @@ -1,23 +1,21 @@ -import Nock from '@fancy-test/nock' import {Fixture} from '@heroku/buildpack-registry' -import {expect, test as otest} from '@oclif/test' +import {expect, test} from '@oclif/test' import * as nock from 'nock' import {BuildpackInstallationsStub as Stubber} from '../../helpers/buildpack-installations-stub' nock.disableNetConnect() -const test = otest.register('nock', Nock) describe('buildpacks:add', () => { describe('URL', () => { test - .nock('https://api.heroku.com', (api: nock.Scope) => { + .nock('https://api.heroku.com', (api: nock.ReplyCallbackResult) => { const registry = new Map() registry.set('https://buildpack-registry.s3.amazonaws.com/buildpacks/hone/test.tgz', {url: 'urn:buildpack:hone/test', name: 'hone/test'}) Stubber.get(api) Stubber.put(api, ['https://buildpack-registry.s3.amazonaws.com/buildpacks/hone/test.tgz'], registry) }) - .nock('https://buildpack-registry.heroku.com', (api: nock.Scope) => { + .nock('https://buildpack-registry.heroku.com', (api: nock.ReplyCallbackResult) => { const buildpack = Fixture.buildpack({ namespace: 'hone', name: 'test', @@ -36,7 +34,7 @@ describe('buildpacks:add', () => { // TODO: On the upgrade to Node 12 this produced an error related to // an older version of nock used by fancy-nock // ctx.stderr contained: 'OutgoingMessage.prototype._headers is deprecated' - // expect(ctx.stderr).to.equal('') + expect(ctx.stderr).to.equal('') expect(ctx.stdout).to.equal( `Buildpack added. Next release on example will use hone/test. @@ -45,7 +43,7 @@ Run git push heroku main to create a new release using this buildpack. }) test - .nock('https://api.heroku.com', (api: nock.Scope) => { + .nock('https://api.heroku.com', (api: nock.ReplyCallbackResult) => { Stubber.get(api) Stubber.put(api, ['https://github.com/heroku/heroku-buildpack-ruby']) }) @@ -61,7 +59,7 @@ Run git push heroku main to create a new release using this buildpack. }) test - .nock('https://api.heroku.com', (api: nock.Scope) => { + .nock('https://api.heroku.com', (api: nock.ReplyCallbackResult) => { Stubber.get(api, ['https://github.com/heroku/heroku-buildpack-java']) Stubber.put(api, [ 'https://github.com/heroku/heroku-buildpack-java', @@ -82,7 +80,7 @@ Run git push heroku main to create a new release using these buildpacks. }) test - .nock('https://api.heroku.com', (api: nock.Scope) => { + .nock('https://api.heroku.com', (api: nock.ReplyCallbackResult) => { Stubber.get(api, [ 'https://github.com/heroku/heroku-buildpack-java', 'https://github.com/heroku/heroku-buildpack-nodejs', @@ -108,7 +106,7 @@ Run git push heroku main to create a new release using these buildpacks. }) test - .nock('https://api.heroku.com', (api: nock.Scope) => { + .nock('https://api.heroku.com', (api: nock.ReplyCallbackResult) => { Stubber.get(api, ['https://github.com/foobar/foobar']) }) .stderr() @@ -117,7 +115,7 @@ Run git push heroku main to create a new release using these buildpacks. .it('# errors out when already exists') test - .nock('https://api.heroku.com', (api: nock.Scope) => { + .nock('https://api.heroku.com', (api: nock.ReplyCallbackResult) => { Stubber.get(api, ['https://codon-buildpacks.s3.amazonaws.com/buildpacks/heroku/jvm-common.tgz']) }) .stderr() @@ -126,7 +124,7 @@ Run git push heroku main to create a new release using these buildpacks. .it('# errors out on unmapped codon urls') test - .nock('https://api.heroku.com', (api: nock.Scope) => { + .nock('https://api.heroku.com', (api: nock.ReplyCallbackResult) => { Stubber.get(api, [ { url: 'urn:buildpack:heroku/ruby', @@ -134,7 +132,7 @@ Run git push heroku main to create a new release using these buildpacks. }, ]) }) - .nock('https://buildpack-registry.heroku.com', (api: nock.Scope) => { + .nock('https://buildpack-registry.heroku.com', (api: nock.ReplyCallbackResult) => { const buildpack = Fixture.buildpack({ namespace: 'heroku', name: 'ruby', @@ -152,7 +150,7 @@ Run git push heroku main to create a new release using these buildpacks. describe('-i INDEX URL', () => { test - .nock('https://api.heroku.com', (api: nock.Scope) => { + .nock('https://api.heroku.com', (api: nock.ReplyCallbackResult) => { Stubber.get(api) Stubber.put(api, ['https://github.com/heroku/heroku-buildpack-ruby']) }) @@ -168,7 +166,7 @@ Run git push heroku main to create a new release using this buildpack. }) test - .nock('https://api.heroku.com', (api: nock.Scope) => { + .nock('https://api.heroku.com', (api: nock.ReplyCallbackResult) => { Stubber.get(api, ['https://github.com/heroku/heroku-buildpack-java']) Stubber.put(api, [ 'https://github.com/heroku/heroku-buildpack-ruby', @@ -189,7 +187,7 @@ Run git push heroku main to create a new release using these buildpacks. }) test - .nock('https://api.heroku.com', (api: nock.Scope) => { + .nock('https://api.heroku.com', (api: nock.ReplyCallbackResult) => { Stubber.get(api, [ 'https://github.com/heroku/heroku-buildpack-java', 'https://github.com/heroku/heroku-buildpack-nodejs', @@ -216,7 +214,7 @@ Run git push heroku main to create a new release using these buildpacks. test .command(['buildpacks:add', 'https://github.com/heroku/heroku-buildpack-ruby', '-i', 'notinteger', '-a', 'example']) - .catch('Expected an integer but received: notinteger') + .catch('Parsing --index \n\tExpected an integer but received: notinteger\nSee more help with --help') .it('# returns an error message when i is not an integer') test diff --git a/packages/buildpacks/test/commands/buildpacks/clear.test.ts b/packages/buildpacks/test/commands/buildpacks/clear.test.ts index 69348ecd4b..06e433ebe7 100644 --- a/packages/buildpacks/test/commands/buildpacks/clear.test.ts +++ b/packages/buildpacks/test/commands/buildpacks/clear.test.ts @@ -1,15 +1,13 @@ -import Nock from '@fancy-test/nock' -import {expect, test as otest} from '@oclif/test' +import {expect, test} from '@oclif/test' import * as nock from 'nock' import {BuildpackInstallationsStub as Stubber} from '../../helpers/buildpack-installations-stub' import {unwrap} from '../../unwrap' nock.disableNetConnect() -const test = otest.register('nock', Nock) describe('buildpacks:clear', () => { test - .nock('https://api.heroku.com', (api: nock.Scope) => { + .nock('https://api.heroku.com', (api: nock.ReplyCallbackResult) => { Stubber.put(api) api .get('/apps/example/config-vars') @@ -24,7 +22,7 @@ describe('buildpacks:clear', () => { }) test - .nock('https://api.heroku.com', (api: nock.Scope) => { + .nock('https://api.heroku.com', (api: nock.ReplyCallbackResult) => { Stubber.put(api) api .get('/apps/example/config-vars') @@ -39,7 +37,7 @@ describe('buildpacks:clear', () => { }) test - .nock('https://api.heroku.com', (api: nock.Scope) => { + .nock('https://api.heroku.com', (api: nock.ReplyCallbackResult) => { Stubber.put(api) api .get('/apps/example/config-vars') diff --git a/packages/buildpacks/test/commands/buildpacks/index.test.ts b/packages/buildpacks/test/commands/buildpacks/index.test.ts index fae4edaafe..123eaf69d0 100644 --- a/packages/buildpacks/test/commands/buildpacks/index.test.ts +++ b/packages/buildpacks/test/commands/buildpacks/index.test.ts @@ -1,14 +1,12 @@ -import Nock from '@fancy-test/nock' -import {expect, test as otest} from '@oclif/test' +import {expect, test} from '@oclif/test' import * as nock from 'nock' import {BuildpackInstallationsStub as Stubber} from '../../helpers/buildpack-installations-stub' nock.disableNetConnect() -const test = otest.register('nock', Nock) describe('buildpacks', () => { test - .nock('https://api.heroku.com', (api: nock.Scope) => { + .nock('https://api.heroku.com', (api: nock.ReplyCallbackResult) => { Stubber.get(api, ['https://github.com/heroku/heroku-buildpack-ruby']) }) .stdout() @@ -18,12 +16,13 @@ describe('buildpacks', () => { expect(ctx.stderr).to.equal('') expect(ctx.stdout).to.equal( `=== example Buildpack URL + https://github.com/heroku/heroku-buildpack-ruby `) }) test - .nock('https://api.heroku.com', (api: nock.Scope) => { + .nock('https://api.heroku.com', (api: nock.ReplyCallbackResult) => { Stubber.get(api, [{url: 'urn:buildpack:heroku/ruby', name: 'heroku/ruby'}]) }) .stdout() @@ -33,12 +32,13 @@ https://github.com/heroku/heroku-buildpack-ruby expect(ctx.stderr).to.equal('') expect(ctx.stdout).to.equal( `=== example Buildpack URL + heroku/ruby `) }) test - .nock('https://api.heroku.com', (api: nock.Scope) => { + .nock('https://api.heroku.com', (api: nock.ReplyCallbackResult) => { Stubber.get(api, ['https://codon-buildpacks.s3.amazonaws.com/buildpacks/heroku/ruby.tgz']) }) .stdout() @@ -48,12 +48,13 @@ heroku/ruby expect(ctx.stderr).to.equal('') expect(ctx.stdout).to.equal( `=== example Buildpack URL + https://codon-buildpacks.s3.amazonaws.com/buildpacks/heroku/ruby.tgz `) }) test - .nock('https://api.heroku.com', (api: nock.Scope) => { + .nock('https://api.heroku.com', (api: nock.ReplyCallbackResult) => { Stubber.get(api) }) .stdout() @@ -67,7 +68,7 @@ https://codon-buildpacks.s3.amazonaws.com/buildpacks/heroku/ruby.tgz }) test - .nock('https://api.heroku.com', (api: nock.Scope) => { + .nock('https://api.heroku.com', (api: nock.ReplyCallbackResult) => { Stubber.get(api, [ 'https://github.com/heroku/heroku-buildpack-java', 'https://github.com/heroku/heroku-buildpack-ruby', @@ -80,13 +81,14 @@ https://codon-buildpacks.s3.amazonaws.com/buildpacks/heroku/ruby.tgz expect(ctx.stderr).to.equal('') expect(ctx.stdout).to.equal( `=== example Buildpack URLs + 1. https://github.com/heroku/heroku-buildpack-java 2. https://github.com/heroku/heroku-buildpack-ruby `) }) test - .nock('https://api.heroku.com', (api: nock.Scope) => { + .nock('https://api.heroku.com', (api: nock.ReplyCallbackResult) => { Stubber.get(api, [ 'https://buildpack-registry.s3.amazonaws.com/buildpacks/heroku/java.tgz', 'https://buildpack-registry.s3.amazonaws.com/buildpacks/rust-lang/rust.tgz', @@ -99,6 +101,7 @@ https://codon-buildpacks.s3.amazonaws.com/buildpacks/heroku/ruby.tgz expect(ctx.stderr).to.equal('') expect(ctx.stdout).to.equal( `=== example Buildpack URLs + 1. heroku/java 2. rust-lang/rust `) diff --git a/packages/buildpacks/test/commands/buildpacks/info.test.ts b/packages/buildpacks/test/commands/buildpacks/info.test.ts index 7917ef8eb1..09cb7e323d 100644 --- a/packages/buildpacks/test/commands/buildpacks/info.test.ts +++ b/packages/buildpacks/test/commands/buildpacks/info.test.ts @@ -1,13 +1,11 @@ -import Nock from '@fancy-test/nock' import {Fixture} from '@heroku/buildpack-registry' -import {expect, test as otest} from '@oclif/test' +import {expect, test} from '@oclif/test' import * as nock from 'nock' nock.disableNetConnect() -const test = otest.register('nock', Nock) describe('buildpacks:info', () => { test - .nock('https://buildpack-registry.heroku.com', (api: nock.Scope) => { + .nock('https://buildpack-registry.heroku.com', (api: nock.ReplyCallbackResult) => { api .get('/buildpacks/heroku%2Fruby') .reply(200, Fixture.buildpack({ @@ -32,7 +30,7 @@ describe('buildpacks:info', () => { }) test - .nock('https://buildpack-registry.heroku.com', (api: nock.Scope) => { + .nock('https://buildpack-registry.heroku.com', (api: nock.ReplyCallbackResult) => { api .get('/buildpacks/hone%2Ftest') .reply(404, {}) @@ -42,7 +40,7 @@ describe('buildpacks:info', () => { .it("handles if the buildpack doesn't exist") test - .nock('https://buildpack-registry.heroku.com', (api: nock.Scope) => { + .nock('https://buildpack-registry.heroku.com', (api: nock.ReplyCallbackResult) => { api .get('/buildpacks/hone%2Ftest') .reply(500, 'some error') diff --git a/packages/buildpacks/test/commands/buildpacks/remove.test.ts b/packages/buildpacks/test/commands/buildpacks/remove.test.ts index 8b287f9996..75afdf75fb 100644 --- a/packages/buildpacks/test/commands/buildpacks/remove.test.ts +++ b/packages/buildpacks/test/commands/buildpacks/remove.test.ts @@ -1,17 +1,15 @@ -import Nock from '@fancy-test/nock' import {Fixture} from '@heroku/buildpack-registry' -import {expect, test as otest} from '@oclif/test' +import {expect, test} from '@oclif/test' import * as nock from 'nock' import {BuildpackInstallationsStub as Stubber} from '../../helpers/buildpack-installations-stub' import {unwrap} from '../../unwrap' nock.disableNetConnect() -const test = otest.register('nock', Nock) describe('buildpacks:remove', () => { describe('-i INDEX', () => { test - .nock('https://api.heroku.com', (api: nock.Scope) => { + .nock('https://api.heroku.com', (api: nock.ReplyCallbackResult) => { Stubber.get(api, ['https://github.com/heroku/heroku-buildpack-ruby']) Stubber.put(api) api @@ -28,7 +26,7 @@ describe('buildpacks:remove', () => { }) test - .nock('https://api.heroku.com', (api: nock.Scope) => { + .nock('https://api.heroku.com', (api: nock.ReplyCallbackResult) => { Stubber.get(api, [ 'https://github.com/heroku/heroku-buildpack-ruby', ]) @@ -48,7 +46,7 @@ describe('buildpacks:remove', () => { }) test - .nock('https://api.heroku.com', (api: nock.Scope) => { + .nock('https://api.heroku.com', (api: nock.ReplyCallbackResult) => { Stubber.get(api, [ 'https://github.com/heroku/heroku-buildpack-ruby', ]) @@ -68,7 +66,7 @@ describe('buildpacks:remove', () => { }) test - .nock('https://api.heroku.com', (api: nock.Scope) => { + .nock('https://api.heroku.com', (api: nock.ReplyCallbackResult) => { Stubber.get(api, [ 'https://github.com/heroku/heroku-buildpack-java', 'https://github.com/heroku/heroku-buildpack-ruby', @@ -87,7 +85,7 @@ Run git push heroku main to create a new release using this buildpack. }) test - .nock('https://api.heroku.com', (api: nock.Scope) => { + .nock('https://api.heroku.com', (api: nock.ReplyCallbackResult) => { Stubber.get(api, [ 'https://github.com/heroku/heroku-buildpack-java', 'https://github.com/heroku/heroku-buildpack-ruby', @@ -106,7 +104,7 @@ Run git push heroku main to create a new release using this buildpack. }) test - .nock('https://api.heroku.com', (api: nock.Scope) => { + .nock('https://api.heroku.com', (api: nock.ReplyCallbackResult) => { Stubber.get(api, [ 'https://github.com/heroku/heroku-buildpack-java', 'https://github.com/heroku/heroku-buildpack-nodejs', @@ -130,11 +128,11 @@ Run git push heroku main to create a new release using these buildpacks. test .command(['buildpacks:remove', '-i', 'notaninteger', '-a', 'example']) - .catch('Expected an integer but received: notaninteger') + .catch('Parsing --index \n\tExpected an integer but received: notaninteger\nSee more help with --help') .it('# returns an error message when i is not an integer') test - .nock('https://api.heroku.com', (api: nock.Scope) => { + .nock('https://api.heroku.com', (api: nock.ReplyCallbackResult) => { Stubber.get(api) }) .command(['buildpacks:remove', '-i', '1', '-a', 'example']) @@ -142,7 +140,7 @@ Run git push heroku main to create a new release using these buildpacks. .it('# with no buildpacks reports an error removing index') test - .nock('https://api.heroku.com', (api: nock.Scope) => { + .nock('https://api.heroku.com', (api: nock.ReplyCallbackResult) => { Stubber.get(api, [ 'https://github.com/foo/foo', ]) @@ -152,7 +150,7 @@ Run git push heroku main to create a new release using these buildpacks. .it('# returns an error when the index > 1 and the size is one') test - .nock('https://api.heroku.com', (api: nock.Scope) => { + .nock('https://api.heroku.com', (api: nock.ReplyCallbackResult) => { Stubber.get(api, [ 'https://github.com/foo/foo', 'https://github.com/bar/bar', @@ -165,7 +163,7 @@ Run git push heroku main to create a new release using these buildpacks. describe('URL', () => { test - .nock('https://api.heroku.com', (api: nock.Scope) => { + .nock('https://api.heroku.com', (api: nock.ReplyCallbackResult) => { Stubber.get(api, [ 'https://github.com/heroku/heroku-buildpack-ruby', ]) @@ -183,7 +181,7 @@ Run git push heroku main to create a new release using these buildpacks. }) test - .nock('https://api.heroku.com', (api: nock.Scope) => { + .nock('https://api.heroku.com', (api: nock.ReplyCallbackResult) => { Stubber.get(api, [ 'https://github.com/heroku/heroku-buildpack-java', 'https://github.com/heroku/heroku-buildpack-ruby', @@ -204,7 +202,7 @@ Run git push heroku main to create a new release using this buildpack. }) test - .nock('https://api.heroku.com', (api: nock.Scope) => { + .nock('https://api.heroku.com', (api: nock.ReplyCallbackResult) => { Stubber.get(api, [ {url: 'urn:buildpack:heroku/ruby', name: 'heroku/ruby'}, ]) @@ -213,7 +211,7 @@ Run git push heroku main to create a new release using this buildpack. .get('/apps/example/config-vars') .reply(200, {}) }) - .nock('https://buildpack-registry.heroku.com', (api: nock.Scope) => { + .nock('https://buildpack-registry.heroku.com', (api: nock.ReplyCallbackResult) => { const buildpack = Fixture.buildpack({ name: 'ruby', }) @@ -232,7 +230,7 @@ Run git push heroku main to create a new release using this buildpack. }) test - .nock('https://api.heroku.com', (api: nock.Scope) => { + .nock('https://api.heroku.com', (api: nock.ReplyCallbackResult) => { Stubber.get(api) }) .command(['buildpacks:remove', 'https://github.com/bar/bar', '-a', 'example']) @@ -240,7 +238,7 @@ Run git push heroku main to create a new release using this buildpack. .it('# with no buildpacks reports an error removing buildpack_url') test - .nock('https://api.heroku.com', (api: nock.Scope) => { + .nock('https://api.heroku.com', (api: nock.ReplyCallbackResult) => { Stubber.get(api, [ 'https://github.com/foo/foo', ]) @@ -250,7 +248,7 @@ Run git push heroku main to create a new release using this buildpack. .it('# returns an error when the url is not found') test - .nock('https://api.heroku.com', (api: nock.Scope) => { + .nock('https://api.heroku.com', (api: nock.ReplyCallbackResult) => { Stubber.get(api, [ 'https://github.com/heroku/heroku-buildpack-java', 'https://github.com/heroku/heroku-buildpack-nodejs', diff --git a/packages/buildpacks/test/commands/buildpacks/search.test.ts b/packages/buildpacks/test/commands/buildpacks/search.test.ts index 80d31796ba..9dbf29ce0c 100644 --- a/packages/buildpacks/test/commands/buildpacks/search.test.ts +++ b/packages/buildpacks/test/commands/buildpacks/search.test.ts @@ -1,14 +1,12 @@ -import Nock from '@fancy-test/nock' import {Fixture} from '@heroku/buildpack-registry' -import {expect, test as otest} from '@oclif/test' +import {expect, test} from '@oclif/test' import * as nock from 'nock' nock.disableNetConnect() -const test = otest.register('nock', Nock) describe('buildpacks:search', () => { test - .nock('https://buildpack-registry.heroku.com', (api: nock.Scope) => { + .nock('https://buildpack-registry.heroku.com', (api: nock.ReplyCallbackResult) => { api .get('/buildpacks?in[namespace][]=heroku') .reply(200, [ @@ -26,7 +24,7 @@ describe('buildpacks:search', () => { }) test - .nock('https://buildpack-registry.heroku.com', (api: nock.Scope) => { + .nock('https://buildpack-registry.heroku.com', (api: nock.ReplyCallbackResult) => { const rubyBuildpack = Fixture.buildpack({ name: 'ruby', description: 'Official Heroku Buildpack for Ruby', diff --git a/packages/buildpacks/test/commands/buildpacks/set.test.ts b/packages/buildpacks/test/commands/buildpacks/set.test.ts index 0a603eb722..566ac4bf52 100644 --- a/packages/buildpacks/test/commands/buildpacks/set.test.ts +++ b/packages/buildpacks/test/commands/buildpacks/set.test.ts @@ -1,15 +1,13 @@ -import Nock from '@fancy-test/nock' -import {expect, test as otest} from '@oclif/test' +import {expect, test} from '@oclif/test' import * as nock from 'nock' import {BuildpackInstallationsStub as Stubber} from '../../helpers/buildpack-installations-stub' nock.disableNetConnect() -const test = otest.register('nock', Nock) describe('buildpacks:set', () => { describe('URL', () => { test - .nock('https://api.heroku.com', (api: nock.Scope) => { + .nock('https://api.heroku.com', (api: nock.ReplyCallbackResult) => { Stubber.get(api) Stubber.put(api, [ 'https://github.com/heroku/heroku-buildpack-ruby', @@ -27,7 +25,7 @@ Run git push heroku main to create a new release using this buildpack. }) test - .nock('https://api.heroku.com', (api: nock.Scope) => { + .nock('https://api.heroku.com', (api: nock.ReplyCallbackResult) => { Stubber.get(api, [ 'https://github.com/foobar/foobar', ]) @@ -37,7 +35,7 @@ Run git push heroku main to create a new release using this buildpack. .it('# errors out when already exists') test - .nock('https://api.heroku.com', (api: nock.Scope) => { + .nock('https://api.heroku.com', (api: nock.ReplyCallbackResult) => { Stubber.get(api, [ 'https://github.com/foo/foo', 'https://github.com/baz/baz', @@ -65,7 +63,7 @@ Run git push heroku main to create a new release using these buildpacks. describe('-i INDEX URL', () => { test - .nock('https://api.heroku.com', (api: nock.Scope) => { + .nock('https://api.heroku.com', (api: nock.ReplyCallbackResult) => { Stubber.get(api) Stubber.put(api, [ 'https://github.com/heroku/heroku-buildpack-ruby', @@ -83,7 +81,7 @@ Run git push heroku main to create a new release using this buildpack. }) test - .nock('https://api.heroku.com', (api: nock.Scope) => { + .nock('https://api.heroku.com', (api: nock.ReplyCallbackResult) => { Stubber.get(api, [ 'https://github.com/heroku/heroku-buildpack-java', ]) @@ -102,7 +100,7 @@ Run git push heroku main to create a new release using this buildpack. `) }) test - .nock('https://api.heroku.com', (api: nock.Scope) => { + .nock('https://api.heroku.com', (api: nock.ReplyCallbackResult) => { Stubber.get(api, [ 'https://github.com/heroku/heroku-buildpack-ruby', ]) @@ -114,7 +112,7 @@ Run git push heroku main to create a new release using this buildpack. .it('# with one existing buildpack unsuccessfully fails if buildpack is already set') test - .nock('https://api.heroku.com', (api: nock.Scope) => { + .nock('https://api.heroku.com', (api: nock.ReplyCallbackResult) => { Stubber.get(api, [ 'https://github.com/heroku/heroku-buildpack-java', 'https://github.com/heroku/heroku-buildpack-nodejs', @@ -138,7 +136,7 @@ Run git push heroku main to create a new release using these buildpacks. }) test - .nock('https://api.heroku.com', (api: nock.Scope) => { + .nock('https://api.heroku.com', (api: nock.ReplyCallbackResult) => { Stubber.get(api, [ 'https://github.com/heroku/heroku-buildpack-java', 'https://github.com/heroku/heroku-buildpack-nodejs', @@ -164,7 +162,7 @@ Run git push heroku main to create a new release using these buildpacks. }) test - .nock('https://api.heroku.com', (api: nock.Scope) => { + .nock('https://api.heroku.com', (api: nock.ReplyCallbackResult) => { Stubber.get(api, [ 'https://github.com/heroku/heroku-buildpack-java', 'https://github.com/heroku/heroku-buildpack-nodejs', @@ -190,7 +188,7 @@ Run git push heroku main to create a new release using these buildpacks. }) test - .nock('https://api.heroku.com', (api: nock.Scope) => { + .nock('https://api.heroku.com', (api: nock.ReplyCallbackResult) => { Stubber.get(api, [ 'https://github.com/heroku/heroku-buildpack-java', 'https://github.com/heroku/heroku-buildpack-nodejs', @@ -204,7 +202,7 @@ Run git push heroku main to create a new release using these buildpacks. test .command(['buildpacks:set', 'https://github.com/bar/bar', '-i', 'notaninteger', '-a', 'example']) - .catch('Expected an integer but received: notaninteger') + .catch('Parsing --index \n\tExpected an integer but received: notaninteger\nSee more help with --help') .it('# returns an error message when i is not an integer') test @@ -220,8 +218,3 @@ See more help with --help`) .it('# handles a missing buildpack URL arg') }) }) - -// -// -// -// }) diff --git a/packages/buildpacks/test/commands/buildpacks/versions.test.ts b/packages/buildpacks/test/commands/buildpacks/versions.test.ts index 5b9db00372..6f1a9bb013 100644 --- a/packages/buildpacks/test/commands/buildpacks/versions.test.ts +++ b/packages/buildpacks/test/commands/buildpacks/versions.test.ts @@ -1,15 +1,13 @@ -import Nock from '@fancy-test/nock' import {Fixture} from '@heroku/buildpack-registry' -import {expect, test as otest} from '@oclif/test' +import {expect, test} from '@oclif/test' import * as nock from 'nock' nock.disableNetConnect() -const test = otest.register('nock', Nock) describe('buildpacks:versions', () => { test .env({HEROKU_API_KEY: 'authtoken'}) - .nock('https://buildpack-registry.heroku.com', (api: nock.Scope) => { + .nock('https://buildpack-registry.heroku.com', (api: nock.ReplyCallbackResult) => { api .get('/buildpacks/heroku%2Fruby/revisions') .reply(200, [ @@ -26,7 +24,7 @@ describe('buildpacks:versions', () => { test .env({HEROKU_API_KEY: 'authtoken'}) - .nock('https://buildpack-registry.heroku.com', (api: nock.Scope) => { + .nock('https://buildpack-registry.heroku.com', (api: nock.ReplyCallbackResult) => { api .get('/buildpacks/hone%2Ftest/revisions') .reply(404, '') @@ -37,7 +35,7 @@ describe('buildpacks:versions', () => { test .env({HEROKU_API_KEY: 'authtoken'}) - .nock('https://buildpack-registry.heroku.com', (api: nock.Scope) => { + .nock('https://buildpack-registry.heroku.com', (api: nock.ReplyCallbackResult) => { api .get('/buildpacks/hone%2Ftest/revisions') .reply(500, 'some error') diff --git a/packages/buildpacks/tsconfig.json b/packages/buildpacks/tsconfig.json index 0ec780a012..0736b62e81 100644 --- a/packages/buildpacks/tsconfig.json +++ b/packages/buildpacks/tsconfig.json @@ -6,6 +6,7 @@ "module": "commonjs", "outDir": "./lib", "rootDirs": [ "./src" ], + "skipLibCheck": true, "strict": true, "target": "es2017", "typeRoots": [ "./node_modules/@types" ] diff --git a/packages/certs-v5/package.json b/packages/certs-v5/package.json index 41ac20713c..c4d600ce0e 100644 --- a/packages/certs-v5/package.json +++ b/packages/certs-v5/package.json @@ -22,14 +22,14 @@ "psl": "^1.1.29" }, "devDependencies": { - "@heroku-cli/dev-cli": "^1.26.13", - "@oclif/plugin-legacy": "^1.2.0", + "@oclif/plugin-legacy": "^1.3.0", "chai": "^4.2.0", "chai-as-promised": "^7.1.1", "lolex": "^3.1.0", "mocha": "^5.2.0", "nock": "^10.0.6", "nyc": "^15.1.0", + "oclif": "3.6.4", "proxyquire": "^2.1.0", "sinon": "^2.3.6", "sinon-chai": "^2.14.0" @@ -48,8 +48,8 @@ "repository": "heroku/cli", "scripts": { "postpublish": "rm oclif.manifest.json", - "prepack": "oclif-dev manifest", + "prepack": "oclif manifest", "test": "nyc mocha", - "version": "oclif-dev readme && git add README.md" + "version": "oclif readme && git add README.md" } } diff --git a/packages/certs/.eslintrc b/packages/certs/.eslintrc index 7c4a11dc71..2b45bde115 100644 --- a/packages/certs/.eslintrc +++ b/packages/certs/.eslintrc @@ -4,6 +4,7 @@ "oclif-typescript" ], "rules": { - "unicorn/no-abusive-eslint-disable": "off" + "unicorn/no-abusive-eslint-disable": "off", + "camelcase": "off" } } diff --git a/packages/certs/bin/run b/packages/certs/bin/run index 3c4ae3ac07..a371425871 100755 --- a/packages/certs/bin/run +++ b/packages/certs/bin/run @@ -1,4 +1,5 @@ #!/usr/bin/env node -require('@oclif/command').run() -.catch(require('@oclif/errors/handle')) +const oclif = require('@oclif/core') + +oclif.run().catch(require('@oclif/core/handle')) diff --git a/packages/certs/package.json b/packages/certs/package.json index 835b5a3ed2..6d83ab76e4 100644 --- a/packages/certs/package.json +++ b/packages/certs/package.json @@ -4,18 +4,13 @@ "author": "Jeff Dickey @jdxcode", "bugs": "https://github.com/heroku/cli/issues", "dependencies": { - "@heroku-cli/command": "^8.4.1", - "@oclif/command": "^1.5.11", - "@oclif/config": "^1.12.10", + "@oclif/core": "^1.26.2", "tslib": "^1.9.3" }, "devDependencies": { - "@heroku-cli/dev-cli": "^1.26.13", - "@oclif/plugin-help": "^2.1.6", - "@oclif/test": "^1.2.4", + "@oclif/test": "^2.2.20", "@types/chai": "^4.1.7", "@types/mocha": "^5.2.6", - "@types/node": "^10.12.24", "chai": "^4.2.0", "eslint": "^6.7.2", "eslint-config-oclif": "^3.1.0", @@ -23,11 +18,12 @@ "globby": "^9.0.0", "mocha": "^5", "nyc": "^15.1.0", + "oclif": "3.6.4", "ts-node": "^10.9.1", - "typescript": "3.3.3333" + "typescript": "4.8.4" }, "engines": { - "node": ">=10.0.0" + "node": ">=14" }, "files": [ "/lib", @@ -39,21 +35,24 @@ ], "license": "MIT", "oclif": { + "additionalHelpFlags": [ + "-h" + ], + "additionalVersionFlags": [ + "-v" + ], "commands": "./lib/commands", "bin": "oclif-example", - "devPlugins": [ - "@oclif/plugin-help" - ], "repositoryPrefix": "<%- repo %>/blob/v<%- version %>/packages/certs/<%- commandPath %>" }, "repository": "heroku/cli", "scripts": { "lint": "eslint . --ext .ts --config .eslintrc", "postpack": "rm -f oclif.manifest.json", - "prepack": "rm -rf lib && tsc && oclif-dev manifest && oclif-dev readme", + "prepack": "rm -rf lib && tsc && oclif manifest", "pretest": "tsc -p test --noEmit", "test": "nyc mocha --forbid-only \"test/**/*.test.ts\"", "posttest": "yarn lint", - "version": "oclif-dev readme && git add README.md" + "version": "oclif readme && git add README.md" } } diff --git a/packages/certs/src/commands/certs/auto/wait.ts b/packages/certs/src/commands/certs/auto/wait.ts index 3683f8600e..28e5a8af1e 100644 --- a/packages/certs/src/commands/certs/auto/wait.ts +++ b/packages/certs/src/commands/certs/auto/wait.ts @@ -1,4 +1,4 @@ -import {Command, flags} from '@oclif/command' +import {Command, Flags} from '@oclif/core' export default class CertsAutoWait extends Command { static description = 'waits for the certificate to be activated' @@ -6,7 +6,7 @@ export default class CertsAutoWait extends Command { static hidden = true static flags = { - help: flags.help({char: 'h'}), + help: Flags.help({char: 'h'}), } async run() { diff --git a/packages/certs/tsconfig.json b/packages/certs/tsconfig.json index 505effc077..d10503c49a 100644 --- a/packages/certs/tsconfig.json +++ b/packages/certs/tsconfig.json @@ -9,6 +9,7 @@ "rootDirs": [ "./src" ], + "skipLibCheck": true, "strict": true, "target": "es2017", "typeRoots": [ diff --git a/packages/ci-v5/package.json b/packages/ci-v5/package.json index d437b2af1c..1092dd1d29 100644 --- a/packages/ci-v5/package.json +++ b/packages/ci-v5/package.json @@ -13,7 +13,7 @@ "repositoryPrefix": "<%- repo %>/blob/v<%- version %>/packages/ci-v5/<%- commandPath %>" }, "dependencies": { - "@heroku-cli/command": "^8.4.1", + "@heroku-cli/command": "^9.0.2", "@heroku-cli/plugin-run-v5": "^7.68.0", "ansi-escapes": "3.2.0", "bluebird": "^3.5.3", @@ -27,17 +27,17 @@ "validator": "^13.7.0" }, "devDependencies": { - "@heroku-cli/dev-cli": "^1.26.13", - "@oclif/plugin-legacy": "^1.2.0", + "@oclif/plugin-legacy": "^1.3.0", "chai": "^4.2.0", "estraverse": "^4.2.0", "mocha": "^5.1.1", "nock": "^10.0.6", + "oclif": "3.6.4", "sinon": "^1.17.6", "std-mocks": "^1.0.1" }, "engines": { - "node": ">=10.0.0" + "node": ">=14" }, "files": [ "oclif.manifest.json", @@ -54,8 +54,8 @@ "repository": "heroku/cli", "scripts": { "postpublish": "rm oclif.manifest.json", - "prepack": "oclif-dev manifest", + "prepack": "oclif manifest", "test": "mocha -R tap", - "version": "oclif-dev readme && git add README.md" + "version": "oclif readme && git add README.md" } } diff --git a/packages/ci/.eslintignore b/packages/ci/.eslintignore index a65b41774a..26fed51c3d 100644 --- a/packages/ci/.eslintignore +++ b/packages/ci/.eslintignore @@ -1 +1,2 @@ lib +src/interfaces/kolkrabbi.ts diff --git a/packages/ci/.eslintrc b/packages/ci/.eslintrc index 7c4a11dc71..2b45bde115 100644 --- a/packages/ci/.eslintrc +++ b/packages/ci/.eslintrc @@ -4,6 +4,7 @@ "oclif-typescript" ], "rules": { - "unicorn/no-abusive-eslint-disable": "off" + "unicorn/no-abusive-eslint-disable": "off", + "camelcase": "off" } } diff --git a/packages/ci/bin/run b/packages/ci/bin/run index 3c4ae3ac07..a371425871 100755 --- a/packages/ci/bin/run +++ b/packages/ci/bin/run @@ -1,4 +1,5 @@ #!/usr/bin/env node -require('@oclif/command').run() -.catch(require('@oclif/errors/handle')) +const oclif = require('@oclif/core') + +oclif.run().catch(require('@oclif/core/handle')) diff --git a/packages/ci/package.json b/packages/ci/package.json index f40c19f36b..08a4662a5b 100644 --- a/packages/ci/package.json +++ b/packages/ci/package.json @@ -6,12 +6,10 @@ "bugs": "https://github.com/heroku/cli/issues", "dependencies": { "@heroku-cli/color": "^1.1.14", - "@heroku-cli/command": "^8.4.1", - "@oclif/command": "^1.5.11", - "@oclif/config": "^1.12.10", + "@heroku-cli/command": "^9.0.2", + "@oclif/core": "^1.26.2", "ansi-escapes": "3.2.0", "async-file": "^2.0.2", - "cli-ux": "^4.9.3", "debug": "^4.1.1", "fs-extra": "^7.0.1", "github-url-to-object": "^4.0.4", @@ -26,15 +24,12 @@ }, "devDependencies": { "@fancy-test/nock": "^0.1.1", - "@heroku-cli/dev-cli": "^1.26.13", "@heroku-cli/schema": "^1.0.25", - "@oclif/plugin-help": "^2.1.6", - "@oclif/test": "^1.2.4", + "@oclif/test": "^2.2.20", "@types/chai": "^4.1.7", "@types/inquirer": "7.3.0", "@types/mocha": "^5.2.6", "@types/nock": "^9.3.1", - "@types/node": "^10.12.24", "@types/phoenix": "^1.4.0", "@types/uuid": "^8.3.0", "@types/validator": "^10.9.0", @@ -47,11 +42,12 @@ "mocha": "^5", "nock": "^10.0.6", "nyc": "^15.1.0", + "oclif": "3.6.4", "ts-node": "^10.9.1", - "typescript": "3.7.5" + "typescript": "4.8.4" }, "engines": { - "node": ">=10.0.0" + "node": ">=14" }, "files": [ "/lib", @@ -65,22 +61,25 @@ ], "license": "MIT", "oclif": { - "commands": "./lib/commands", - "bin": "heroku", - "devPlugins": [ - "@oclif/plugin-help" + "additionalHelpFlags": [ + "-h" + ], + "additionalVersionFlags": [ + "-v" ], + "bin": "heroku", + "commands": "./lib/commands", "repositoryPrefix": "<%- repo %>/blob/v<%- version %>/packages/ci/<%- commandPath %>" }, "repository": "heroku/cli", "scripts": { "lint": "eslint . --ext .ts --config .eslintrc", "postpack": "rm -f oclif.manifest.json npm-shrinkwrap.json", - "prepack": "rm -rf lib && tsc && oclif-dev manifest && oclif-dev readme", + "prepack": "rm -rf lib && tsc && oclif manifest", "prepare": "rm -rf lib && tsc", "pretest": "tsc -p test --noEmit", "test": "nyc mocha --forbid-only \"test/**/*.test.ts\"", "posttest": "yarn lint", - "version": "oclif-dev readme && git add README.md" + "version": "oclif readme && git add README.md" } } diff --git a/packages/ci/src/commands/ci/index.ts b/packages/ci/src/commands/ci/index.ts index 2de04d1990..feb6bfc7d3 100644 --- a/packages/ci/src/commands/ci/index.ts +++ b/packages/ci/src/commands/ci/index.ts @@ -20,7 +20,7 @@ export default class CiIndex extends Command { } async run() { - const {flags} = this.parse(CiIndex) + const {flags} = await this.parse(CiIndex) const pipeline = await getPipeline(flags, this) const {body: testRuns} = await this.heroku.get(`/pipelines/${pipeline.id}/test-runs`) diff --git a/packages/ci/src/commands/ci/info.ts b/packages/ci/src/commands/ci/info.ts index b0b8322d19..a75d99bfe9 100644 --- a/packages/ci/src/commands/ci/info.ts +++ b/packages/ci/src/commands/ci/info.ts @@ -21,7 +21,7 @@ export default class CiInfo extends Command { static args = [{name: 'test-run', required: true}] async run() { - const {args, flags} = this.parse(CiInfo) + const {args, flags} = await this.parse(CiInfo) const pipeline = await getPipeline(flags, this) const {body: testRun} = await this.heroku.get(`/pipelines/${pipeline.id}/test-runs/${args['test-run']}`) const {body: testNodes} = await this.heroku.get(`/test-runs/${testRun.id}/test-nodes`) diff --git a/packages/ci/src/commands/ci/last.ts b/packages/ci/src/commands/ci/last.ts index 3d3bbd253e..241bac3f85 100644 --- a/packages/ci/src/commands/ci/last.ts +++ b/packages/ci/src/commands/ci/last.ts @@ -1,10 +1,12 @@ import {Command, flags} from '@heroku-cli/command' import * as Heroku from '@heroku-cli/schema' -import {cli} from 'cli-ux' +import {CliUx} from '@oclif/core' import {getPipeline} from '../../utils/pipelines' import {displayTestRunInfo} from '../../utils/test-run' +const cli = CliUx.ux + export default class CiLast extends Command { static description = 'looks for the most recent run and returns the output of that run' @@ -20,7 +22,7 @@ export default class CiLast extends Command { } async run() { - const {flags} = this.parse(CiLast) + const {flags} = await this.parse(CiLast) const pipeline = await getPipeline(flags, this) const headers = {Range: 'number ..; order=desc,max=1'} const {body: latestTestRuns} = await this.heroku.get(`/pipelines/${pipeline.id}/test-runs`, {headers}) diff --git a/packages/ci/src/commands/ci/rerun.ts b/packages/ci/src/commands/ci/rerun.ts index 527ef1997a..4fb8d8f577 100644 --- a/packages/ci/src/commands/ci/rerun.ts +++ b/packages/ci/src/commands/ci/rerun.ts @@ -1,13 +1,15 @@ import {Command, flags} from '@heroku-cli/command' import * as Heroku from '@heroku-cli/schema' -import cli from 'cli-ux' +import {CliUx} from '@oclif/core' import * as Kolkrabbi from '../../interfaces/kolkrabbi' import {getPipeline} from '../../utils/pipelines' import {createSourceBlob} from '../../utils/source' import {displayAndExit} from '../../utils/test-run' +const cli = CliUx.ux + export default class CiReRun extends Command { static description = 'rerun tests against current directory' @@ -24,7 +26,7 @@ export default class CiReRun extends Command { static args = [{name: 'number', required: false}] async run() { - const {flags, args} = this.parse(CiReRun) + const {flags, args} = await this.parse(CiReRun) const pipeline = await getPipeline(flags, this) let sourceTestRun: Heroku.TestRun diff --git a/packages/ci/src/commands/ci/run.ts b/packages/ci/src/commands/ci/run.ts index adeaa32899..e08f2905c0 100644 --- a/packages/ci/src/commands/ci/run.ts +++ b/packages/ci/src/commands/ci/run.ts @@ -1,12 +1,15 @@ import {Command, flags} from '@heroku-cli/command' import * as Heroku from '@heroku-cli/schema' -import cli from 'cli-ux' +import {CliUx} from '@oclif/core' import * as Kolkrabbi from '../../interfaces/kolkrabbi' import * as git from '../../utils/git' import {getPipeline} from '../../utils/pipelines' import {createSourceBlob} from '../../utils/source' import {displayAndExit} from '../../utils/test-run' + +const cli = CliUx.ux + export default class CiRun extends Command { static description = 'run tests against current directory' @@ -21,7 +24,7 @@ export default class CiRun extends Command { } async run() { - const {flags} = this.parse(CiRun) + const {flags} = await this.parse(CiRun) const pipeline = await getPipeline(flags, this) const commit = await git.readCommit('HEAD') diff --git a/packages/ci/src/utils/source.ts b/packages/ci/src/utils/source.ts index e76d460204..7f30a0f373 100644 --- a/packages/ci/src/utils/source.ts +++ b/packages/ci/src/utils/source.ts @@ -1,9 +1,11 @@ import {Command} from '@heroku-cli/command' import * as fs from 'async-file' -import {ux} from 'cli-ux' +import {CliUx} from '@oclif/core' import * as git from './git' +const ux = CliUx.ux + const got = require('got') async function uploadArchive(url: string, filePath: string) { diff --git a/packages/ci/src/utils/test-run.ts b/packages/ci/src/utils/test-run.ts index dcebf60ee6..86e8c473b9 100644 --- a/packages/ci/src/utils/test-run.ts +++ b/packages/ci/src/utils/test-run.ts @@ -1,7 +1,7 @@ import color from '@heroku-cli/color' import {Command} from '@heroku-cli/command' import * as Heroku from '@heroku-cli/schema' -import cli from 'cli-ux' +import {CliUx} from '@oclif/core' import * as http from 'http' import {get, RequestOptions} from 'https' import {Socket} from 'phoenix' @@ -9,6 +9,8 @@ import {inspect} from 'util' import {v4 as uuid} from 'uuid' import WebSocket = require('ws') +const cli = CliUx.ux + const debug = require('debug')('ci') const ansiEscapes = require('ansi-escapes') @@ -19,7 +21,7 @@ function logStream(url: RequestOptions | string, fn: (res: http.IncomingMessage) } function stream(url: string) { - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { const request = logStream(url, output => { output.on('data', data => { if (data.toString() === Buffer.from('').toString()) { @@ -127,16 +129,20 @@ function draw(testRuns: Heroku.TestRun[], watchOption = false, jsonOption = fals ) }) - cli.table(data, { - printHeader: undefined, - columns: [ - {key: 'iconStatus', width: 1, label: ''}, // label '' is to make sure that widh is 1 character - {key: 'number', label: ''}, - {key: 'branch'}, - {key: 'sha'}, - {key: 'status'}, - ], - }) + cli.table( + data, + { + iconStatus: { + minWidth: 1, header: '', // header '' is to make sure that width is 1 character + }, + number: { + header: '', // header '' is to make sure that width is 1 character + }, + branch: {}, + sha: {}, + status: {}, + }, + {printHeader: undefined}) if (watchOption) { process.stdout.write(ansiEscapes.cursorUp(latestTestRuns.length)) diff --git a/packages/ci/test/commands/ci/index.test.ts b/packages/ci/test/commands/ci/index.test.ts index 33e027f17e..131e3d1bf8 100644 --- a/packages/ci/test/commands/ci/index.test.ts +++ b/packages/ci/test/commands/ci/index.test.ts @@ -1,8 +1,4 @@ -import Nock from '@fancy-test/nock' -import * as Test from '@oclif/test' -const test = Test.test -.register('nock', Nock) -const expect = Test.expect +import {expect, test} from '@oclif/test' describe('ci', () => { test @@ -53,10 +49,10 @@ describe('ci', () => { expect(stdout).to.contain(`=== Showing latest test runs for the ${pipeline.name} pipeline`) for (let i = 5; i < 10; i++) { - expect(stdout).to.contain(`${statusIcon[i % 4]} ${testRuns[i].number} main ${testRuns[i].commit_sha} ${testRuns[i].status}\n`) + expect(stdout).to.contain(`${statusIcon[i % 4]} ${testRuns[i].number} main ${testRuns[i].commit_sha} ${testRuns[i].status} `) } for (let i = 10; i < 20; i++) { - expect(stdout).to.contain(`${statusIcon[i % 4]} ${testRuns[i].number} main ${testRuns[i].commit_sha} ${testRuns[i].status}\n`) + expect(stdout).to.contain(`${statusIcon[i % 4]} ${testRuns[i].number} main ${testRuns[i].commit_sha} ${testRuns[i].status} `) } expect(stdout).not.to.contain(`${testRuns[4].number} ${testRuns[4].commit_sha}`) diff --git a/packages/ci/test/commands/ci/info.test.ts b/packages/ci/test/commands/ci/info.test.ts index 329a719316..25867c4dff 100644 --- a/packages/ci/test/commands/ci/info.test.ts +++ b/packages/ci/test/commands/ci/info.test.ts @@ -1,9 +1,4 @@ -import Nock from '@fancy-test/nock' -import * as Test from '@oclif/test' - -const test = Test.test -.register('nock', Nock) -const expect = Test.expect +import {expect, test} from '@oclif/test' describe('ci:info', () => { const testRunNumber = 10 diff --git a/packages/ci/test/commands/ci/last.test.ts b/packages/ci/test/commands/ci/last.test.ts index 831831ae09..78161d94cd 100644 --- a/packages/ci/test/commands/ci/last.test.ts +++ b/packages/ci/test/commands/ci/last.test.ts @@ -1,9 +1,4 @@ -import Nock from '@fancy-test/nock' -import * as Test from '@oclif/test' - -const test = Test.test -.register('nock', Nock) -const expect = Test.expect +import {expect, test} from '@oclif/test' describe('ci:last', () => { const testRunNumber = 10 diff --git a/packages/ci/test/commands/ci/rerun.test.ts b/packages/ci/test/commands/ci/rerun.test.ts index 3997b55e2c..35b7ea4559 100644 --- a/packages/ci/test/commands/ci/rerun.test.ts +++ b/packages/ci/test/commands/ci/rerun.test.ts @@ -1,12 +1,7 @@ -import Nock from '@fancy-test/nock' -import * as Test from '@oclif/test' +import {test, expect} from '@oclif/test' import * as git from '../../../src/utils/git' -const test = Test.test -.register('nock', Nock) -const expect = Test.expect - describe('ci:rerun', () => { test .command(['ci:rerun']) diff --git a/packages/ci/test/commands/ci/run.test.ts b/packages/ci/test/commands/ci/run.test.ts index 2784710cf1..d5a82d63ac 100644 --- a/packages/ci/test/commands/ci/run.test.ts +++ b/packages/ci/test/commands/ci/run.test.ts @@ -1,14 +1,9 @@ -import Nock from '@fancy-test/nock' -import * as Test from '@oclif/test' +import {expect, test} from '@oclif/test' import * as fs from 'async-file' import * as git from '../../../src/utils/git' const got = require('got') -const test = Test.test -.register('nock', Nock) -const expect = Test.expect - describe('ci:run', () => { test .command(['ci:run']) @@ -207,7 +202,14 @@ describe('ci:run', () => { .stub(git, 'createArchive', gitFake.createArchive) .stub(fs, 'stat', fsFake.stat) .stub(fs, 'createReadStream', fsFake.createReadStream) - .stub(got, 'stream', gotFake.stream) + .stub( + got, + 'stream', + // disable below is due to incomplete type definition of `stub` + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore-next-line + gotFake.stream, + ) .command(['ci:run', `--pipeline=${pipeline.name}`]) .it('it runs the test and displays the test output for the first node', ({stdout}) => { expect(stdout).to.equal('New Test setup outputNew Test output\n✓ #11 my-test-branch:668a5ce succeeded\n') diff --git a/packages/ci/tsconfig.json b/packages/ci/tsconfig.json index c6454f7a5f..7069ac7c9c 100644 --- a/packages/ci/tsconfig.json +++ b/packages/ci/tsconfig.json @@ -9,6 +9,7 @@ "rootDirs": [ "./src" ], + "skipLibCheck": true, "strict": true, "target": "es2017" }, diff --git a/packages/cli/.eslintignore b/packages/cli/.eslintignore index a65b41774a..9f8fb98c67 100644 --- a/packages/cli/.eslintignore +++ b/packages/cli/.eslintignore @@ -1 +1,3 @@ lib +tmp +dst diff --git a/packages/cli/.eslintrc b/packages/cli/.eslintrc index 68c6a917b5..ee72301381 100644 --- a/packages/cli/.eslintrc +++ b/packages/cli/.eslintrc @@ -4,5 +4,6 @@ "oclif-typescript" ], "rules": { + "camelcase": "off" } } diff --git a/packages/cli/bin/run b/packages/cli/bin/run index 7e10f5dc76..4912fadd35 100755 --- a/packages/cli/bin/run +++ b/packages/cli/bin/run @@ -2,6 +2,6 @@ process.env.HEROKU_UPDATE_INSTRUCTIONS = process.env.HEROKU_UPDATE_INSTRUCTIONS || 'update with: "npm update -g heroku"' -require('@oclif/command').run() -.then(require('@oclif/command/flush')) -.catch(require('@oclif/errors/handle')) +const oclif = require('@oclif/core') + +oclif.run().then(require('@oclif/core/flush')).catch(require('@oclif/core/handle')) diff --git a/packages/cli/package.json b/packages/cli/package.json index b8f619da1e..7785f0c46d 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -3,13 +3,11 @@ "description": "CLI to interact with Heroku", "version": "7.69.1", "author": "Jeff Dickey @jdxcode", - "bin": { - "heroku": "./bin/run" - }, + "bin": "./bin/run", "bugs": "https://github.com/heroku/cli/issues", "dependencies": { "@heroku-cli/color": "1.1.14", - "@heroku-cli/command": "^8.4.1", + "@heroku-cli/command": "^9.0.2", "@heroku-cli/plugin-addons-v5": "^7.68.0", "@heroku-cli/plugin-apps": "^7.68.0", "@heroku-cli/plugin-apps-v5": "^7.68.1", @@ -35,18 +33,16 @@ "@heroku-cli/plugin-spaces": "^7.68.0", "@heroku-cli/plugin-status": "^7.68.0", "@heroku-cli/plugin-webhooks": "^7.68.0", - "@oclif/command": "1.8.16", - "@oclif/config": "1.13.2", - "@oclif/errors": "1.2.2", - "@oclif/plugin-commands": "^1.2.2", - "@oclif/plugin-help": "2.2.0", - "@oclif/plugin-legacy": "1.2.0", - "@oclif/plugin-not-found": "1.2.2", - "@oclif/plugin-plugins": "1.10.1", - "@oclif/plugin-update": "1.5.0", + "@oclif/core": "^1.26.2", + "@oclif/plugin-commands": "2.2.2", + "@oclif/plugin-help": "^5", + "@oclif/plugin-legacy": "^1.3.0", + "@oclif/plugin-not-found": "2.3.16", + "@oclif/plugin-plugins": "2.1.12", + "@oclif/plugin-update": "3.0.13", + "@oclif/plugin-version": "^1.2.1", "@oclif/plugin-warn-if-update-available": "2.0.29", - "@oclif/plugin-which": "1.0.3", - "cli-ux": "4.9.3", + "@oclif/plugin-which": "2.2.8", "debug": "4.1.1", "execa": "1.0.0", "fs-extra": "7.0.1", @@ -57,8 +53,7 @@ "uuid": "3.3.2" }, "devDependencies": { - "@heroku-cli/dev-cli": "^1.26.13", - "@oclif/test": "^1.2.4", + "@oclif/test": "^2.2.20", "@types/ansi-styles": "^3.2.1", "@types/chai": "^4.1.7", "@types/debug": "^4.1.2", @@ -68,7 +63,6 @@ "@types/lodash": "^4.14.123", "@types/mocha": "^5.2.6", "@types/nock": "^9.3.1", - "@types/node": "^10.12.24", "@types/supports-color": "^5.3.0", "@types/write-json-file": "^3.2.1", "aws-sdk": "^2.421.0", @@ -80,14 +74,15 @@ "lodash": "^4.17.11", "mocha": "^5.2.0", "nock": "^10.0.6", + "oclif": "3.6.4", "qqjs": "0.3.10", "read-pkg": "^4.0.1", "sinon": "^7.2.4", "ts-node": "^10.9.1", - "typescript": "3.7.5" + "typescript": "4.8.4" }, "engines": { - "node": ">=10.0.0" + "node": ">=14" }, "files": [ "/oclif.manifest.json", @@ -104,6 +99,12 @@ "license": "ISC", "main": "lib/index.js", "oclif": { + "additionalHelpFlags": [ + "-h" + ], + "additionalVersionFlags": [ + "-v" + ], "commands": "./lib/commands", "plugins": [ "@oclif/plugin-legacy", @@ -137,6 +138,7 @@ "@oclif/plugin-not-found", "@oclif/plugin-plugins", "@oclif/plugin-update", + "@oclif/plugin-version", "@oclif/plugin-warn-if-update-available", "@oclif/plugin-which" ], @@ -240,7 +242,7 @@ }, "update": { "node": { - "version": "14.19.0" + "version": "16.19.0" }, "s3": { "xz": true, @@ -277,11 +279,11 @@ "lint": "eslint . --ext .ts --config .eslintrc", "build": "rm -rf lib && tsc", "postpublish": "rm -f oclif.manifest.json", - "prepack": "yarn run build && oclif-dev manifest", + "prepack": "yarn run build && oclif manifest", "pretest": "tsc -p test --noEmit", "test": "mocha --forbid-only \"test/**/*.test.ts\"", "posttest": "yarn lint", - "version": "oclif-dev readme --multi && git add README.md ../../docs" + "version": "oclif readme --multi && git add README.md ../../docs" }, "types": "lib/index.d.ts" } diff --git a/packages/cli/src/analytics.ts b/packages/cli/src/analytics.ts index 8019de47ae..cff957f593 100644 --- a/packages/cli/src/analytics.ts +++ b/packages/cli/src/analytics.ts @@ -1,5 +1,5 @@ import {vars} from '@heroku-cli/command' -import * as Config from '@oclif/config' +import {Interfaces} from '@oclif/core' import netrc from 'netrc-parser' import * as path from 'path' @@ -8,7 +8,7 @@ import deps from './deps' const debug = require('debug')('heroku:analytics') export interface RecordOpts { - Command: Config.Command.Class; + Command: Interfaces.Command.Class; argv: string[]; } @@ -31,13 +31,13 @@ export interface AnalyticsInterface { } export default class AnalyticsCommand { - config: Config.IConfig + config: Interfaces.Config userConfig!: typeof deps.UserConfig.prototype http: typeof deps.HTTP - constructor(config: Config.IConfig) { + constructor(config: Interfaces.Config) { this.config = config this.http = deps.HTTP.create({ headers: {'user-agent': config.userAgent}, diff --git a/packages/cli/src/file.ts b/packages/cli/src/file.ts index 07545ed97c..e3ca7fea86 100644 --- a/packages/cli/src/file.ts +++ b/packages/cli/src/file.ts @@ -35,7 +35,7 @@ export async function removeEmptyDirs(dir: string): Promise { let files try { files = await ls(dir) - } catch (error) { + } catch (error: any) { if (error.code === 'ENOENT') return throw error } diff --git a/packages/cli/src/hooks/init/terms-of-service.ts b/packages/cli/src/hooks/init/terms-of-service.ts index 173444c9be..e6f01179ec 100644 --- a/packages/cli/src/hooks/init/terms-of-service.ts +++ b/packages/cli/src/hooks/init/terms-of-service.ts @@ -1,7 +1,6 @@ -import {Hook} from '@oclif/config' +import {Hook, CliUx} from '@oclif/core' import * as path from 'path' import * as fs from 'fs-extra' -import cli from 'cli-ux' export function checkTos(options: any) { const tosPath: string = path.join(options.config.cacheDir, 'terms-of-service') @@ -9,7 +8,7 @@ export function checkTos(options: any) { const message = 'Our terms of service have changed: https://dashboard.heroku.com/terms-of-service' if (!viewedBanner) { - cli.warn(message) + CliUx.ux.warn(message) fs.createFile(tosPath) } } diff --git a/packages/cli/src/hooks/init/version.ts b/packages/cli/src/hooks/init/version.ts index 3f83bbef78..ea24fca0a3 100644 --- a/packages/cli/src/hooks/init/version.ts +++ b/packages/cli/src/hooks/init/version.ts @@ -1,4 +1,4 @@ -import {Hook} from '@oclif/config' +import {Hook} from '@oclif/core' const allowlist = [ 'HEROKU_API_KEY', diff --git a/packages/cli/src/hooks/prerun/analytics.ts b/packages/cli/src/hooks/prerun/analytics.ts index 7dab3cd222..fcc705cd51 100644 --- a/packages/cli/src/hooks/prerun/analytics.ts +++ b/packages/cli/src/hooks/prerun/analytics.ts @@ -1,4 +1,4 @@ -import {Hook} from '@oclif/config' +import {Hook} from '@oclif/core' import Analytics from '../../analytics' diff --git a/packages/cli/src/hooks/update/b.ts b/packages/cli/src/hooks/update/b.ts index 3ab8968d30..cdd3b755ca 100644 --- a/packages/cli/src/hooks/update/b.ts +++ b/packages/cli/src/hooks/update/b.ts @@ -1,4 +1,4 @@ -import {Hook} from '@oclif/config' +import {Hook} from '@oclif/core' import {spawnSync, SpawnSyncOptions} from 'child_process' import * as path from 'path' @@ -24,7 +24,7 @@ export const brewHook: Hook<'update'> = async function () { let binPath try { binPath = fs.realpathSync(path.join(brewRoot, 'bin/heroku')) - } catch (error) { + } catch (error: any) { if (error.code === 'ENOENT') return throw error } diff --git a/packages/cli/src/hooks/update/brew.ts b/packages/cli/src/hooks/update/brew.ts index 3ab8968d30..cdd3b755ca 100644 --- a/packages/cli/src/hooks/update/brew.ts +++ b/packages/cli/src/hooks/update/brew.ts @@ -1,4 +1,4 @@ -import {Hook} from '@oclif/config' +import {Hook} from '@oclif/core' import {spawnSync, SpawnSyncOptions} from 'child_process' import * as path from 'path' @@ -24,7 +24,7 @@ export const brewHook: Hook<'update'> = async function () { let binPath try { binPath = fs.realpathSync(path.join(brewRoot, 'bin/heroku')) - } catch (error) { + } catch (error: any) { if (error.code === 'ENOENT') return throw error } diff --git a/packages/cli/src/hooks/update/completions.ts b/packages/cli/src/hooks/update/completions.ts index 90a53692c6..319338278f 100644 --- a/packages/cli/src/hooks/update/completions.ts +++ b/packages/cli/src/hooks/update/completions.ts @@ -1,4 +1,4 @@ -import {Hook} from '@oclif/config' +import {Hook} from '@oclif/core' export const brewHook: Hook<'update'> = async function () { // autocomplete is now in core, skip windows diff --git a/packages/cli/src/hooks/update/plugin-migrate.ts b/packages/cli/src/hooks/update/plugin-migrate.ts index 3eafbfa7a4..2519632aa4 100644 --- a/packages/cli/src/hooks/update/plugin-migrate.ts +++ b/packages/cli/src/hooks/update/plugin-migrate.ts @@ -1,4 +1,4 @@ -import {Hook} from '@oclif/config' +import {Hook} from '@oclif/core' import * as fs from 'fs-extra' import * as path from 'path' @@ -34,7 +34,7 @@ export const migrate: Hook<'init'> = async function () { await exec('heroku', ['plugins:install', plugin]) } } - } catch (error) { + } catch (error: any) { this.warn(error) } try { @@ -47,7 +47,7 @@ export const migrate: Hook<'init'> = async function () { await exec('heroku', ['plugins:link', root]) } } - } catch (error) { + } catch (error: any) { this.warn(error) } await fs.remove(pluginsDir) diff --git a/packages/cli/src/hooks/update/tidy.ts b/packages/cli/src/hooks/update/tidy.ts index d97bbe46f9..bad867b467 100644 --- a/packages/cli/src/hooks/update/tidy.ts +++ b/packages/cli/src/hooks/update/tidy.ts @@ -1,4 +1,4 @@ -import {Hook} from '@oclif/config' +import {Hook} from '@oclif/core' import * as path from 'path' import deps from '../../deps' @@ -10,11 +10,11 @@ export const tidy: Hook<'update'> = async function () { let pjson try { pjson = await deps.file.readJSON(path.join(pluginsDir, 'package.json')) - } catch (error) { + } catch (error: any) { if (error.code !== 'ENOENT') throw error return } - if (!pjson.dependencies || pjson.dependencies === {}) { + if (!pjson.dependencies || Object.keys(pjson.dependencies).length === 0) { await deps.file.remove(path.join(pluginsDir)) } } diff --git a/packages/cli/src/index.ts b/packages/cli/src/index.ts index 4caa481eee..e32b0b2e58 100644 --- a/packages/cli/src/index.ts +++ b/packages/cli/src/index.ts @@ -1 +1 @@ -export {run} from '@oclif/command' +export {run} from '@oclif/core' diff --git a/packages/cli/src/user-config.ts b/packages/cli/src/user-config.ts index 1e1f48bd75..1e729c4a04 100644 --- a/packages/cli/src/user-config.ts +++ b/packages/cli/src/user-config.ts @@ -1,4 +1,4 @@ -import * as Config from '@oclif/config' +import {Interfaces} from '@oclif/core' import * as path from 'path' import deps from './deps' @@ -21,7 +21,7 @@ export default class UserConfig { private _init!: Promise // eslint-disable-next-line no-useless-constructor - constructor(private readonly config: Config.IConfig) {} + constructor(private readonly config: Interfaces.Config) {} public get install() { return this.body.install || this.genInstall() @@ -90,7 +90,7 @@ export default class UserConfig { this.mtime = await this.getLastUpdated() const body = await deps.file.readJSON(this.file) return body - } catch (error) { + } catch (error: any) { if (error.code !== 'ENOENT') throw error this.debug('not found') } @@ -113,7 +113,7 @@ export default class UserConfig { try { const stat = await deps.file.stat(this.file) return stat.mtime.getTime() - } catch (error) { + } catch (error: any) { if (error.code !== 'ENOENT') throw error } } diff --git a/packages/cli/test/analytics.test.ts b/packages/cli/test/analytics.test.ts index 5e872d5ad2..bbdef0e41a 100644 --- a/packages/cli/test/analytics.test.ts +++ b/packages/cli/test/analytics.test.ts @@ -1,5 +1,4 @@ -import Login from '@heroku-cli/plugin-auth/src/commands/auth/login' -import * as Config from '@oclif/config' +import {Config} from '@oclif/core' import {expect} from 'chai' import nock from 'nock' import sinon from 'sinon' @@ -7,6 +6,14 @@ import sinon from 'sinon' import AnalyticsCommand, {AnalyticsInterface} from '../src/analytics' import UserConfig from '../src/user-config' +const mockCommand = { + plugin: { + name: 'foo', + version: '123', + }, + id: 'login', +} + function createBackboardMock(expectedGetter: (data: AnalyticsInterface) => any, actual: any) { const backboard = nock('https://backboard.heroku.com/', { reqheaders: { @@ -33,12 +40,10 @@ async function runAnalyticsTest(expectedCbk: (data: AnalyticsInterface) => any, config.userAgent = '@oclif/command/1.5.6 darwin-x64 node-v10.2.1' config.name = 'heroku' const analytics = new AnalyticsCommand(config) - Login.plugin = {name: 'foo', version: '123'} as any - Login.id = 'login' const backboard = createBackboardMock(expectedCbk, actual) await analytics.record({ - Command: Login, argv: ['foo', 'bar'], + Command: mockCommand as any, argv: ['foo', 'bar'], }) backboard.done() } @@ -64,12 +69,10 @@ describe('analytics (backboard has an error)', () => { config.userAgent = '@oclif/command/1.5.6 darwin-x64 node-v10.2.1' config.name = 'heroku' const analytics = new AnalyticsCommand(config) - Login.plugin = {name: 'foo', version: '123'} as any - Login.id = 'login' try { await analytics.record({ - Command: Login, argv: ['foo', 'bar'], + Command: mockCommand as any, argv: ['foo', 'bar'], }) } catch { throw new Error('Expected analytics hook to 🦃 error') diff --git a/packages/cli/tsconfig.json b/packages/cli/tsconfig.json index a4b474986c..cc4f007209 100644 --- a/packages/cli/tsconfig.json +++ b/packages/cli/tsconfig.json @@ -10,6 +10,7 @@ "rootDirs": [ "./src" ], + "skipLibCheck": true, "strict": true, "target": "es2017" }, diff --git a/packages/config/.eslintrc b/packages/config/.eslintrc index 7c4a11dc71..2b45bde115 100644 --- a/packages/config/.eslintrc +++ b/packages/config/.eslintrc @@ -4,6 +4,7 @@ "oclif-typescript" ], "rules": { - "unicorn/no-abusive-eslint-disable": "off" + "unicorn/no-abusive-eslint-disable": "off", + "camelcase": "off" } } diff --git a/packages/config/bin/run b/packages/config/bin/run index 3c4ae3ac07..a371425871 100755 --- a/packages/config/bin/run +++ b/packages/config/bin/run @@ -1,4 +1,5 @@ #!/usr/bin/env node -require('@oclif/command').run() -.catch(require('@oclif/errors/handle')) +const oclif = require('@oclif/core') + +oclif.run().catch(require('@oclif/core/handle')) diff --git a/packages/config/package.json b/packages/config/package.json index 520a81641c..afd49f9e62 100644 --- a/packages/config/package.json +++ b/packages/config/package.json @@ -5,26 +5,21 @@ "bugs": "https://github.com/heroku/cli/issues", "dependencies": { "@heroku-cli/color": "^1.1.14", - "@heroku-cli/command": "^8.4.1", - "@oclif/command": "^1.5.11", - "@oclif/config": "^1.12.10", - "cli-ux": "^4.9.3", + "@heroku-cli/command": "^9.0.2", + "@oclif/core": "^1.26.2", "edit-string": "^1.1.6", "lodash": "^4.17.11", "shell-quote": "^1.6.1" }, "devDependencies": { "@fancy-test/nock": "^0.1.1", - "@heroku-cli/dev-cli": "^1.26.13", "@heroku-cli/schema": "^1.0.25", - "@oclif/plugin-help": "^2.1.6", - "@oclif/test": "^1.2.4", + "@oclif/test": "^2.2.20", "@types/chai": "^4.1.7", "@types/fs-extra": "^5.0.5", "@types/lodash": "^4.14.123", "@types/mocha": "^5.2.6", "@types/nock": "^9.3.1", - "@types/node": "^10.12.24", "@types/supports-color": "^5.3.0", "chai": "^4.2.0", "eslint": "^6.7.2", @@ -34,13 +29,14 @@ "mocha": "^5.2.0", "nock": "^10.0.6", "nyc": "^15.1.0", + "oclif": "3.6.4", "sinon": "^7.2.4", "ts-node": "^10.9.1", "tslib": "^1.9.3", - "typescript": "3.7.5" + "typescript": "4.8.4" }, "engines": { - "node": ">=10.0.0" + "node": ">=14" }, "files": [ "oclif.manifest.json", @@ -52,21 +48,24 @@ ], "license": "MIT", "oclif": { - "commands": "./lib/commands", - "bin": "heroku", - "devPlugins": [ - "@oclif/plugin-help" + "additionalHelpFlags": [ + "-h" + ], + "additionalVersionFlags": [ + "-v" ], + "bin": "heroku", + "commands": "./lib/commands", "repositoryPrefix": "<%- repo %>/blob/v<%- version %>/packages/config/<%- commandPath %>" }, "repository": "heroku/cli", "scripts": { "lint": "eslint . --ext .ts --config .eslintrc", "postpack": "rm -f oclif.manifest.json", - "prepack": "rm -rf lib && tsc && oclif-dev manifest && oclif-dev readme", + "prepack": "rm -rf lib && tsc && oclif manifest", "pretest": "tsc -p test --noEmit", "test": "nyc mocha --forbid-only \"test/**/*.test.ts\"", "posttest": "yarn lint", - "version": "oclif-dev readme && git add README.md" + "version": "oclif readme && git add README.md" } } diff --git a/packages/config/src/commands/config/edit.ts b/packages/config/src/commands/config/edit.ts index a8d2fad5d1..a6ec017161 100644 --- a/packages/config/src/commands/config/edit.ts +++ b/packages/config/src/commands/config/edit.ts @@ -1,13 +1,14 @@ import {color} from '@heroku-cli/color' import {Command, flags} from '@heroku-cli/command' import * as Heroku from '@heroku-cli/schema' -import {cli} from 'cli-ux' +import {CliUx} from '@oclif/core' import * as _ from 'lodash' import {parse, quote} from '../../quote' import {Editor} from '../../util' const editor = new Editor() +const cli = CliUx.ux interface Config { [key: string]: string; @@ -91,7 +92,7 @@ $ VISUAL="atom --wait" heroku config:edit`, app!: string async run() { - const {flags: {app}, args: {key}} = this.parse(ConfigEdit) + const {flags: {app}, args: {key}} = await this.parse(ConfigEdit) this.app = app cli.action.start('Fetching config') const original = await this.fetchLatestConfig() diff --git a/packages/config/src/commands/config/get.ts b/packages/config/src/commands/config/get.ts index c47f83326d..9a9330144a 100644 --- a/packages/config/src/commands/config/get.ts +++ b/packages/config/src/commands/config/get.ts @@ -22,7 +22,7 @@ production` } async run() { - const {flags, argv} = this.parse(ConfigGet) + const {flags, argv} = await this.parse(ConfigGet) const {body: config} = await this.heroku.get(`/apps/${flags.app}/config-vars`) for (const key of argv) { const v = config[key] diff --git a/packages/config/src/commands/config/index.ts b/packages/config/src/commands/config/index.ts index 1e91ed374d..7c76d2a555 100644 --- a/packages/config/src/commands/config/index.ts +++ b/packages/config/src/commands/config/index.ts @@ -1,10 +1,11 @@ import color from '@heroku-cli/color' import {Command, flags} from '@heroku-cli/command' import * as Heroku from '@heroku-cli/schema' -import ux from 'cli-ux' +import {CliUx} from '@oclif/core' import * as _ from 'lodash' import {quote} from '../../quote' +const ux = CliUx.ux export class ConfigIndex extends Command { static description = 'display the config vars for an app' @@ -17,7 +18,7 @@ export class ConfigIndex extends Command { } async run() { - const {flags} = this.parse(ConfigIndex) + const {flags} = await this.parse(ConfigIndex) const {body: config} = await this.heroku.get(`/apps/${flags.app}/config-vars`) if (flags.shell) { Object.entries(config) diff --git a/packages/config/src/commands/config/unset.ts b/packages/config/src/commands/config/unset.ts index 0b039904b2..a6b335fae4 100644 --- a/packages/config/src/commands/config/unset.ts +++ b/packages/config/src/commands/config/unset.ts @@ -1,9 +1,11 @@ import color from '@heroku-cli/color' import {Command, flags} from '@heroku-cli/command' import * as Heroku from '@heroku-cli/schema' -import ux from 'cli-ux' +import {CliUx} from '@oclif/core' import * as _ from 'lodash' +const ux = CliUx.ux + export class ConfigUnset extends Command { static aliases = [ 'config:remove', @@ -26,7 +28,7 @@ Unsetting RAILS_ENV, RACK_ENV and restarting example... done, v10`, } async run() { - const {argv, flags} = this.parse(ConfigUnset) + const {argv, flags} = await this.parse(ConfigUnset) const lastRelease = async () => { const {body: releases} = await this.heroku.get(`/apps/${flags.app}/releases`, { partial: true, diff --git a/packages/config/test/commands/config/edit.test.ts b/packages/config/test/commands/config/edit.test.ts index 927753d23b..085942e9f7 100644 --- a/packages/config/test/commands/config/edit.test.ts +++ b/packages/config/test/commands/config/edit.test.ts @@ -1,12 +1,14 @@ -import {cli} from 'cli-ux' +import {CliUx} from '@oclif/core' import sinon from 'sinon' import {stringToConfig} from '../../../src/commands/config/edit' import {Editor} from '../../../src/util' -import {expect, test} from '../../test' +import {expect, test} from '@oclif/test' + +const cli = CliUx.ux let sandbox: any -let updated: {} +let updated: string | Record let editedConfig = '' describe('config:edit', () => { @@ -59,7 +61,7 @@ describe('config:edit', () => { ) .nock('https://api.heroku.com', api => api .patch('/apps/myapp/config-vars') - .reply(function (_uri: string, requestBody: {}) { + .reply(function (_uri, requestBody) { updated = requestBody return [200, {}] }), @@ -84,7 +86,7 @@ describe('config:edit', () => { ) .nock('https://api.heroku.com', api => api .patch('/apps/myapp/config-vars') - .reply(function (_uri: string, requestBody: {}) { + .reply(function (_uri, requestBody) { updated = requestBody return [200, {NOT_BLANK: 'not blank', BLANK: ''}] }), diff --git a/packages/config/test/commands/config/get.test.ts b/packages/config/test/commands/config/get.test.ts index 48eef301b6..29e8d9cb63 100644 --- a/packages/config/test/commands/config/get.test.ts +++ b/packages/config/test/commands/config/get.test.ts @@ -1,4 +1,4 @@ -import {expect, test} from '../../test' +import {expect, test} from '@oclif/test' describe('config', () => { test diff --git a/packages/config/test/commands/config/index.test.ts b/packages/config/test/commands/config/index.test.ts index 1b135dc0c7..184461d778 100644 --- a/packages/config/test/commands/config/index.test.ts +++ b/packages/config/test/commands/config/index.test.ts @@ -1,4 +1,4 @@ -import {expect, test} from '../../test' +import {expect, test} from '@oclif/test' describe('config', () => { test @@ -9,7 +9,7 @@ describe('config', () => { .stdout() .command(['config', '--app=myapp']) .it('shows config vars', ({stdout}) => { - expect(stdout).to.equal('=== myapp Config Vars\nLANG: en_US.UTF-8\nRACK_ENV: production\n') + expect(stdout).to.equal('=== myapp Config Vars\n\nLANG: en_US.UTF-8\nRACK_ENV: production\n') }) test diff --git a/packages/config/test/commands/config/unset.test.ts b/packages/config/test/commands/config/unset.test.ts index 44cccedae6..bec94bec56 100644 --- a/packages/config/test/commands/config/unset.test.ts +++ b/packages/config/test/commands/config/unset.test.ts @@ -1,4 +1,4 @@ -import {test} from '../../test' +import {test} from '@oclif/test' describe('config', () => { test diff --git a/packages/config/test/test.ts b/packages/config/test/test.ts deleted file mode 100644 index 0e5c0d12de..0000000000 --- a/packages/config/test/test.ts +++ /dev/null @@ -1,6 +0,0 @@ -import Nock from '@fancy-test/nock' -import * as Test from '@oclif/test' -export {expect} from '@oclif/test' - -export const test = Test.test -.register('nock', Nock) diff --git a/packages/config/tsconfig.json b/packages/config/tsconfig.json index 4a130a2d98..aa791643f3 100644 --- a/packages/config/tsconfig.json +++ b/packages/config/tsconfig.json @@ -10,6 +10,7 @@ "rootDirs": [ "./src" ], + "skipLibCheck": true, "strict": true, "target": "es2017" }, diff --git a/packages/container-registry-v5/package.json b/packages/container-registry-v5/package.json index 34f4b0d844..e7cc4eddc1 100644 --- a/packages/container-registry-v5/package.json +++ b/packages/container-registry-v5/package.json @@ -19,8 +19,7 @@ "inquirer": "^6.2.2" }, "devDependencies": { - "@heroku-cli/dev-cli": "^1.26.13", - "@oclif/plugin-legacy": "^1.2.0", + "@oclif/plugin-legacy": "^1.3.0", "chai": "^4.2.0", "chai-as-promised": "^7.1.1", "cross-env": "^7.0.2", @@ -30,6 +29,7 @@ "mockdate": "^2.0.2", "nock": "^10.0.6", "nyc": "^15.1.0", + "oclif": "3.6.4", "sinon": "^5.0.7", "std-mocks": "^1.0.1" }, @@ -52,9 +52,9 @@ "scripts": { "depcheck": "depcheck || true", "postpublish": "rm oclif.manifest.json", - "prepack": "oclif-dev manifest", + "prepack": "oclif manifest", "test": "cross-env TZ=utc nyc mocha", - "version": "oclif-dev readme && git add README.md" + "version": "oclif readme && git add README.md" }, "topic": "container" } diff --git a/packages/git/.eslintrc b/packages/git/.eslintrc index 7c4a11dc71..b455a55b98 100644 --- a/packages/git/.eslintrc +++ b/packages/git/.eslintrc @@ -4,6 +4,8 @@ "oclif-typescript" ], "rules": { - "unicorn/no-abusive-eslint-disable": "off" + "unicorn/no-abusive-eslint-disable": "off", + "camelcase": "off", + } } diff --git a/packages/git/bin/run b/packages/git/bin/run index 3c4ae3ac07..a371425871 100755 --- a/packages/git/bin/run +++ b/packages/git/bin/run @@ -1,4 +1,5 @@ #!/usr/bin/env node -require('@oclif/command').run() -.catch(require('@oclif/errors/handle')) +const oclif = require('@oclif/core') + +oclif.run().catch(require('@oclif/core/handle')) diff --git a/packages/git/package.json b/packages/git/package.json index 3ccf74cd8a..3cd812e533 100644 --- a/packages/git/package.json +++ b/packages/git/package.json @@ -6,22 +6,16 @@ "bugs": "https://github.com/heroku/cli/issues", "dependencies": { "@heroku-cli/color": "^1.1.14", - "@heroku-cli/command": "^8.4.1", - "@oclif/command": "^1.5.11", - "@oclif/config": "^1.12.10", - "cli-ux": "^4.9.3", + "@heroku-cli/command": "9.0.1", + "@oclif/core": "^1.26.2", "debug": "4.3.4" }, "devDependencies": { - "@heroku-cli/dev-cli": "^1.26.13", "@heroku-cli/schema": "^1.0.25", - "@oclif/plugin-help": "^2.1.6", - "@oclif/plugin-legacy": "^1.2.0", - "@oclif/test": "^1.2.4", + "@oclif/test": "2.2.13", "@types/chai": "^4.1.7", "@types/fs-extra": "^5.0.5", "@types/mocha": "^5.2.6", - "@types/node": "^10.12.24", "@types/supports-color": "^5.3.0", "chai": "^4.2.0", "eslint": "^6.7.2", @@ -31,12 +25,13 @@ "mocha": "^5.2.0", "nock": "^10.0.6", "nyc": "^15.1.0", + "oclif": "3.6.4", "ts-node": "^10.9.1", "tslib": "^1.9.3", - "typescript": "3.7.5" + "typescript": "4.8.4" }, "engines": { - "node": ">=10.0.0" + "node": ">=14" }, "files": [ "/lib", @@ -53,21 +48,24 @@ "description": "manage local git repository for app" } }, + "additionalHelpFlags": [ + "-h" + ], + "additionalVersionFlags": [ + "-v" + ], "commands": "./lib/commands", "bin": "oclif-example", - "devPlugins": [ - "@oclif/plugin-help" - ], "repositoryPrefix": "<%- repo %>/blob/v<%- version %>/packages/git/<%- commandPath %>" }, "repository": "heroku/cli", "scripts": { "lint": "eslint . --ext .ts --config .eslintrc", "postpack": "rm -f oclif.manifest.json", - "prepack": "rm -rf lib && tsc && oclif-dev manifest && oclif-dev readme", + "prepack": "rm -rf lib && tsc && oclif manifest", "pretest": "tsc -p test --noEmit", "test": "echo NO TESTS", "posttest": "yarn lint", - "version": "oclif-dev readme && git add README.md" + "version": "oclif readme && git add README.md" } } diff --git a/packages/git/src/commands/git/clone.ts b/packages/git/src/commands/git/clone.ts index 53d3406bd9..a843b10a42 100644 --- a/packages/git/src/commands/git/clone.ts +++ b/packages/git/src/commands/git/clone.ts @@ -22,7 +22,7 @@ remote: Counting objects: 42, done. async run() { const git = new Git() - const {flags, args} = this.parse(GitClone) + const {flags, args} = await this.parse(GitClone) const {body: app} = await this.heroku.get(`/apps/${flags.app}`) const directory = args.DIRECTORY || app.name const remote = flags.remote || 'heroku' diff --git a/packages/git/src/commands/git/credentials.ts b/packages/git/src/commands/git/credentials.ts index adcfe1ab57..5d30feae0e 100644 --- a/packages/git/src/commands/git/credentials.ts +++ b/packages/git/src/commands/git/credentials.ts @@ -10,7 +10,7 @@ export class GitCredentials extends Command { ] async run() { - const {args} = this.parse(GitCredentials) + const {args} = await this.parse(GitCredentials) switch (args.command) { case 'get': if (!this.heroku.auth) throw new Error('not logged in') diff --git a/packages/git/src/commands/git/remote.ts b/packages/git/src/commands/git/remote.ts index 9998da5bfa..3fd77a61cd 100644 --- a/packages/git/src/commands/git/remote.ts +++ b/packages/git/src/commands/git/remote.ts @@ -23,7 +23,7 @@ extra arguments will be passed to git remote add static strict = false async run() { - const {argv, flags} = this.parse(GitRemote) + const {argv, flags} = await this.parse(GitRemote) const git = new Git() const appName = flags.app || argv.shift() || process.env.HEROKU_APP if (!appName) { diff --git a/packages/git/src/git.ts b/packages/git/src/git.ts index 06d23b4500..1f820549b7 100644 --- a/packages/git/src/git.ts +++ b/packages/git/src/git.ts @@ -1,6 +1,6 @@ import {vars} from '@heroku-cli/command' import * as cp from 'child_process' -import ux from 'cli-ux' +import {CliUx} from '@oclif/core' import {promisify} from 'util' const execFile = promisify(cp.execFile) @@ -13,9 +13,9 @@ export default class Git { const {stdout, stderr} = await execFile('git', args) if (stderr) process.stderr.write(stderr) return stdout.trim() - } catch (error) { + } catch (error: any) { if (error.code === 'ENOENT') { - ux.error('Git must be installed to use the Heroku CLI. See instructions here: https://git-scm.com') + CliUx.ux.error('Git must be installed to use the Heroku CLI. See instructions here: https://git-scm.com') } throw error } @@ -27,7 +27,7 @@ export default class Git { const s = cp.spawn('git', args, {stdio: [0, 1, 2]}) s.on('error', (err: Error & {code?: string}) => { if (err.code === 'ENOENT') { - ux.error('Git must be installed to use the Heroku CLI. See instructions here: https://git-scm.com') + CliUx.ux.error('Git must be installed to use the Heroku CLI. See instructions here: https://git-scm.com') } else reject(err) }) s.on('close', resolve) diff --git a/packages/git/tsconfig.json b/packages/git/tsconfig.json index c6454f7a5f..7069ac7c9c 100644 --- a/packages/git/tsconfig.json +++ b/packages/git/tsconfig.json @@ -9,6 +9,7 @@ "rootDirs": [ "./src" ], + "skipLibCheck": true, "strict": true, "target": "es2017" }, diff --git a/packages/local/.eslintrc b/packages/local/.eslintrc index 68c6a917b5..2b45bde115 100644 --- a/packages/local/.eslintrc +++ b/packages/local/.eslintrc @@ -4,5 +4,7 @@ "oclif-typescript" ], "rules": { + "unicorn/no-abusive-eslint-disable": "off", + "camelcase": "off" } } diff --git a/packages/local/bin/run b/packages/local/bin/run index 3c4ae3ac07..a371425871 100755 --- a/packages/local/bin/run +++ b/packages/local/bin/run @@ -1,4 +1,5 @@ #!/usr/bin/env node -require('@oclif/command').run() -.catch(require('@oclif/errors/handle')) +const oclif = require('@oclif/core') + +oclif.run().catch(require('@oclif/core/handle')) diff --git a/packages/local/package.json b/packages/local/package.json index 4de8187fe8..50e9b1cf9a 100644 --- a/packages/local/package.json +++ b/packages/local/package.json @@ -5,19 +5,15 @@ "author": "Chad Carbert @chadian", "bugs": "https://github.com/heroku/cli/issues", "dependencies": { - "@heroku-cli/command": "^8.4.1", - "@oclif/command": "^1", - "@oclif/config": "^1", + "@heroku-cli/command": "9.0.1", + "@oclif/core": "^1.26.2", "foreman": "^3.0.1", "tslib": "^1" }, "devDependencies": { - "@heroku-cli/dev-cli": "^1.26.13", - "@oclif/plugin-help": "^2", - "@oclif/test": "^1", + "@oclif/test": "^2.2.20", "@types/chai": "^4", "@types/mocha": "^5", - "@types/node": "^10", "bats": "^1.1.0", "chai": "^4", "eslint": "^6.7.2", @@ -26,11 +22,13 @@ "globby": "^8", "mocha": "^5", "nyc": "^15.1.0", + "oclif": "3.6.4", "ts-node": "^10", - "typescript": "3.3.3333" + "tslib": "^1.9.3", + "typescript": "4.8.4" }, "engines": { - "node": ">=10.0.0" + "node": ">=14" }, "files": [ "/lib", @@ -44,22 +42,24 @@ ], "license": "MIT", "oclif": { + "additionalHelpFlags": [ + "-h" + ], + "additionalVersionFlags": [ + "-v" + ], "commands": "./lib/commands", - "bin": "heroku", - "devPlugins": [ - "@oclif/plugin-help" - ] + "bin": "heroku" }, "repository": "heroku/cli", "scripts": { "lint": "eslint . --ext .ts --config .eslintrc", "postpack": "rm -f oclif.manifest.json", - "prepack": "rm -rf lib && tsc -b && oclif-dev manifest && oclif-dev readme", + "prepack": "rm -rf lib && tsc -b && oclif manifest", "pretest": "tsc -p test --noEmit", - "test": "npm run test:unit && npm run test:integration", + "test": "nyc --extension .ts mocha --forbid-only \"test/**/*.test.ts\"", "posttest": "yarn lint", - "test:unit": "nyc --extension .ts mocha --forbid-only \"test/**/*.test.ts\"", - "test:integration": "node ./bin/bats-test-runner", - "version": "oclif-dev readme && git add README.md" + "test:acceptance": "node ./bin/bats-test-runner", + "version": "oclif readme && git add README.md" } } diff --git a/packages/local/src/commands/local/index.ts b/packages/local/src/commands/local/index.ts index ed0a77fd76..549daf17b0 100644 --- a/packages/local/src/commands/local/index.ts +++ b/packages/local/src/commands/local/index.ts @@ -1,5 +1,5 @@ import {FileCompletion} from '@heroku-cli/command/lib/completions' -import {Command, flags} from '@oclif/command' +import {Command, Flags} from '@oclif/core' import {fork as foreman} from '../../fork-foreman' @@ -23,26 +23,26 @@ $ heroku local web=1,worker=2`, ] static flags = { - procfile: flags.string({ + procfile: Flags.string({ char: 'f', description: 'use a different Procfile', completion: FileCompletion, }), - env: flags.string({ + env: Flags.string({ char: 'e', description: 'location of env file (defaults to .env)', completion: FileCompletion, }), - port: flags.string({ + port: Flags.string({ char: 'p', description: 'port to listen on', }), - restart: flags.boolean({ + restart: Flags.boolean({ char: 'r', description: 'restart process if it dies', hidden: true, }), - concurrency: flags.string({ + concurrency: Flags.string({ char: 'c', description: 'number of processes to start', hidden: true, @@ -51,7 +51,7 @@ $ heroku local web=1,worker=2`, async run() { const execArgv = ['start'] - const {args, flags} = this.parse(Index) + const {args, flags} = await this.parse(Index) if (flags.restart) { this.error('--restart is no longer available\nUse forego instead: https://github.com/ddollar/forego') diff --git a/packages/local/src/commands/local/run.ts b/packages/local/src/commands/local/run.ts index 97fdb59ba0..b35ac7e712 100644 --- a/packages/local/src/commands/local/run.ts +++ b/packages/local/src/commands/local/run.ts @@ -1,5 +1,5 @@ import {FileCompletion} from '@heroku-cli/command/lib/completions' -import {Command, flags} from '@oclif/command' +import {Command, Flags} from '@oclif/core' import {fork as foreman} from '../../fork-foreman' @@ -13,11 +13,11 @@ export default class Run extends Command { static strict = false static flags = { - env: flags.string({ + env: Flags.string({ char: 'e', completion: FileCompletion, }), - port: flags.string({ + port: Flags.string({ char: 'p', default: '5001', }), @@ -25,7 +25,7 @@ export default class Run extends Command { async run() { const execArgv: string[] = ['run'] - const {argv, flags} = this.parse(Run) + const {argv, flags} = await this.parse(Run) if (argv.length === 0) { const errorMessage = 'Usage: heroku local:run [COMMAND]\nMust specify command to run' diff --git a/packages/local/src/commands/local/version.ts b/packages/local/src/commands/local/version.ts index 95a21d029a..88fbbd9267 100644 --- a/packages/local/src/commands/local/version.ts +++ b/packages/local/src/commands/local/version.ts @@ -1,4 +1,4 @@ -import {Command} from '@oclif/command' +import {Command} from '@oclif/core' import {fork as foreman} from '../../fork-foreman' @@ -6,7 +6,7 @@ export default class Version extends Command { static description = 'display node-foreman version' async run() { - this.parse(Version) + await this.parse(Version) const execArgv = ['--version'] await foreman(execArgv) diff --git a/packages/local/test/commands/local/index.test.ts b/packages/local/test/commands/local/index.test.ts index 614be3616d..185e974f8a 100644 --- a/packages/local/test/commands/local/index.test.ts +++ b/packages/local/test/commands/local/index.test.ts @@ -14,7 +14,9 @@ describe('local', () => { describe('with the local:start alias', function () { test .stub(procfile, 'loadProc', loadProcMock) - .stub(foreman, 'fork', (argv: string[]) => { + .stub(foreman, 'fork', function () { + // eslint-disable-next-line prefer-rest-params + const argv = arguments[0] expect(argv).is.eql(['start', 'web,other']) }) .command(['local:start']) @@ -24,16 +26,18 @@ describe('local', () => { describe('without arguments', function () { describe('without flags', function () { test - .stub(procfile, 'loadProc', function (procfile: any) { - expect(procfile).is.equal('Procfile', 'it defaults to loading `Procfile`') + .stub(procfile, 'loadProc', function () { + // eslint-disable-next-line prefer-rest-params + expect(arguments[0]).is.equal('Procfile', 'it defaults to loading `Procfile`') return { web: './web-command', other: './other-command', } }) - .stub(foreman, 'fork', (argv: string[]) => { - expect(argv).is.eql(['start', 'web,other']) + .stub(foreman, 'fork', function () { + // eslint-disable-next-line prefer-rest-params + expect(arguments[0]).is.eql(['start', 'web,other']) }) .command(['local']) .it('can call foreman start with no arguments') @@ -41,8 +45,9 @@ describe('local', () => { describe('with a --procfile flag', function () { test - .stub(procfile, 'loadProc', (procfile: string) => { - expect(procfile).is.equal('Procfile.other') + .stub(procfile, 'loadProc', function () { + // eslint-disable-next-line prefer-rest-params + expect(arguments[0]).is.equal('Procfile.other') return { release: './release', @@ -50,7 +55,9 @@ describe('local', () => { background: './background', } }) - .stub(foreman, 'fork', (argv: string[]) => { + .stub(foreman, 'fork', function () { + // eslint-disable-next-line prefer-rest-params + const argv = arguments[0] expect(argv).is.eql(['start', '--procfile', 'Procfile.other', 'web,background']) expect(argv).to.not.include('release', 'the release process is not included') }) @@ -61,7 +68,9 @@ describe('local', () => { describe('with --procfile, --env, --port flags together', function () { test .stub(procfile, 'loadProc', loadProcMock) - .stub(foreman, 'fork', (argv: string[]) => { + .stub(foreman, 'fork', function () { + // eslint-disable-next-line prefer-rest-params + const argv = arguments[0] expect(argv).is.eql([ 'start', '--procfile', @@ -81,15 +90,19 @@ describe('local', () => { describe('with arguments', function () { describe('without flags', function () { test - .stub(procfile, 'loadProc', function (procfile: any) { - expect(procfile).is.equal('Procfile', 'it defaults to loading `Procfile`') + .stub(procfile, 'loadProc', function () { + // eslint-disable-next-line prefer-rest-params + const [procArg] = arguments + expect(procArg).is.equal('Procfile', 'it defaults to loading `Procfile`') return { web: './web-command', other: './other-command', } }) - .stub(foreman, 'fork', (argv: string[]) => { + .stub(foreman, 'fork', function () { + // eslint-disable-next-line prefer-rest-params + const argv = arguments[0] expect(argv).is.eql(['start', 'web,other']) }) .command(['local', 'web,other']) @@ -99,7 +112,9 @@ describe('local', () => { describe('with --port, --env and --procfile flags', function () { test .stub(procfile, 'loadProc', loadProcMock) - .stub(foreman, 'fork', (argv: string[]) => { + .stub(foreman, 'fork', function () { + // eslint-disable-next-line prefer-rest-params + const argv = arguments[0] expect(argv).is.eql([ 'start', '--procfile', diff --git a/packages/local/test/commands/local/run.test.ts b/packages/local/test/commands/local/run.test.ts index 8c3e44a1be..767fa5d382 100644 --- a/packages/local/test/commands/local/run.test.ts +++ b/packages/local/test/commands/local/run.test.ts @@ -12,14 +12,18 @@ describe('local:run', () => { describe('when arguments are given', function () { test - .stub(foreman, 'fork', (argv: string[]) => { + .stub(foreman, 'fork', function () { + // eslint-disable-next-line prefer-rest-params + const argv = arguments[0] expect(argv).is.eql(['run', '--port', '5001', '--', 'echo', 'hello']) }) .command(['local:run', 'echo', 'hello']) .it('can handle one argument passed to foreman after the -- argument separator') test - .stub(foreman, 'fork', (argv: string[]) => { + .stub(foreman, 'fork', function () { + // eslint-disable-next-line prefer-rest-params + const argv = arguments[0] expect(argv).is.eql(['run', '--port', '5001', '--', 'echo', 'hello', 'world']) }) .command(['local:run', 'echo', 'hello', 'world']) @@ -28,14 +32,18 @@ describe('local:run', () => { describe('when the environemnt flag is given', function () { test - .stub(foreman, 'fork', (argv: string[]) => { + .stub(foreman, 'fork', function () { + // eslint-disable-next-line prefer-rest-params + const argv = arguments[0] expect(argv).is.eql(['run', '--env', 'env-file', '--port', '5001', '--', 'bin/migrate']) }) .command(['local:run', 'bin/migrate', '--env', 'env-file']) .it('is passed to foreman an an --env flag before the `--` argument separator') test - .stub(foreman, 'fork', (argv: string[]) => { + .stub(foreman, 'fork', function () { + // eslint-disable-next-line prefer-rest-params + const argv = arguments[0] expect(argv).is.eql(['run', '--env', 'env-file', '--port', '5001', '--', 'bin/migrate']) }) .command(['local:run', 'bin/migrate', '-e', 'env-file']) @@ -44,14 +52,18 @@ describe('local:run', () => { describe('when the port flag is given', function () { test - .stub(foreman, 'fork', (argv: string[]) => { + .stub(foreman, 'fork', function () { + // eslint-disable-next-line prefer-rest-params + const argv = arguments[0] expect(argv).is.eql(['run', '--port', '4200', '--', 'bin/serve']) }) .command(['local:run', 'bin/serve', '--port', '4200']) .it('is passed to foreman an a --port flag before the `--` argument separator') test - .stub(foreman, 'fork', (argv: string[]) => { + .stub(foreman, 'fork', function () { + // eslint-disable-next-line prefer-rest-params + const argv = arguments[0] expect(argv).is.eql(['run', '--port', '4200', '--', 'bin/serve']) }) .command(['local:run', 'bin/serve', '-p', '4200']) diff --git a/packages/local/test/commands/local/version.test.ts b/packages/local/test/commands/local/version.test.ts index 3806945c2c..d13ee96f94 100644 --- a/packages/local/test/commands/local/version.test.ts +++ b/packages/local/test/commands/local/version.test.ts @@ -4,7 +4,9 @@ import * as foreman from '../../../src/fork-foreman' describe('local:version', () => { test - .stub(foreman, 'fork', (argv: string[]) => { + .stub(foreman, 'fork', function () { + // eslint-disable-next-line prefer-rest-params + const argv = arguments[0] expect(argv).is.eql(['--version']) }) .command(['local:version']) diff --git a/packages/local/tsconfig.json b/packages/local/tsconfig.json index b4c5d7686b..41f29f4536 100644 --- a/packages/local/tsconfig.json +++ b/packages/local/tsconfig.json @@ -5,6 +5,7 @@ "module": "commonjs", "outDir": "lib", "rootDir": "src", + "skipLibCheck": true, "strict": true, "target": "es2017" }, diff --git a/packages/oauth-v5/lib/commands/authorizations/revoke.js b/packages/oauth-v5/lib/commands/authorizations/revoke.js index 5f9f053e21..00e0ec5572 100644 --- a/packages/oauth-v5/lib/commands/authorizations/revoke.js +++ b/packages/oauth-v5/lib/commands/authorizations/revoke.js @@ -13,7 +13,7 @@ async function run(context, heroku) { module.exports = { topic: 'authorizations', command: 'revoke', - aliases: ['authorizations:destroy'], + aliases: ['authorizations:destroy', 'authorizations:revoke'], description: 'revoke OAuth authorization', needsAuth: true, args: [{name: 'id'}], diff --git a/packages/oauth-v5/package.json b/packages/oauth-v5/package.json index 529e1ce315..6328ee223e 100644 --- a/packages/oauth-v5/package.json +++ b/packages/oauth-v5/package.json @@ -26,15 +26,15 @@ "lodash": "^4.17.11" }, "devDependencies": { - "@heroku-cli/dev-cli": "^1.26.13", - "@oclif/plugin-legacy": "^1.2.0", + "@oclif/plugin-legacy": "^1.3.0", "chai": "^4.2.0", "chai-as-promised": "^7.1.1", "cross-env": "^7.0.2", "mocha": "^5.2.0", "mocha-junit-reporter": "1.18.0", "nock": "10.0.6", - "nyc": "^15.1.0" + "nyc": "^15.1.0", + "oclif": "3.6.4" }, "files": [ "oclif.manifest.json", @@ -52,8 +52,8 @@ "repository": "heroku/cli", "scripts": { "postpublish": "rm oclif.manifest.json", - "prepack": "oclif-dev manifest", + "prepack": "oclif manifest", "test": "cross-env TZ=UTC nyc mocha", - "version": "oclif-dev readme && git add README.md" + "version": "oclif readme && git add README.md" } } diff --git a/packages/oauth/.eslintrc b/packages/oauth/.eslintrc index 68c6a917b5..ee72301381 100644 --- a/packages/oauth/.eslintrc +++ b/packages/oauth/.eslintrc @@ -4,5 +4,6 @@ "oclif-typescript" ], "rules": { + "camelcase": "off" } } diff --git a/packages/oauth/bin/run b/packages/oauth/bin/run index 30b14e1773..a7635de86e 100755 --- a/packages/oauth/bin/run +++ b/packages/oauth/bin/run @@ -1,5 +1,5 @@ #!/usr/bin/env node -require('@oclif/command').run() -.then(require('@oclif/command/flush')) -.catch(require('@oclif/errors/handle')) +const oclif = require('@oclif/core') + +oclif.run().then(require('@oclif/core/flush')).catch(require('@oclif/core/handle')) diff --git a/packages/oauth/package.json b/packages/oauth/package.json index 634caa5906..c35de2204d 100644 --- a/packages/oauth/package.json +++ b/packages/oauth/package.json @@ -9,22 +9,17 @@ "bugs": "https://github.com/heroku/cli/issues", "dependencies": { "@heroku-cli/color": "^1.1.14", - "@heroku-cli/command": "^8.4.1", + "@heroku-cli/command": "^9.0.2", "@heroku-cli/schema": "^1.0.25", - "@oclif/command": "^1", - "@oclif/config": "^1", - "@oclif/plugin-help": "^2", - "cli-ux": "^5.3.1", + "@oclif/core": "1.22.0", "date-fns": "^1.30.1", "lodash.sortby": "^4.7.0", "tslib": "^1" }, "devDependencies": { - "@heroku-cli/dev-cli": "^1.26.13", - "@oclif/test": "^1", + "@oclif/test": "^2.2.20", "@types/chai": "^4", "@types/mocha": "^5", - "@types/node": "^10", "chai": "^4", "eslint": "^6.7.2", "eslint-config-oclif": "^3.1.0", @@ -32,11 +27,12 @@ "globby": "^10", "mocha": "^5", "nyc": "^15.1.0", + "oclif": "3.6.4", "ts-node": "^10", - "typescript": "3.7.5" + "typescript": "4.8.4" }, "engines": { - "node": ">=10.0.0" + "node": ">=14" }, "files": [ "/bin", @@ -51,21 +47,24 @@ "license": "MIT", "main": "lib/index.js", "oclif": { + "additionalHelpFlags": [ + "-h" + ], + "additionalVersionFlags": [ + "-v" + ], "commands": "./lib/commands", - "bin": "heroku", - "plugins": [ - "@oclif/plugin-help" - ] + "bin": "heroku" }, "repository": "heroku/cli", "scripts": { "lint": "eslint . --ext .ts --config .eslintrc", "postpack": "rm -f oclif.manifest.json", - "prepack": "rm -rf lib && tsc -b && oclif-dev manifest && oclif-dev readme", + "prepack": "rm -rf lib && tsc -b && oclif manifest", "pretest": "tsc -p test --noEmit", "test": "nyc --extension .ts mocha --forbid-only \"test/**/*.test.ts\"", "posttest": "yarn lint", - "version": "oclif-dev readme && git add README.md" + "version": "oclif readme && git add README.md" }, "types": "lib/index.d.ts" } diff --git a/packages/oauth/src/commands/authorizations/create.ts b/packages/oauth/src/commands/authorizations/create.ts index d543e639be..fe94a7edb7 100644 --- a/packages/oauth/src/commands/authorizations/create.ts +++ b/packages/oauth/src/commands/authorizations/create.ts @@ -1,7 +1,7 @@ import {Command, flags} from '@heroku-cli/command' import {ScopeCompletion} from '@heroku-cli/command/lib/completions' import * as Heroku from '@heroku-cli/schema' -import {cli} from 'cli-ux' +import {CliUx} from '@oclif/core' import {display} from '../../lib/authorizations' @@ -21,9 +21,9 @@ export default class AuthorizationsCreate extends Command { } async run() { - const {flags} = this.parse(AuthorizationsCreate) + const {flags} = await this.parse(AuthorizationsCreate) - cli.action.start('Creating OAuth Authorization') + CliUx.ux.action.start('Creating OAuth Authorization') const {body: auth} = await this.heroku.post('/oauth/authorizations', { body: { @@ -33,12 +33,12 @@ export default class AuthorizationsCreate extends Command { }, }) - cli.action.stop() + CliUx.ux.action.stop() if (flags.short) { - cli.log(auth.access_token && auth.access_token.token) + CliUx.ux.log(auth.access_token && auth.access_token.token) } else if (flags.json) { - cli.styledJSON(auth) + CliUx.ux.styledJSON(auth) } else { display(auth) } diff --git a/packages/oauth/src/commands/authorizations/index.ts b/packages/oauth/src/commands/authorizations/index.ts index e20840080b..2460b7a204 100644 --- a/packages/oauth/src/commands/authorizations/index.ts +++ b/packages/oauth/src/commands/authorizations/index.ts @@ -1,7 +1,7 @@ import color from '@heroku-cli/color' import {Command, flags} from '@heroku-cli/command' import * as Heroku from '@heroku-cli/schema' -import {cli} from 'cli-ux' +import {CliUx} from '@oclif/core' const sortBy = require('lodash.sortby') export default class AuthorizationsIndex extends Command { @@ -16,22 +16,23 @@ export default class AuthorizationsIndex extends Command { } async run() { - const {flags} = this.parse(AuthorizationsIndex) + const {flags} = await this.parse(AuthorizationsIndex) let {body: authorizations} = await this.heroku.get>('/oauth/authorizations') authorizations = sortBy(authorizations, 'description') if (flags.json) { - cli.styledJSON(authorizations) + CliUx.ux.styledJSON(authorizations) } else if (authorizations.length === 0) { - cli.log('No OAuth authorizations.') + CliUx.ux.log('No OAuth authorizations.') } else { - cli.table(authorizations, { + const printLine: typeof this.log = (...args) => this.log(...args) + CliUx.ux.table(authorizations, { description: {get: (v: any) => color.green(v.description)}, id: {}, scope: {get: (v: any) => v.scope.join(',')}, - }, {'no-header': true, printLine: this.log}) + }, {'no-header': true, printLine}) } } } diff --git a/packages/oauth/src/commands/authorizations/info.ts b/packages/oauth/src/commands/authorizations/info.ts index e055fefd89..61f251b160 100644 --- a/packages/oauth/src/commands/authorizations/info.ts +++ b/packages/oauth/src/commands/authorizations/info.ts @@ -1,6 +1,6 @@ import {Command, flags} from '@heroku-cli/command' import * as Heroku from '@heroku-cli/schema' -import {cli} from 'cli-ux' +import {CliUx} from '@oclif/core' import {display} from '../../lib/authorizations' @@ -14,14 +14,14 @@ export default class AuthorizationsInfo extends Command { static args = [{name: 'id', required: true}] async run() { - const {args, flags} = this.parse(AuthorizationsInfo) + const {args, flags} = await this.parse(AuthorizationsInfo) const {body: authentication} = await this.heroku.get( `/oauth/authorizations/${args.id}`, ) if (flags.json) { - cli.styledJSON(authentication) + CliUx.ux.styledJSON(authentication) } else { display(authentication) } diff --git a/packages/oauth/src/commands/authorizations/revoke.ts b/packages/oauth/src/commands/authorizations/revoke.ts index a2310a803a..db1514891d 100644 --- a/packages/oauth/src/commands/authorizations/revoke.ts +++ b/packages/oauth/src/commands/authorizations/revoke.ts @@ -1,7 +1,7 @@ import color from '@heroku-cli/color' import {Command} from '@heroku-cli/command' import * as Heroku from '@heroku-cli/schema' -import {cli} from 'cli-ux' +import {CliUx} from '@oclif/core' export default class AuthorizationsRevoke extends Command { static description = 'revoke OAuth authorization' @@ -13,14 +13,14 @@ export default class AuthorizationsRevoke extends Command { static args = [{name: 'id', required: true}] async run() { - const {args} = this.parse(AuthorizationsRevoke) + const {args} = await this.parse(AuthorizationsRevoke) - cli.action.start('Revoking OAuth Authorization') + CliUx.ux.action.start('Revoking OAuth Authorization') const {body: auth} = await this.heroku.delete( `/oauth/authorizations/${encodeURIComponent(args.id)}`, ) - cli.action.stop(`done, revoked authorization from ${color.cyan(auth.description)}`) + CliUx.ux.action.stop(`done, revoked authorization from ${color.cyan(auth.description)}`) } } diff --git a/packages/oauth/src/commands/authorizations/rotate.ts b/packages/oauth/src/commands/authorizations/rotate.ts index c2e24b129b..bf2b297b70 100644 --- a/packages/oauth/src/commands/authorizations/rotate.ts +++ b/packages/oauth/src/commands/authorizations/rotate.ts @@ -1,6 +1,6 @@ import {Command} from '@heroku-cli/command' import * as Heroku from '@heroku-cli/schema' -import {cli} from 'cli-ux' +import {CliUx} from '@oclif/core' import {display} from '../../lib/authorizations' @@ -10,15 +10,15 @@ export default class AuthorizationsRotate extends Command { static args = [{name: 'id', required: true}] async run() { - const {args} = this.parse(AuthorizationsRotate) + const {args} = await this.parse(AuthorizationsRotate) - cli.action.start('Rotating OAuth Authorization') + CliUx.ux.action.start('Rotating OAuth Authorization') const {body: authorization} = await this.heroku.post( `/oauth/authorizations/${encodeURIComponent(args.id)}/actions/regenerate-tokens`, ) - cli.action.stop() + CliUx.ux.action.stop() display(authorization) } diff --git a/packages/oauth/src/commands/authorizations/update.ts b/packages/oauth/src/commands/authorizations/update.ts index db2374b320..625ac306c2 100644 --- a/packages/oauth/src/commands/authorizations/update.ts +++ b/packages/oauth/src/commands/authorizations/update.ts @@ -1,6 +1,6 @@ import {Command, flags} from '@heroku-cli/command' import * as Heroku from '@heroku-cli/schema' -import {cli} from 'cli-ux' +import {CliUx} from '@oclif/core' import {display} from '../../lib/authorizations' @@ -16,9 +16,9 @@ export default class AuthorizationsUpdate extends Command { static args = [{name: 'id', required: true}] async run() { - const {args, flags} = this.parse(AuthorizationsUpdate) + const {args, flags} = await this.parse(AuthorizationsUpdate) - cli.action.start('Updating OAuth Authorization') + CliUx.ux.action.start('Updating OAuth Authorization') let client if (flags['client-id']) { @@ -38,7 +38,7 @@ export default class AuthorizationsUpdate extends Command { }, ) - cli.action.stop() + CliUx.ux.action.stop() display(authentication) } diff --git a/packages/oauth/src/commands/clients/create.ts b/packages/oauth/src/commands/clients/create.ts index 508ab98231..6f6f7ce234 100644 --- a/packages/oauth/src/commands/clients/create.ts +++ b/packages/oauth/src/commands/clients/create.ts @@ -1,6 +1,6 @@ import {Command, flags} from '@heroku-cli/command' import * as Heroku from '@heroku-cli/schema' -import {cli} from 'cli-ux' +import {CliUx} from '@oclif/core' import {validateURL} from '../../lib/clients' @@ -22,24 +22,24 @@ export default class ClientsCreate extends Command { ] async run() { - const {args, flags} = this.parse(ClientsCreate) + const {args, flags} = await this.parse(ClientsCreate) const {redirect_uri, name} = args validateURL(redirect_uri) - cli.action.start(`Creating ${args.name}`) + CliUx.ux.action.start(`Creating ${args.name}`) const {body: client} = await this.heroku.post('/oauth/clients', { body: {name, redirect_uri}, }) - cli.action.stop() + CliUx.ux.action.stop() if (flags.json) { - cli.styledJSON(client) + CliUx.ux.styledJSON(client) } else { - cli.log(`HEROKU_OAUTH_ID=${client.id}`) - cli.log(`HEROKU_OAUTH_SECRET=${client.secret}`) + CliUx.ux.log(`HEROKU_OAUTH_ID=${client.id}`) + CliUx.ux.log(`HEROKU_OAUTH_SECRET=${client.secret}`) } } } diff --git a/packages/oauth/src/commands/clients/destroy.ts b/packages/oauth/src/commands/clients/destroy.ts index d10c6e91ce..6e245c7bd4 100644 --- a/packages/oauth/src/commands/clients/destroy.ts +++ b/packages/oauth/src/commands/clients/destroy.ts @@ -1,7 +1,7 @@ import color from '@heroku-cli/color' import {Command} from '@heroku-cli/command' import * as Heroku from '@heroku-cli/schema' -import {cli} from 'cli-ux' +import {CliUx} from '@oclif/core' export default class ClientsDestroy extends Command { static description = 'delete client by ID' @@ -9,14 +9,14 @@ export default class ClientsDestroy extends Command { static args = [{name: 'id', required: true}] async run() { - const {args} = this.parse(ClientsDestroy) + const {args} = await this.parse(ClientsDestroy) - cli.action.start(`Destroying ${color.cyan(args.id)}`) + CliUx.ux.action.start(`Destroying ${color.cyan(args.id)}`) await this.heroku.delete( `/oauth/clients/${args.id}`, ) - cli.action.stop() + CliUx.ux.action.stop() } } diff --git a/packages/oauth/src/commands/clients/index.ts b/packages/oauth/src/commands/clients/index.ts index 235605ff12..b6642378bf 100644 --- a/packages/oauth/src/commands/clients/index.ts +++ b/packages/oauth/src/commands/clients/index.ts @@ -1,7 +1,7 @@ import color from '@heroku-cli/color' import {Command, flags} from '@heroku-cli/command' import * as Heroku from '@heroku-cli/schema' -import {cli} from 'cli-ux' +import {CliUx} from '@oclif/core' const sortBy = require('lodash.sortby') export default class ClientsIndex extends Command { @@ -12,22 +12,23 @@ export default class ClientsIndex extends Command { } async run() { - const {flags} = this.parse(ClientsIndex) + const {flags} = await this.parse(ClientsIndex) let {body: clients} = await this.heroku.get>('/oauth/clients') clients = sortBy(clients, 'name') if (flags.json) { - cli.styledJSON(clients) + CliUx.ux.styledJSON(clients) } else if (clients.length === 0) { - cli.log('No OAuth clients.') + CliUx.ux.log('No OAuth clients.') } else { - cli.table(clients, { + const printLine: typeof this.log = (...args) => this.log(...args) + CliUx.ux.table(clients, { name: {get: (w: any) => color.green(w.name)}, id: {}, redirect_uri: {}, - }, {'no-header': true, printLine: this.log}) + }, {'no-header': true, printLine}) } } } diff --git a/packages/oauth/src/commands/clients/info.ts b/packages/oauth/src/commands/clients/info.ts index 96147479b9..9f6bd17767 100644 --- a/packages/oauth/src/commands/clients/info.ts +++ b/packages/oauth/src/commands/clients/info.ts @@ -1,6 +1,6 @@ import {Command, flags} from '@heroku-cli/command' import * as Heroku from '@heroku-cli/schema' -import {cli} from 'cli-ux' +import {CliUx} from '@oclif/core' export default class ClientsInfo extends Command { static description = 'show details of an oauth client' @@ -17,18 +17,18 @@ export default class ClientsInfo extends Command { static args = [{name: 'id', required: true}] async run() { - const {args, flags} = this.parse(ClientsInfo) + const {args, flags} = await this.parse(ClientsInfo) const {body: client} = await this.heroku.get(`/oauth/clients/${args.id}`) if (flags.json) { - cli.styledJSON(client) + CliUx.ux.styledJSON(client) } else if (flags.shell) { - cli.log(`HEROKU_OAUTH_ID=${client.id}`) - cli.log(`HEROKU_OAUTH_SECRET=${client.secret}`) + CliUx.ux.log(`HEROKU_OAUTH_ID=${client.id}`) + CliUx.ux.log(`HEROKU_OAUTH_SECRET=${client.secret}`) } else { - cli.styledHeader(`${client.name}`) - cli.styledObject(client) + CliUx.ux.styledHeader(`${client.name}`) + CliUx.ux.styledObject(client) } } } diff --git a/packages/oauth/src/commands/clients/rotate.ts b/packages/oauth/src/commands/clients/rotate.ts index a5428784a5..9f29d09cf3 100644 --- a/packages/oauth/src/commands/clients/rotate.ts +++ b/packages/oauth/src/commands/clients/rotate.ts @@ -1,7 +1,7 @@ import color from '@heroku-cli/color' import {Command, flags} from '@heroku-cli/command' import * as Heroku from '@heroku-cli/schema' -import {cli} from 'cli-ux' +import {CliUx} from '@oclif/core' export default class ClientsRotate extends Command { static description = 'rotate OAuth client secret' @@ -14,24 +14,24 @@ export default class ClientsRotate extends Command { static args = [{name: 'id', required: true}] async run() { - const {args, flags} = this.parse(ClientsRotate) + const {args, flags} = await this.parse(ClientsRotate) - cli.action.start(`Updating ${color.cyan(args.id)}`) + CliUx.ux.action.start(`Updating ${color.cyan(args.id)}`) const {body: client} = await this.heroku.post( `/oauth/clients/${encodeURIComponent(args.id)}/actions/rotate-credentials`, ) - cli.action.stop() + CliUx.ux.action.stop() if (flags.json) { - cli.styledJSON(client) + CliUx.ux.styledJSON(client) } else if (flags.shell) { - cli.log(`HEROKU_OAUTH_ID=${client.id}`) - cli.log(`HEROKU_OAUTH_SECRET=${client.secret}`) + CliUx.ux.log(`HEROKU_OAUTH_ID=${client.id}`) + CliUx.ux.log(`HEROKU_OAUTH_SECRET=${client.secret}`) } else { - cli.styledHeader(`${client.name}`) - cli.styledObject(client) + CliUx.ux.styledHeader(`${client.name}`) + CliUx.ux.styledObject(client) } } } diff --git a/packages/oauth/src/commands/clients/update.ts b/packages/oauth/src/commands/clients/update.ts index 353e83eb4f..bb77f55371 100644 --- a/packages/oauth/src/commands/clients/update.ts +++ b/packages/oauth/src/commands/clients/update.ts @@ -1,7 +1,7 @@ import color from '@heroku-cli/color' import {Command, flags} from '@heroku-cli/command' import * as Heroku from '@heroku-cli/schema' -import {cli} from 'cli-ux' +import {CliUx} from '@oclif/core' import {validateURL} from '../../lib/clients' @@ -36,18 +36,18 @@ export default class ClientsUpdate extends Command { static args = [{name: 'id', required: true}] async run() { - const {args, flags} = this.parse(ClientsUpdate) + const {args, flags} = await this.parse(ClientsUpdate) const body = getUpdates(flags) if (isEmpty(body)) this.error('No changes provided.') - cli.action.start(`Updating ${color.cyan(args.id)}`) + CliUx.ux.action.start(`Updating ${color.cyan(args.id)}`) await this.heroku.patch( `/oauth/clients/${encodeURIComponent(args.id)}`, {body}, ) - cli.action.stop() + CliUx.ux.action.stop() } } diff --git a/packages/oauth/src/commands/sessions/destroy.ts b/packages/oauth/src/commands/sessions/destroy.ts index 8c6c1bc794..f3201436d1 100644 --- a/packages/oauth/src/commands/sessions/destroy.ts +++ b/packages/oauth/src/commands/sessions/destroy.ts @@ -1,6 +1,6 @@ import color from '@heroku-cli/color' import {Command} from '@heroku-cli/command' -import {cli} from 'cli-ux' +import {CliUx} from '@oclif/core' import {OAuthSession} from '../../lib/sessions' @@ -10,14 +10,14 @@ export default class SessionsDestroy extends Command { static args = [{name: 'id', required: true}] async run() { - const {args: {id}} = this.parse(SessionsDestroy) + const {args: {id}} = await this.parse(SessionsDestroy) - cli.action.start(`Destroying ${color.cyan(id)}`) + CliUx.ux.action.start(`Destroying ${color.cyan(id)}`) await this.heroku.delete( `/oauth/sessions/${encodeURIComponent(id)}`, ) - cli.action.stop() + CliUx.ux.action.stop() } } diff --git a/packages/oauth/src/commands/sessions/index.ts b/packages/oauth/src/commands/sessions/index.ts index 02a554b21e..3d20d69372 100644 --- a/packages/oauth/src/commands/sessions/index.ts +++ b/packages/oauth/src/commands/sessions/index.ts @@ -1,6 +1,6 @@ import color from '@heroku-cli/color' import {Command, flags} from '@heroku-cli/command' -import {cli} from 'cli-ux' +import {CliUx} from '@oclif/core' import {OAuthSession} from '../../lib/sessions' const sortBy = require('lodash.sortby') @@ -13,21 +13,22 @@ export default class SessionsIndex extends Command { } async run() { - const {flags} = this.parse(SessionsIndex) + const {flags} = await this.parse(SessionsIndex) let {body: sessions} = await this.heroku.get>('/oauth/sessions') sessions = sortBy(sessions, 'description') if (flags.json) { - cli.styledJSON(sessions) + CliUx.ux.styledJSON(sessions) } else if (sessions.length === 0) { - cli.log('No OAuth sessions.') + CliUx.ux.log('No OAuth sessions.') } else { - cli.table(sessions, { + const printLine: typeof this.log = (...args) => this.log(...args) + CliUx.ux.table(sessions, { description: {get: (v: any) => color.green(v.description)}, id: {}, - }, {'no-header': true, printLine: this.log}) + }, {'no-header': true, printLine}) } } } diff --git a/packages/oauth/src/lib/authorizations.ts b/packages/oauth/src/lib/authorizations.ts index afcb110b27..5a15687d96 100644 --- a/packages/oauth/src/lib/authorizations.ts +++ b/packages/oauth/src/lib/authorizations.ts @@ -1,7 +1,7 @@ 'use strict' import * as Heroku from '@heroku-cli/schema' -import {cli} from 'cli-ux' +import {CliUx} from '@oclif/core' import * as addSeconds from 'date-fns/add_seconds' import * as distanceInWordsToNow from 'date-fns/distance_in_words_to_now' @@ -40,7 +40,7 @@ export function display(auth: Heroku.OAuthAuthorization) { } } - cli.styledObject(obj, [ + CliUx.ux.styledObject(obj, [ 'Client', 'Redirect URI', 'ID', diff --git a/packages/oauth/test/commands/authorizations/create.test.ts b/packages/oauth/test/commands/authorizations/create.test.ts index 887f96977a..349b49b17d 100644 --- a/packages/oauth/test/commands/authorizations/create.test.ts +++ b/packages/oauth/test/commands/authorizations/create.test.ts @@ -16,8 +16,9 @@ describe('authorizations:create', () => { expect(ctx.stdout).to.contain('Client: \n') expect(ctx.stdout).to.contain('Scope: global\n') expect(ctx.stdout).to.contain('Token: secrettoken\n') - // TODO: Not currently testable due to a cli-ux mocking issue - // expect(ctx.stderr).to.contain('Creating OAuth Authorization... done') + if (ctx.error?.message) { + expect(ctx.error.message).to.contain('Creating OAuth Authorization... done') + } }) context('with short flag', () => { diff --git a/packages/oauth/test/commands/authorizations/index.test.ts b/packages/oauth/test/commands/authorizations/index.test.ts index 7c415acae8..77dab492e6 100644 --- a/packages/oauth/test/commands/authorizations/index.test.ts +++ b/packages/oauth/test/commands/authorizations/index.test.ts @@ -23,8 +23,8 @@ describe('authorizations', () => { .command(['authorizations']) .it('lists the authorizations alphabetically by description', ctx => { expect(ctx.stdout).to.equal( - 'awesome f6e8d969-129f-42d2-854b-c2eca9d5a42e app,user \n' + - 'b description aBcD1234-129f-42d2-854b-dEf123abc123 global \n', + ' awesome f6e8d969-129f-42d2-854b-c2eca9d5a42e app,user \n' + + ' b description aBcD1234-129f-42d2-854b-dEf123abc123 global \n', ) }) diff --git a/packages/oauth/test/commands/sessions/index.test.ts b/packages/oauth/test/commands/sessions/index.test.ts index c3b1541f50..bdf36444d6 100644 --- a/packages/oauth/test/commands/sessions/index.test.ts +++ b/packages/oauth/test/commands/sessions/index.test.ts @@ -21,8 +21,8 @@ describe('sessions:index', () => { .command(['sessions']) .it('lists the sessions alphabetically by description', ctx => { expect(ctx.stdout).to.equal( - 'A Session @ 166.176.184.223 f6e8d969-129f-42d2-854b-c2eca9d5a42e \n' + - 'B Session @ 166.176.184.223 aBcD1234-129f-42d2-854b-dEf123abc123 \n', + ' A Session @ 166.176.184.223 f6e8d969-129f-42d2-854b-c2eca9d5a42e \n' + + ' B Session @ 166.176.184.223 aBcD1234-129f-42d2-854b-dEf123abc123 \n', ) }) diff --git a/packages/oauth/tsconfig.json b/packages/oauth/tsconfig.json index b4c5d7686b..41f29f4536 100644 --- a/packages/oauth/tsconfig.json +++ b/packages/oauth/tsconfig.json @@ -5,6 +5,7 @@ "module": "commonjs", "outDir": "lib", "rootDir": "src", + "skipLibCheck": true, "strict": true, "target": "es2017" }, diff --git a/packages/orgs-v5/package.json b/packages/orgs-v5/package.json index 566d59a277..9408e0f277 100644 --- a/packages/orgs-v5/package.json +++ b/packages/orgs-v5/package.json @@ -38,19 +38,19 @@ "repositoryPrefix": "<%- repo %>/blob/v<%- version %>/packages/orgs-v5/<%- commandPath %>" }, "dependencies": { - "@heroku-cli/command": "^8.4.1", + "@heroku-cli/command": "^9.0.2", "heroku-cli-util": "^8.0.11", "inquirer": "^6.2.2", "lodash": "^4.17.11", "lodash.flatten": "^4.4.0" }, "devDependencies": { - "@heroku-cli/dev-cli": "^1.26.13", - "@oclif/plugin-legacy": "^1.2.0", + "@oclif/plugin-legacy": "^1.3.0", "chai": "^4.2.0", "mocha": "^5.2.0", "nock": "^10.0.6", "nyc": "^15.1.0", + "oclif": "3.6.4", "proxyquire": "^2.1.0" }, "files": [ @@ -68,8 +68,8 @@ "repository": "heroku/cli", "scripts": { "postpublish": "rm oclif.manifest.json", - "prepack": "oclif-dev manifest", + "prepack": "oclif manifest", "test": "nyc mocha", - "version": "oclif-dev readme && git add README.md" + "version": "oclif readme && git add README.md" } } diff --git a/packages/pg-v5/package.json b/packages/pg-v5/package.json index c9fc05ff7d..999651964e 100644 --- a/packages/pg-v5/package.json +++ b/packages/pg-v5/package.json @@ -27,8 +27,7 @@ "uuid": "^8.3.1" }, "devDependencies": { - "@heroku-cli/dev-cli": "^1.26.13", - "@oclif/plugin-legacy": "^1.2.0", + "@oclif/plugin-legacy": "^1.3.0", "chai": "^4.2.0", "chai-as-promised": "^7.1.1", "cross-env": "^7.0.2", @@ -36,6 +35,7 @@ "mocha": "^5.1.1", "nock": "^10.0.6", "nyc": "^15.1.0", + "oclif": "3.6.4", "proxyquire": "^2.1.0", "sinon": "^7.2.3", "standard": "^12.0.1" @@ -56,9 +56,9 @@ "repository": "heroku/cli", "scripts": { "postpublish": "rm oclif.manifest.json", - "prepack": "oclif-dev manifest", + "prepack": "oclif manifest", "release": "np", "test": "cross-env TZ=utc nyc mocha", - "version": "oclif-dev readme && git add README.md" + "version": "oclif readme && git add README.md" } } diff --git a/packages/pipelines/.eslintrc b/packages/pipelines/.eslintrc index 7c4a11dc71..2b45bde115 100644 --- a/packages/pipelines/.eslintrc +++ b/packages/pipelines/.eslintrc @@ -4,6 +4,7 @@ "oclif-typescript" ], "rules": { - "unicorn/no-abusive-eslint-disable": "off" + "unicorn/no-abusive-eslint-disable": "off", + "camelcase": "off" } } diff --git a/packages/pipelines/bin/run b/packages/pipelines/bin/run index 3c4ae3ac07..a371425871 100755 --- a/packages/pipelines/bin/run +++ b/packages/pipelines/bin/run @@ -1,4 +1,5 @@ #!/usr/bin/env node -require('@oclif/command').run() -.catch(require('@oclif/errors/handle')) +const oclif = require('@oclif/core') + +oclif.run().catch(require('@oclif/core/handle')) diff --git a/packages/pipelines/package.json b/packages/pipelines/package.json index 8a94cdd3a7..3a1942109c 100644 --- a/packages/pipelines/package.json +++ b/packages/pipelines/package.json @@ -5,12 +5,9 @@ "bugs": "https://github.com/heroku/cli/issues", "dependencies": { "@heroku-cli/color": "^1.1.14", - "@heroku-cli/command": "^8.4.1", + "@heroku-cli/command": "^9.0.2", "@heroku-cli/schema": "^1.0.25", - "@oclif/command": "^1", - "@oclif/config": "^1", - "@oclif/errors": "^1.3.4", - "cli-ux": "^5.5.1", + "@oclif/core": "^1.26.2", "heroku-cli-util": "^8.0.11", "http-call": "^5.2.4", "inquirer": "^7.0.0", @@ -20,31 +17,31 @@ "validator": "^13.7.0" }, "devDependencies": { - "@heroku-cli/dev-cli": "^1.26.13", - "@oclif/plugin-help": "^2", - "@oclif/test": "^1", - "@types/chai": "^4", + "@oclif/test": "2.2.20", + "@types/chai": "4.1.7", "@types/got": "^9.6.7", "@types/lodash.keyby": "^4.6.6", "@types/lodash.sortby": "^4.7.6", - "@types/mocha": "^5", - "@types/node": "^10", - "chai": "^4", + "@types/mocha": "5.2.6", + "@types/nock": "^9.3.1", + "@typescript-eslint/eslint-plugin": "4.18.0", + "@typescript-eslint/parser": "4.18.0", + "chai": "4.2.0", "debug": "^4.1.1", "eslint": "^6.7.2", "eslint-config-oclif": "^3.1.0", "eslint-config-oclif-typescript": "^0.1.0", - "globby": "^8", - "mocha": "^5", + "globby": "9.0.0", + "mocha": "5.2.0", "nock": "^10.0.6", "nyc": "^15.1.0", + "oclif": "3.6.4", "sinon": "^7.4.1", - "ts-node": "^10", - "tslib": "^1", - "typescript": "3.7.5" + "ts-node": "10.9.1", + "typescript": "4.8.4" }, "engines": { - "node": ">=10.0.0" + "node": ">=14" }, "files": [ "/lib", @@ -57,11 +54,14 @@ ], "license": "MIT", "oclif": { - "commands": "./lib/commands", - "bin": "heroku", - "devPlugins": [ - "@oclif/plugin-help" + "additionalHelpFlags": [ + "-h" + ], + "additionalVersionFlags": [ + "-v" ], + "bin": "heroku", + "commands": "./lib/commands", "topics": { "pipelines": { "description": "manage pipelines" @@ -75,10 +75,10 @@ "scripts": { "lint": "eslint . --ext .ts --config .eslintrc", "postpack": "rm -f oclif.manifest.json", - "prepack": "rm -rf lib && tsc -b && oclif-dev manifest && oclif-dev readme", + "prepack": "rm -rf lib && tsc -b && oclif manifest", "pretest": "tsc -p test --noEmit", "test": "nyc --extension .ts mocha \"test/**/*.test.ts\"", "posttest": "yarn lint", - "version": "oclif-dev readme && git add README.md" + "version": "oclif readme && git add README.md" } } diff --git a/packages/pipelines/src/commands/pipelines/add.ts b/packages/pipelines/src/commands/pipelines/add.ts index 08bb92ee6b..650fc6cec5 100644 --- a/packages/pipelines/src/commands/pipelines/add.ts +++ b/packages/pipelines/src/commands/pipelines/add.ts @@ -1,7 +1,7 @@ import color from '@heroku-cli/color' import {Command, flags} from '@heroku-cli/command' import {StageCompletion} from '@heroku-cli/command/lib/completions' -import cli from 'cli-ux' +import {CliUx} from '@oclif/core' import {prompt} from 'inquirer' import {createCoupling} from '../../api' @@ -9,6 +9,8 @@ import disambiguate from '../../disambiguate' import infer from '../../infer' import {inferrableStageNames as stageNames} from '../../stages' +const cli = CliUx.ux + export default class PipelinesAdd extends Command { static description = `add this app to a pipeline The app and pipeline names must be specified. @@ -35,7 +37,7 @@ The stage of the app will be guessed based on its name if not specified.` }] async run() { - const {args, flags} = this.parse(PipelinesAdd) + const {args, flags} = await this.parse(PipelinesAdd) const app = flags.app let stage diff --git a/packages/pipelines/src/commands/pipelines/connect.ts b/packages/pipelines/src/commands/pipelines/connect.ts index 6c3018a1eb..0dbba80a87 100644 --- a/packages/pipelines/src/commands/pipelines/connect.ts +++ b/packages/pipelines/src/commands/pipelines/connect.ts @@ -1,5 +1,5 @@ import {Command, flags} from '@heroku-cli/command' -import cli from 'cli-ux' +import {CliUx} from '@oclif/core' import {getPipeline} from '../../api' import GitHubAPI from '../../github-api' @@ -9,6 +9,8 @@ import getNameAndRepo from '../../setup/get-name-and-repo' import getRepo from '../../setup/get-repo' import {nameAndRepo} from '../../setup/validate' +const cli = CliUx.ux + export default class Connect extends Command { static description = 'connect a github repo to an existing pipeline' @@ -32,7 +34,7 @@ export default class Connect extends Command { }] async run() { - const {args, flags} = this.parse(Connect) + const {args, flags} = await this.parse(Connect) const combinedInputs = { name: args.name, diff --git a/packages/pipelines/src/commands/pipelines/create.ts b/packages/pipelines/src/commands/pipelines/create.ts index fd36db4ab5..31f859558a 100644 --- a/packages/pipelines/src/commands/pipelines/create.ts +++ b/packages/pipelines/src/commands/pipelines/create.ts @@ -1,13 +1,15 @@ import color from '@heroku-cli/color' import {Command, flags} from '@heroku-cli/command' import {StageCompletion} from '@heroku-cli/command/lib/completions' -import cli from 'cli-ux' +import {CliUx} from '@oclif/core' import {prompt} from 'inquirer' import {createCoupling, createPipeline, getAccountInfo, getTeam} from '../../api' import infer from '../../infer' import {inferrableStageNames as stages} from '../../stages' +const cli = CliUx.ux + export default class Create extends Command { static description = `create a new pipeline An existing app must be specified as the first app in the pipeline. @@ -41,7 +43,7 @@ export default class Create extends Command { }] async run() { - const {args, flags} = this.parse(Create) + const {args, flags} = await this.parse(Create) let name let stage diff --git a/packages/pipelines/src/commands/pipelines/destroy.ts b/packages/pipelines/src/commands/pipelines/destroy.ts index 258863062d..aaafbe5802 100644 --- a/packages/pipelines/src/commands/pipelines/destroy.ts +++ b/packages/pipelines/src/commands/pipelines/destroy.ts @@ -1,11 +1,13 @@ import color from '@heroku-cli/color' import {Command} from '@heroku-cli/command' import * as Heroku from '@heroku-cli/schema' -import cli from 'cli-ux' +import {CliUx} from '@oclif/core' import {destroyPipeline} from '../../api' import disambiguate from '../../disambiguate' +const cli = CliUx.ux + export default class PipelinesDestroy extends Command { static description = 'destroy a pipeline' @@ -20,7 +22,7 @@ export default class PipelinesDestroy extends Command { }] async run() { - const {args} = this.parse(PipelinesDestroy) + const {args} = await this.parse(PipelinesDestroy) const pipeline: Heroku.Pipeline = await disambiguate(this.heroku, args.pipeline) cli.action.start(`Destroying ${color.pipeline(pipeline.name!)} pipeline`) diff --git a/packages/pipelines/src/commands/pipelines/diff.ts b/packages/pipelines/src/commands/pipelines/diff.ts index 307608805f..ad2bb0f404 100644 --- a/packages/pipelines/src/commands/pipelines/diff.ts +++ b/packages/pipelines/src/commands/pipelines/diff.ts @@ -1,12 +1,20 @@ import color from '@heroku-cli/color' import {Command, flags} from '@heroku-cli/command' import Heroku from '@heroku-cli/schema' -import cli from 'cli-ux' +import {CliUx} from '@oclif/core' import HTTP from 'http-call' import {getCoupling, getReleases, listPipelineApps, V3_HEADER} from '../../api' import KolkrabbiAPI from '../../kolkrabbi-api' +interface AppInfo { + name: string; + repo?: string; + hash?: string; +} + +const cli = CliUx.ux + const PROMOTION_ORDER = ['development', 'staging', 'production'] async function diff(targetApp: AppInfo, downstreamApp: AppInfo, githubToken: string, herokuUserAgent: string) { @@ -65,12 +73,6 @@ async function diff(targetApp: AppInfo, downstreamApp: AppInfo, githubToken: str } } -interface AppInfo { - name: string; - repo?: string; - hash?: string; -} - export default class PipelinesDiff extends Command { static description = 'compares the latest release of this app to its downstream app(s)' @@ -111,7 +113,7 @@ export default class PipelinesDiff extends Command { } async run() { - const {flags} = this.parse(PipelinesDiff) + const {flags} = await this.parse(PipelinesDiff) const targetAppName = flags.app const coupling = await getCoupling(this.heroku, targetAppName) diff --git a/packages/pipelines/src/commands/pipelines/index.ts b/packages/pipelines/src/commands/pipelines/index.ts index b8f6c355ef..700fbf9eb0 100644 --- a/packages/pipelines/src/commands/pipelines/index.ts +++ b/packages/pipelines/src/commands/pipelines/index.ts @@ -1,6 +1,8 @@ import {Command, flags} from '@heroku-cli/command' import Heroku from '@heroku-cli/schema' -import cli from 'cli-ux' +import {CliUx} from '@oclif/core' + +const cli = CliUx.ux export default class Pipelines extends Command { static description = 'list pipelines you have access to' @@ -14,7 +16,7 @@ export default class Pipelines extends Command { } async run() { - const {flags} = this.parse(Pipelines) + const {flags} = await this.parse(Pipelines) const {body: pipelines} = await this.heroku.get('/pipelines') diff --git a/packages/pipelines/src/commands/pipelines/info.ts b/packages/pipelines/src/commands/pipelines/info.ts index 533022c830..203d33d778 100644 --- a/packages/pipelines/src/commands/pipelines/info.ts +++ b/packages/pipelines/src/commands/pipelines/info.ts @@ -1,11 +1,13 @@ import {Command, flags} from '@heroku-cli/command' import Heroku from '@heroku-cli/schema' -import cli from 'cli-ux' +import {CliUx} from '@oclif/core' import {listPipelineApps} from '../../api' import disambiguate from '../../disambiguate' import renderPipeline from '../../render-pipeline' +const cli = CliUx.ux + export default class PipelinesInfo extends Command { static description = 'show list of apps in a pipeline' @@ -30,7 +32,7 @@ export default class PipelinesInfo extends Command { }] async run() { - const {args, flags} = this.parse(PipelinesInfo) + const {args, flags} = await this.parse(PipelinesInfo) const pipeline: Heroku.Pipeline = await disambiguate(this.heroku, args.pipeline) const pipelineApps = await listPipelineApps(this.heroku, pipeline.id!) diff --git a/packages/pipelines/src/commands/pipelines/open.ts b/packages/pipelines/src/commands/pipelines/open.ts index 00aa04b7cc..fc86253f94 100644 --- a/packages/pipelines/src/commands/pipelines/open.ts +++ b/packages/pipelines/src/commands/pipelines/open.ts @@ -1,8 +1,10 @@ import {Command} from '@heroku-cli/command' -import cli from 'cli-ux' +import {CliUx} from '@oclif/core' import disambiguate from '../../disambiguate' +const cli = CliUx.ux + export default class Open extends Command { static description = 'open a pipeline in dashboard' @@ -13,7 +15,7 @@ export default class Open extends Command { }] async run() { - const {args} = this.parse(Open) + const {args} = await this.parse(Open) const pipeline: any = await disambiguate(this.heroku, args.pipeline) await cli.open(`https://dashboard.heroku.com/pipelines/${pipeline.id}`) diff --git a/packages/pipelines/src/commands/pipelines/promote.ts b/packages/pipelines/src/commands/pipelines/promote.ts index 264db478c9..ab5ddb31e0 100644 --- a/packages/pipelines/src/commands/pipelines/promote.ts +++ b/packages/pipelines/src/commands/pipelines/promote.ts @@ -1,15 +1,17 @@ import color from '@heroku-cli/color' import {APIClient, Command, flags} from '@heroku-cli/command' import Heroku from '@heroku-cli/schema' +import {CliUx} from '@oclif/core' import assert from 'assert' -import cli from 'cli-ux' import fetch from 'node-fetch' -import util from 'util' import Stream from 'stream' +import util from 'util' import {listPipelineApps} from '../../api' import keyBy from '../../key-by' +const cli = CliUx.ux + export const sleep = (time: number) => { return new Promise(resolve => setTimeout(resolve, time)) } @@ -88,7 +90,7 @@ async function promote(heroku: APIClient, label: string, id: string, sourceAppId cli.log(`${label}...`) const {body: promotions} = await heroku.post('/pipeline-promotions', options) return promotions - } catch (error) { + } catch (error: any) { if (!error.body || error.body.id !== 'two_factor') { throw error } @@ -185,7 +187,7 @@ export default class Promote extends Command { } async run() { - const {flags} = this.parse(Promote) + const {flags} = await this.parse(Promote) const appNameOrId = flags.app const coupling = await getCoupling(this.heroku, appNameOrId) cli.log(`Fetching apps from ${color.pipeline(coupling.pipeline!.name)}...`) @@ -235,7 +237,7 @@ export default class Promote extends Command { try { promotionTargets = await streamReleaseCommand(this.heroku, promotionTargets, promotion) - } catch (error) { + } catch (error: any) { cli.error(error) } diff --git a/packages/pipelines/src/commands/pipelines/remove.ts b/packages/pipelines/src/commands/pipelines/remove.ts index e73b1e61f7..822e68eb11 100644 --- a/packages/pipelines/src/commands/pipelines/remove.ts +++ b/packages/pipelines/src/commands/pipelines/remove.ts @@ -1,9 +1,11 @@ import color from '@heroku-cli/color' import {Command, flags} from '@heroku-cli/command' -import cli from 'cli-ux' +import {CliUx} from '@oclif/core' import {removeCoupling} from '../../api' +const cli = CliUx.ux + export default class PipelinesRemove extends Command { static description = 'remove this app from its pipeline' @@ -17,7 +19,7 @@ export default class PipelinesRemove extends Command { } async run() { - const {flags: {app}} = this.parse(PipelinesRemove) + const {flags: {app}} = await this.parse(PipelinesRemove) cli.action.start(`Removing ${color.app(app)}`) await removeCoupling(this.heroku, app) diff --git a/packages/pipelines/src/commands/pipelines/rename.ts b/packages/pipelines/src/commands/pipelines/rename.ts index a73c1c5eaa..871cde6eb5 100644 --- a/packages/pipelines/src/commands/pipelines/rename.ts +++ b/packages/pipelines/src/commands/pipelines/rename.ts @@ -1,10 +1,12 @@ import color from '@heroku-cli/color' import {Command} from '@heroku-cli/command' -import cli from 'cli-ux' +import {CliUx} from '@oclif/core' import {updatePipeline} from '../../api' import disambiguate from '../../disambiguate' +const cli = CliUx.ux + export default class PipelinesRename extends Command { static description = 'rename a pipeline' @@ -26,7 +28,7 @@ export default class PipelinesRename extends Command { ] async run() { - const {args} = this.parse(PipelinesRename) + const {args} = await this.parse(PipelinesRename) const pipeline = await disambiguate(this.heroku, args.pipeline) diff --git a/packages/pipelines/src/commands/pipelines/setup.ts b/packages/pipelines/src/commands/pipelines/setup.ts index 7ac9ec5e36..d5417aa729 100644 --- a/packages/pipelines/src/commands/pipelines/setup.ts +++ b/packages/pipelines/src/commands/pipelines/setup.ts @@ -1,7 +1,8 @@ import color from '@heroku-cli/color' import {Command, flags} from '@heroku-cli/command' -import cli from 'cli-ux' +import {CliUx} from '@oclif/core' + import Debug from 'debug' import {createPipeline, getAccountInfo, getTeam} from '../../api' @@ -20,6 +21,8 @@ import {nameAndRepo, STAGING_APP_INDICATOR} from '../../setup/validate' // eslint-disable-next-line new-cap const debug = Debug('pipelines:setup') +const cli = CliUx.ux + export default class Setup extends Command { static description = 'bootstrap a new pipeline with common settings and create a production and staging app (requires a fully formed app.json in the repo)' @@ -51,7 +54,7 @@ export default class Setup extends Command { ] async run() { - const {args, flags} = this.parse(Setup) + const {args, flags} = await this.parse(Setup) const errors = nameAndRepo(args) @@ -106,7 +109,7 @@ export default class Setup extends Command { try { await setup await cli.open(`https://dashboard.heroku.com/pipelines/${pipeline.id}`) - } catch (error) { + } catch (error: any) { debug(error) cli.error(error) } finally { diff --git a/packages/pipelines/src/commands/pipelines/transfer.ts b/packages/pipelines/src/commands/pipelines/transfer.ts index 9abcee7c0a..4802bda401 100644 --- a/packages/pipelines/src/commands/pipelines/transfer.ts +++ b/packages/pipelines/src/commands/pipelines/transfer.ts @@ -1,11 +1,13 @@ import color from '@heroku-cli/color' import {APIClient, Command, flags} from '@heroku-cli/command' -import cli from 'cli-ux' +import {CliUx} from '@oclif/core' import {createPipelineTransfer, getAccountInfo, getTeam, listPipelineApps} from '../../api' import disambiguate from '../../disambiguate' import renderPipeline from '../../render-pipeline' +const cli = CliUx.ux + async function getTeamOwner(heroku: APIClient, name: string) { const {body: team} = await getTeam(heroku, name) return {id: team.id, type: 'team'} @@ -48,7 +50,7 @@ export default class PipelinesTransfer extends Command { } async run() { - const {args, flags} = this.parse(PipelinesTransfer) + const {args, flags} = await this.parse(PipelinesTransfer) const pipeline = await disambiguate(this.heroku, flags.pipeline) const newOwner = await getOwner(this.heroku, args.owner) const apps = await listPipelineApps(this.heroku, pipeline.id!) diff --git a/packages/pipelines/src/commands/pipelines/update.ts b/packages/pipelines/src/commands/pipelines/update.ts index 2b762b153d..c7227c5d25 100644 --- a/packages/pipelines/src/commands/pipelines/update.ts +++ b/packages/pipelines/src/commands/pipelines/update.ts @@ -1,10 +1,12 @@ import color from '@heroku-cli/color' import {Command, flags} from '@heroku-cli/command' import {StageCompletion} from '@heroku-cli/command/lib/completions' -import cli from 'cli-ux' +import {CliUx} from '@oclif/core' import {updateCoupling} from '../../api' +const cli = CliUx.ux + export default class PipelinesUpdate extends Command { static description = 'update the app\'s stage in a pipeline' @@ -24,7 +26,7 @@ export default class PipelinesUpdate extends Command { } async run() { - const {flags} = this.parse(PipelinesUpdate) + const {flags} = await this.parse(PipelinesUpdate) const app = flags.app const stage = flags.stage diff --git a/packages/pipelines/src/commands/reviewapps/disable.ts b/packages/pipelines/src/commands/reviewapps/disable.ts index 8867c890ce..23775a45c3 100644 --- a/packages/pipelines/src/commands/reviewapps/disable.ts +++ b/packages/pipelines/src/commands/reviewapps/disable.ts @@ -1,9 +1,11 @@ import {Command, flags} from '@heroku-cli/command' import * as Heroku from '@heroku-cli/schema' -import cli from 'cli-ux' +import {CliUx} from '@oclif/core' import KolkrabbiAPI from '../../kolkrabbi-api' +const cli = CliUx.ux + export default class ReviewappsDisable extends Command { static description = 'disable review apps and/or settings on an existing pipeline' @@ -43,7 +45,7 @@ export default class ReviewappsDisable extends Command { } async run() { - const {flags} = this.parse(ReviewappsDisable) + const {flags} = await this.parse(ReviewappsDisable) if (flags.app) { // remove app & remote flags when Review Apps 1.0 is deprecated @@ -94,7 +96,7 @@ export default class ReviewappsDisable extends Command { const {body: feature} = await this.heroku.get('/account/features/dashboard-repositories-api') if (feature.enabled) { - const {body: repo} = await this.heroku.get(`/pipelines/${pipeline.id}/repo`, { + const {body: repo} = await this.heroku.get<{full_name: string}>(`/pipelines/${pipeline.id}/repo`, { headers: {Accept: 'application/vnd.heroku+json; version=3.repositories-api'}, }) settings.repo = repo.full_name diff --git a/packages/pipelines/src/commands/reviewapps/enable.ts b/packages/pipelines/src/commands/reviewapps/enable.ts index e616c6f260..1194d7b707 100644 --- a/packages/pipelines/src/commands/reviewapps/enable.ts +++ b/packages/pipelines/src/commands/reviewapps/enable.ts @@ -1,9 +1,11 @@ import {Command, flags} from '@heroku-cli/command' import * as Heroku from '@heroku-cli/schema' -import cli from 'cli-ux' +import {CliUx} from '@oclif/core' import KolkrabbiAPI from '../../kolkrabbi-api' +const cli = CliUx.ux + export default class ReviewappsEnable extends Command { static description = 'enable review apps and/or settings on an existing pipeline' @@ -33,7 +35,7 @@ export default class ReviewappsEnable extends Command { } async run() { - const {flags} = this.parse(ReviewappsEnable) + const {flags} = await this.parse(ReviewappsEnable) if (flags.app) { // remove app & remote flags when Review Apps 1.0 is deprecated @@ -81,7 +83,7 @@ export default class ReviewappsEnable extends Command { const {body: feature} = await this.heroku.get('/account/features/dashboard-repositories-api') if (feature.enabled) { - const {body: repo} = await this.heroku.get(`/pipelines/${pipeline.id}/repo`, { + const {body: repo} = await this.heroku.get<{full_name: string}>(`/pipelines/${pipeline.id}/repo`, { headers: {Accept: 'application/vnd.heroku+json; version=3.repositories-api'}, }) settings.repo = repo.full_name diff --git a/packages/pipelines/src/ownership.ts b/packages/pipelines/src/ownership.ts index 33950a39cb..04d8626c89 100644 --- a/packages/pipelines/src/ownership.ts +++ b/packages/pipelines/src/ownership.ts @@ -1,10 +1,12 @@ import color from '@heroku-cli/color' import {APIClient} from '@heroku-cli/command' import Heroku from '@heroku-cli/schema' -import cli from 'cli-ux' +import {CliUx} from '@oclif/core' import {getTeam} from './api' +const cli = CliUx.ux + export function warnMixedOwnership(pipelineApps: Array, pipeline: Heroku.Pipeline, owner: string) { const hasMixedOwnership = pipelineApps.some(app => { return (app.owner && app.owner.id) !== pipeline.owner.id diff --git a/packages/pipelines/src/render-pipeline.ts b/packages/pipelines/src/render-pipeline.ts index 6bc419a425..04056adac2 100644 --- a/packages/pipelines/src/render-pipeline.ts +++ b/packages/pipelines/src/render-pipeline.ts @@ -1,11 +1,13 @@ import color from '@heroku-cli/color' import {APIClient} from '@heroku-cli/command' import Heroku from '@heroku-cli/schema' -import cli, {Table} from 'cli-ux' +import {CliUx} from '@oclif/core' import sortBy from 'lodash.sortby' import {getOwner, warnMixedOwnership} from './ownership' +const cli = CliUx.ux + export default async function renderPipeline( heroku: APIClient, pipeline: Heroku.Pipeline, @@ -22,7 +24,7 @@ export default async function renderPipeline( cli.log('') - const columns: Table.table.Columns = { + const columns: CliUx.Table.table.Columns = { name: { header: 'app name', get(row) { diff --git a/packages/pipelines/src/setup/create-apps.ts b/packages/pipelines/src/setup/create-apps.ts index 72c0dc779f..cc8687d415 100644 --- a/packages/pipelines/src/setup/create-apps.ts +++ b/packages/pipelines/src/setup/create-apps.ts @@ -1,12 +1,14 @@ import Heroku from '@heroku-cli/schema' -import cli from 'cli-ux' +import {CliUx} from '@oclif/core' // eslint-disable-next-line @typescript-eslint/no-unused-vars import http from 'http-call' import {createAppSetup} from '../api' +const cli = CliUx.ux + interface CreateAppOptions { archiveURL: string; name: string; diff --git a/packages/pipelines/src/setup/get-ci-settings.ts b/packages/pipelines/src/setup/get-ci-settings.ts index 3334a699d0..bb06a7fbe0 100644 --- a/packages/pipelines/src/setup/get-ci-settings.ts +++ b/packages/pipelines/src/setup/get-ci-settings.ts @@ -1,4 +1,6 @@ -import cli from 'cli-ux' +import {CliUx} from '@oclif/core' + +const cli = CliUx.ux export default async function getCISettings(yes: any, organization: any) { const settings = { diff --git a/packages/pipelines/src/setup/get-name-and-repo.ts b/packages/pipelines/src/setup/get-name-and-repo.ts index 0c14408a79..6ce013484f 100644 --- a/packages/pipelines/src/setup/get-name-and-repo.ts +++ b/packages/pipelines/src/setup/get-name-and-repo.ts @@ -1,7 +1,9 @@ -import cli from 'cli-ux' +import {CliUx} from '@oclif/core' import {pipelineName, repoName} from './validate' +const cli = CliUx.ux + function filter(obj: any) { const ret: any = {} Object.keys(obj) diff --git a/packages/pipelines/src/setup/get-settings.ts b/packages/pipelines/src/setup/get-settings.ts index 2fec022ca3..00ccab46d4 100644 --- a/packages/pipelines/src/setup/get-settings.ts +++ b/packages/pipelines/src/setup/get-settings.ts @@ -1,4 +1,6 @@ -import cli from 'cli-ux' +import {CliUx} from '@oclif/core' + +const cli = CliUx.ux const DEFAULT_SETTINGS = { auto_deploy: true, diff --git a/packages/pipelines/src/setup/setup-pipeline.ts b/packages/pipelines/src/setup/setup-pipeline.ts index ccae9fc415..2b6b3b3992 100644 --- a/packages/pipelines/src/setup/setup-pipeline.ts +++ b/packages/pipelines/src/setup/setup-pipeline.ts @@ -1,4 +1,6 @@ -import cli from 'cli-ux' +import {CliUx} from '@oclif/core' + +const cli = CliUx.ux export default function setupPipeline(kolkrabbi: any, app: any, settings: any, pipelineID: any, ciSettings: any = {}) { const promises = [kolkrabbi.updateAppLink(app, settings)] diff --git a/packages/pipelines/src/setup/validate.ts b/packages/pipelines/src/setup/validate.ts index ead5c80d1a..969b044677 100644 --- a/packages/pipelines/src/setup/validate.ts +++ b/packages/pipelines/src/setup/validate.ts @@ -6,6 +6,8 @@ const ERR_REPO_FORMAT = 'Repository name must be in the format organization/repo const REPO_REGEX = /.+\/.+/ +type ValidatedResponse = [true] | [false, string] + export function pipelineName(name: any): ValidatedResponse { const isValid = name.length >= PIPELINE_MIN_LENGTH && name.length <= PIPELINE_MAX_LENGTH @@ -27,4 +29,3 @@ export function nameAndRepo({name, repo}: {name?: string; repo?: string}) { return errors } -type ValidatedResponse = [true] | [false, string] diff --git a/packages/pipelines/test/commands/pipelines/add.test.ts b/packages/pipelines/test/commands/pipelines/add.test.ts index 1f6cf15bdc..448e0ea6bf 100644 --- a/packages/pipelines/test/commands/pipelines/add.test.ts +++ b/packages/pipelines/test/commands/pipelines/add.test.ts @@ -37,7 +37,9 @@ describe('pipelines:add', () => { // the inqurier package to simulate what would be // returned from answering if "development" was // selected by the user - .stub(inquirer, 'prompt', (questions: any) => { + .stub(inquirer, 'prompt', function () { + // eslint-disable-next-line prefer-rest-params + const questions = arguments[0] if (questions[0].name === 'stage') { return Promise.resolve({stage: 'development'}) } @@ -72,8 +74,9 @@ describe('pipelines:add', () => { // similuating that the user picked the identical // pipeline value with id: '0987' for the pipeline // question - .stub(inquirer, 'prompt', (questions: any) => { - const question = questions[0] + .stub(inquirer, 'prompt', function () { + // eslint-disable-next-line prefer-rest-params + const question = arguments[0][0] if (question && question.name === 'pipeline') { return Promise.resolve({pipeline: { diff --git a/packages/pipelines/test/commands/pipelines/info.test.ts b/packages/pipelines/test/commands/pipelines/info.test.ts index afa49e4ea7..6d92bcaed8 100644 --- a/packages/pipelines/test/commands/pipelines/info.test.ts +++ b/packages/pipelines/test/commands/pipelines/info.test.ts @@ -24,19 +24,21 @@ function itShowsPipelineApps(ctx: TestContext) { }) const expectedTable = [ - 'app name stage ', - '⬢ development-app-1 development ', - '⬢ development-app-2 development ', - '⬢ review-app-1 review ', - '⬢ review-app-2 review ', - '⬢ review-app-3 review ', - '⬢ review-app-4 review ', - '⬢ staging-app-1 staging ', - '⬢ staging-app-2 staging ', + 'app name stage \n', + '⬢ development-app-1 development \n', + '⬢ development-app-2 development \n', + '⬢ review-app-1 review \n', + '⬢ review-app-2 review \n', + '⬢ review-app-3 review \n', + '⬢ review-app-4 review \n', + '⬢ staging-app-1 staging \n', + '⬢ staging-app-2 staging \n', '⬢ production-app-1 production ', - ].join('\n') + ] - expect(ctx.stdout).to.contain(expectedTable) + expectedTable.forEach(ln => { + expect(ctx.stdout).to.contain(ln) + }) } describe('pipelines:info', function () { @@ -114,7 +116,8 @@ describe('pipelines:info', function () { `Warning: Some apps in this pipeline do not belong to ${owner}.`, 'All apps in a pipeline must have the same owner as the pipeline owner.', 'Transfer these apps or change the pipeline owner in pipeline settings.', - 'See https://devcenter.heroku.com/articles/pipeline-ownership-transition for more info.', + 'See https://devcenter.heroku.com/articles/pipeline-ownership-transition', + 'for more info.', ] warningMessage.forEach(message => { diff --git a/packages/pipelines/test/commands/pipelines/open.test.ts b/packages/pipelines/test/commands/pipelines/open.test.ts index 53d107c6f1..6336831067 100644 --- a/packages/pipelines/test/commands/pipelines/open.test.ts +++ b/packages/pipelines/test/commands/pipelines/open.test.ts @@ -1,5 +1,7 @@ +import {CliUx} from '@oclif/core' import {expect, test} from '@oclif/test' -import cli from 'cli-ux' + +const cli = CliUx.ux describe('pipelines:open', () => { const pipeline = {id: '0123', name: 'Rigel'} diff --git a/packages/pipelines/test/commands/pipelines/promote.test.ts b/packages/pipelines/test/commands/pipelines/promote.test.ts index 112974a516..6e00e198a9 100644 --- a/packages/pipelines/test/commands/pipelines/promote.test.ts +++ b/packages/pipelines/test/commands/pipelines/promote.test.ts @@ -1,4 +1,5 @@ import {expect, test} from '@oclif/test' + import * as PromoteCmd from '../../../src/commands/pipelines/promote' describe('pipelines:promote', () => { diff --git a/packages/pipelines/test/commands/pipelines/setup.test.ts b/packages/pipelines/test/commands/pipelines/setup.test.ts index c0cc39e028..f703fa497a 100644 --- a/packages/pipelines/test/commands/pipelines/setup.test.ts +++ b/packages/pipelines/test/commands/pipelines/setup.test.ts @@ -1,7 +1,9 @@ +import {CliUx} from '@oclif/core' import {expect, test} from '@oclif/test' -import {cli} from 'cli-ux' import sinon from 'sinon' +const cli = CliUx.ux + describe('pipelines:setup', () => { test .nock('https://kolkrabbi.heroku.com', kolkrabbi => kolkrabbi.get('/account/github/token').replyWithError('')) diff --git a/packages/pipelines/test/helpers/init.js b/packages/pipelines/test/helpers/init.js index 8cada20491..8f091c9148 100644 --- a/packages/pipelines/test/helpers/init.js +++ b/packages/pipelines/test/helpers/init.js @@ -1,4 +1,4 @@ global.columns = 140 -const { color } = require('@heroku-cli/color') +const {color} = require('@heroku-cli/color') color.enabled = true diff --git a/packages/pipelines/test/tsconfig.json b/packages/pipelines/test/tsconfig.json index cc70e12d43..151a8450a0 100644 --- a/packages/pipelines/test/tsconfig.json +++ b/packages/pipelines/test/tsconfig.json @@ -1,6 +1,7 @@ { "extends": "../tsconfig", "compilerOptions": { - "noEmit": true + "noEmit": true, + "skipLibCheck": true } } diff --git a/packages/pipelines/tsconfig.json b/packages/pipelines/tsconfig.json index c6477fa01e..aaea80e564 100644 --- a/packages/pipelines/tsconfig.json +++ b/packages/pipelines/tsconfig.json @@ -5,6 +5,7 @@ "module": "commonjs", "outDir": "lib", "rootDir": "src", + "skipLibCheck": true, "strict": true, "target": "es2017", "esModuleInterop": true diff --git a/packages/ps/.eslintrc b/packages/ps/.eslintrc index 7c4a11dc71..2b45bde115 100644 --- a/packages/ps/.eslintrc +++ b/packages/ps/.eslintrc @@ -4,6 +4,7 @@ "oclif-typescript" ], "rules": { - "unicorn/no-abusive-eslint-disable": "off" + "unicorn/no-abusive-eslint-disable": "off", + "camelcase": "off" } } diff --git a/packages/ps/bin/run b/packages/ps/bin/run index 3c4ae3ac07..7bd7df0b58 100755 --- a/packages/ps/bin/run +++ b/packages/ps/bin/run @@ -1,4 +1,6 @@ #!/usr/bin/env node -require('@oclif/command').run() -.catch(require('@oclif/errors/handle')) +const oclif = require('@oclif/core') + +oclif.run().catch(require('@oclif/core/handle')) + diff --git a/packages/ps/package.json b/packages/ps/package.json index da3ae4aaef..f1698c91b9 100644 --- a/packages/ps/package.json +++ b/packages/ps/package.json @@ -6,23 +6,18 @@ "bugs": "https://github.com/heroku/cli/issues", "dependencies": { "@heroku-cli/color": "^1.1.14", - "@heroku-cli/command": "^8.4.1", - "@oclif/command": "^1.5.11", - "@oclif/config": "^1.12.10", - "cli-ux": "^4.9.3", + "@heroku-cli/command": "^9.0.2", + "@oclif/core": "^1.26.2", "lodash": "^4.17.11" }, "devDependencies": { "@fancy-test/nock": "^0.1.1", - "@heroku-cli/dev-cli": "^1.26.13", "@heroku-cli/schema": "^1.0.25", - "@oclif/plugin-help": "^2.1.6", - "@oclif/test": "^1.2.4", + "@oclif/test": "^2.2.20", "@types/chai": "^4.1.7", "@types/lodash": "^4.14.123", "@types/mocha": "^5.2.6", "@types/nock": "^9.3.1", - "@types/node": "^10.12.24", "@types/supports-color": "^5.3.0", "chai": "^4.2.0", "eslint": "^6.7.2", @@ -31,12 +26,13 @@ "globby": "^9.0.0", "mocha": "^5.2.0", "nock": "^10.0.6", + "oclif": "3.6.4", "ts-node": "10.9.1", "tslib": "^1.9.3", - "typescript": "3.7.5" + "typescript": "4.8.4" }, "engines": { - "node": ">=10.0.0" + "node": ">=14" }, "files": [ "oclif.manifest.json", @@ -48,11 +44,14 @@ ], "license": "MIT", "oclif": { + "additionalHelpFlags": [ + "-h" + ], + "additionalVersionFlags": [ + "-v" + ], "commands": "./lib/commands", "bin": "heroku", - "devPlugins": [ - "@oclif/plugin-help" - ], "repositoryPrefix": "<%- repo %>/blob/v<%- version %>/packages/ps/<%- commandPath %>" }, "repository": "heroku/cli", @@ -63,9 +62,9 @@ "lint": "eslint . --ext .ts --config .eslintrc", "posttest": "yarn lint", "postpublish": "yarn run clean", - "prepack": "yarn run build && oclif-dev manifest && oclif-dev readme", + "prepack": "yarn run build && oclif manifest", "preversion": "yarn run clean", "test": "mocha --forbid-only \"test/**/*.test.ts\"", - "version": "oclif-dev readme && git add README.md" + "version": "oclif readme && git add README.md" } } diff --git a/packages/ps/src/commands/ps/autoscale/disable.ts b/packages/ps/src/commands/ps/autoscale/disable.ts index 3d0037ed80..60d40691fc 100644 --- a/packages/ps/src/commands/ps/autoscale/disable.ts +++ b/packages/ps/src/commands/ps/autoscale/disable.ts @@ -1,6 +1,6 @@ import {Command, flags} from '@heroku-cli/command' import * as Heroku from '@heroku-cli/schema' -import {cli} from 'cli-ux' +import {CliUx} from '@oclif/core' const METRICS_HOST = 'api.metrics.heroku.com' @@ -13,8 +13,8 @@ export default class Disable extends Command { } async run() { - const {flags} = this.parse(Disable) - cli.action.start('Disabling dyno autoscaling') + const {flags} = await this.parse(Disable) + CliUx.ux.action.start('Disabling dyno autoscaling') const appResponse = await this.heroku.get(`/apps/${flags.app}`) const app = appResponse.body @@ -35,6 +35,6 @@ export default class Disable extends Command { }, }) - cli.action.stop() + CliUx.ux.action.stop() } } diff --git a/packages/ps/src/commands/ps/autoscale/enable.ts b/packages/ps/src/commands/ps/autoscale/enable.ts index fed9302627..03030e8523 100644 --- a/packages/ps/src/commands/ps/autoscale/enable.ts +++ b/packages/ps/src/commands/ps/autoscale/enable.ts @@ -1,6 +1,6 @@ import {Command, flags} from '@heroku-cli/command' import * as Heroku from '@heroku-cli/schema' -import {cli} from 'cli-ux' +import {CliUx} from '@oclif/core' const METRICS_HOST = 'api.metrics.heroku.com' @@ -22,8 +22,8 @@ export default class Enable extends Command { } async run() { - const {flags} = this.parse(Enable) - cli.action.start('Enabling dyno autoscaling') + const {flags} = await this.parse(Enable) + CliUx.ux.action.start('Enabling dyno autoscaling') const [appResponse, formationResponse] = await Promise.all([ this.heroku.get(`/apps/${flags.app}`), @@ -80,6 +80,6 @@ export default class Enable extends Command { }) } - cli.action.stop() + CliUx.ux.action.stop() } } diff --git a/packages/ps/src/commands/ps/wait.ts b/packages/ps/src/commands/ps/wait.ts index 7d364fb3dd..be4abac3fb 100644 --- a/packages/ps/src/commands/ps/wait.ts +++ b/packages/ps/src/commands/ps/wait.ts @@ -1,5 +1,5 @@ import {Command, flags} from '@heroku-cli/command' -import {cli} from 'cli-ux' +import {CliUx} from '@oclif/core' import {Dyno, Release} from '@heroku-cli/schema' @@ -16,10 +16,10 @@ export default class Wait extends Command { 'wait-interval': flags.integer({ char: 'w', description: 'how frequently to poll in seconds (to avoid hitting Heroku API rate limits)', - parse: input => { + parse: async input => { const w = parseInt(input, 10) if (w < 10) { - cli.error('wait-interval must be at least 10', {exit: 1}) + CliUx.ux.error('wait-interval must be at least 10', {exit: 1}) } return w }, @@ -33,7 +33,7 @@ export default class Wait extends Command { } async run() { - const {flags} = this.parse(Wait) + const {flags} = await this.parse(Wait) const {body: releases} = await this.heroku.request(`/apps/${flags.app}/releases`, { partial: true, @@ -70,20 +70,20 @@ export default class Wait extends Command { const releasedFraction = `${onLatest.length} / ${relevantDynos.length}` if (onLatest.length === relevantDynos.length) { if (!released) { - cli.action.stop(`${releasedFraction}, done`) + CliUx.ux.action.stop(`${releasedFraction}, done`) } break } if (released) { released = false - cli.action.start(`Waiting for every dyno to be running v${latestRelease.version}`) + CliUx.ux.action.start(`Waiting for every dyno to be running v${latestRelease.version}`) } - cli.action.status = releasedFraction + CliUx.ux.action.status = releasedFraction // eslint-disable-next-line no-await-in-loop - await cli.wait(interval * 1000) + await CliUx.ux.wait(interval * 1000) } } } diff --git a/packages/ps/src/commands/regions.ts b/packages/ps/src/commands/regions.ts index 62a22c9386..f82ac370cb 100644 --- a/packages/ps/src/commands/regions.ts +++ b/packages/ps/src/commands/regions.ts @@ -1,7 +1,7 @@ import color from '@heroku-cli/color' import {Command, flags} from '@heroku-cli/command' import * as Heroku from '@heroku-cli/schema' -import {cli} from 'cli-ux' +import {CliUx} from '@oclif/core' import * as _ from 'lodash' export default class Regions extends Command { @@ -16,7 +16,7 @@ export default class Regions extends Command { } async run() { - const {flags} = this.parse(Regions) + const {flags} = await this.parse(Regions) let {body: regions} = await this.heroku.get('/regions') if (flags.private) { regions = regions.filter((region: any) => region.private_capable) @@ -26,14 +26,20 @@ export default class Regions extends Command { regions = _.sortBy(regions, ['private_capable', 'name']) if (flags.json) { - cli.styledJSON(regions) + CliUx.ux.styledJSON(regions) } else { - cli.table(regions, { - columns: [ - {key: 'name', label: 'ID', format: (n: any) => color.green(n)}, - {key: 'description', label: 'Location'}, - {key: 'private_capable', label: 'Runtime', format: (c: any) => c ? 'Private Spaces' : 'Common Runtime'}, - ], + CliUx.ux.table(regions, { + name: { + header: 'ID', + get: ({name}: any) => color.green(name), + }, + description: { + header: 'Location', + }, + private_capable: { + header: 'Runtime', + get: ({private_capable}: any) => private_capable ? 'Private Spaces' : 'Common Runtime', + }, }) } } diff --git a/packages/ps/test/commands/enable.test.ts b/packages/ps/test/commands/enable.test.ts index 1a9c0608fd..061f689bda 100644 --- a/packages/ps/test/commands/enable.test.ts +++ b/packages/ps/test/commands/enable.test.ts @@ -44,7 +44,7 @@ describe('without specifying an app', () => { test .stderr() .command(['ps:autoscale:enable', '--min', '1', '--max', '2']) - .catch(error => expect(error.message).to.contain('--app')) + .catch(error => expect(error.message).to.contain('Missing required flag app')) .it('aborts the command') }) @@ -52,7 +52,7 @@ describe('without specify a minimum', () => { test .stderr() .command(['ps:autoscale:enable', '--max', '2', '--app', APP_NAME]) - .catch(error => expect(error.message).to.contain('--min')) + .catch(error => expect(error.message).to.contain('Missing required flag min')) .it('aborts the command') }) @@ -60,7 +60,7 @@ describe('without specify a maximum', () => { test .stderr() .command(['ps:autoscale:enable', '--min', '1', '--app', APP_NAME]) - .catch(error => expect(error.message).to.contain('--max')) + .catch(error => expect(error.message).to.contain('Missing required flag max')) .it('aborts the command') }) diff --git a/packages/ps/test/commands/regions.test.ts b/packages/ps/test/commands/regions.test.ts index 5a266d3854..7005730a3c 100644 --- a/packages/ps/test/commands/regions.test.ts +++ b/packages/ps/test/commands/regions.test.ts @@ -1,4 +1,4 @@ -import {expect, test} from '../test' +import {expect, test} from '@oclif/test' const withRegions = test .nock('https://api.heroku.com', api => api @@ -15,33 +15,21 @@ describe('regions', () => { .stdout() .command(['regions']) .it('list regions', async ({stdout}) => { - expect(stdout).to.equal(`ID Location Runtime -────── ───────────────────── ────────────── -eu Europe Common Runtime -us United States Common Runtime -oregon Oregon, United States Private Spaces -`) + expect(stdout).to.equal(' ID Location Runtime \n ────── ───────────────────── ────────────── \n eu Europe Common Runtime \n us United States Common Runtime \n oregon Oregon, United States Private Spaces \n') }) withRegions .stdout() .command(['regions', '--private']) .it('--private', async ({stdout}) => { - expect(stdout).to.equal(`ID Location Runtime -────── ───────────────────── ────────────── -oregon Oregon, United States Private Spaces -`) + expect(stdout).to.equal(' ID Location Runtime \n ────── ───────────────────── ────────────── \n oregon Oregon, United States Private Spaces \n') }) withRegions .stdout() .command(['regions', '--common']) .it('--common', async ({stdout}) => { - expect(stdout).to.equal(`ID Location Runtime -── ───────────── ────────────── -eu Europe Common Runtime -us United States Common Runtime -`) + expect(stdout).to.equal(' ID Location Runtime \n ── ───────────── ────────────── \n eu Europe Common Runtime \n us United States Common Runtime \n') }) withRegions diff --git a/packages/ps/test/commands/wait.test.ts b/packages/ps/test/commands/wait.test.ts index 7cd07a2d21..7354dbd3c6 100644 --- a/packages/ps/test/commands/wait.test.ts +++ b/packages/ps/test/commands/wait.test.ts @@ -1,5 +1,5 @@ import {expect, test} from '@oclif/test' -import {cli} from 'cli-ux' +import {CliUx} from '@oclif/core' const API_HOST = 'https://api.heroku.com' const APP_NAME = 'wubalubadubdub' @@ -65,7 +65,7 @@ describe('heroku ps:wait', () => { ]), ) // eslint-disable-next-line @typescript-eslint/no-empty-function - .stub(cli, 'wait', () => () => {}) + .stub(CliUx.ux, 'wait', () => () => {}) .command(['ps:wait', '--app', APP_NAME]) .it('waits for all dynos to be on latest release', ctx => { expect(ctx.stderr).to.contain('Waiting for every dyno to be running v23... 2 / 2, done') @@ -114,7 +114,7 @@ describe('heroku ps:wait', () => { ]), ) // eslint-disable-next-line @typescript-eslint/no-empty-function - .stub(cli, 'wait', () => () => {}) + .stub(CliUx.ux, 'wait', () => () => {}) .command(['ps:wait', '--with-run', '--app', APP_NAME]) .it('includes run dynos with the --with-run flag', ctx => { expect(ctx.stderr).to.contain('Waiting for every dyno to be running v23... 2 / 2, done') diff --git a/packages/ps/test/test.ts b/packages/ps/test/test.ts deleted file mode 100644 index 47dd014012..0000000000 --- a/packages/ps/test/test.ts +++ /dev/null @@ -1,4 +0,0 @@ -import * as Test from '@oclif/test' -export {expect} from '@oclif/test' - -export const test = Test.test diff --git a/packages/ps/tsconfig.json b/packages/ps/tsconfig.json index c6454f7a5f..7069ac7c9c 100644 --- a/packages/ps/tsconfig.json +++ b/packages/ps/tsconfig.json @@ -9,6 +9,7 @@ "rootDirs": [ "./src" ], + "skipLibCheck": true, "strict": true, "target": "es2017" }, diff --git a/packages/redis-v5/package.json b/packages/redis-v5/package.json index a0965c37c6..37fb976c46 100644 --- a/packages/redis-v5/package.json +++ b/packages/redis-v5/package.json @@ -19,14 +19,14 @@ "ssh2": "^1.11.0" }, "devDependencies": { - "@heroku-cli/dev-cli": "^1.26.13", - "@oclif/plugin-legacy": "^1.2.0", + "@oclif/plugin-legacy": "^1.3.0", "chai": "^4.2.0", "chai-as-promised": "^7.1.1", "lolex": "^3.1.0", "mocha": "^5.2.0", "nock": "^10.0.6", "nyc": "^15.1.0", + "oclif": "3.6.4", "proxyquire": "^2.1.0", "sinon": "^7.2.3" }, @@ -45,8 +45,8 @@ "repository": "heroku/cli", "scripts": { "postpublish": "rm oclif.manifest.json", - "prepack": "oclif-dev manifest", + "prepack": "oclif manifest", "test": "nyc mocha", - "version": "oclif-dev readme && git add README.md" + "version": "oclif readme && git add README.md" } } diff --git a/packages/run-v5/lib/colorize.js b/packages/run-v5/lib/colorize.js index 53a47f2158..70380a3ccd 100644 --- a/packages/run-v5/lib/colorize.js +++ b/packages/run-v5/lib/colorize.js @@ -1,4 +1,4 @@ -const {default: ux} = require('cli-ux') +const {CliUx} = require('@oclif/core') const {default: c} = require('@heroku-cli/color') const COLORS = [ @@ -87,7 +87,7 @@ function colorizeRouter (body) { return other(k + '=') + v }).join(' ') } catch (err) { - ux.warn(err) + CliUx.ux.warn(err) return body } } @@ -131,7 +131,7 @@ function colorizeRun (body) { ].join('') } } catch (err) { - ux.warn(err) + CliUx.ux.warn(err) } return body } @@ -189,7 +189,7 @@ function colorizeWeb (body) { ].join('') } } catch (err) { - ux.warn(err) + CliUx.ux.warn(err) } return body } diff --git a/packages/run-v5/package.json b/packages/run-v5/package.json index 46d179222b..83a7bb9330 100644 --- a/packages/run-v5/package.json +++ b/packages/run-v5/package.json @@ -19,7 +19,7 @@ }, "dependencies": { "@heroku-cli/color": "^1.1.14", - "@heroku-cli/command": "^8.4.1", + "@heroku-cli/command": "^9.0.2", "@heroku-cli/notifications": "^1.2.2", "@heroku/eventsource": "^1.0.7", "fs-extra": "^7.0.1", @@ -27,14 +27,15 @@ "shellwords": "^0.1.1" }, "devDependencies": { - "@heroku-cli/dev-cli": "^1.26.13", - "@oclif/plugin-legacy": "^1.2.0", + "@oclif/core": "^1.26.2", + "@oclif/plugin-legacy": "^1.3.0", "chai": "^4.2.0", "fixture-stdout": "0.2.1", "mocha": "^5.2.0", "mocha-junit-reporter": "1.18.0", "netrc": "0.1.4", "nock": "^10.0.6", + "oclif": "3.6.4", "sinon": "^7.2.3" }, "files": [ @@ -48,12 +49,20 @@ "heroku-plugin" ], "license": "ISC", + "oclif": { + "additionalHelpFlags": [ + "-h" + ], + "additionalVersionFlags": [ + "-v" + ] + }, "repository": "heroku/cli", "scripts": { "postpack": "rm oclif.manifest.json", - "prepack": "oclif-dev manifest", + "prepack": "oclif manifest", "test": "mocha", "test:acceptance": "yarn test --grep='@acceptance'", - "version": "oclif-dev readme && git add README.md" + "version": "oclif readme && git add README.md" } } diff --git a/packages/run/.eslintignore b/packages/run/.eslintignore new file mode 100644 index 0000000000..a65b41774a --- /dev/null +++ b/packages/run/.eslintignore @@ -0,0 +1 @@ +lib diff --git a/packages/run/.eslintrc b/packages/run/.eslintrc index 7c4a11dc71..a6a3611d45 100644 --- a/packages/run/.eslintrc +++ b/packages/run/.eslintrc @@ -4,6 +4,7 @@ "oclif-typescript" ], "rules": { - "unicorn/no-abusive-eslint-disable": "off" + "unicorn/no-abusive-eslint-disable": 0, + "camelcase": "off" } } diff --git a/packages/run/bin/run b/packages/run/bin/run index 3c4ae3ac07..7f51ae939d 100755 --- a/packages/run/bin/run +++ b/packages/run/bin/run @@ -1,4 +1,4 @@ #!/usr/bin/env node -require('@oclif/command').run() -.catch(require('@oclif/errors/handle')) +require('@oclif/core').Command.run() +.catch(require('@oclif/core').Errors.handle) diff --git a/packages/run/package.json b/packages/run/package.json index 1dfec5b44a..99e32014f8 100644 --- a/packages/run/package.json +++ b/packages/run/package.json @@ -5,23 +5,18 @@ "bugs": "https://github.com/heroku/cli/issues", "dependencies": { "@heroku-cli/color": "^1.1.14", - "@heroku-cli/command": "^8.4.1", + "@heroku-cli/command": "^9.0.2", "@heroku-cli/notifications": "^1.2.2", "@heroku/eventsource": "^1.0.7", - "@oclif/command": "^1", - "@oclif/config": "^1", - "cli-ux": "^5.3.1", + "@oclif/core": "1.22.0", "debug": "^4.1.1", "tslib": "^1" }, "devDependencies": { - "@heroku-cli/dev-cli": "^1.26.13", "@heroku-cli/schema": "^1.0.25", - "@oclif/plugin-help": "^2", - "@oclif/test": "^1", + "@oclif/test": "^2.2.20", "@types/chai": "^4", "@types/mocha": "^5", - "@types/node": "^10", "@types/node-notifier": "^5.4.0", "bats": "^1.1.0", "chai": "^4", @@ -32,12 +27,13 @@ "http-call": "^5.2.5", "mocha": "^5", "nyc": "^15.1.0", + "oclif": "3.6.4", "sinon": "^7.4.1", "ts-node": "^10", - "typescript": "3.7.5" + "typescript": "4.8.4" }, "engines": { - "node": ">=10.0.0" + "node": ">=14" }, "files": [ "/lib", @@ -50,11 +46,14 @@ ], "license": "MIT", "oclif": { + "additionalHelpFlags": [ + "-h" + ], + "additionalVersionFlags": [ + "-v" + ], "commands": "./lib/commands", "bin": "heroku", - "devPlugins": [ - "@oclif/plugin-help" - ], "topics": { "run": { "description": "run a one-off process inside a Heroku dyno" @@ -68,11 +67,11 @@ "scripts": { "lint": "eslint . --ext .ts --config .eslintrc", "postpack": "rm -f oclif.manifest.json", - "prepack": "rm -rf lib && tsc -b && oclif-dev manifest && oclif-dev readme", + "prepack": "rm -rf lib && tsc -b && oclif manifest", "pretest": "tsc -p test --noEmit", "test": "nyc --extension .ts mocha --forbid-only \"test/**/*.test.ts\"", "test:acceptance": "yarn test --grep='@acceptance'", "posttest": "yarn lint", - "version": "oclif-dev readme && git add README.md" + "version": "oclif readme && git add README.md" } } diff --git a/packages/run/src/commands/console.ts b/packages/run/src/commands/console.ts index d76c933eeb..796ec0c0f7 100644 --- a/packages/run/src/commands/console.ts +++ b/packages/run/src/commands/console.ts @@ -15,7 +15,7 @@ export default class RunConsole extends Command { } async run() { - const {flags} = this.parse(RunConsole) + const {flags} = await this.parse(RunConsole) const opts = { heroku: this.heroku, diff --git a/packages/run/src/commands/logs.ts b/packages/run/src/commands/logs.ts index 2710a23a5b..68cdff91d5 100644 --- a/packages/run/src/commands/logs.ts +++ b/packages/run/src/commands/logs.ts @@ -32,7 +32,7 @@ disable colors with --no-color, HEROKU_LOGS_COLOR=0, or HEROKU_COLOR=0` } async run() { - const {flags} = this.parse(Logs) + const {flags} = await this.parse(Logs) color.enabled = flags['force-colors'] || color.enabled diff --git a/packages/run/src/commands/rake.ts b/packages/run/src/commands/rake.ts index 0962d3cb0c..53e878cba7 100644 --- a/packages/run/src/commands/rake.ts +++ b/packages/run/src/commands/rake.ts @@ -1,7 +1,7 @@ // tslint:disable:file-name-casing import {Command, flags} from '@heroku-cli/command' import {DynoSizeCompletion} from '@heroku-cli/command/lib/completions' -import cli from 'cli-ux' +import {CliUx} from '@oclif/core' import Dyno from '../lib/dyno' import {buildCommand} from '../lib/helpers' @@ -21,7 +21,7 @@ export default class RunRake extends Command { } async run() { - const {flags, argv} = this.parse(RunRake) + const {flags, argv} = await this.parse(RunRake) const opts = { heroku: this.heroku, @@ -39,7 +39,7 @@ export default class RunRake extends Command { await dyno.start() } catch (error) { if (error.exitCode) { - cli.error(error, {exit: error.exitCode}) + CliUx.ux.error(error, {exit: error.exitCode}) } else { throw error } diff --git a/packages/run/src/commands/run/detached.ts b/packages/run/src/commands/run/detached.ts index 3f95f618e1..493bfc2b83 100644 --- a/packages/run/src/commands/run/detached.ts +++ b/packages/run/src/commands/run/detached.ts @@ -2,7 +2,7 @@ import color from '@heroku-cli/color' import {Command, flags} from '@heroku-cli/command' import {DynoSizeCompletion, ProcessTypeCompletion} from '@heroku-cli/command/lib/completions' -import cli from 'cli-ux' +import {CliUx} from '@oclif/core' import Dyno from '../../lib/dyno' import {buildCommand} from '../../lib/helpers' @@ -27,7 +27,7 @@ export default class RunDetached extends Command { } async run() { - const {flags, argv} = this.parse(RunDetached) + const {flags, argv} = await this.parse(RunDetached) const opts = { heroku: this.heroku, @@ -54,7 +54,7 @@ export default class RunDetached extends Command { tail: true, }) } else { - cli.log(`Run ${color.cmd('heroku logs --app ' + dyno.opts.app + ' --dyno ' + dyno.dyno.name)} to view the output.`) + CliUx.ux.log(`Run ${color.cmd('heroku logs --app ' + dyno.opts.app + ' --dyno ' + dyno.dyno.name)} to view the output.`) } } } diff --git a/packages/run/src/commands/run/index.ts b/packages/run/src/commands/run/index.ts index 5e04e46d7c..af6722a307 100644 --- a/packages/run/src/commands/run/index.ts +++ b/packages/run/src/commands/run/index.ts @@ -1,6 +1,6 @@ import {Command, flags} from '@heroku-cli/command' import {DynoSizeCompletion, ProcessTypeCompletion} from '@heroku-cli/command/lib/completions' -import cli from 'cli-ux' +import {CliUx} from '@oclif/core' import debugFactory from 'debug' import * as Heroku from '@heroku-cli/schema' @@ -33,7 +33,7 @@ export default class Run extends Command { } async run() { - const {argv, flags} = this.parse(Run) + const {argv, flags} = await this.parse(Run) const opts = { 'exit-code': flags['exit-code'], @@ -61,7 +61,7 @@ export default class Run extends Command { } catch (error) { debug(error) if (error.exitCode) { - cli.error(error.message, {code: error.exitCode, exit: error.exitCode}) + CliUx.ux.error(error.message, {code: error.exitCode, exit: error.exitCode}) } else { throw error } diff --git a/packages/run/src/commands/run/inside.ts b/packages/run/src/commands/run/inside.ts index c12a3133aa..7733b3350b 100644 --- a/packages/run/src/commands/run/inside.ts +++ b/packages/run/src/commands/run/inside.ts @@ -1,6 +1,6 @@ // tslint:disable:file-name-casing import {Command, flags} from '@heroku-cli/command' -import cli from 'cli-ux' +import {CliUx} from '@oclif/core' import debugFactory from 'debug' import Dyno from '../../lib/dyno' @@ -28,7 +28,7 @@ export default class RunInside extends Command { static strict = false async run() { - const {flags, argv} = this.parse(RunInside) + const {flags, argv} = await this.parse(RunInside) if (argv.length < 2) { throw new Error('Usage: heroku run:inside DYNO COMMAND\n\nExample: heroku run:inside web.1 bash') @@ -51,7 +51,7 @@ export default class RunInside extends Command { } catch (error) { debug(error) if (error.exitCode) { - cli.exit(error.exitCode) + CliUx.ux.exit(error.exitCode) } else { throw error } diff --git a/packages/run/src/lib/colorize.ts b/packages/run/src/lib/colorize.ts index b08e677757..a4bb231235 100644 --- a/packages/run/src/lib/colorize.ts +++ b/packages/run/src/lib/colorize.ts @@ -1,5 +1,5 @@ import c from '@heroku-cli/color' -import ux from 'cli-ux' +import {CliUx} from '@oclif/core' export const COLORS: Array<(s: string) => string> = [ s => c.yellow(s), @@ -88,7 +88,7 @@ function colorizeRouter(body: string) { return other(k + '=') + v }).join(' ') } catch (error) { - ux.warn(error) + CliUx.ux.warn(error) return body } } @@ -132,7 +132,7 @@ function colorizeRun(body: string) { ].join('') } } catch (error) { - ux.warn(error) + CliUx.ux.warn(error) } return body } @@ -190,7 +190,7 @@ function colorizeWeb(body: string) { ].join('') } } catch (error) { - ux.warn(error) + CliUx.ux.warn(error) } return body } diff --git a/packages/run/src/lib/dyno.ts b/packages/run/src/lib/dyno.ts index 9b58338b20..f50fc91a95 100644 --- a/packages/run/src/lib/dyno.ts +++ b/packages/run/src/lib/dyno.ts @@ -4,7 +4,7 @@ import {IOptions} from '@heroku-cli/command/lib/api-client' import {Notification, notify} from '@heroku-cli/notifications' import {Dyno as APIDyno} from '@heroku-cli/schema' import {spawn} from 'child_process' -import cli from 'cli-ux' +import {CliUx} from '@oclif/core' import debugFactory from 'debug' import {HTTP} from 'http-call' import * as https from 'https' @@ -18,7 +18,7 @@ import {URL, parse} from 'url' import {buildEnvFromFlag} from '../lib/helpers' const debug = debugFactory('heroku:run') -const wait = (ms: number) => new Promise(resolve => setTimeout(() => resolve(), ms)) +const wait = (ms: number) => new Promise(resolve => setTimeout(() => resolve(), ms)) interface HerokuApiClientRun extends APIClient { options: IOptions & { @@ -92,7 +92,7 @@ export default class Dyno extends Duplex { async start() { this._startedAt = Date.now() if (this.opts.showStatus) { - cli.action.start(`Running ${color.cyan.bold(this.opts.command)} on ${color.app(this.opts.app)}`) + CliUx.ux.action.start(`Running ${color.cyan.bold(this.opts.command)} on ${color.app(this.opts.app)}`) } await this._doStart() @@ -122,7 +122,7 @@ export default class Dyno extends Duplex { } await this.attach() } else if (this.opts.showStatus) { - cli.action.stop(this._status('done')) + CliUx.ux.action.stop(this._status('done')) } } catch (error) { // Currently the runtime API sends back a 409 in the event the @@ -136,7 +136,7 @@ export default class Dyno extends Duplex { } throw error } finally { - cli.action.stop() + CliUx.ux.action.stop() } } @@ -163,7 +163,7 @@ export default class Dyno extends Duplex { this.reject = reject if (this.opts.showStatus) { - cli.action.status = this._status('starting') + CliUx.ux.action.status = this._status('starting') } const c = tls.connect(parseInt(this.uri.port, 10), this.uri.hostname, { @@ -176,7 +176,7 @@ export default class Dyno extends Duplex { const pathnameWithSearchParams = this.uri.pathname + this.uri.search c.write(pathnameWithSearchParams.substr(1) + '\r\n', () => { if (this.opts.showStatus) { - cli.action.status = this._status('connecting') + CliUx.ux.action.status = this._status('connecting') } }) }) @@ -204,7 +204,7 @@ export default class Dyno extends Duplex { try { const {body: dyno} = await this.heroku.get(`/apps/${this.opts.app}/dynos/${this.opts.dyno}`) this.dyno = dyno - cli.action.stop(this._status(this.dyno.state)) + CliUx.ux.action.stop(this._status(this.dyno.state)) if (this.dyno.state === 'starting' || this.dyno.state === 'up') { return this._connect() @@ -270,7 +270,7 @@ export default class Dyno extends Duplex { // does not actually uncork but allows error to be displayed when attempting to read this.uncork() if (this.opts.listen) { - cli.log(`listening on port ${host}:${port} for ssh client`) + CliUx.ux.log(`listening on port ${host}:${port} for ssh client`) } else { const params = [host, '-p', port.toString(), '-oStrictHostKeyChecking=no', '-oUserKnownHostsFile=/dev/null', '-oServerAliveInterval=20'] @@ -312,7 +312,7 @@ export default class Dyno extends Duplex { } msgs.push('Check that your ssh key has been uploaded to heroku with `heroku keys:add`.') msgs.push(`See ${color.cyan('https://devcenter.heroku.com/articles/one-off-dynos#shield-private-spaces')}`) - cli.error(msgs.join('\n')) + CliUx.ux.error(msgs.join('\n')) } // cleanup local server localServer.close() @@ -350,7 +350,7 @@ export default class Dyno extends Duplex { debug('input: %o', data) // discard first line if (c && firstLine) { - if (this.opts.showStatus) cli.action.stop(this._status('up')) + if (this.opts.showStatus) CliUx.ux.action.stop(this._status('up')) firstLine = false this._readStdin(c) return @@ -404,7 +404,7 @@ export default class Dyno extends Duplex { sigints = sigints.filter(d => d > Date.now() - 1000) if (sigints.length >= 4) { - cli.error('forcing dyno disconnect', {exit: 1}) + CliUx.ux.error('forcing dyno disconnect', {exit: 1}) } }) } else { @@ -450,7 +450,7 @@ export default class Dyno extends Duplex { notify(notification) } catch (error) { - cli.warn(error) + CliUx.ux.warn(error) } } } diff --git a/packages/run/src/lib/helpers.ts b/packages/run/src/lib/helpers.ts index 72e70b213d..01a2daa2cc 100644 --- a/packages/run/src/lib/helpers.ts +++ b/packages/run/src/lib/helpers.ts @@ -1,4 +1,4 @@ -import cli from 'cli-ux' +import {CliUx} from '@oclif/core' export function buildCommand(args: Array) { if (args.length === 1) { @@ -21,7 +21,7 @@ export function buildEnvFromFlag(flag: string) { for (const v of flag.split(';')) { const m = v.match(/^\s*([\w.-]+)\s*=\s*(.*)?\s*$/) if (m) env[m[1]] = m[2] - else cli.warn(`env flag ${v} appears invalid. Avoid using ';' in values.`) + else CliUx.ux.warn(`env flag ${v} appears invalid. Avoid using ';' in values.`) } return env } diff --git a/packages/run/src/lib/log-displayer.ts b/packages/run/src/lib/log-displayer.ts index b724f9a584..3432d3225c 100644 --- a/packages/run/src/lib/log-displayer.ts +++ b/packages/run/src/lib/log-displayer.ts @@ -1,6 +1,6 @@ import {APIClient} from '@heroku-cli/command' import * as EventSource from '@heroku/eventsource' -import cli from 'cli-ux' +import {CliUx} from '@oclif/core' import HTTP from 'http-call' import {URL} from 'url' @@ -21,14 +21,14 @@ async function readLogsV1(logplexURL: string) { response.setEncoding('utf8') liner.setEncoding('utf8') response.pipe(liner) - liner.on('data', line => cli.log(colorize(line))) + liner.on('data', line => CliUx.ux.log(colorize(line))) response.on('end', resolve) response.on('error', reject) }) } function readLogsV2(logplexURL: string) { - return new Promise(function (resolve, reject) { + return new Promise(function (resolve, reject) { const u = new URL(logplexURL) const isTail = u.searchParams.get('tail') === 'true' const userAgent = process.env.HEROKU_DEBUG_USER_AGENT || 'heroku-run' @@ -59,7 +59,7 @@ function readLogsV2(logplexURL: string) { es.addEventListener('message', function (e) { e.data.trim().split(/\n+/).forEach(line => { - cli.log(colorize(line)) + CliUx.ux.log(colorize(line)) }) }) }) @@ -81,7 +81,7 @@ async function logDisplayer(heroku: APIClient, options: LogDisplayerOptions) { // eslint-disable-next-line unicorn/no-process-exit, no-process-exit process.exit(0) } else { - cli.error(err.stack, {exit: 1}) + CliUx.ux.error(err.stack, {exit: 1}) } }) diff --git a/packages/run/test/commands/run.test.ts b/packages/run/test/commands/run.test.ts index ea505aa3a4..007cfb87b5 100644 --- a/packages/run/test/commands/run.test.ts +++ b/packages/run/test/commands/run.test.ts @@ -11,7 +11,7 @@ describeOrSkip('@acceptance run', () => { return test .stdout() .do(() => { - // eslint-disable-next-line @typescript-eslint/ban-ts-ignore + // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore process.stdout.isTTY = false }) @@ -20,19 +20,19 @@ describeOrSkip('@acceptance run', () => { testFactory() .command(['run', '--app=heroku-cli-ci-smoke-test-app', 'echo 1 2 3']) .it('runs a command', async ctx => { - expect(ctx.stdout).to.include('1 2 3\n') + expect(ctx.stdout).to.include('1 2 3') }) testFactory() .command(['run', '--app=heroku-cli-ci-smoke-test-app', 'ruby -e "puts ARGV[0]" "{"foo": "bar"} " ']) .it('runs a command with spaces', ctx => { - expect(ctx.stdout).to.contain('{foo: bar} \n') + expect(ctx.stdout).to.contain('{foo: bar}') }) testFactory() .command(['run', '--app=heroku-cli-ci-smoke-test-app', 'ruby -e "puts ARGV[0]" "{"foo":"bar"}"']) .it('runs a command with quotes', ctx => { - expect(ctx.stdout).to.contain('{foo:bar}\n') + expect(ctx.stdout).to.contain('{foo:bar}') }) testFactory() diff --git a/packages/run/tsconfig.json b/packages/run/tsconfig.json index 9ffaeef8ce..9e3c8baa1d 100644 --- a/packages/run/tsconfig.json +++ b/packages/run/tsconfig.json @@ -6,6 +6,7 @@ "outDir": "lib", "rootDir": "src", "strict": false, + "skipLibCheck": true, "target": "es2017" }, "include": [ diff --git a/packages/spaces/package.json b/packages/spaces/package.json index 986f82fb5b..e620737a54 100644 --- a/packages/spaces/package.json +++ b/packages/spaces/package.json @@ -17,20 +17,20 @@ "repositoryPrefix": "<%- repo %>/blob/v<%- version %>/packages/spaces/<%- commandPath %>" }, "dependencies": { - "@heroku-cli/command": "^8.4.1", + "@heroku-cli/command": "^9.0.2", "@heroku-cli/notifications": "^1.2.2", "heroku-cli-util": "^8.0.11", "lodash": "^4.17.11", "strftime": "^0.10.0" }, "devDependencies": { - "@heroku-cli/dev-cli": "^1.26.13", - "@oclif/plugin-legacy": "^1.2.0", + "@oclif/plugin-legacy": "^1.3.0", "chai": "^4.2.0", "chai-as-promised": "^7.1.1", "mocha": "^5.2.0", "nock": "^10.0.6", "nyc": "^15.1.0", + "oclif": "3.6.4", "sinon": "^7.2.3" }, "files": [ @@ -48,9 +48,9 @@ "repository": "heroku/cli", "scripts": { "postpublish": "rm oclif.manifest.json", - "prepack": "oclif-dev manifest", + "prepack": "oclif manifest", "test": "nyc mocha", "posttest": "standard", - "version": "oclif-dev readme && git add README.md" + "version": "oclif readme && git add README.md" } } diff --git a/packages/status/.eslintignore b/packages/status/.eslintignore new file mode 100644 index 0000000000..a65b41774a --- /dev/null +++ b/packages/status/.eslintignore @@ -0,0 +1 @@ +lib diff --git a/packages/status/.eslintrc b/packages/status/.eslintrc index 68c6a917b5..ee72301381 100644 --- a/packages/status/.eslintrc +++ b/packages/status/.eslintrc @@ -4,5 +4,6 @@ "oclif-typescript" ], "rules": { + "camelcase": "off" } } diff --git a/packages/status/bin/run b/packages/status/bin/run new file mode 100755 index 0000000000..7bd7df0b58 --- /dev/null +++ b/packages/status/bin/run @@ -0,0 +1,6 @@ +#!/usr/bin/env node + +const oclif = require('@oclif/core') + +oclif.run().catch(require('@oclif/core/handle')) + diff --git a/packages/run/bin/run.cmd b/packages/status/bin/run.cmd similarity index 100% rename from packages/run/bin/run.cmd rename to packages/status/bin/run.cmd diff --git a/packages/status/package.json b/packages/status/package.json index 2c7670381a..877251c173 100644 --- a/packages/status/package.json +++ b/packages/status/package.json @@ -11,33 +11,22 @@ "description": "status of the Heroku platform" } }, - "devPlugins": [ - "@oclif/plugin-help" - ], "repositoryPrefix": "<%- repo %>/blob/v<%- version %>/packages/status/<%- commandPath %>" }, "dependencies": { "@heroku-cli/color": "^1.1.14", - "@heroku-cli/command": "^8.4.1", - "@oclif/command": "^1.5.11", - "@oclif/config": "^1.12.10", - "@oclif/errors": "^1.2.2", - "cli-ux": "^4.9.3", + "@oclif/core": "^1.26.2", "date-fns": "^1.29.0", "http-call": "^5.2.3" }, "devDependencies": { "@fancy-test/nock": "^0.1.1", - "@heroku-cli/dev-cli": "^1.26.13", "@heroku-cli/tslint": "1.1.4", - "@oclif/plugin-help": "^2.1.6", - "@oclif/plugin-legacy": "^1.2.0", - "@oclif/test": "^1.2.4", + "@oclif/test": "^2.2.20", "@types/ansi-styles": "^3.2.1", "@types/chai": "^4.1.7", "@types/mocha": "^5.2.6", "@types/nock": "^9.3.1", - "@types/node": "^10.12.24", "@types/supports-color": "^5.3.0", "chai": "^4.2.0", "eslint": "^6.7.2", @@ -46,11 +35,12 @@ "globby": "^9.0.0", "mocha": "^5.1.1", "nock": "^10.0.6", + "oclif": "3.6.4", "ts-node": "^10.9.1", - "typescript": "3.7.5" + "typescript": "4.8.4" }, "engines": { - "node": ">=10.0.0" + "node": ">=14" }, "files": [ "oclif.manifest.json", @@ -61,16 +51,25 @@ "heroku-plugin" ], "license": "ISC", + "oclif": { + "additionalHelpFlags": [ + "-h" + ], + "additionalVersionFlags": [ + "-v" + ], + "commands": "./lib/commands" + }, "repository": "heroku/cli", "scripts": { "build": "rm -rf lib && tsc", "lint": "eslint . --ext .ts --config .eslintrc", "postpublish": "rm -f oclif.manifest.json", - "prepack": "yarn run build && oclif-dev manifest", + "prepack": "yarn run build && oclif manifest", "preversion": "yarn run postpublish", "pretest": "tsc -p test --noEmit", "test": "mocha --forbid-only \"test/**/*.test.ts\"", "posttest": "yarn lint", - "version": "oclif-dev readme && git add README.md" + "version": "oclif readme && git add README.md" } } diff --git a/packages/status/src/commands/status.ts b/packages/status/src/commands/status.ts index 3946a26061..62e2ec0165 100644 --- a/packages/status/src/commands/status.ts +++ b/packages/status/src/commands/status.ts @@ -1,6 +1,5 @@ import color from '@heroku-cli/color' -import {Command, flags} from '@heroku-cli/command' -import cli from 'cli-ux' +import {Command, Flags, CliUx} from '@oclif/core' import * as distanceInWordsToNow from 'date-fns/distance_in_words_to_now' import HTTP from 'http-call' @@ -10,11 +9,11 @@ export default class Status extends Command { static description = 'display current status of the Heroku platform' static flags = { - json: flags.boolean({description: 'output in json format'}), + json: Flags.boolean({description: 'output in json format'}), } async run() { - const {flags} = this.parse(Status) + const {flags} = await this.parse(Status) const apiPath = '/api/v4/current-status' const capitalize = (str: string) => str.substr(0, 1).toUpperCase() + str.substr(1) @@ -32,7 +31,7 @@ export default class Status extends Command { const {body} = await HTTP.get(host + apiPath) if (flags.json) { - cli.styledJSON(body) + CliUx.ux.styledJSON(body) return } @@ -43,13 +42,13 @@ export default class Status extends Command { } for (const incident of body.incidents) { - cli.log() - cli.styledHeader(`${incident.title} ${color.yellow(incident.created_at)} ${color.cyan(incident.full_url)}`) + CliUx.ux.log() + CliUx.ux.styledHeader(`${incident.title} ${color.yellow(incident.created_at)} ${color.cyan(incident.full_url)}`) const padding = maxBy(incident.updates, (i: any) => i.update_type.length).update_type.length + 0 for (const u of incident.updates) { - cli.log(`${color.yellow(u.update_type.padEnd(padding))} ${new Date(u.updated_at).toISOString()} (${distanceInWordsToNow(new Date(u.updated_at))} ago)`) - cli.log(`${u.contents}\n`) + CliUx.ux.log(`${color.yellow(u.update_type.padEnd(padding))} ${new Date(u.updated_at).toISOString()} (${distanceInWordsToNow(new Date(u.updated_at))} ago)`) + CliUx.ux.log(`${u.contents}\n`) } } } diff --git a/packages/status/test/status.test.ts b/packages/status/test/status.test.ts index 196fb70de8..eae361896f 100644 --- a/packages/status/test/status.test.ts +++ b/packages/status/test/status.test.ts @@ -79,6 +79,7 @@ Data: No known issues at this time. Tools: No known issues at this time. === incident title ${time.toISOString()} https://status.heroku.com + update type ${time.toISOString()} (less than a minute ago) update contents diff --git a/packages/status/tsconfig.json b/packages/status/tsconfig.json index 12491d28d6..cc511211fd 100644 --- a/packages/status/tsconfig.json +++ b/packages/status/tsconfig.json @@ -8,6 +8,7 @@ "noUnusedParameters": true, "outDir": "./lib", "pretty": true, + "skipLibCheck": true, "rootDirs": [ "./src" ], diff --git a/packages/webhooks/.eslintrc b/packages/webhooks/.eslintrc index 68c6a917b5..ee72301381 100644 --- a/packages/webhooks/.eslintrc +++ b/packages/webhooks/.eslintrc @@ -4,5 +4,6 @@ "oclif-typescript" ], "rules": { + "camelcase": "off" } } diff --git a/packages/webhooks/bin/run b/packages/webhooks/bin/run index 3c4ae3ac07..a371425871 100755 --- a/packages/webhooks/bin/run +++ b/packages/webhooks/bin/run @@ -1,4 +1,5 @@ #!/usr/bin/env node -require('@oclif/command').run() -.catch(require('@oclif/errors/handle')) +const oclif = require('@oclif/core') + +oclif.run().catch(require('@oclif/core/handle')) diff --git a/packages/webhooks/package.json b/packages/webhooks/package.json index 874c8a9d37..62f0424e04 100644 --- a/packages/webhooks/package.json +++ b/packages/webhooks/package.json @@ -6,19 +6,14 @@ "bugs": "https://github.com/heroku/cli/issues", "dependencies": { "@heroku-cli/color": "^1.1.14", - "@heroku-cli/command": "^8.4.1", - "@oclif/command": "^1", - "@oclif/config": "^1", - "cli-ux": "^5.2.1", + "@heroku-cli/command": "^9.0.2", + "@oclif/core": "^1.26.2", "tslib": "^1" }, "devDependencies": { - "@heroku-cli/dev-cli": "^1.26.13", - "@oclif/plugin-help": "^2", - "@oclif/test": "^1", + "@oclif/test": "^2.2.20", "@types/chai": "^4", "@types/mocha": "^5", - "@types/node": "^10", "chai": "^4", "date-fns": "^1.30.1", "eslint": "^6.7.2", @@ -27,11 +22,12 @@ "globby": "^8", "mocha": "^5", "nyc": "^15.1.0", + "oclif": "3.6.4", "ts-node": "^10", - "typescript": "3.7.5" + "typescript": "^4.8.4" }, "engines": { - "node": ">=10.0.0" + "node": ">=14" }, "files": [ "/lib", @@ -44,20 +40,23 @@ ], "license": "MIT", "oclif": { + "additionalHelpFlags": [ + "-h" + ], + "additionalVersionFlags": [ + "-v" + ], "commands": "./lib/commands", - "bin": "heroku", - "devPlugins": [ - "@oclif/plugin-help" - ] + "bin": "heroku" }, "repository": "heroku/cli", "scripts": { "lint": "eslint . --ext .ts --config .eslintrc", "postpack": "rm -f oclif.manifest.json", "posttest": "yarn lint", - "prepack": "rm -rf lib && tsc -b && oclif-dev manifest && oclif-dev readme", + "prepack": "rm -rf lib && tsc -b && oclif manifest", "pretest": "tsc -p test --noEmit", "test": "nyc --extension .ts mocha --forbid-only \"test/**/*.test.ts\"", - "version": "oclif-dev readme && git add README.md" + "version": "oclif readme && git add README.md" } } diff --git a/packages/webhooks/src/base.ts b/packages/webhooks/src/base.ts index 21a2766106..6d6d3b3262 100644 --- a/packages/webhooks/src/base.ts +++ b/packages/webhooks/src/base.ts @@ -1,12 +1,12 @@ import color from '@heroku-cli/color' import {APIClient, Command} from '@heroku-cli/command' -import {IConfig} from '@oclif/config' +import {Config} from '@oclif/core' export default abstract class extends Command { webhooksClient: APIClient - protected constructor(argv: string[], config: IConfig) { + protected constructor(argv: string[], config: Config) { super(argv, config) const client = new APIClient(this.config, {}) diff --git a/packages/webhooks/src/commands/webhooks/add.ts b/packages/webhooks/src/commands/webhooks/add.ts index e53946d383..aa68ab7417 100644 --- a/packages/webhooks/src/commands/webhooks/add.ts +++ b/packages/webhooks/src/commands/webhooks/add.ts @@ -1,5 +1,6 @@ import {flags} from '@heroku-cli/command' -import {cli} from 'cli-ux' +import {CliUx} from '@oclif/core' +import Spinner from '@oclif/core/lib/cli-ux/action/spinner' import BaseCommand from '../../base' @@ -22,10 +23,11 @@ export default class WebhooksAdd extends BaseCommand { } async run() { - const {flags} = this.parse(WebhooksAdd) + const {flags} = await this.parse(WebhooksAdd) const {path, display} = this.webhookType(flags) + const action = new Spinner() - cli.action.start(`Adding webhook to ${display}`) + action.start(`Adding webhook to ${display}`) const response = await this.webhooksClient.post(`${path}/webhooks`, { body: { @@ -38,14 +40,12 @@ export default class WebhooksAdd extends BaseCommand { }) const secret = response.headers && response.headers['heroku-webhook-secret'] as string - - cli.action.stop() - if (secret) { - cli.styledHeader('Webhooks Signing Secret') + CliUx.ux.styledHeader('Webhooks Signing Secret') this.log(secret) } else { - cli.warn('no secret found') + CliUx.ux.warn('no secret found') } + action.stop() } } diff --git a/packages/webhooks/src/commands/webhooks/deliveries/index.ts b/packages/webhooks/src/commands/webhooks/deliveries/index.ts index c9f2e8ca0f..ae6636cdd7 100644 --- a/packages/webhooks/src/commands/webhooks/deliveries/index.ts +++ b/packages/webhooks/src/commands/webhooks/deliveries/index.ts @@ -1,5 +1,5 @@ import {flags} from '@heroku-cli/command' -import {cli} from 'cli-ux' +import {CliUx} from '@oclif/core' import BaseCommand from '../../../base' @@ -18,7 +18,7 @@ export default class Deliveries extends BaseCommand { } async run() { - const {flags} = this.parse(Deliveries) + const {flags} = await this.parse(Deliveries) const webhookType = this.webhookType(flags) let {path} = webhookType const {display} = webhookType @@ -29,7 +29,7 @@ export default class Deliveries extends BaseCommand { path += `?eq[status]=${encodeURIComponent(flags.status)}` } - const {body: deliveries} = await this.webhooksClient.get(path, { + const {body: deliveries}: { body: any[]} = await this.webhooksClient.get(path, { headers: { Range: `seq ..; order=desc,max=${max}`, }, @@ -50,7 +50,8 @@ export default class Deliveries extends BaseCommand { this.warn('It is possible to filter deliveries by using the --status flag') } - cli.table(deliveries, { + const printLine: typeof this.log = (...args) => this.log(...args) + CliUx.ux.table(deliveries, { id: { header: 'Delivery ID', }, @@ -79,7 +80,7 @@ export default class Deliveries extends BaseCommand { header: 'Next Attempt', get: (w: any) => w.next_attempt_at || '', }, }, { - printLine: this.log, + 'no-header': false, printLine, }) } } diff --git a/packages/webhooks/src/commands/webhooks/deliveries/info.ts b/packages/webhooks/src/commands/webhooks/deliveries/info.ts index 6367f2b080..78c6fba8a1 100644 --- a/packages/webhooks/src/commands/webhooks/deliveries/info.ts +++ b/packages/webhooks/src/commands/webhooks/deliveries/info.ts @@ -1,5 +1,5 @@ import {flags} from '@heroku-cli/command' -import {cli} from 'cli-ux' +import {CliUx} from '@oclif/core' import BaseCommand from '../../../base' @@ -21,12 +21,12 @@ export default class DeliveriesInfo extends BaseCommand { ] async run() { - const {flags, args} = this.parse(DeliveriesInfo) + const {flags, args} = await this.parse(DeliveriesInfo) const {path} = this.webhookType(flags) - const {body: delivery} = await this.webhooksClient.get(`${path}/webhook-deliveries/${args.id}`) + const {body: delivery}: {body: any} = await this.webhooksClient.get(`${path}/webhook-deliveries/${args.id}`) - const {body: event} = await this.webhooksClient.get(`${path}/webhook-events/${delivery.event.id}`) + const {body: event}: {body: any} = await this.webhooksClient.get(`${path}/webhook-events/${delivery.event.id}`) const obj = { Created: delivery.created_at, @@ -41,10 +41,10 @@ export default class DeliveriesInfo extends BaseCommand { 'Next Attempt': delivery.next_attempt_at, } - cli.styledHeader(delivery.id) - cli.styledObject(obj) + CliUx.ux.styledHeader(delivery.id) + CliUx.ux.styledObject(obj) - cli.styledHeader('Event Payload') - cli.styledJSON(event.payload) + CliUx.ux.styledHeader('Event Payload') + CliUx.ux.styledJSON(event.payload) } } diff --git a/packages/webhooks/src/commands/webhooks/events/index.ts b/packages/webhooks/src/commands/webhooks/events/index.ts index 98e1b432f8..9cc3ff470c 100644 --- a/packages/webhooks/src/commands/webhooks/events/index.ts +++ b/packages/webhooks/src/commands/webhooks/events/index.ts @@ -1,5 +1,5 @@ import {flags} from '@heroku-cli/command' -import {cli} from 'cli-ux' +import {CliUx} from '@oclif/core' import BaseCommand from '../../../base' @@ -17,19 +17,21 @@ export default class EventsIndex extends BaseCommand { } async run() { - const {flags} = this.parse(EventsIndex) + const {flags} = await this.parse(EventsIndex) const {path, display} = this.webhookType(flags) - cli.warn('heroku webhooks:event is deprecated, please use heroku webhooks:deliveries') + CliUx.ux.warn('heroku webhooks:event is deprecated, please use heroku webhooks:deliveries') - const {body: events} = await this.webhooksClient.get(`${path}/webhook-events`) + const {body: events}: {body: any} = await this.webhooksClient.get(`${path}/webhook-events`) if (events.length === 0) { this.log(`${display} has no events`) } else { events.sort((a: any, b: any) => Date.parse(a.created_at) - Date.parse(b.created_at)) - cli.table(events, { + const printLine: typeof this.log = (...args) => this.log(...args) + + CliUx.ux.table(events, { id: { header: 'Event ID', }, @@ -43,7 +45,7 @@ export default class EventsIndex extends BaseCommand { header: 'Published At', get: (w: any) => w.payload.published_at, }, }, { - printLine: this.log, + 'no-header': false, printLine, }) } } diff --git a/packages/webhooks/src/commands/webhooks/events/info.ts b/packages/webhooks/src/commands/webhooks/events/info.ts index 2a7addf611..9c6831cf5f 100644 --- a/packages/webhooks/src/commands/webhooks/events/info.ts +++ b/packages/webhooks/src/commands/webhooks/events/info.ts @@ -1,5 +1,5 @@ import {flags} from '@heroku-cli/command' -import {cli} from 'cli-ux' +import {CliUx} from '@oclif/core' import BaseCommand from '../../../base' @@ -21,18 +21,18 @@ export default class Info extends BaseCommand { ] async run() { - const {flags, args} = this.parse(Info) + const {flags, args} = await this.parse(Info) const {path} = this.webhookType(flags) - cli.warn('heroku webhooks:event:info is deprecated, please use heroku webhooks:deliveries:info') + CliUx.ux.warn('heroku webhooks:event:info is deprecated, please use heroku webhooks:deliveries:info') - const {body: webhookEvent} = await this.webhooksClient.get(`${path}/webhook-events/${args.id}`) + const {body: webhookEvent}: {body: any} = await this.webhooksClient.get(`${path}/webhook-events/${args.id}`) const obj = { payload: JSON.stringify(webhookEvent.payload, null, 2), } - cli.styledHeader(webhookEvent.id) - cli.styledObject(obj) + CliUx.ux.styledHeader(webhookEvent.id) + CliUx.ux.styledObject(obj) } } diff --git a/packages/webhooks/src/commands/webhooks/index.ts b/packages/webhooks/src/commands/webhooks/index.ts index 3bfbf69c3b..7bcffb0486 100644 --- a/packages/webhooks/src/commands/webhooks/index.ts +++ b/packages/webhooks/src/commands/webhooks/index.ts @@ -1,6 +1,6 @@ import color from '@heroku-cli/color' import {flags} from '@heroku-cli/command' -import {cli} from 'cli-ux' +import {CliUx} from '@oclif/core' import BaseCommand from '../../base' @@ -21,10 +21,10 @@ export default class Webhooks extends BaseCommand { } async run() { - const {flags} = this.parse(Webhooks) + const {flags} = await this.parse(Webhooks) const {path, display} = this.webhookType(flags) - const {body: webhooks} = await this.webhooksClient.get(`${path}/webhooks`) + const {body: webhooks}: {body: any} = await this.webhooksClient.get(`${path}/webhooks`) if (webhooks.length === 0) { this.log(`${display} has no webhooks\nUse ${color.cmd('heroku webhooks:add')} to add one.`) @@ -33,7 +33,9 @@ export default class Webhooks extends BaseCommand { webhooks.sort((a: any, b: any) => Date.parse(a.created_at) - Date.parse(b.created_at)) - cli.table(webhooks, { + const printLine: typeof this.log = (...args) => this.log(...args) + + CliUx.ux.table(webhooks, { id: { header: 'Webhook ID', }, @@ -45,7 +47,7 @@ export default class Webhooks extends BaseCommand { }, level: {}, }, { - printLine: this.log, + 'no-header': false, printLine, }) } } diff --git a/packages/webhooks/src/commands/webhooks/info.ts b/packages/webhooks/src/commands/webhooks/info.ts index c468eb2464..61ea1969c6 100644 --- a/packages/webhooks/src/commands/webhooks/info.ts +++ b/packages/webhooks/src/commands/webhooks/info.ts @@ -1,5 +1,5 @@ import {flags} from '@heroku-cli/command' -import {cli} from 'cli-ux' +import {CliUx} from '@oclif/core' import BaseCommand from '../../base' @@ -17,10 +17,10 @@ export default class WebhooksInfo extends BaseCommand { static args = [{name: 'id', required: true}] async run() { - const {flags, args} = this.parse(WebhooksInfo) + const {flags, args} = await this.parse(WebhooksInfo) const {path} = this.webhookType(flags) - const {body: webhook} = await this.webhooksClient.get(`${path}/webhooks/${args.id}`) + const {body: webhook}: {body: any} = await this.webhooksClient.get(`${path}/webhooks/${args.id}`) const obj = { 'Webhook ID': webhook.id, @@ -29,7 +29,7 @@ export default class WebhooksInfo extends BaseCommand { Level: webhook.level, } - cli.styledHeader(webhook.id) - cli.styledObject(obj) + CliUx.ux.styledHeader(webhook.id) + CliUx.ux.styledObject(obj) } } diff --git a/packages/webhooks/src/commands/webhooks/remove.ts b/packages/webhooks/src/commands/webhooks/remove.ts index f9b6eec5f0..fcb3521571 100644 --- a/packages/webhooks/src/commands/webhooks/remove.ts +++ b/packages/webhooks/src/commands/webhooks/remove.ts @@ -1,5 +1,5 @@ import {flags} from '@heroku-cli/command' -import {cli} from 'cli-ux' +import Spinner from '@oclif/core/lib/cli-ux/action/spinner' import BaseCommand from '../../base' export default class WebhooksRemove extends BaseCommand { @@ -20,13 +20,14 @@ export default class WebhooksRemove extends BaseCommand { ] async run() { - const {flags, args} = this.parse(WebhooksRemove) + const {flags, args} = await this.parse(WebhooksRemove) const {path, display} = this.webhookType(flags) + const action = new Spinner() - cli.action.start(`Removing webhook ${args.id} from ${display}`) + action.start(`Removing webhook ${args.id} from ${display}`) await this.webhooksClient.delete(`${path}/webhooks/${args.id}`) - cli.action.stop() + action.stop() } } diff --git a/packages/webhooks/src/commands/webhooks/update.ts b/packages/webhooks/src/commands/webhooks/update.ts index 0ffe56c879..0913c566d7 100644 --- a/packages/webhooks/src/commands/webhooks/update.ts +++ b/packages/webhooks/src/commands/webhooks/update.ts @@ -1,5 +1,5 @@ import {flags} from '@heroku-cli/command' -import {cli} from 'cli-ux' +import Spinner from '@oclif/core/lib/cli-ux/action/spinner' import BaseCommand from '../../base' @@ -26,10 +26,11 @@ export default class WebhooksUpdate extends BaseCommand { ] async run() { - const {flags, args} = this.parse(WebhooksUpdate) + const {flags, args} = await this.parse(WebhooksUpdate) const {path, display} = this.webhookType(flags) + const action = new Spinner() - cli.action.start(`Updating webhook ${args.id} for ${display}`) + action.start(`Updating webhook ${args.id} for ${display}`) await this.webhooksClient.patch(`${path}/webhooks/${args.id}`, { body: { @@ -40,6 +41,6 @@ export default class WebhooksUpdate extends BaseCommand { }, }) - cli.action.stop() + action.stop() } } diff --git a/packages/webhooks/test/commands/base.test.ts b/packages/webhooks/test/commands/base.test.ts index d484696334..bb08ca1d24 100644 --- a/packages/webhooks/test/commands/base.test.ts +++ b/packages/webhooks/test/commands/base.test.ts @@ -1,4 +1,4 @@ -import {Config, IConfig} from '@oclif/config' +import {Config} from '@oclif/core' import {expect, test} from '@oclif/test' import * as path from 'path' @@ -6,7 +6,7 @@ import webhooksAbstractClass from '../../src/base' class Webhooks extends webhooksAbstractClass { // eslint-disable-next-line no-useless-constructor - constructor(argv: string[], config: IConfig) { + constructor(argv: string[], config: Config) { super(argv, config) } diff --git a/packages/webhooks/test/commands/webhooks/add.test.ts b/packages/webhooks/test/commands/webhooks/add.test.ts index cc8a1c4977..4603c7d71b 100644 --- a/packages/webhooks/test/commands/webhooks/add.test.ts +++ b/packages/webhooks/test/commands/webhooks/add.test.ts @@ -27,8 +27,8 @@ describe('webhooks:add', () => { 'http://foobar.com', ]) .it('adds a specific app webhook', ctx => { - expect(ctx.stdout).to.equal('') - expect(ctx.stderr).to.contain('Adding webhook to example-app... done\n') + expect(ctx.stdout.trim()).to.equal('') + expect(ctx.stderr).to.include('Adding webhook to example-app... done') }) test @@ -84,7 +84,8 @@ describe('webhooks:add', () => { 'http://foobar.com', ]) .it('adds a specific pipeline webhook', ctx => { - expect(ctx.stdout).to.equal('=== Webhooks Signing Secret\n1234\n') - expect(ctx.stderr).to.contain('Adding webhook to example-pipeline... done\n') + expect(ctx.stdout).to.contain('=== Webhooks Signing Secret') + expect(ctx.stdout).to.contain('1234') + expect(ctx.stderr).to.contain('Adding webhook to example-pipeline... done') }) }) diff --git a/packages/webhooks/test/commands/webhooks/deliveries/index.test.ts b/packages/webhooks/test/commands/webhooks/deliveries/index.test.ts index a063f54bd3..d149e6f300 100644 --- a/packages/webhooks/test/commands/webhooks/deliveries/index.test.ts +++ b/packages/webhooks/test/commands/webhooks/deliveries/index.test.ts @@ -48,10 +48,12 @@ describe('webhooks:deliveries', () => { .command(['webhooks:deliveries', '--app', 'example-app']) .it('lists webhooks deliveries for app webhooks', ctx => { expect(ctx.stderr).to.equal('') - expect(ctx.stdout.trim()).to.equal( - `Delivery ID Created Status Include Level Attempts Code Error Next Attempt -99999999-9999-9999-9999-999999999999 2017-08-17T20:22:37Z retrying api:build notify 4 401 Foobar 2017-08-17T20:22:39Z -66666666-6666-6666-6666-666666666666 2017-08-17T20:22:38Z pending api:build notify 4`) + expect(ctx.stdout).to.contain('Delivery ID') + expect(ctx.stdout).to.contain('Created') + expect(ctx.stdout).to.contain('Status Include Level Attempts Code Error Next Attempt') + expect(ctx.stdout).to.contain(' 99999999-9999-9999-9999-999999999999 2017-08-17T20:22:37Z retrying api:build notify 4') + expect(ctx.stdout).to.contain('401 Foobar 2017-08-17T20:22:39Z') + expect(ctx.stdout).to.contain(' 66666666-6666-6666-6666-666666666666 2017-08-17T20:22:38Z pending api:build notify 4') }) test @@ -81,9 +83,10 @@ describe('webhooks:deliveries', () => { .command(['webhooks:deliveries', '--app', 'example-app', '--status', 'pending']) .it('lists webhook deliveries for app webhooks filtered by status', ctx => { expect(ctx.stderr).to.equal('') - expect(ctx.stdout.trim()).to.equal( - `Delivery ID Created Status Include Level Attempts Code Error Next Attempt -66666666-6666-6666-6666-666666666666 2017-08-17T20:22:38Z pending api:build notify 4`) + expect(ctx.stdout).to.contain('Delivery ID') + expect(ctx.stdout).to.contain('Created') + expect(ctx.stdout).to.contain('Status Include Level Attempts Code Error Next Attempt') + expect(ctx.stdout).to.contain('66666666-6666-6666-6666-666666666666 2017-08-17T20:22:38Z pending api:build notify 4') }) test @@ -115,17 +118,19 @@ describe('webhooks:deliveries', () => { .command(['webhooks:deliveries', '--app', 'example-app']) .it('only shows 1000 webhook deliveries', ctx => { const expectedHeader = 'Delivery ID Created Status Include Level Attempts Code Error Next Attempt' + const expectedUnderline = '──────────────────────────────────── ──────────────────── ─────── ───────── ────── ──────── ──── ───── ────────────' const expectedRow = '66666666-6666-6666-6666-666666666666 2017-08-17T20:22:38Z pending api:build notify 4' const angleBrackets = process.platform === 'win32' ? '»' : '›' const rows = ctx.stdout.split('\n') - const headerRowCount = 1 + const headerRowCount = 2 const dataRowsCount = 1000 const finalTrailingRowCount = 1 expect(rows.length).to.equal(headerRowCount + dataRowsCount + finalTrailingRowCount) expect(rows[0].trim()).to.equal(expectedHeader) - expect(rows[1].trim()).to.equal(expectedRow) + expect(rows[1].trim()).to.equal(expectedUnderline) + expect(rows[2].trim()).to.equal(expectedRow) expect(ctx.stderr).to.include(` ${angleBrackets} Warning: Only showing the 1000 most recent deliveries\n ${angleBrackets} Warning: It is possible to filter deliveries by using the --status flag\n`) }) @@ -193,10 +198,9 @@ describe('webhooks:deliveries', () => { .command(['webhooks:deliveries', '--pipeline', 'example-pipeline']) .it('lists webhooks deliveries for pipeline webhooks', ctx => { expect(ctx.stderr).to.equal('') - expect(ctx.stdout.trim()).to.equal( - `Delivery ID Created Status Include Level Attempts Code Error Next Attempt -99999999-9999-9999-9999-999999999999 2017-08-17T20:22:37Z retrying api:build notify 4 401 Foobar 2017-08-17T20:22:39Z -66666666-6666-6666-6666-666666666666 2017-08-17T20:22:38Z pending api:build notify 4`) + expect(ctx.stdout).to.contain('Delivery ID Created Status Include Level Attempts Code Error Next Attempt') + expect(ctx.stdout).to.contain('99999999-9999-9999-9999-999999999999 2017-08-17T20:22:37Z retrying api:build notify 4 401 Foobar 2017-08-17T20:22:39Z') + expect(ctx.stdout).to.contain('66666666-6666-6666-6666-666666666666 2017-08-17T20:22:38Z pending api:build notify 4') }) test diff --git a/packages/webhooks/test/commands/webhooks/deliveries/info.test.ts b/packages/webhooks/test/commands/webhooks/deliveries/info.test.ts index 45a244557c..832920438b 100644 --- a/packages/webhooks/test/commands/webhooks/deliveries/info.test.ts +++ b/packages/webhooks/test/commands/webhooks/deliveries/info.test.ts @@ -39,21 +39,16 @@ describe('webhooks:deliveries:info', () => { ]) .it('shows an app webhook delivery', ctx => { expect(ctx.stderr).to.equal('') - expect(ctx.stdout).to.equal( - `=== 99999999-9999-9999-9999-999999999999 -Event: 88888888-8888-8888-8888-888888888888 -Status: pending -Webhook: 77777777-7777-7777-7777-777777777777 -=== Event Payload -{ - "published_at": "2016-08-31T21:55:06Z", - "resource": "api:release", - "action": "create", - "data": { - "foo": "bar" - } -} -`) + expect(ctx.stdout).to.contain('=== 99999999-9999-9999-9999-999999999999') + expect(ctx.stdout).to.contain('Event: 88888888-8888-8888-8888-888888888888') + expect(ctx.stdout).to.contain('Status: pending') + expect(ctx.stdout).to.contain('Webhook: 77777777-7777-7777-7777-777777777777') + expect(ctx.stdout).to.contain('=== Event Payload') + expect(ctx.stdout).to.contain('"published_at": "2016-08-31T21:55:06Z",') + expect(ctx.stdout).to.contain('"resource": "api:release",') + expect(ctx.stdout).to.contain('"action": "create",') + expect(ctx.stdout).to.contain('"data": {') + expect(ctx.stdout).to.contain('"foo": "bar"') }) test @@ -94,20 +89,15 @@ Webhook: 77777777-7777-7777-7777-777777777777 ]) .it('shows a pipeline webhook delivery ', ctx => { expect(ctx.stderr).to.equal('') - expect(ctx.stdout).to.equal( - `=== 99999999-9999-9999-9999-999999999999 -Event: 88888888-8888-8888-8888-888888888888 -Status: pending -Webhook: 77777777-7777-7777-7777-777777777777 -=== Event Payload -{ - "published_at": "2016-08-31T21:55:06Z", - "resource": "api:release", - "action": "create", - "data": { - "foo": "bar" - } -} -`) + expect(ctx.stdout).to.contain('=== 99999999-9999-9999-9999-999999999999') + expect(ctx.stdout).to.contain('Event: 88888888-8888-8888-8888-888888888888') + expect(ctx.stdout).to.contain('Status: pending') + expect(ctx.stdout).to.contain('Webhook: 77777777-7777-7777-7777-777777777777') + expect(ctx.stdout).to.contain('=== Event Payload') + expect(ctx.stdout).to.contain('"published_at": "2016-08-31T21:55:06Z",') + expect(ctx.stdout).to.contain('"resource": "api:release",') + expect(ctx.stdout).to.contain('"action": "create",') + expect(ctx.stdout).to.contain('"data": {') + expect(ctx.stdout).to.contain('"foo": "bar"') }) }) diff --git a/packages/webhooks/test/commands/webhooks/events/index.test.ts b/packages/webhooks/test/commands/webhooks/events/index.test.ts index aa45f49c8d..330ae4c858 100644 --- a/packages/webhooks/test/commands/webhooks/events/index.test.ts +++ b/packages/webhooks/test/commands/webhooks/events/index.test.ts @@ -2,7 +2,8 @@ import {expect, test} from '@oclif/test' import {addDays, parse} from 'date-fns' describe('webhooks:events', () => { - const deprecationWarning = 'Warning: heroku webhooks:event is deprecated, please use heroku webhooks:deliveries\n' + const deprecationWarning = 'Warning: heroku webhooks:event is deprecated, please use heroku' + const deprecationWarning2 = 'webhooks:deliveries' describe('app webhooks', () => { const appWebhookEventsPath = '/apps/example-app/webhook-events' @@ -24,9 +25,9 @@ describe('webhooks:events', () => { .command(['webhooks:events', '--app', 'example-app']) .it('lists app webhook events', ctx => { expect(ctx.stderr).to.include(deprecationWarning) - expect(ctx.stdout).to.equal(`Event ID Resource Action Published At -99999999-9999-9999-9999-999999999999 api:release create 2016-08-31T21:55:06Z -`) + expect(ctx.stderr).to.include(deprecationWarning2) + expect(ctx.stdout).to.contain('Event ID Resource Action Published At') + expect(ctx.stdout).to.contain('99999999-9999-9999-9999-999999999999 api:release create 2016-08-31T21:55:06Z') }) test @@ -39,6 +40,7 @@ describe('webhooks:events', () => { .command(['webhooks:events', '--app', 'example-app']) .it('displays an empty events message', ctx => { expect(ctx.stderr).to.include(deprecationWarning) + expect(ctx.stderr).to.include(deprecationWarning2) expect(ctx.stdout).to.equal('example-app has no events\n') }) }) @@ -63,9 +65,9 @@ describe('webhooks:events', () => { .command(['webhooks:events', '--pipeline', 'example-pipeline']) .it('lists pipeline webhook events', ctx => { expect(ctx.stderr).to.include(deprecationWarning) - expect(ctx.stdout).to.equal(`Event ID Resource Action Published At -99999999-9999-9999-9999-999999999999 api:release create 2016-08-31T21:55:06Z -`) + expect(ctx.stderr).to.include(deprecationWarning2) + expect(ctx.stdout).to.contain('Event ID Resource Action Published At') + expect(ctx.stdout).to.contain('99999999-9999-9999-9999-999999999999 api:release create 2016-08-31T21:55:06Z') }) test @@ -78,11 +80,12 @@ describe('webhooks:events', () => { .command(['webhooks:events', '--pipeline', 'example-pipeline']) .it('displays an empty events message', ctx => { expect(ctx.stderr).to.include(deprecationWarning) + expect(ctx.stderr).to.include(deprecationWarning2) expect(ctx.stdout).to.equal('example-pipeline has no events\n') }) }) - describe('by default the table is sorted by `created_at`', () => { + describe('by default the table is sorted by "created_at"', () => { const firstDate = parse('2019-06-11T14:20:42Z') const secondDate = addDays(parse(firstDate), 1) const thirdDate = addDays(parse(firstDate), 2) @@ -94,8 +97,8 @@ describe('webhooks:events', () => { .get('/apps/example-app/webhook-events') .reply(200, [ // the returned ordered from the api is not ordered by - // `created_at` but the results displayed by the cli - // in thae table *are* ordered by `created_at` + // "created_at" but the results displayed by the cli + // in thae table *are* ordered by "created_at" // first date { @@ -132,16 +135,15 @@ describe('webhooks:events', () => { ]), ) .command(['webhooks:events', '--app', 'example-app']) - .it('displays webhooks sorted by `created_at`', ctx => { + .it('displays webhooks sorted by "created_at"', ctx => { expect(ctx.stderr).to.include(deprecationWarning) - - // Note: The table is sorted by `created_at` date even though + expect(ctx.stderr).to.include(deprecationWarning2) + // Note: The table is sorted by "created_at" date even though // it is not displayed in the table - expect(ctx.stdout).to.equal(`Event ID Resource Action Published At -00000000-0000-0000-0000-000000000000 api:release create 2019-06-15T14:20:42Z -22222222-2222-2222-2222-222222222222 api:release create 2019-06-15T14:20:42Z -11111111-1111-1111-1111-111111111111 api:release create 2019-06-15T14:20:42Z -`) + expect(ctx.stdout).to.contain('Event ID Resource Action Published At') + expect(ctx.stdout).to.contain('00000000-0000-0000-0000-000000000000 api:release create 2019-06-15T14:20:42Z') + expect(ctx.stdout).to.contain('22222222-2222-2222-2222-222222222222 api:release create 2019-06-15T14:20:42Z') + expect(ctx.stdout).to.contain('11111111-1111-1111-1111-111111111111 api:release create 2019-06-15T14:20:42Z') }) }) }) diff --git a/packages/webhooks/test/commands/webhooks/events/info.test.ts b/packages/webhooks/test/commands/webhooks/events/info.test.ts index adc13e80b6..3697ad2e8f 100644 --- a/packages/webhooks/test/commands/webhooks/events/info.test.ts +++ b/packages/webhooks/test/commands/webhooks/events/info.test.ts @@ -1,7 +1,8 @@ import {expect, test} from '@oclif/test' describe('webhooks:events:info', () => { - const deprecationWarning = 'Warning: heroku webhooks:event:info is deprecated, please use heroku webhooks:deliveries:info\n' + const deprecationWarning = 'Warning: heroku webhooks:event:info is deprecated, please use heroku' + const deprecationWarning2 = 'webhooks:deliveries:info' test .stdout() @@ -28,16 +29,14 @@ describe('webhooks:events:info', () => { ]) .it('lists webhooks events info for app webhooks', ctx => { expect(ctx.stderr).to.include(deprecationWarning) - expect(ctx.stdout).to.equal(`=== 99999999-9999-9999-9999-999999999999 -payload: { - "published_at": "2016-08-31T21:55:06Z", - "resource": "api:release", - "action": "create", - "data": { - "foo": "bar" - } -} -`) + expect(ctx.stderr).to.include(deprecationWarning2) + expect(ctx.stdout).to.contain('=== 99999999-9999-9999-9999-999999999999') + expect(ctx.stdout).to.contain('payload: {') + expect(ctx.stdout).to.contain('"published_at": "2016-08-31T21:55:06Z",') + expect(ctx.stdout).to.contain('"resource": "api:release",') + expect(ctx.stdout).to.contain('"action": "create",') + expect(ctx.stdout).to.contain('"data": {') + expect(ctx.stdout).to.contain('"foo": "bar"') }) test @@ -65,15 +64,13 @@ payload: { ]) .it('lists webhooks events info for pipeline webhooks', ctx => { expect(ctx.stderr).to.include(deprecationWarning) - expect(ctx.stdout).to.equal(`=== 99999999-9999-9999-9999-999999999999 -payload: { - "published_at": "2016-08-31T21:55:06Z", - "resource": "api:release", - "action": "create", - "data": { - "foo": "bar" - } -} -`) + expect(ctx.stderr).to.include(deprecationWarning2) + expect(ctx.stdout).to.contain('=== 99999999-9999-9999-9999-999999999999') + expect(ctx.stdout).to.contain('payload: {') + expect(ctx.stdout).to.contain('"published_at": "2016-08-31T21:55:06Z",') + expect(ctx.stdout).to.contain('"resource": "api:release",') + expect(ctx.stdout).to.contain('"action": "create",') + expect(ctx.stdout).to.contain('"data": {') + expect(ctx.stdout).to.contain('"foo": "bar"') }) }) diff --git a/packages/webhooks/test/commands/webhooks/index.test.ts b/packages/webhooks/test/commands/webhooks/index.test.ts index b9469be46a..f992b73129 100644 --- a/packages/webhooks/test/commands/webhooks/index.test.ts +++ b/packages/webhooks/test/commands/webhooks/index.test.ts @@ -20,9 +20,8 @@ describe('webhooks:index', () => { .command(['webhooks', '--app', 'example']) .it('lists webhooks', ctx => { expect(ctx.stderr).to.equal('') - expect(ctx.stdout).to.equal(`Webhook ID URL Include Level -99999999-9999-9999-9999-999999999999 http://foobar.com foo,bar notify -`) + expect(ctx.stdout).to.contain('Webhook ID URL Include Level') + expect(ctx.stdout).to.contain('99999999-9999-9999-9999-999999999999 http://foobar.com foo,bar notify') }) test @@ -57,9 +56,8 @@ describe('webhooks:index', () => { .command(['webhooks', '--pipeline', 'example']) .it('lists webhooks', ctx => { expect(ctx.stderr).to.equal('') - expect(ctx.stdout).to.equal(`Webhook ID URL Include Level -99999999-9999-9999-9999-999999999999 http://foobar.com foo,bar notify -`) + expect(ctx.stdout).to.contain('Webhook ID URL Include Level') + expect(ctx.stdout).to.contain('99999999-9999-9999-9999-999999999999 http://foobar.com foo,bar notify') }) test @@ -76,7 +74,7 @@ describe('webhooks:index', () => { }) }) - describe('by default the table is sorted by `created_at`', () => { + describe('by default the table is sorted by "created_at"', () => { const firstDate = parse('2019-06-11T14:20:42Z') const secondDate = addDays(parse(firstDate), 1) const thirdDate = addDays(parse(firstDate), 2) @@ -88,8 +86,8 @@ describe('webhooks:index', () => { .get('/apps/example/webhooks') .reply(200, [ // the returned ordered from the api is not ordered by - // `created_at` but the results displayed by the cli - // in thae table *are* ordered by `created_at` + // "created_at" but the results displayed by the cli + // in thae table *are* ordered by "created_at" // first date { @@ -120,13 +118,12 @@ describe('webhooks:index', () => { ]), ) .command(['webhooks', '--app', 'example']) - .it('displays webhooks sorted by `created_at`', ctx => { + .it('displays webhooks sorted by "created_at"', ctx => { expect(ctx.stderr).to.equal('') - expect(ctx.stdout).to.equal(`Webhook ID URL Include Level -00000000-0000-0000-0000-000000000000 https://test.com/hook api:release sync -22222222-2222-2222-2222-222222222222 https://test.com/hook api:release sync -11111111-1111-1111-1111-111111111111 https://test.com/hook api:release sync -`) + expect(ctx.stdout).to.contain('Webhook ID URL Include Level') + expect(ctx.stdout).to.contain('00000000-0000-0000-0000-000000000000 https://test.com/hook api:release sync') + expect(ctx.stdout).to.contain('22222222-2222-2222-2222-222222222222 https://test.com/hook api:release sync') + expect(ctx.stdout).to.contain('11111111-1111-1111-1111-111111111111 https://test.com/hook api:release sync') }) }) }) diff --git a/packages/webhooks/test/commands/webhooks/info.test.ts b/packages/webhooks/test/commands/webhooks/info.test.ts index 7ceeb1127d..f4032193e0 100644 --- a/packages/webhooks/test/commands/webhooks/info.test.ts +++ b/packages/webhooks/test/commands/webhooks/info.test.ts @@ -16,12 +16,11 @@ describe('webhooks:info', () => { .command(['webhooks:info', '--app', 'example-app', '99999999-9999-9999-9999-999999999999']) .it('displays info for a given app webhook', ctx => { expect(ctx.stderr).to.equal('') - expect(ctx.stdout).to.equal(`=== 99999999-9999-9999-9999-999999999999 -Include: foo,bar -Level: notify -URL: http://foobar.com -Webhook ID: 99999999-9999-9999-9999-999999999999 -`) + expect(ctx.stdout).to.contain('=== 99999999-9999-9999-9999-999999999999') + expect(ctx.stdout).to.contain('Include: foo,bar') + expect(ctx.stdout).to.contain('Level: notify') + expect(ctx.stdout).to.contain('URL: http://foobar.com') + expect(ctx.stdout).to.contain('Webhook ID: 99999999-9999-9999-9999-999999999999') }) test @@ -39,11 +38,10 @@ Webhook ID: 99999999-9999-9999-9999-999999999999 .command(['webhooks:info', '--pipeline', 'example-pipeline', '99999999-9999-9999-9999-999999999999']) .it('displays info for a given pipeline webhook', ctx => { expect(ctx.stderr).to.equal('') - expect(ctx.stdout).to.equal(`=== 99999999-9999-9999-9999-999999999999 -Include: foo,bar -Level: notify -URL: http://foobar.com -Webhook ID: 99999999-9999-9999-9999-999999999999 -`) + expect(ctx.stdout).to.contain('=== 99999999-9999-9999-9999-999999999999') + expect(ctx.stdout).to.contain('Include: foo,bar') + expect(ctx.stdout).to.contain('Level: notify') + expect(ctx.stdout).to.contain('URL: http://foobar.com') + expect(ctx.stdout).to.contain('Webhook ID: 99999999-9999-9999-9999-999999999999') }) }) diff --git a/packages/webhooks/test/tsconfig.json b/packages/webhooks/test/tsconfig.json index 9d1e03aa35..479e16d66f 100644 --- a/packages/webhooks/test/tsconfig.json +++ b/packages/webhooks/test/tsconfig.json @@ -1,7 +1,8 @@ { "extends": "../tsconfig", "compilerOptions": { - "noEmit": true + "noEmit": true, + "skipLibCheck": true }, "references": [ ] diff --git a/packages/webhooks/tsconfig.json b/packages/webhooks/tsconfig.json index f20eee7215..a487d9de28 100644 --- a/packages/webhooks/tsconfig.json +++ b/packages/webhooks/tsconfig.json @@ -5,6 +5,7 @@ "module": "commonjs", "outDir": "lib", "rootDir": "src", + "skipLibCheck": true, "strict": true, "target": "es2017", }, diff --git a/scripts/pack/deb b/scripts/pack/deb index 30e4da0761..41d45dcba7 100755 --- a/scripts/pack/deb +++ b/scripts/pack/deb @@ -8,7 +8,7 @@ const CLI_ROOT = path.join(root, 'packages', 'cli') async function main() { await require('../utils/_update_channel')() - await execa('./node_modules/.bin/oclif-dev', ['pack:deb'], { + await execa('./node_modules/.bin/oclif', ['pack:deb'], { cwd: CLI_ROOT, stdio: 'inherit' }) diff --git a/scripts/pack/tarballs b/scripts/pack/tarballs index d2c6b6fbc1..690f0e02d9 100755 --- a/scripts/pack/tarballs +++ b/scripts/pack/tarballs @@ -8,10 +8,10 @@ const CLI_ROOT = path.join(root, 'packages', 'cli') async function main() { await require('../utils/_update_channel')() - await execa('./node_modules/.bin/oclif-dev', ['pack'], { + await execa('./node_modules/.bin/oclif', ['pack', 'tarballs'], { cwd: CLI_ROOT, stdio: 'inherit' }) } -main() \ No newline at end of file +main() diff --git a/scripts/pack/win b/scripts/pack/win index e51a21eabe..cc37a70df1 100755 --- a/scripts/pack/win +++ b/scripts/pack/win @@ -8,10 +8,10 @@ const CLI_ROOT = path.join(root, 'packages', 'cli') async function main() { await require('../utils/_update_channel')() - await execa('./node_modules/.bin/oclif-dev', ['pack:win'], { + await execa('./node_modules/.bin/oclif', ['pack:win'], { cwd: CLI_ROOT, stdio: 'inherit', }) } -main() \ No newline at end of file +main() diff --git a/scripts/postrelease/dev_center_docs b/scripts/postrelease/dev_center_docs index 75580191ed..85223ca67a 100755 --- a/scripts/postrelease/dev_center_docs +++ b/scripts/postrelease/dev_center_docs @@ -33,7 +33,7 @@ These are the help texts for each of the core Heroku CLI commands. You can also EOF -oclif-dev readme +oclif readme grep -v "^\\* \\[\`" README.md | grep -v "^