diff --git a/src/commands/app/get-url.js b/src/commands/app/get-url.js index 4dd94f39..738016ca 100644 --- a/src/commands/app/get-url.js +++ b/src/commands/app/get-url.js @@ -18,6 +18,7 @@ const BaseCommand = require('../../BaseCommand') const { wrapError } = require('../../lib/app-helper') const { getActionUrls } = require('@adobe/aio-lib-runtime').utils const yaml = require('js-yaml') +const { loadLocalDevConfig } = require('../../lib/run-local-runtime') class GetUrlCommand extends BaseCommand { async run () { @@ -45,9 +46,16 @@ class GetUrlCommand extends BaseCommand { } const actionUrls = {} - Object.values(fullConfig.all).forEach(config => { - Object.assign(actionUrls, getActionUrls(config, true)) - }) + if (flags.local) { + Object.values(fullConfig.all).forEach(config => { + const localDevConfig = loadLocalDevConfig(config) + Object.assign(actionUrls, getActionUrls(localDevConfig, false, true)) + }) + } else { + Object.values(fullConfig.all).forEach(config => { + Object.assign(actionUrls, getActionUrls(config, true)) + }) + } urls.runtime = actionUrls const cdnUrls = {} if (options.cdn) { @@ -102,6 +110,9 @@ GetUrlCommand.flags = { yml: flags.boolean({ description: 'Output yml', char: 'y' + }), + local: flags.boolean({ + description: 'Display locally based action URLs' }) } diff --git a/src/commands/app/run.js b/src/commands/app/run.js index f91efc02..536d25c8 100644 --- a/src/commands/app/run.js +++ b/src/commands/app/run.js @@ -60,6 +60,7 @@ class Run extends BaseCommand { async runOneExtensionPoint (name, config, flags, spinner) { const hasBackend = config.app.hasBackend const hasFrontend = config.app.hasFrontend + const headlessApp = hasBackend && !hasFrontend if (!hasBackend && !hasFrontend) { this.error(new Error('nothing to run.. there is no frontend and no manifest.yml, are you in a valid app?')) @@ -97,7 +98,8 @@ class Run extends BaseCommand { } } - const onProgress = !flags.verbose + const verboseOutput = flags.verbose || flags.local || headlessApp + const onProgress = !verboseOutput ? info => { spinner.text = info } diff --git a/src/lib/deploy-actions.js b/src/lib/deploy-actions.js index fcd88245..fdebbd45 100644 --- a/src/lib/deploy-actions.js +++ b/src/lib/deploy-actions.js @@ -17,17 +17,17 @@ const { deployActions } = require('@adobe/aio-lib-runtime') * Deploys actions. * * @param {object} config see src/lib/config-loader.js - * @param {boolean} isLocal default false, set to true if it's a local deploy + * @param {boolean} isLocalDev default false, set to true if it's a local deploy * @param {Function} [log] a log function * @param {boolean} filter true if a filter by built actions is desired. */ /** @private */ -module.exports = async (config, isLocal = false, log = () => {}, filter = false) => { +module.exports = async (config, isLocalDev = false, log = () => {}, filter = false) => { utils.runScript(config.hooks['pre-app-deploy']) const script = await utils.runScript(config.hooks['deploy-actions']) if (!script) { const deployConfig = { - isLocalDev: isLocal, + isLocalDev, filterEntities: { byBuiltActions: filter } diff --git a/src/lib/run-dev.js b/src/lib/run-dev.js index 9dacf6fd..6776ef04 100644 --- a/src/lib/run-dev.js +++ b/src/lib/run-dev.js @@ -19,7 +19,7 @@ const bundleServe = require('./bundle-serve') const { defaultHttpServerPort: SERVER_DEFAULT_PORT } = require('./defaults') const serve = require('./serve') const Cleanup = require('./cleanup') -const runLocalRuntime = require('./run-local-runtime') +const { runLocalRuntime } = require('./run-local-runtime') const buildActions = require('./build-actions') const deployActions = require('./deploy-actions') diff --git a/src/lib/run-local-runtime.js b/src/lib/run-local-runtime.js index 41fe52f2..11b1153d 100644 --- a/src/lib/run-local-runtime.js +++ b/src/lib/run-local-runtime.js @@ -32,6 +32,12 @@ const OW_WAIT_INIT_TIME = 2000 const OW_WAIT_PERIOD_TIME = 500 const OW_TIMEOUT = 60000 +const LOCAL_RUNTIME = { + namespace: OW_LOCAL_NAMESPACE, + auth: OW_LOCAL_AUTH, + apihost: OW_LOCAL_APIHOST +} + /** * @typedef {object} RunDevLocalObject * @property {string} config the modified dev config @@ -55,9 +61,8 @@ const OW_TIMEOUT = 60000 * @returns {RunDevLocalObject} the RunDevLocalObject */ async function runDevLocal (config, dataDir, log = () => undefined, verbose = false) { - const devConfig = cloneDeep(config) - devConfig.envFile = path.join(config.app.dist, '.env.local') const owJarFile = path.join(dataDir, OW_JAR_PATH) + const devConfig = loadLocalDevConfig(config) // take following steps only when we have a backend log('checking if java is installed...') @@ -91,16 +96,8 @@ async function runDevLocal (config, dataDir, log = () => undefined, verbose = fa } const res = await utils.runOpenWhiskJar(owJarFile, OW_CONFIG_RUNTIMES_FILE, OW_LOCAL_APIHOST, OW_WAIT_INIT_TIME, OW_WAIT_PERIOD_TIME, OW_TIMEOUT, owExecaOptions) - log('setting local openwhisk credentials...') - const runtime = { - namespace: OW_LOCAL_NAMESPACE, - auth: OW_LOCAL_AUTH, - apihost: OW_LOCAL_APIHOST - } - devConfig.ow = { ...devConfig.ow, ...runtime } - log(`writing credentials to tmp wskdebug config '${devConfig.envFile}'`) - await writeLocalEnvFile(devConfig, runtime) + await writeLocalEnvFile(devConfig, LOCAL_RUNTIME) const cleanup = () => { aioLogger.debug('stopping local OpenWhisk stack...') @@ -118,6 +115,19 @@ async function runDevLocal (config, dataDir, log = () => undefined, verbose = fa } } +/** + * @param {object} config the app config + * @param {Function} [log] function to log application logs + * @returns {RunDevLocalObject} the RunDevLocalObject + */ +function loadLocalDevConfig (config, log) { + const devConfig = cloneDeep(config) + devConfig.envFile = path.join(config.app.dist, '.env.local') + log && log('setting local openwhisk credentials...') + devConfig.ow = { ...devConfig.ow, ...LOCAL_RUNTIME } + return devConfig +} + /** * Writes the local debugging .env file * @@ -141,4 +151,4 @@ async function writeLocalEnvFile (appConfig, runtimeCredentials) { `)) } -module.exports = runDevLocal +module.exports = { runLocalRuntime: runDevLocal, loadLocalDevConfig } diff --git a/test/commands/app/geturl.test.js b/test/commands/app/geturl.test.js index 846fc81b..fc7d7d25 100644 --- a/test/commands/app/geturl.test.js +++ b/test/commands/app/geturl.test.js @@ -15,6 +15,7 @@ const BaseCommand = require('../../../src/BaseCommand') const mockRuntimeLib = require('@adobe/aio-lib-runtime') const dataMocks = require('../../data-mocks/config-loader') +const { loadLocalDevConfig } = require('../../../src/lib/run-local-runtime') const createFullConfig = (aioConfig = {}, appFixtureName = 'legacy-app') => { const appConfig = dataMocks(appFixtureName, aioConfig) @@ -58,17 +59,23 @@ describe('run', () => { beforeEach(() => { mockRuntimeLib.utils.getActionUrls.mockReset() mockRuntimeLib.utils.getActionUrls.mockImplementation(jest.fn( - (config, isRemoteDev) => { + (config, isRemoteDev, isLocalDev) => { if (isRemoteDev) { return { action: 'https://fake_ns.adobeioruntime.net/api/v1/web/sample-app-1.0.0/action' } - } else { + } + if (isLocalDev) { return { - action: 'https://fake_ns.adobeio-static.net/api/v1/web/sample-app-1.0.0/action' + action: 'http://localhost:3233/api/v1/web/sample-app-1.0.0/action' } } - })) + // !isRemoteDev + return { + action: 'https://fake_ns.adobeio-static.net/api/v1/web/sample-app-1.0.0/action' + } + } + )) command = new TheCommand([]) command.error = jest.fn() @@ -267,4 +274,24 @@ describe('run', () => { await command.run() expect(command.error).toHaveBeenCalledWith(new Error('No action with name invalid found')) }) + + test('get local actions, --local', async () => { + const appConfig = createFullConfig(command.appConfig) + command.getFullConfig.mockReturnValueOnce(appConfig) + + const res = { + runtime: { + action: 'http://localhost:3233/api/v1/web/sample-app-1.0.0/action' + } + } + command.argv = ['--local'] + const urls = await command.run() + expect(command.error).toHaveBeenCalledTimes(0) + Object.values(appConfig.all).forEach(config => { + const localConfig = loadLocalDevConfig(config) + expect(mockRuntimeLib.utils.getActionUrls).toBeCalledWith(localConfig, false, true) + }) + expect(urls).toEqual(res) + expect(command.log).toHaveBeenCalledWith(expect.stringContaining(urls.runtime.action)) + }) }) diff --git a/test/commands/lib/run-dev.test.js b/test/commands/lib/run-dev.test.js index 4dab42da..fdd56e82 100644 --- a/test/commands/lib/run-dev.test.js +++ b/test/commands/lib/run-dev.test.js @@ -11,7 +11,7 @@ governing permissions and limitations under the License. */ const runDev = require('../../../src/lib/run-dev') -const runLocalRuntime = require('../../../src/lib/run-local-runtime') +const { runLocalRuntime } = require('../../../src/lib/run-local-runtime') const cloneDeep = require('lodash.clonedeep') const dataMocks = require('../../data-mocks/config-loader') const defaults = require('../../../src/lib/defaults') diff --git a/test/commands/lib/run-local-runtime.test.js b/test/commands/lib/run-local-runtime.test.js index feb0095a..b828e801 100644 --- a/test/commands/lib/run-local-runtime.test.js +++ b/test/commands/lib/run-local-runtime.test.js @@ -20,7 +20,10 @@ governing permissions and limitations under the License. ] */ -const runLocalRuntime = require('../../../src/lib/run-local-runtime') +const { + runLocalRuntime, + loadLocalDevConfig +} = require('../../../src/lib/run-local-runtime') const utils = require('../../../src/lib/app-helper') const mockLogger = require('@adobe/aio-lib-core-logging') const path = require('path') @@ -172,3 +175,23 @@ test('return value', async () => { } }) }) + +describe('loadLocalDevConfig', () => { + test('returns local config dev config', () => { + const localConfig = loadLocalDevConfig(LOCAL_CONFIG) + expect(localConfig).toEqual({ + ...LOCAL_CONFIG, + envFile: path.join(LOCAL_CONFIG.app.dist, '.env.local'), + ow: { + namespace: OW_LOCAL_NAMESPACE, + auth: OW_LOCAL_AUTH, + apihost: OW_LOCAL_APIHOST + } + }) + }) + test('calls logger when available (coverage)', () => { + jest.spyOn(console, 'log') + loadLocalDevConfig(LOCAL_CONFIG, console.log) + expect(console.log).toHaveBeenCalledWith(expect.any(String)) + }) +})