From cf62ba73ebeb338ef09b04e634e3b2b3a56b65f0 Mon Sep 17 00:00:00 2001 From: Justin Edelson Date: Wed, 29 Sep 2021 15:55:15 -0400 Subject: [PATCH] fix: ensure that -h works for all commands. fixes #506 (#507) --- src/hooks/prerun/help-override.js | 22 +++++++ src/hooks/prerun/prerun-all.js | 4 ++ test/hooks/prerun/help-override.test.js | 85 +++++++++++++++++++++++++ test/hooks/prerun/prerun-all.test.js | 30 +++++++-- 4 files changed, 137 insertions(+), 4 deletions(-) create mode 100644 src/hooks/prerun/help-override.js create mode 100644 test/hooks/prerun/help-override.test.js diff --git a/src/hooks/prerun/help-override.js b/src/hooks/prerun/help-override.js new file mode 100644 index 00000000..c53024b3 --- /dev/null +++ b/src/hooks/prerun/help-override.js @@ -0,0 +1,22 @@ +/* +Copyright 2021 Adobe. All rights reserved. +This file is licensed to you under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. You may obtain a copy +of the License at http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under +the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +OF ANY KIND, either express or implied. See the License for the specific language +governing permissions and limitations under the License. +*/ + +const { isThisPlugin } = require('../../cloudmanager-hook-helpers') + +module.exports = function (hookOptions) { + if (!isThisPlugin(hookOptions)) { + return + } + if (hookOptions && hookOptions.argv && hookOptions.argv.includes('-h')) { + new hookOptions.Command(hookOptions.argv, hookOptions.config)._help() + } +} diff --git a/src/hooks/prerun/prerun-all.js b/src/hooks/prerun/prerun-all.js index 0a733208..bd1f9752 100644 --- a/src/hooks/prerun/prerun-all.js +++ b/src/hooks/prerun/prerun-all.js @@ -17,10 +17,14 @@ const { handleError } = require('../../cloudmanager-helpers') module.exports = function (hookOptions) { try { + require('./help-override').apply(this, [hookOptions]) require('./permission-info').apply(this, [hookOptions]) require('./environment-id-from-config').apply(this, [hookOptions]) require('./check-ims-context-config').apply(this, [hookOptions]) } catch (err) { + if (err.code && err.code === 'EEXIT') { // code from @oclif/errors - ExitError + throw err + } handleError(err, this.error) } } diff --git a/test/hooks/prerun/help-override.test.js b/test/hooks/prerun/help-override.test.js new file mode 100644 index 00000000..744a63f5 --- /dev/null +++ b/test/hooks/prerun/help-override.test.js @@ -0,0 +1,85 @@ +/* +Copyright 2021 Adobe. All rights reserved. +This file is licensed to you under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. You may obtain a copy +of the License at http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under +the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +OF ANY KIND, either express or implied. See the License for the specific language +governing permissions and limitations under the License. +*/ + +const hook = require('../../../src/hooks/prerun/help-override') + +let mockHelp +let mockConstructor + +beforeEach(() => { + mockHelp = jest.fn() + mockConstructor = jest.fn() +}) + +const invoke = (options) => { + return () => hook.apply({}, [{ + Command: Fixture, + config: {}, + ...options, + }]) +} + +test('hook -- command from other plugin', async () => { + expect(invoke({ + Command: FixtureFromOtherPlugin, + argv: [], + })).not.toThrowError() +}) + +test("hook -- no argv doesn't call help", async () => { + invoke({ + argv: [], + })() + expect(mockHelp.mock.calls.length).toBe(0) +}) + +test("hook -- some other argv doesn't call help", async () => { + invoke({ + argv: ['--environmentId=3'], + })() + expect(mockHelp.mock.calls.length).toBe(0) +}) + +test('hook -- -h calls help', async () => { + invoke({ + argv: ['-h'], + config: { + MOCKCONFIG: true, + }, + })() + expect(mockHelp.mock.calls.length).toBe(1) + expect(mockConstructor.mock.calls.length).toBe(1) + expect(mockConstructor.mock.calls[0][0]).toEqual(['-h']) + expect(mockConstructor.mock.calls[0][1]).toEqual({ + MOCKCONFIG: true, + }) +}) + +class Fixture { + constructor (argv, config) { + mockConstructor(argv, config) + } + + _help () { + mockHelp() + } +} +Fixture.id = 'somecommand' +Fixture.plugin = { + name: '@adobe/aio-cli-plugin-cloudmanager', +} + +class FixtureFromOtherPlugin { +} +FixtureFromOtherPlugin.plugin = { + name: 'something-else', +} diff --git a/test/hooks/prerun/prerun-all.test.js b/test/hooks/prerun/prerun-all.test.js index 213c4ed0..4ead950d 100644 --- a/test/hooks/prerun/prerun-all.test.js +++ b/test/hooks/prerun/prerun-all.test.js @@ -3,14 +3,16 @@ const { RequiredArgsError } = require('@oclif/parser/lib/errors') const hook = require('../../../src/hooks/prerun/prerun-all') let parse +let error beforeEach(() => { setStore({}) parse = jest.fn() + error = jest.fn() }) const invoke = (options) => { - return () => hook.apply({ error: (msg) => { throw new Error(msg) } }, [{ + return () => hook.apply({ error }, [{ ...options, }]) } @@ -65,12 +67,23 @@ test('hook -- bad configuration', async () => { parse = jest.fn().mockImplementationOnce(() => true) - expect.assertions(1) + expect.assertions(2) - expect(invoke({ + invoke({ Command: FixtureWithEnvironmentIdArg, argv: [], - })).toThrowError('One or more of the required fields in ims.contexts.aio-cli-plugin-cloudmanager were not set. Missing keys were private_key.') + })() + expect(error.mock.calls.length).toBe(1) + expect(error.mock.calls[0][0]).toBe('[CloudManagerCLI:IMS_CONTEXT_MISSING_FIELDS] One or more of the required fields in ims.contexts.aio-cli-plugin-cloudmanager were not set. Missing keys were private_key.') +}) + +test('hook -- exit error is not handled', async () => { + expect.assertions(1) + + expect(invoke({ + Command: HelpFixture, + argv: ['-h'], + })).toThrowError('') }) const thisPlugin = { @@ -87,3 +100,12 @@ FixtureWithEnvironmentIdArg.args = [ { name: 'environmentId' }, ] FixtureWithEnvironmentIdArg.plugin = thisPlugin + +class HelpFixture { + _help () { + const err = new Error() + err.code = 'EEXIT' + throw err + } +} +HelpFixture.plugin = thisPlugin