diff --git a/src/commands/app/pack.js b/src/commands/app/pack.js index 7beec721..a0138784 100644 --- a/src/commands/app/pack.js +++ b/src/commands/app/pack.js @@ -135,13 +135,23 @@ class Pack extends BaseCommand { // TODO: send a PR to their plugin to have a `--json` flag const command = await this.config.findCommand('api-mesh:get') if (command) { - this.spinner.start('Getting api-mesh config...') - const { stdout } = await execa('aio', ['api-mesh', 'get'], { cwd: process.cwd() }) - // until we get the --json flag, we parse the output - const idx = stdout.indexOf('{') - meshConfig = JSON.parse(stdout.substring(idx)) - aioLogger.debug(`api-mesh:get - ${JSON.stringify(meshConfig, null, 2)}`) - this.spinner.succeed('Got api-mesh config') + try { + this.spinner.start('Getting api-mesh config...') + const { stdout } = await execa('aio', ['api-mesh', 'get'], { cwd: process.cwd() }) + // until we get the --json flag, we parse the output + const idx = stdout.indexOf('{') + meshConfig = JSON.parse(stdout.substring(idx)) + aioLogger.debug(`api-mesh:get - ${JSON.stringify(meshConfig, null, 2)}`) + this.spinner.succeed('Got api-mesh config') + } catch (err) { + // Ignore error if no mesh found, otherwise throw + if (err?.stderr.includes('Error: Unable to get mesh config. No mesh found for Org')) { + aioLogger.debug('No api-mesh config found') + } else { + console.error(err) + throw err + } + } } else { aioLogger.debug('api-mesh:get command was not found, meshConfig is not available for app:pack') } diff --git a/test/commands/app/pack.test.js b/test/commands/app/pack.test.js index 60728f59..4fdcc7cb 100644 --- a/test/commands/app/pack.test.js +++ b/test/commands/app/pack.test.js @@ -164,6 +164,58 @@ test('createDeployYamlFile (1 extension)', async () => { await expect(importHelper.writeFile.mock.calls[0][2]).toMatchObject({ overwrite: true }) }) +test('createDeployYamlFile (1 extension), no api-mesh', async () => { + const extConfig = fixtureJson('pack/2.all.config.json') + + const command = new TheCommand() + command.argv = [] + command.config = { + findCommand: jest.fn().mockReturnValue({}), + runCommand: jest.fn(), + runHook: jest.fn() + } + + execa.mockImplementationOnce((cmd, args) => { + expect(cmd).toEqual('aio') + expect(args).toEqual(['api-mesh', 'get']) + // eslint-disable-next-line no-throw-literal + throw { + stderr: 'Error: Unable to get mesh config. No mesh found for Org' + } + }) + + await command.createDeployYamlFile(extConfig) + + await expect(importHelper.writeFile.mock.calls[0][0]).toMatch(path.join('app-package', 'deploy.yaml')) + await expect(importHelper.writeFile.mock.calls[0][1]).toMatchFixture('pack/2.deploy.no-mesh.yaml') + await expect(importHelper.writeFile.mock.calls[0][2]).toMatchObject({ overwrite: true }) +}) + +test('createDeployYamlFile (1 extension), api-mesh get call throws non 404 error', async () => { + const extConfig = fixtureJson('pack/2.all.config.json') + + const command = new TheCommand() + command.argv = [] + command.config = { + findCommand: jest.fn().mockReturnValue({}), + runCommand: jest.fn(), + runHook: jest.fn() + } + + execa.mockImplementationOnce((cmd, args) => { + expect(cmd).toEqual('aio') + expect(args).toEqual(['api-mesh', 'get']) + // eslint-disable-next-line no-throw-literal + throw { + stderr: 'Error: api-mesh service is unavailable' + } + }) + + await expect(command.createDeployYamlFile(extConfig)).rejects.toEqual(expect.objectContaining({ + stderr: expect.stringContaining('Error: api-mesh service is unavailable') + })) +}) + test('createDeployYamlFile (coverage: standalone app, no services)', async () => { const extConfig = fixtureJson('pack/4.all.config.json')