From 13eb8abfd29d678e95c9e7ef52ccc22575386519 Mon Sep 17 00:00:00 2001 From: Kanad Gupta Date: Wed, 4 Dec 2024 18:56:08 -0600 Subject: [PATCH] feat!: switch topic separator to space (#1100) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## ๐Ÿงฐ Changes BREAKING CHANGE: the topic separator (i.e., what separates a command from its subcommand) has changed from a colon to a space by default. For example, `rdme openapi:validate` is now `rdme openapi validate`. The colon topic separator will continue to be supported so there is no need to change any existing commands, but all documentation and help screens will reflect the space topic separator. ## ๐Ÿงฌ QA & Testing Do tests still pass? --- .github/workflows/ci.yml | 15 ++++--- CONTRIBUTING.md | 6 +-- README.md | 2 +- __tests__/commands/categories/create.test.ts | 2 +- __tests__/commands/docs/prune.test.ts | 6 +-- .../__snapshots__/inspect.test.ts.snap | 16 +++---- .../__snapshots__/validate.test.ts.snap | 40 ++++++++--------- __tests__/commands/openapi/convert.test.ts | 2 +- __tests__/commands/openapi/inspect.test.ts | 2 +- __tests__/commands/openapi/reduce.test.ts | 2 +- __tests__/commands/openapi/validate.test.ts | 4 +- __tests__/commands/versions/create.test.ts | 4 +- __tests__/commands/versions/delete.test.ts | 2 +- __tests__/commands/versions/update.test.ts | 2 +- __tests__/lib/createGHA.test.ts | 2 + documentation/commands/categories.md | 10 ++--- documentation/commands/docs.md | 12 ++--- documentation/commands/openapi.md | 44 +++++++++---------- documentation/commands/versions.md | 28 ++++++------ documentation/rdme.md | 4 +- package.json | 2 +- src/commands/docs/prune.ts | 2 +- src/commands/openapi/convert.ts | 2 +- src/commands/openapi/inspect.ts | 2 +- src/commands/openapi/reduce.ts | 2 +- src/commands/openapi/validate.ts | 4 +- src/commands/versions/create.ts | 2 +- src/index.ts | 10 +++++ src/lib/castStringOptToBool.ts | 2 +- src/lib/flags.ts | 2 +- src/lib/prepareOas.ts | 6 +-- src/lib/prompts.ts | 6 +-- 32 files changed, 132 insertions(+), 115 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 703c69ede..48ac6f03c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -73,22 +73,27 @@ jobs: run: npm ci && npm run build:gha working-directory: rdme-repo - - name: Run `openapi:validate` command + - name: Run `openapi validate` command + uses: ./rdme-repo/ + with: + rdme: openapi validate oas-examples-repo/3.1/json/petstore.json + + - name: Run `openapi validate` command (legacy topic separator) uses: ./rdme-repo/ with: rdme: openapi:validate oas-examples-repo/3.1/json/petstore.json - - name: Run `openapi:validate` with filename in quotes + - name: Run `openapi validate` with filename in quotes uses: ./rdme-repo/ with: - rdme: openapi:validate "oas-examples-repo/3.1/json/petstore.json" + rdme: openapi validate "oas-examples-repo/3.1/json/petstore.json" - - name: Run `openapi:validate` on an invalid file + - name: Run `openapi validate` on an invalid file uses: ./rdme-repo/ id: openapi-validate-fail continue-on-error: true with: - rdme: openapi:validate rdme-repo/__tests__/__fixtures__/invalid-oas.json + rdme: openapi validate rdme-repo/__tests__/__fixtures__/invalid-oas.json - name: Assert that previous validation step failed if: ${{ steps.openapi-validate-fail.outcome == 'failure' }} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e828a3f99..6c9acb5cf 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -12,10 +12,10 @@ To run test commands, swap out `rdme` for `bin/dev.js`. For example: ```sh # if the production command you're testing looks like this... -rdme openapi:validate __tests__/__fixtures__/ref-oas/petstore.json +rdme openapi validate __tests__/__fixtures__/ref-oas/petstore.json # ... your local test command will look like this: -bin/dev.js openapi:validate __tests__/__fixtures__/ref-oas/petstore.json +bin/dev.js openapi validate __tests__/__fixtures__/ref-oas/petstore.json ``` The `bin/dev.js` file has a few features that are useful for local development: @@ -27,7 +27,7 @@ The `bin/dev.js` file has a few features that are useful for local development: ```sh npm run build -bin/run.js openapi:validate __tests__/__fixtures__/ref-oas/petstore.json +bin/run.js openapi validate __tests__/__fixtures__/ref-oas/petstore.json ``` Your changes to the command code may make changes to [the command reference documents](./documentation/commands) โ€” it is up to you whether you include those changes in your PR or if you let the release process take care of it. More information on that can be found in [`MAINTAINERS.md`](./MAINTAINERS.md). diff --git a/README.md b/README.md index b7c93034d..08236b4dd 100644 --- a/README.md +++ b/README.md @@ -81,7 +81,7 @@ npm install rdme --save-dev Once installed in your project, you can use the `npx` prefix (which is included if you have `npm` installed) to run your CLI commands locally. For example: ```sh -npx rdme openapi:validate [file] +npx rdme openapi validate [file] ``` To ensure you're getting the latest features and security updates, we recommend using a tool like [Dependabot](https://docs.github.com/code-security/dependabot/dependabot-version-updates/about-dependabot-version-updates) to keep `rdme` (and your other dependencies) up-to-date. diff --git a/__tests__/commands/categories/create.test.ts b/__tests__/commands/categories/create.test.ts index 3c692aadb..540d89df4 100644 --- a/__tests__/commands/categories/create.test.ts +++ b/__tests__/commands/categories/create.test.ts @@ -8,7 +8,7 @@ import { runCommandAndReturnResult } from '../../helpers/oclif.js'; const key = 'API_KEY'; const version = '1.0.0'; -describe('rdme categories:create', () => { +describe('rdme categories create', () => { let run: (args?: string[]) => Promise; beforeAll(() => { diff --git a/__tests__/commands/docs/prune.test.ts b/__tests__/commands/docs/prune.test.ts index 1211098fc..88b4f0b3d 100644 --- a/__tests__/commands/docs/prune.test.ts +++ b/__tests__/commands/docs/prune.test.ts @@ -11,7 +11,7 @@ const fixturesBaseDir = '__fixtures__/docs'; const key = 'API_KEY'; const version = '1.0.0'; -describe('rdme docs:prune', () => { +describe('rdme docs prune', () => { const folder = `./__tests__/${fixturesBaseDir}/delete-docs`; let run: (args?: string[]) => Promise; @@ -162,10 +162,10 @@ describe('rdme docs:prune', () => { versionMock.done(); }); - describe('rdme guides:prune', () => { + describe('rdme guides prune', () => { it('should error if no folder provided', async () => { return expect( - (await runCommandWithHooks(['guides:prune', '--key', key, '--version', version])).error.message, + (await runCommandWithHooks(['guides', 'prune', '--key', key, '--version', version])).error.message, ).toContain('Missing 1 required arg:\nfolder'); }); }); diff --git a/__tests__/commands/openapi/__snapshots__/inspect.test.ts.snap b/__tests__/commands/openapi/__snapshots__/inspect.test.ts.snap index 256829bb0..a26aab331 100644 --- a/__tests__/commands/openapi/__snapshots__/inspect.test.ts.snap +++ b/__tests__/commands/openapi/__snapshots__/inspect.test.ts.snap @@ -1,6 +1,6 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html -exports[`rdme openapi:inspect > feature reports > should generate a report for '@readme/oas-examples/3.0/json/readme.โ€ฆ' (w/ [ 'polymorphism' ]) 1`] = ` +exports[`rdme openapi inspect > feature reports > should generate a report for '@readme/oas-examples/3.0/json/readme.โ€ฆ' (w/ [ 'polymorphism' ]) 1`] = ` " polymorphism: ยท #/components/responses/authForbidden/content/application~1json/schema @@ -50,7 +50,7 @@ polymorphism: ยท #/paths/~1version/post/responses/400/content/application~1json/schema" `; -exports[`rdme openapi:inspect > feature reports > should generate a report for '@readme/oas-examples/3.0/json/readme-โ€ฆ' (w/ [ 'readme' ]) 1`] = ` +exports[`rdme openapi inspect > feature reports > should generate a report for '@readme/oas-examples/3.0/json/readme-โ€ฆ' (w/ [ 'readme' ]) 1`] = ` " x-default: You do not use this. x-readme.code-samples: @@ -76,7 +76,7 @@ x-readme.samples-languages: ยท swift" `; -exports[`rdme openapi:inspect > feature reports > should generate a report for '@readme/oas-examples/3.0/json/schema-โ€ฆ' (w/ [ 'additionalProperties', โ€ฆ(1) ]) 1`] = ` +exports[`rdme openapi inspect > feature reports > should generate a report for '@readme/oas-examples/3.0/json/schema-โ€ฆ' (w/ [ 'additionalProperties', โ€ฆ(1) ]) 1`] = ` " additionalProperties: ยท #/components/schemas/BodyPart/properties/headers/additionalProperties @@ -97,7 +97,7 @@ circularRefs: ยท #/components/schemas/ZoneOffset/properties/rules" `; -exports[`rdme openapi:inspect > feature reports > should generate a report for '@readme/oas-examples/3.0/json/schema-โ€ฆ' (w/ [ 'additionalProperties', โ€ฆ(2) ]) 1`] = ` +exports[`rdme openapi inspect > feature reports > should generate a report for '@readme/oas-examples/3.0/json/schema-โ€ฆ' (w/ [ 'additionalProperties', โ€ฆ(2) ]) 1`] = ` " additionalProperties: ยท #/components/schemas/BodyPart/properties/headers/additionalProperties @@ -125,7 +125,7 @@ x-readme.proxy-enabled: You do not use this. x-readme.samples-languages: You do not use this." `; -exports[`rdme openapi:inspect > feature reports > should generate a report for '@readme/oas-examples/3.0/json/schema-โ€ฆ' (w/ [ 'circularRefs', 'readme' ]) 1`] = ` +exports[`rdme openapi inspect > feature reports > should generate a report for '@readme/oas-examples/3.0/json/schema-โ€ฆ' (w/ [ 'circularRefs', 'readme' ]) 1`] = ` " circularRefs: ยท #/components/schemas/MultiPart/properties/parent @@ -139,7 +139,7 @@ x-readme.proxy-enabled: You do not use this. x-readme.samples-languages: You do not use this." `; -exports[`rdme openapi:inspect > full reports > should generate a report for @readme/oas-examples/3.0/json/petstore.json 1`] = ` +exports[`rdme openapi inspect > full reports > should generate a report for @readme/oas-examples/3.0/json/petstore.json 1`] = ` "Here are some interesting things we found in your API definition. ๐Ÿ•ต๏ธ ยท You are using 4 Media Types throughout your API: application/json, application/x-www-form-urlencoded, application/xml, and multipart/form-data @@ -249,7 +249,7 @@ ReadMe-Specific Features and Extensions " `; -exports[`rdme openapi:inspect > full reports > should generate a report for @readme/oas-examples/3.0/json/readme.json 1`] = ` +exports[`rdme openapi inspect > full reports > should generate a report for @readme/oas-examples/3.0/json/readme.json 1`] = ` "Here are some interesting things we found in your API definition. ๐Ÿ•ต๏ธ ยท You are using 2 Media Types throughout your API: application/json and multipart/form-data @@ -359,7 +359,7 @@ ReadMe-Specific Features and Extensions " `; -exports[`rdme openapi:inspect > full reports > should generate a report for @readme/oas-examples/3.0/json/readme-extensions.json 1`] = ` +exports[`rdme openapi inspect > full reports > should generate a report for @readme/oas-examples/3.0/json/readme-extensions.json 1`] = ` "Here are some interesting things we found in your API definition. ๐Ÿ•ต๏ธ ยท You are using a single Media Type throughout your API: application/json diff --git a/__tests__/commands/openapi/__snapshots__/validate.test.ts.snap b/__tests__/commands/openapi/__snapshots__/validate.test.ts.snap index 3ff2607eb..157b3a188 100644 --- a/__tests__/commands/openapi/__snapshots__/validate.test.ts.snap +++ b/__tests__/commands/openapi/__snapshots__/validate.test.ts.snap @@ -1,6 +1,6 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html -exports[`rdme openapi:validate > GHA onboarding E2E tests > should create GHA workflow if user passes in spec via opt (github flag enabled) 1`] = ` +exports[`rdme openapi validate > GHA onboarding E2E tests > should create GHA workflow if user passes in spec via opt (github flag enabled) 1`] = ` " Your GitHub Actions workflow file has been created! โœจ @@ -10,7 +10,7 @@ Almost done! Push your newly created file (.github/workflows/validate-test-opt-s " `; -exports[`rdme openapi:validate > GHA onboarding E2E tests > should create GHA workflow if user passes in spec via opt (github flag enabled) 2`] = ` +exports[`rdme openapi validate > GHA onboarding E2E tests > should create GHA workflow if user passes in spec via opt (github flag enabled) 2`] = ` "# This GitHub Actions workflow was auto-generated by the \`rdme\` cli on 2022-01-01T00:00:00.000Z # You can view our full documentation here: https://docs.readme.com/docs/rdme name: ReadMe GitHub Action ๐Ÿฆ‰ @@ -30,14 +30,14 @@ jobs: - name: Check out repo ๐Ÿ“š uses: actions/checkout@v4 - - name: Run \`openapi:validate\` command ๐Ÿš€ + - name: Run \`openapi validate\` command ๐Ÿš€ uses: readmeio/rdme@v7 with: - rdme: openapi:validate __tests__/__fixtures__/petstore-simple-weird-version.json + rdme: openapi validate __tests__/__fixtures__/petstore-simple-weird-version.json " `; -exports[`rdme openapi:validate > GHA onboarding E2E tests > should create GHA workflow if user passes in spec via opt (including workingDirectory) 1`] = ` +exports[`rdme openapi validate > GHA onboarding E2E tests > should create GHA workflow if user passes in spec via opt (including workingDirectory) 1`] = ` " Your GitHub Actions workflow file has been created! โœจ @@ -47,7 +47,7 @@ Almost done! Push your newly created file (.github/workflows/validate-test-opt-s " `; -exports[`rdme openapi:validate > GHA onboarding E2E tests > should create GHA workflow if user passes in spec via opt (including workingDirectory) 2`] = ` +exports[`rdme openapi validate > GHA onboarding E2E tests > should create GHA workflow if user passes in spec via opt (including workingDirectory) 2`] = ` "# This GitHub Actions workflow was auto-generated by the \`rdme\` cli on 2022-01-01T00:00:00.000Z # You can view our full documentation here: https://docs.readme.com/docs/rdme name: ReadMe GitHub Action ๐Ÿฆ‰ @@ -67,14 +67,14 @@ jobs: - name: Check out repo ๐Ÿ“š uses: actions/checkout@v4 - - name: Run \`openapi:validate\` command ๐Ÿš€ + - name: Run \`openapi validate\` command ๐Ÿš€ uses: readmeio/rdme@v7 with: - rdme: openapi:validate petstore.json --workingDirectory=./__tests__/__fixtures__/relative-ref-oas + rdme: openapi validate petstore.json --workingDirectory=./__tests__/__fixtures__/relative-ref-oas " `; -exports[`rdme openapi:validate > GHA onboarding E2E tests > should create GHA workflow if user passes in spec via opt 1`] = ` +exports[`rdme openapi validate > GHA onboarding E2E tests > should create GHA workflow if user passes in spec via opt 1`] = ` " Your GitHub Actions workflow file has been created! โœจ @@ -84,7 +84,7 @@ Almost done! Push your newly created file (.github/workflows/validate-test-opt-s " `; -exports[`rdme openapi:validate > GHA onboarding E2E tests > should create GHA workflow if user passes in spec via opt 2`] = ` +exports[`rdme openapi validate > GHA onboarding E2E tests > should create GHA workflow if user passes in spec via opt 2`] = ` "# This GitHub Actions workflow was auto-generated by the \`rdme\` cli on 2022-01-01T00:00:00.000Z # You can view our full documentation here: https://docs.readme.com/docs/rdme name: ReadMe GitHub Action ๐Ÿฆ‰ @@ -104,14 +104,14 @@ jobs: - name: Check out repo ๐Ÿ“š uses: actions/checkout@v4 - - name: Run \`openapi:validate\` command ๐Ÿš€ + - name: Run \`openapi validate\` command ๐Ÿš€ uses: readmeio/rdme@v7 with: - rdme: openapi:validate __tests__/__fixtures__/petstore-simple-weird-version.json + rdme: openapi validate __tests__/__fixtures__/petstore-simple-weird-version.json " `; -exports[`rdme openapi:validate > GHA onboarding E2E tests > should create GHA workflow if user passes in spec via prompts 1`] = ` +exports[`rdme openapi validate > GHA onboarding E2E tests > should create GHA workflow if user passes in spec via prompts 1`] = ` " Your GitHub Actions workflow file has been created! โœจ @@ -121,7 +121,7 @@ Almost done! Push your newly created file (.github/workflows/validate-test-file. " `; -exports[`rdme openapi:validate > GHA onboarding E2E tests > should create GHA workflow if user passes in spec via prompts 2`] = ` +exports[`rdme openapi validate > GHA onboarding E2E tests > should create GHA workflow if user passes in spec via prompts 2`] = ` "# This GitHub Actions workflow was auto-generated by the \`rdme\` cli on 2022-01-01T00:00:00.000Z # You can view our full documentation here: https://docs.readme.com/docs/rdme name: ReadMe GitHub Action ๐Ÿฆ‰ @@ -141,14 +141,14 @@ jobs: - name: Check out repo ๐Ÿ“š uses: actions/checkout@v4 - - name: Run \`openapi:validate\` command ๐Ÿš€ + - name: Run \`openapi validate\` command ๐Ÿš€ uses: readmeio/rdme@v7 with: - rdme: openapi:validate __tests__/__fixtures__/petstore-simple-weird-version.json + rdme: openapi validate __tests__/__fixtures__/petstore-simple-weird-version.json " `; -exports[`rdme openapi:validate > error handling > should throw an error if an invalid API definition has many errors 1`] = ` +exports[`rdme openapi validate > error handling > should throw an error if an invalid API definition has many errors 1`] = ` [SyntaxError: OpenAPI schema validation failed. REQUIRED must have required property 'url' @@ -172,9 +172,9 @@ ADDITIONAL PROPERTY must NOT have additional properties 29 | "summary": "Finds Pets by status",] `; -exports[`rdme openapi:validate > error handling > should throw an error if an invalid OpenAPI 3.0 definition is supplied 1`] = `[MissingPointerError: Token "Error" does not exist.]`; +exports[`rdme openapi validate > error handling > should throw an error if an invalid OpenAPI 3.0 definition is supplied 1`] = `[MissingPointerError: Token "Error" does not exist.]`; -exports[`rdme openapi:validate > error handling > should throw an error if an invalid OpenAPI 3.1 definition is supplied 1`] = ` +exports[`rdme openapi validate > error handling > should throw an error if an invalid OpenAPI 3.1 definition is supplied 1`] = ` [SyntaxError: OpenAPI schema validation failed. REQUIRED must have required property 'name' @@ -188,7 +188,7 @@ REQUIRED must have required property 'name' 29 | }] `; -exports[`rdme openapi:validate > error handling > should throw an error if an invalid Swagger definition is supplied 1`] = ` +exports[`rdme openapi validate > error handling > should throw an error if an invalid Swagger definition is supplied 1`] = ` [SyntaxError: Swagger schema validation failed. ADDITIONAL PROPERTY must NOT have additional properties diff --git a/__tests__/commands/openapi/convert.test.ts b/__tests__/commands/openapi/convert.test.ts index f2c5ae805..1469beef2 100644 --- a/__tests__/commands/openapi/convert.test.ts +++ b/__tests__/commands/openapi/convert.test.ts @@ -8,7 +8,7 @@ import { runCommandAndReturnResult } from '../../helpers/oclif.js'; const successfulConversion = () => 'Your API definition has been converted and bundled and saved to output.json!'; -describe('rdme openapi:convert', () => { +describe('rdme openapi convert', () => { let run: (args?: string[]) => Promise; let testWorkingDir: string; diff --git a/__tests__/commands/openapi/inspect.test.ts b/__tests__/commands/openapi/inspect.test.ts index b03f04c7f..c5a0137f2 100644 --- a/__tests__/commands/openapi/inspect.test.ts +++ b/__tests__/commands/openapi/inspect.test.ts @@ -7,7 +7,7 @@ import { describe, it, expect, beforeAll } from 'vitest'; import Command from '../../../src/commands/openapi/inspect.js'; import { runCommandAndReturnResult } from '../../helpers/oclif.js'; -describe('rdme openapi:inspect', () => { +describe('rdme openapi inspect', () => { let run: (args?: string[]) => Promise; beforeAll(() => { diff --git a/__tests__/commands/openapi/reduce.test.ts b/__tests__/commands/openapi/reduce.test.ts index 428cddcb8..a695f8baa 100644 --- a/__tests__/commands/openapi/reduce.test.ts +++ b/__tests__/commands/openapi/reduce.test.ts @@ -13,7 +13,7 @@ const successfulReduction = () => 'Your reduced API definition has been saved to let consoleInfoSpy: MockInstance; const getCommandOutput = () => consoleInfoSpy.mock.calls.join('\n\n'); -describe('rdme openapi:reduce', () => { +describe('rdme openapi reduce', () => { let run: (args?: string[]) => Promise; let testWorkingDir: string; diff --git a/__tests__/commands/openapi/validate.test.ts b/__tests__/commands/openapi/validate.test.ts index 534e66869..f2ddb81ec 100644 --- a/__tests__/commands/openapi/validate.test.ts +++ b/__tests__/commands/openapi/validate.test.ts @@ -16,7 +16,7 @@ const getCommandOutput = () => { return [consoleInfoSpy.mock.calls.join('\n\n')].filter(Boolean).join('\n\n'); }; -describe('rdme openapi:validate', () => { +describe('rdme openapi validate', () => { let run: (args?: string[]) => Promise; let testWorkingDir: string; @@ -122,7 +122,7 @@ describe('rdme openapi:validate', () => { return expect( ( await runCommandWithHooks([ - 'openapi:validate', + 'openapi validate', '__tests__/__fixtures__/petstore-simple-weird-version.json', '--github', ]) diff --git a/__tests__/commands/versions/create.test.ts b/__tests__/commands/versions/create.test.ts index c85c73755..04ea9fac3 100644 --- a/__tests__/commands/versions/create.test.ts +++ b/__tests__/commands/versions/create.test.ts @@ -10,7 +10,7 @@ import { runCommandAndReturnResult } from '../../helpers/oclif.js'; const key = 'API_KEY'; const version = '1.0.0'; -describe('rdme versions:create', () => { +describe('rdme versions create', () => { let run: (args?: string[]) => Promise; beforeAll(() => { @@ -26,7 +26,7 @@ describe('rdme versions:create', () => { it('should error if invalid version provided', () => { return expect(run(['--key', key, 'test'])).rejects.toStrictEqual( - new Error('Please specify a semantic version. See `rdme help versions:create` for help.'), + new Error('Please specify a semantic version. See `rdme help versions create` for help.'), ); }); diff --git a/__tests__/commands/versions/delete.test.ts b/__tests__/commands/versions/delete.test.ts index c0692bac3..3dd192506 100644 --- a/__tests__/commands/versions/delete.test.ts +++ b/__tests__/commands/versions/delete.test.ts @@ -9,7 +9,7 @@ import { runCommandAndReturnResult } from '../../helpers/oclif.js'; const key = 'API_KEY'; const version = '1.0.0'; -describe('rdme versions:delete', () => { +describe('rdme versions delete', () => { let run: (args?: string[]) => Promise; beforeAll(() => { diff --git a/__tests__/commands/versions/update.test.ts b/__tests__/commands/versions/update.test.ts index 6be05bd2f..1dd531cb4 100644 --- a/__tests__/commands/versions/update.test.ts +++ b/__tests__/commands/versions/update.test.ts @@ -10,7 +10,7 @@ import { runCommandAndReturnResult } from '../../helpers/oclif.js'; const key = 'API_KEY'; const version = '1.0.0'; -describe('rdme versions:update', () => { +describe('rdme versions update', () => { let run: (args?: string[]) => Promise; beforeAll(() => { diff --git a/__tests__/lib/createGHA.test.ts b/__tests__/lib/createGHA.test.ts index 1b8da6c7c..a1cd3d9b8 100644 --- a/__tests__/lib/createGHA.test.ts +++ b/__tests__/lib/createGHA.test.ts @@ -55,6 +55,8 @@ describe('#createGHA', () => { label: string; opts: Record; }>([ + // `openapi:validate` is the ID we define in src/index.ts for backwards compatibility, + // hence we're using this command ID here { cmd: 'openapi:validate', opts: { spec: 'petstore.json' }, label: '' }, { cmd: 'openapi', opts: { key, spec: 'petstore.json', id: 'spec_id' }, label: '' }, { cmd: 'docs', opts: { key, path: './docs', version: '1.0.0' }, label: '' }, diff --git a/documentation/commands/categories.md b/documentation/commands/categories.md index 804f2e84b..70021b722 100644 --- a/documentation/commands/categories.md +++ b/documentation/commands/categories.md @@ -4,7 +4,7 @@ List or create categories in your ReadMe developer hub. * [`rdme categories`](#rdme-categories) -* [`rdme categories:create TITLE`](#rdme-categoriescreate-title) +* [`rdme categories create TITLE`](#rdme-categories-create-title) ## `rdme categories` @@ -28,13 +28,13 @@ EXAMPLES $ rdme categories --version={project-version} ``` -## `rdme categories:create TITLE` +## `rdme categories create TITLE` Create a category with the specified title and guide in your ReadMe project. ``` USAGE - $ rdme categories:create TITLE --categoryType guide|reference --key [--preventDuplicates] [--version ] + $ rdme categories create TITLE --categoryType guide|reference --key [--preventDuplicates] [--version ] ARGUMENTS TITLE Title of the category @@ -54,11 +54,11 @@ DESCRIPTION EXAMPLES Create a new category for your project version: - $ rdme categories:create --categoryType={guide|reference} --version={project-version} + $ rdme categories create <title> --categoryType={guide|reference} --version={project-version} If you want to prevent the creation of a duplicate category with a matching `title` and `categoryType`, supply the `--preventDuplicates` flag: - $ rdme categories:create <title> --categoryType={guide|reference} --version={project-version} \ + $ rdme categories create <title> --categoryType={guide|reference} --version={project-version} \ --preventDuplicates ``` diff --git a/documentation/commands/docs.md b/documentation/commands/docs.md index 51419b6cb..2db00b5fe 100644 --- a/documentation/commands/docs.md +++ b/documentation/commands/docs.md @@ -4,7 +4,7 @@ Sync or prune Guides pages in your ReadMe developer hub. * [`rdme docs PATH`](#rdme-docs-path) -* [`rdme docs:prune FOLDER`](#rdme-docsprune-folder) +* [`rdme docs prune FOLDER`](#rdme-docs-prune-folder) ## `rdme docs PATH` @@ -46,13 +46,13 @@ EXAMPLES $ rdme docs [path] --version={project-version} --dryRun ``` -## `rdme docs:prune FOLDER` +## `rdme docs prune FOLDER` Delete any docs from ReadMe if their slugs are not found in the target folder. ``` USAGE - $ rdme docs:prune FOLDER --key <value> [--version <value>] [--github] [--confirm] [--dryRun] + $ rdme docs prune FOLDER --key <value> [--version <value>] [--github] [--confirm] [--dryRun] ARGUMENTS FOLDER A local folder containing the files you wish to prune. @@ -69,14 +69,14 @@ DESCRIPTION Delete any docs from ReadMe if their slugs are not found in the target folder. ALIASES - $ rdme guides:prune + $ rdme guides prune EXAMPLES If you wish to delete documents from ReadMe that are no longer present in your local directory: - $ rdme docs:prune [path-to-directory-of-markdown] + $ rdme docs prune [path-to-directory-of-markdown] Run with `--confirm` to bypass the confirmation prompt (useful for CI environments): - $ rdme docs:prune [path-to-directory-of-markdown] --confirm + $ rdme docs prune [path-to-directory-of-markdown] --confirm ``` diff --git a/documentation/commands/openapi.md b/documentation/commands/openapi.md index 7509f5b29..0b39f4f77 100644 --- a/documentation/commands/openapi.md +++ b/documentation/commands/openapi.md @@ -4,10 +4,10 @@ Manage your API definition (e.g., syncing, validation, analysis, conversion, etc.). Supports OpenAPI, Swagger, and Postman collections, in either JSON or YAML formats. * [`rdme openapi [SPEC]`](#rdme-openapi-spec) -* [`rdme openapi:convert [SPEC]`](#rdme-openapiconvert-spec) -* [`rdme openapi:inspect [SPEC]`](#rdme-openapiinspect-spec) -* [`rdme openapi:reduce [SPEC]`](#rdme-openapireduce-spec) -* [`rdme openapi:validate [SPEC]`](#rdme-openapivalidate-spec) +* [`rdme openapi convert [SPEC]`](#rdme-openapi-convert-spec) +* [`rdme openapi inspect [SPEC]`](#rdme-openapi-inspect-spec) +* [`rdme openapi reduce [SPEC]`](#rdme-openapi-reduce-spec) +* [`rdme openapi validate [SPEC]`](#rdme-openapi-validate-spec) ## `rdme openapi [SPEC]` @@ -104,13 +104,13 @@ FLAG DESCRIPTIONS flag only works if there's only one API definition associated with the current version. ``` -## `rdme openapi:convert [SPEC]` +## `rdme openapi convert [SPEC]` Converts an API definition to OpenAPI and bundles any external references. ``` USAGE - $ rdme openapi:convert [SPEC] [--out <value>] [--title <value>] [--workingDirectory <value>] + $ rdme openapi convert [SPEC] [--out <value>] [--title <value>] [--workingDirectory <value>] ARGUMENTS SPEC A file/URL to your API definition @@ -131,21 +131,21 @@ EXAMPLES By default, this command will display a comprehensive table of all OpenAPI and ReadMe features found in your API definition: - $ rdme openapi:convert [url-or-local-path-to-file] + $ rdme openapi convert [url-or-local-path-to-file] You can omit the file name and `rdme` will scan your working directory (and any subdirectories) for OpenAPI/Swagger files. This approach will provide you with CLI prompts, so we do not recommend this technique in CI environments. - $ rdme openapi:convert + $ rdme openapi convert ``` -## `rdme openapi:inspect [SPEC]` +## `rdme openapi inspect [SPEC]` Analyze an OpenAPI/Swagger definition for various OpenAPI and ReadMe feature usage. ``` USAGE - $ rdme openapi:inspect [SPEC] [--feature + $ rdme openapi inspect [SPEC] [--feature additionalProperties|callbacks|circularRefs|discriminators|links|style|polymorphism|serverVariables|webhooks|xml|rea dme...] [--workingDirectory <value>] @@ -171,27 +171,27 @@ EXAMPLES By default, this command will display a comprehensive table of all OpenAPI and ReadMe features found in your API definition: - $ rdme openapi:inspect [url-or-local-path-to-file] + $ rdme openapi inspect [url-or-local-path-to-file] You can omit the file name and `rdme` will scan your working directory (and any subdirectories) for OpenAPI/Swagger files. This approach will provide you with CLI prompts, so we do not recommend this technique in CI environments. - $ rdme openapi:inspect + $ rdme openapi inspect If you wish to automate this command, it contains a `--feature` flag so you can filter for one or several specific features. If you pass in one or more `--feature` flags, the command returns a `0` exit code if your definition contains all of the given features and a `1` exit code if your definition lacks any of the given features: - $ rdme openapi:inspect [url-or-local-path-to-file] --feature circularRefs --feature polymorphism + $ rdme openapi inspect [url-or-local-path-to-file] --feature circularRefs --feature polymorphism ``` -## `rdme openapi:reduce [SPEC]` +## `rdme openapi reduce [SPEC]` Reduce an OpenAPI definition into a smaller subset. ``` USAGE - $ rdme openapi:reduce [SPEC] [--method <value>...] [--out <value>] [--path <value>...] [--tag <value>...] [--title + $ rdme openapi reduce [SPEC] [--method <value>...] [--out <value>] [--path <value>...] [--tag <value>...] [--title <value>] [--workingDirectory <value>] ARGUMENTS @@ -214,25 +214,25 @@ DESCRIPTION EXAMPLES By default, this command will ask you a couple questions about how you wish to reduce the file and then do so: - $ rdme openapi:reduce [url-or-local-path-to-file] + $ rdme openapi reduce [url-or-local-path-to-file] You can omit the file name and `rdme` will scan your working directory (and any subdirectories) for OpenAPI/Swagger files. This approach will provide you with CLI prompts, so we do not recommend this technique in CI environments. - $ rdme openapi:reduce + $ rdme openapi reduce If you wish to automate this command, you can pass in CLI arguments to bypass the prompts: - $ rdme openapi:reduce petstore.json --path /pet/{id} --method get --method put --out petstore.reduced.json + $ rdme openapi reduce petstore.json --path /pet/{id} --method get --method put --out petstore.reduced.json ``` -## `rdme openapi:validate [SPEC]` +## `rdme openapi validate [SPEC]` Validate your OpenAPI/Swagger definition. ``` USAGE - $ rdme openapi:validate [SPEC] [--github] [--workingDirectory <value>] + $ rdme openapi validate [SPEC] [--github] [--workingDirectory <value>] ARGUMENTS SPEC A file/URL to your API definition @@ -250,10 +250,10 @@ DESCRIPTION EXAMPLES This will validate the API definition at the given URL or path: - $ rdme openapi:validate [url-or-local-path-to-file] + $ rdme openapi validate [url-or-local-path-to-file] You can omit the file name and `rdme` will scan your working directory (and any subdirectories) for OpenAPI/Swagger files. This approach will provide you with CLI prompts, so we do not recommend this technique in CI environments. - $ rdme openapi:validate + $ rdme openapi validate ``` diff --git a/documentation/commands/versions.md b/documentation/commands/versions.md index 260e873be..f15cd0101 100644 --- a/documentation/commands/versions.md +++ b/documentation/commands/versions.md @@ -4,9 +4,9 @@ Manage your documentation versions. * [`rdme versions`](#rdme-versions) -* [`rdme versions:create VERSION`](#rdme-versionscreate-version) -* [`rdme versions:delete [VERSION]`](#rdme-versionsdelete-version) -* [`rdme versions:update [VERSION]`](#rdme-versionsupdate-version) +* [`rdme versions create VERSION`](#rdme-versions-create-version) +* [`rdme versions delete [VERSION]`](#rdme-versions-delete-version) +* [`rdme versions update [VERSION]`](#rdme-versions-update-version) ## `rdme versions` @@ -33,13 +33,13 @@ EXAMPLES $ rdme versions --version={project-version} ``` -## `rdme versions:create VERSION` +## `rdme versions create VERSION` Create a new version for your project. ``` USAGE - $ rdme versions:create VERSION --key <value> [--fork <value>] [--codename <value>] [--main true|false] [--beta + $ rdme versions create VERSION --key <value> [--fork <value>] [--codename <value>] [--main true|false] [--beta true|false] [--deprecated true|false] [--hidden true|false] ARGUMENTS @@ -64,22 +64,22 @@ DESCRIPTION EXAMPLES Create a new version (with no flags): - $ rdme versions:create + $ rdme versions create If you wish to automate the process of creating a new project version, and not have the CLI prompt you for input, you can do so by supplying the necessary flags: - $ rdme versions:create <version> --fork={version-fork} --main={true|false} --beta={true|false} \ + $ rdme versions create <version> --fork={version-fork} --main={true|false} --beta={true|false} \ --deprecated={true|false} --hidden={true|false} ``` -## `rdme versions:delete [VERSION]` +## `rdme versions delete [VERSION]` Delete a version associated with your ReadMe project. ``` USAGE - $ rdme versions:delete [VERSION] --key <value> + $ rdme versions delete [VERSION] --key <value> ARGUMENTS VERSION The version you'd like to delete. @@ -93,16 +93,16 @@ DESCRIPTION EXAMPLES Remove a specific version from your project, as well as all of the associated documentation: - $ rdme versions:delete <version> + $ rdme versions delete <version> ``` -## `rdme versions:update [VERSION]` +## `rdme versions update [VERSION]` Update an existing version for your project. ``` USAGE - $ rdme versions:update [VERSION] --key <value> [--newVersion <value>] [--codename <value>] [--main true|false] + $ rdme versions update [VERSION] --key <value> [--newVersion <value>] [--codename <value>] [--main true|false] [--beta true|false] [--deprecated true|false] [--hidden true|false] ARGUMENTS @@ -127,11 +127,11 @@ DESCRIPTION EXAMPLES Update an existing version (with no flags): - $ rdme versions:update + $ rdme versions update If you wish to automate the process of updating a project version, and not have the CLI prompt you for input, you can do so by supplying the necessary flags: - $ rdme versions:update <version> --newVersion={new-version-name} --main={true|false} --beta={true|false} \ + $ rdme versions update <version> --newVersion={new-version-name} --main={true|false} --beta={true|false} \ --deprecated={true|false} --hidden={true|false} ``` diff --git a/documentation/rdme.md b/documentation/rdme.md index 476af5132..51441500a 100644 --- a/documentation/rdme.md +++ b/documentation/rdme.md @@ -194,7 +194,7 @@ We recommend using the [quick start](#quick-start) to get started with GitHub Ac The command syntax in GitHub Actions is functionally equivalent to the CLI. For example, take the following CLI command: ```sh -rdme openapi:validate [url-or-local-path-to-file] +rdme openapi validate [url-or-local-path-to-file] ``` To execute this command via GitHub Actions, the step would look like this: @@ -202,7 +202,7 @@ To execute this command via GitHub Actions, the step would look like this: ```yml - uses: readmeio/rdme@RDME_VERSION with: - rdme: openapi:validate [url-or-local-path-to-file] + rdme: openapi validate [url-or-local-path-to-file] ``` The following section has links to full GitHub Actions workflow file examples. diff --git a/package.json b/package.json index 7ddd2c231..ea976d1f5 100644 --- a/package.json +++ b/package.json @@ -157,7 +157,7 @@ "target": "./dist/index.js", "identifier": "COMMANDS" }, - "topicSeparator": ":", + "topicSeparator": " ", "helpClass": "./dist/lib/help", "hooks": { "prerun": { diff --git a/src/commands/docs/prune.ts b/src/commands/docs/prune.ts index 70a4b09dd..a2bcfa49a 100644 --- a/src/commands/docs/prune.ts +++ b/src/commands/docs/prune.ts @@ -17,7 +17,7 @@ function getSlug(filename: string): string { } export default class DocsPruneCommand extends BaseCommand<typeof DocsPruneCommand> { - static aliases = ['guides:prune']; + static aliases = ['guides prune']; static description = 'Delete any docs from ReadMe if their slugs are not found in the target folder.'; diff --git a/src/commands/openapi/convert.ts b/src/commands/openapi/convert.ts index d74929231..a84127923 100644 --- a/src/commands/openapi/convert.ts +++ b/src/commands/openapi/convert.ts @@ -53,7 +53,7 @@ export default class OpenAPIConvertCommand extends BaseCommand<typeof OpenAPICon this.debug(`switching working directory from ${previousWorkingDirectory} to ${process.cwd()}`); } - const { preparedSpec, specPath, specType } = await prepareOas(spec, 'openapi:convert', { + const { preparedSpec, specPath, specType } = await prepareOas(spec, 'openapi convert', { convertToLatest: true, title, }); diff --git a/src/commands/openapi/inspect.ts b/src/commands/openapi/inspect.ts index d5a8ceff4..95da80df7 100644 --- a/src/commands/openapi/inspect.ts +++ b/src/commands/openapi/inspect.ts @@ -224,7 +224,7 @@ export default class OpenAPIInspectCommand extends BaseCommand<typeof OpenAPIIns this.debug(`switching working directory from ${previousWorkingDirectory} to ${process.cwd()}`); } - const { preparedSpec, definitionVersion } = await prepareOas(spec, 'openapi:inspect', { convertToLatest: true }); + const { preparedSpec, definitionVersion } = await prepareOas(spec, 'openapi inspect', { convertToLatest: true }); const parsedPreparedSpec: OASDocument = JSON.parse(preparedSpec); const spinner = ora({ ...oraOptions() }); diff --git a/src/commands/openapi/reduce.ts b/src/commands/openapi/reduce.ts index 9d54cda00..629c33edd 100644 --- a/src/commands/openapi/reduce.ts +++ b/src/commands/openapi/reduce.ts @@ -68,7 +68,7 @@ export default class OpenAPIReduceCommand extends BaseCommand<typeof OpenAPIRedu this.debug(`switching working directory from ${previousWorkingDirectory} to ${process.cwd()}`); } - const { preparedSpec, specPath, specType } = await prepareOas(spec, 'openapi:reduce', { title }); + const { preparedSpec, specPath, specType } = await prepareOas(spec, 'openapi reduce', { title }); const parsedPreparedSpec: OASDocument = JSON.parse(preparedSpec); if (specType !== 'OpenAPI') { diff --git a/src/commands/openapi/validate.ts b/src/commands/openapi/validate.ts index 96b8e69fe..957ac91b2 100644 --- a/src/commands/openapi/validate.ts +++ b/src/commands/openapi/validate.ts @@ -12,7 +12,7 @@ export default class OpenAPIValidateCommand extends BaseCommand<typeof OpenAPIVa 'Perform a local validation of your API definition (no ReadMe account required!), which can be useful when constructing or editing your API definition.'; // needed for unit tests, even though we also specify this in src/index.ts - static id = 'openapi:validate'; + static id = 'openapi validate' as const; static args = { spec: Args.string({ description: 'A file/URL to your API definition' }), @@ -42,7 +42,7 @@ export default class OpenAPIValidateCommand extends BaseCommand<typeof OpenAPIVa this.debug(`switching working directory from ${previousWorkingDirectory} to ${process.cwd()}`); } - const { specPath, specType } = await prepareOas(this.args.spec, 'openapi:validate'); + const { specPath, specType } = await prepareOas(this.args.spec, OpenAPIValidateCommand.id); return this.runCreateGHAHook({ parsedOpts: { ...this.flags, spec: specPath }, diff --git a/src/commands/versions/create.ts b/src/commands/versions/create.ts index 51c3933dd..12fb2c57d 100644 --- a/src/commands/versions/create.ts +++ b/src/commands/versions/create.ts @@ -15,7 +15,7 @@ export default class CreateVersionCommand extends BaseCommand<typeof CreateVersi static description = 'Create a new version for your project.'; // needed for unit tests, even though we also specify this in src/index.ts - static id = 'versions:create'; + static id = 'versions create'; static args = { version: Args.string({ diff --git a/src/index.ts b/src/index.ts index ab4bdda9a..6039677ad 100644 --- a/src/index.ts +++ b/src/index.ts @@ -21,6 +21,16 @@ import WhoAmICommand from './commands/whoami.js'; export { default as createGHA } from './lib/hooks/createGHA.js'; export { default as prerun } from './lib/hooks/prerun.js'; +/** + * All the commands available in the CLI. We use the `explicit` command discovery strategy + * so we can properly bundle the CLI for usage in GitHub Actions. + * + * Also, we use colon separators for subcommands below. This ensures that users can use both colons + * and spaces when running subcommands. The documentation will always show spaces, but colons are + * also supported. + * + * @see {@link https://oclif.io/docs/command_discovery_strategies/#explicit-strategy} + */ export const COMMANDS = { categories: CategoriesCommand, 'categories:create': CategoriesCreateCommand, diff --git a/src/lib/castStringOptToBool.ts b/src/lib/castStringOptToBool.ts index 2a4ee3c5b..455445a7f 100644 --- a/src/lib/castStringOptToBool.ts +++ b/src/lib/castStringOptToBool.ts @@ -1,7 +1,7 @@ import type { baseVersionFlags } from './flags.js'; /** - * All the boolean flags from the `versions:create` and `versions:update` commands + * All the boolean flags from the `versions create` and `versions update` commands */ type VersionBooleanOpts = Exclude<keyof typeof baseVersionFlags, 'codename'>; diff --git a/src/lib/flags.ts b/src/lib/flags.ts index 428dfcfe6..16c355419 100644 --- a/src/lib/flags.ts +++ b/src/lib/flags.ts @@ -26,7 +26,7 @@ export const versionFlag = Flags.string({ }); /** - * Used in the `versions:create` and `versions:update` commands. + * Used in the `versions create` and `versions update` commands. */ export const baseVersionFlags = { codename: Flags.string({ diff --git a/src/lib/prepareOas.ts b/src/lib/prepareOas.ts index d85d28c00..555bc0a88 100644 --- a/src/lib/prepareOas.ts +++ b/src/lib/prepareOas.ts @@ -49,7 +49,7 @@ const capitalizeSpecType = (type: string) => */ export default async function prepareOas( path: string | undefined, - command: 'openapi:convert' | 'openapi:inspect' | 'openapi:reduce' | 'openapi:validate' | 'openapi', + command: 'openapi convert' | 'openapi inspect' | 'openapi reduce' | 'openapi validate' | 'openapi', opts: { /** * Optionally convert the supplied or discovered API definition to the latest OpenAPI release. @@ -90,7 +90,7 @@ export default async function prepareOas( action = 'upload'; break; default: - action = command.split(':')[1] as 'convert' | 'inspect' | 'reduce' | 'validate'; + action = command.split(' ')[1] as 'convert' | 'inspect' | 'reduce' | 'validate'; } const jsonAndYamlFiles = readdirRecursive('.', true).filter( @@ -213,7 +213,7 @@ export default async function prepareOas( const specVersion: string = api.info.version; debug(`version in spec: ${specVersion}`); - if (['openapi', 'openapi:inspect', 'openapi:reduce'].includes(command)) { + if (['openapi', 'openapi inspect', 'openapi reduce'].includes(command)) { api = await oas.bundle(); debug('spec bundled'); diff --git a/src/lib/prompts.ts b/src/lib/prompts.ts index ecc964cc0..ff1a989a8 100644 --- a/src/lib/prompts.ts +++ b/src/lib/prompts.ts @@ -135,7 +135,7 @@ export function createOasPrompt( /** * Series of prompts to construct a version object, - * used in our `versions:create` and `versions:update` commands + * used in our `versions create` and `versions update` commands */ export function versionPrompt( /** list of versions, used for prompt about which version to fork */ @@ -147,7 +147,7 @@ export function versionPrompt( ): PromptObject[] { return [ { - // only runs for versions:create command + // only runs for versions create command type: existingVersion ? null : 'select', name: 'from', message: 'Which version would you like to fork from?', @@ -159,7 +159,7 @@ export function versionPrompt( }), }, { - // only runs for versions:update command + // only runs for versions update command type: !existingVersion ? null : 'text', name: 'newVersion', message: 'What should the version be renamed to?',