Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feat.][ACNA-1056] Support workspace creation in aio app use -w and aio app init -w #498

Merged
merged 11 commits into from
Nov 2, 2021
23 changes: 19 additions & 4 deletions src/commands/app/init.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ class InitCommand extends AddCommand {
// 3. select or create project
const project = await this.selectOrCreateConsoleProject(consoleCLI, org)
// 4. retrieve workspace details, defaults to Stage
const workspace = await this.retrieveWorkspaceFromName(consoleCLI, org, project, flags.workspace)
const workspace = await this.retrieveWorkspaceFromName(consoleCLI, org, project, flags)
// 5. ask for exensionPoints, only allow selection for extensions that have services enabled in Org
const extensionPoints = await this.selectExtensionPoints(flags, orgSupportedServices)
// 6. add any required services to Workspace
Expand Down Expand Up @@ -186,12 +186,23 @@ class InitCommand extends AddCommand {
return project
}

async retrieveWorkspaceFromName (consoleCLI, org, project, workspaceName) {
async retrieveWorkspaceFromName (consoleCLI, org, project, flags) {
const workspaceName = flags.workspace
// get workspace details
const workspaces = await consoleCLI.getWorkspaces(org.id, project.id)
const workspace = workspaces.find(w => w.name.toLowerCase() === workspaceName.toLowerCase())
let workspace = workspaces.find(w => w.name.toLowerCase() === workspaceName.toLowerCase())
if (!workspace) {
florind-ens marked this conversation as resolved.
Show resolved Hide resolved
throw new Error(`'--workspace=${workspaceName}' in Project '${project.name}' not found.`)
if (!flags['confirm-new-workspace']) {
const shouldNewWorkspace = await consoleCLI.prompt.promptConfirm(`Workspace '${workspaceName}' does not exist \n > Do you wish to create a new workspace?`)
if (!shouldNewWorkspace) {
this.error(`Workspace '${workspaceName}' does not exist and creation aborted`)
}
}
this.log(`'--workspace=${workspaceName}' in Project '${project.name}' not found. \n Creating one...`)
purplecabbage marked this conversation as resolved.
Show resolved Hide resolved
workspace = await consoleCLI.createWorkspace(org.id, project.id, {
name: workspaceName,
title: ''
})
}
return workspace
}
Expand Down Expand Up @@ -329,6 +340,10 @@ InitCommand.flags = {
default: DEFAULT_WORKSPACE,
char: 'w',
exclusive: ['import'] // also no-login
}),
'confirm-new-workspace': flags.boolean({
description: 'Skip and confirm prompt for creating a new workspace',
default: false
})
}

Expand Down
62 changes: 29 additions & 33 deletions src/commands/app/use.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,14 +78,6 @@ class Use extends BaseCommand {
this.error(message)
}
newConfig = globalConfig
if (
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok nice :) this should solve #392 too ! Make sure to test this case manually too and close the issue once me merge that PR

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested manually, works as expected.
Changing the workspace to the same workspace would update the .aio and .env files

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

perfect !

currentConfigIsComplete &&
newConfig.org.id === currentConfig.org.id &&
newConfig.project.id === currentConfig.project.id &&
newConfig.workspace.id === currentConfig.workspace.id
) {
this.error('The selected configuration is the same as the current configuration.')
}
} else {
// useOperation = 'workspace'
if (!currentConfigIsComplete) {
Expand Down Expand Up @@ -190,37 +182,37 @@ class Use extends BaseCommand {
* @returns {Buffer} the Adobe Developer Console configuration file for the workspace
*/
async selectTargetWorkspaceInProject (consoleCLI, config, flags) {
const project = { name: config.project.name, id: config.project.id }
const currentWorkspace = { name: config.workspace.name, id: config.workspace.id }

// make sure user is not trying to switch to current workspace
const workspaceFlag = flags.workspace
if (workspaceFlag === currentWorkspace.name) {
this.cleanConsoleCLIOutput()
this.error(`--workspace=${workspaceFlag} is the same as the currently selected workspace, nothing to be done.`)
}
const { project, org } = config
const workspaceNameOrId = flags.workspace

// retrieve all workspaces
const workspaces = await consoleCLI.getWorkspaces(
config.org.id,
config.project.id
org.id,
project.id
)
const workspacesButCurrent = workspaces.filter(w => w.id !== currentWorkspace.id)

let workspace

if (workspaceFlag) {
// workspace name is given, make sure the workspace is in there
workspace = workspacesButCurrent.find(w => w.name === workspaceFlag)
if (!workspace) {
this.cleanConsoleCLIOutput()
this.error(`--workspace=${workspaceFlag} does not exist in current Project ${project.name}.`)
let workspaceData = { name: workspaceNameOrId }
// does not prompt if workspaceNameOrId is defined via the flag
workspace = await consoleCLI.promptForSelectWorkspace(workspaces, { workspaceId: workspaceNameOrId, workspaceName: workspaceNameOrId }, { allowCreate: true })
florind-ens marked this conversation as resolved.
Show resolved Hide resolved
if (!workspace) {
aioLogger.debug(`--workspace=${workspaceNameOrId} was not found in the current Project ${project.name}`)
if (workspaceNameOrId) {
if (!flags['confirm-new-workspace']) {
const shouldNewWorkspace = await consoleCLI.prompt.promptConfirm(`Workspace '${workspaceNameOrId}' does not exist \n > Do you wish to create a new workspace?`)
if (!shouldNewWorkspace) {
this.error('Workspace creation aborted')
}
}
} else {
workspaceData = await consoleCLI.promptForCreateWorkspaceDetails()
}
} else {
// workspace name is not given, let the user choose the
workspace = await consoleCLI.promptForSelectWorkspace(workspacesButCurrent)
aioLogger.debug(`Creating workspace: ${workspaceData.name}`)
workspace = await consoleCLI.createWorkspace(org.id, project.id, workspaceData)
}
return {
name: workspace.name,
id: workspace.id
}
return { name: workspace.name, id: workspace.id }
}

/**
Expand Down Expand Up @@ -395,11 +387,15 @@ Use.flags = {
exclusive: ['workspace']
}),
workspace: flags.string({
description: 'Specify the Adobe Developer Console Workspace name to import the configuration from',
description: 'Specify the Adobe Developer Console Workspace name or Workspace id to import the configuration from',
default: '',
char: 'w',
exclusive: ['global', 'workspace-name']
}),
'confirm-new-workspace': flags.boolean({
description: 'Skip and confirm prompt for creating a new workspace',
default: false
}),
'workspace-name': flags.string({
description: '[DEPRECATED]: please use --workspace instead',
default: '',
Expand Down
53 changes: 47 additions & 6 deletions test/commands/app/init.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,18 +48,25 @@ const mockConsoleCLIInstance = {
promptForSelectWorkspace: jest.fn(),
getServicePropertiesFromWorkspace: jest.fn(),
subscribeToServices: jest.fn(),
getWorkspaceConfig: jest.fn()
getWorkspaceConfig: jest.fn(),
createWorkspace: jest.fn(),
prompt: {
promptConfirm: jest.fn()
}
// promptForServiceSubscriptionsOperation: jest.fn(),
// confirmNewServiceSubscriptions: jest.fn(),
// promptForSelectServiceProperties: jest.fn()
}
LibConsoleCLI.init.mockResolvedValue(mockConsoleCLIInstance)
/** @private */
function resetMockConsoleCLI () {
Object.keys(mockConsoleCLIInstance).forEach(
k => mockConsoleCLIInstance[k].mockReset()
)
Object.keys(mockConsoleCLIInstance).forEach(k => {
if ('mockReset' in mockConsoleCLIInstance[k]) {
mockConsoleCLIInstance[k].mockReset()
}
})
LibConsoleCLI.init.mockClear()
mockConsoleCLIInstance.prompt.promptConfirm.mockReset()
}

jest.mock('@adobe/generator-aio-app', () => ({
Expand Down Expand Up @@ -669,15 +676,49 @@ describe('run', () => {
expect(mockConsoleCLIInstance.createProject).not.toHaveBeenCalled()
})

test('with login, select excshell, -w notexists', async () => {
test('with login, select excshell, -w notexists, promptConfirm true', async () => {
mockConsoleCLIInstance.prompt.promptConfirm.mockResolvedValue(true)
mockConsoleCLIInstance.promptForSelectOrganization.mockResolvedValue(fakeOrg)
mockConsoleCLIInstance.promptForSelectProject.mockResolvedValue(fakeProject)
mockConsoleCLIInstance.getWorkspaces.mockResolvedValue(fakeWorkspaces)
mockConsoleCLIInstance.getServicePropertiesFromWorkspace.mockResolvedValue(fakeServicePropertiesNoAssetCompute)
mockConsoleCLIInstance.getEnabledServicesForOrg.mockResolvedValue(fakeSupportedOrgServices)
mockConsoleCLIInstance.getWorkspaceConfig.mockResolvedValue(fakeConfig)
mockExtensionPrompt.mockReturnValue({ res: excshellSelection })
mockConsoleCLIInstance.createWorkspace.mockResolvedValue(fakeWorkspaces[0])

await TheCommand.run(['-w', 'notexists'])
expect(mockConsoleCLIInstance.createWorkspace).toHaveBeenCalledWith(expect.anything(), expect.anything(), expect.objectContaining({ name: 'notexists', title: '' }))
})

test('with login, select excshell, -w notexists, promptConfirm false, should throw', async () => {
const workspaceName = 'notexists'
mockConsoleCLIInstance.prompt.promptConfirm.mockResolvedValue(false)
mockConsoleCLIInstance.promptForSelectOrganization.mockResolvedValue(fakeOrg)
mockConsoleCLIInstance.promptForSelectProject.mockResolvedValue(fakeProject)
mockConsoleCLIInstance.getWorkspaces.mockResolvedValue(fakeWorkspaces)
mockConsoleCLIInstance.getServicePropertiesFromWorkspace.mockResolvedValue(fakeServicePropertiesNoAssetCompute)
mockConsoleCLIInstance.getEnabledServicesForOrg.mockResolvedValue(fakeSupportedOrgServices)
mockConsoleCLIInstance.getWorkspaceConfig.mockResolvedValue(fakeConfig)
mockExtensionPrompt.mockReturnValue({ res: excshellSelection })
mockConsoleCLIInstance.createWorkspace.mockResolvedValue(fakeWorkspaces[0])

await expect(TheCommand.run(['-w', workspaceName])).rejects.toThrow(`Workspace '${workspaceName}' does not exist and creation aborted`)
})
test('with login, select excshell, -w notexists, --confirm-new-workspace', async () => {
const notexistsWorkspace = 'notexists'
mockConsoleCLIInstance.prompt.promptConfirm.mockResolvedValue(true)
mockConsoleCLIInstance.promptForSelectOrganization.mockResolvedValue(fakeOrg)
mockConsoleCLIInstance.promptForSelectProject.mockResolvedValue(fakeProject)
mockConsoleCLIInstance.getWorkspaces.mockResolvedValue(fakeWorkspaces)
mockConsoleCLIInstance.getServicePropertiesFromWorkspace.mockResolvedValue(fakeServicePropertiesNoAssetCompute)
mockConsoleCLIInstance.getEnabledServicesForOrg.mockResolvedValue(fakeSupportedOrgServices)
mockConsoleCLIInstance.getWorkspaceConfig.mockResolvedValue(fakeConfig)
mockExtensionPrompt.mockReturnValue({ res: excshellSelection })
mockConsoleCLIInstance.createWorkspace.mockResolvedValue(fakeWorkspaces[0])

await expect(TheCommand.run(['-w', 'notexists'])).rejects.toThrow('\'--workspace=notexists\' in Project \'bestproject\' not found.')
await TheCommand.run(['-w', notexistsWorkspace, '--confirm-new-workspace'])
expect(mockConsoleCLIInstance.prompt.promptConfirm).not.toHaveBeenCalled()
expect(mockConsoleCLIInstance.createWorkspace).toHaveBeenCalledWith(expect.anything(), expect.anything(), expect.objectContaining({ name: 'notexists', title: '' }))
})
})
Loading