Skip to content

Commit

Permalink
Merge branch 'main' into fix/2309/odata_service_url_prompt_annotations
Browse files Browse the repository at this point in the history
  • Loading branch information
longieirl authored Sep 2, 2024
2 parents 3ff3f36 + d4c8a62 commit d8ff746
Show file tree
Hide file tree
Showing 27 changed files with 555 additions and 111 deletions.
6 changes: 6 additions & 0 deletions packages/abap-deploy-config-inquirer/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# @sap-ux/abap-deploy-config-inquirer

## 0.0.9

### Patch Changes

- 99d7394: adds create command add deploy-config

## 0.0.8

### Patch Changes
Expand Down
2 changes: 1 addition & 1 deletion packages/abap-deploy-config-inquirer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"url": "https://github.com/SAP/open-ux-tools.git",
"directory": "packages/abap-deploy-config-inquirer"
},
"version": "0.0.8",
"version": "0.0.9",
"license": "Apache-2.0",
"main": "dist/index.js",
"scripts": {
Expand Down
6 changes: 2 additions & 4 deletions packages/abap-deploy-config-inquirer/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,13 @@ async function prompt(
const abapDeployConfigPrompts = (await getPrompts(promptOptions, logger, isYUI)).prompts;
const answers = await adapter.prompt<AbapDeployConfigAnswersInternal>(abapDeployConfigPrompts);

// Add dervied service answers to the answers object
Object.assign(answers, PromptState.abapDeployConfig);

return reconcileAnswers(answers);
return reconcileAnswers(answers, PromptState.abapDeployConfig);
}

export {
getPrompts,
prompt,
reconcileAnswers,
TargetSystemType,
PackageInputChoices,
TransportChoices,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,8 +185,11 @@ function defaultOrShowPackageQuestion(): boolean {
* @returns boolean
*/
export function showPackageInputChoiceQuestion(useAutocomplete = false): boolean {
// Only show the input choice (manual/search) when the autocomplete option is true, the prompt is supported; CLI or YUI specific version
return Boolean((!PromptState.isYUI || useAutocomplete) && defaultOrShowPackageQuestion());
if (!useAutocomplete) {
return false;
}
const isPromptSupported = !PromptState.isYUI || (PromptState.isYUI && useAutocomplete);
return isPromptSupported && defaultOrShowPackageQuestion();
}

/**
Expand All @@ -202,7 +205,6 @@ export function defaultOrShowManualPackageQuestion(
packageInputChoice?: string,
useAutocomplete = false
): boolean {
// Until the version of YUI installed supports auto-complete we must continue to show a manual input for packages
return (
(!isCli || packageInputChoice === PackageInputChoices.EnterManualChoice || !useAutocomplete) &&
defaultOrShowPackageQuestion()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ function getDestinationPrompt(
name: abapDeployConfigInternalPromptNames.destination,
message: t('prompts.target.destination.message'),
guiOptions: {
mandatory: true,
breadcrumb: true
},
default: (): string | undefined => backendTarget?.abapTarget?.destination,
Expand Down Expand Up @@ -97,6 +98,7 @@ function getTargetSystemPrompt(
name: abapDeployConfigInternalPromptNames.targetSystem,
message: t('prompts.target.targetSystem.message'),
guiOptions: {
mandatory: true,
breadcrumb: t('prompts.target.targetSystem.breadcrumb')
},
choices: (): AbapSystemChoice[] => choices,
Expand Down Expand Up @@ -199,7 +201,7 @@ function getClientChoicePrompt(

if (!PromptState.isYUI) {
prompts.push({
when: async (answers: AbapDeployConfigAnswersInternal): Promise<boolean> => {
when: (answers: AbapDeployConfigAnswersInternal): boolean => {
const clientChoice = answers[abapDeployConfigInternalPromptNames.clientChoice];
if (clientChoice) {
validateClientChoiceQuestion(clientChoice as ClientChoiceValue, backendTarget?.abapTarget?.client);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export function getPackagePrompts(options: AbapDeployConfigPromptOptions): Quest
let morePackageResultsMsg = '';
const isCli = !PromptState.isYUI;

const questions: Question[] = [
const questions: Question<AbapDeployConfigAnswersInternal>[] = [
{
when: (): boolean => showPackageInputChoiceQuestion(options.useAutocomplete),
type: 'list',
Expand Down Expand Up @@ -71,7 +71,7 @@ export function getPackagePrompts(options: AbapDeployConfigPromptOptions): Quest
},
type: 'input',
name: abapDeployConfigInternalPromptNames.packageCliExecution
},
} as InputQuestion<AbapDeployConfigAnswersInternal>,
{
when: (previousAnswers: AbapDeployConfigAnswersInternal): boolean =>
defaultOrShowManualPackageQuestion(isCli, previousAnswers.packageInputChoice, options.useAutocomplete),
Expand Down
14 changes: 9 additions & 5 deletions packages/abap-deploy-config-inquirer/src/prompts/validators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,22 +47,26 @@ export function validateDestinationQuestion(destination: string, destinations?:
* @param props.client - client
* @param props.isS4HC - is S/4HANA Cloud
* @param props.scp - is SCP
* @param props.target - target system
*/
function updatePromptState({
url,
client,
isS4HC,
scp
scp,
target
}: {
url: string;
client?: string;
isS4HC?: boolean;
scp?: boolean;
target?: string;
}): void {
PromptState.abapDeployConfig.url = url;
PromptState.abapDeployConfig.client = client;
PromptState.abapDeployConfig.isS4HC = isS4HC;
PromptState.abapDeployConfig.scp = scp;
PromptState.abapDeployConfig.targetSystem = target;
}

/**
Expand Down Expand Up @@ -104,7 +108,8 @@ export function validateTargetSystem(target?: string, choices?: AbapSystemChoice
url: choice.value,
client: choice.client ?? '',
scp: choice.scp,
isS4HC: choice.isS4HC
isS4HC: choice.isS4HC,
target: target
});
}
}
Expand Down Expand Up @@ -419,7 +424,7 @@ async function handleCreateNewTransportChoice(
const description = `For ABAP repository ${previousAnswers?.ui5AbapRepo?.toUpperCase()}, created by SAP Fiori Tools`;
PromptState.transportAnswers.newTransportNumber = await createTransportNumber(
{
packageName: getPackageAnswer(previousAnswers),
packageName: getPackageAnswer(previousAnswers, PromptState.abapDeployConfig.package),
ui5AppName: previousAnswers?.ui5AbapRepo ?? '',
description: description.length > 60 ? description.slice(0, 57) + '...' : description
},
Expand Down Expand Up @@ -486,7 +491,7 @@ export async function validateTransportChoiceInput(
prevTransportInputChoice?: TransportChoices,
backendTarget?: BackendTarget
): Promise<boolean | string> {
const packageAnswer = getPackageAnswer(previousAnswers);
const packageAnswer = getPackageAnswer(previousAnswers, PromptState.abapDeployConfig.package);
const systemConfig: SystemConfig = {
url: PromptState.abapDeployConfig.url,
client: PromptState.abapDeployConfig.client,
Expand All @@ -500,7 +505,6 @@ export async function validateTransportChoiceInput(
case TransportChoices.CreateNewChoice: {
return handleCreateNewTransportChoice(
packageAnswer,

systemConfig,
input,
previousAnswers,
Expand Down
4 changes: 2 additions & 2 deletions packages/abap-deploy-config-inquirer/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,14 +101,14 @@ export interface TransportAnswers {
}

export interface AbapDeployConfigAnswers {
url: string;
destination?: string;
targetSystem?: string;
url?: string;
client?: string;
scp?: boolean;
ui5AbapRepo?: string;
description?: string;
package?: string;
package: string;
transport?: string;
index?: boolean;
overwrite?: boolean;
Expand Down
52 changes: 26 additions & 26 deletions packages/abap-deploy-config-inquirer/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import type {
import type { BackendSystem, BackendSystemKey } from '@sap-ux/store';
import type { Destinations, Destination } from '@sap-ux/btp-utils';
import { CREATE_TR_DURING_DEPLOY } from './constants';
import { PromptState } from './prompts/prompt-state';

let cachedDestinations: Destinations = {};
let cachedBackendSystems: BackendSystem[] = [];
Expand Down Expand Up @@ -170,12 +169,12 @@ export async function queryPackages(
* Determines the package from the various package related prompts.
*
* @param previousAnswers - previous answers
* @param statePackage - package from state
* @returns package name
*/
export function getPackageAnswer(previousAnswers?: AbapDeployConfigAnswersInternal): string {
export function getPackageAnswer(previousAnswers?: AbapDeployConfigAnswersInternal, statePackage?: string): string {
// Older versions of YUI do not have a packageInputChoice question
return PromptState.abapDeployConfig.package ??
previousAnswers?.packageInputChoice === PackageInputChoices.ListExistingChoice
return statePackage || previousAnswers?.packageInputChoice === PackageInputChoices.ListExistingChoice
? previousAnswers?.packageAutocomplete ?? ''
: previousAnswers?.packageManual ?? '';
}
Expand Down Expand Up @@ -212,25 +211,36 @@ export function useCreateTrDuringDeploy(existingDeployTaskConfig?: DeployTaskCon
* Determines the url from the various sources.
*
* @param answers - internal abap deploy config answers
* @param stateUrl - url from state
* @returns url if found
*/
function getUrlAnswer(answers: AbapDeployConfigAnswersInternal): string | undefined {
let url;
if (answers.targetSystem && answers.targetSystem === TargetSystemType.Url && answers.url) {
url = answers.url;
} else if (PromptState.abapDeployConfig.url) {
url = PromptState.abapDeployConfig.url;
function getUrlAnswer(answers: AbapDeployConfigAnswersInternal, stateUrl?: string): string {
let url = answers.url;
if (stateUrl) {
url = stateUrl;
}
return url;
}

/**
* Convert internal answers to external answers to be used for writing deploy config.
*
* @param answers - internal abap deploy config answers
* @param answers - internal abap deploy config answers, direct from prompting
* @param state - partial internal abap deploy config answers derived from the state
* @returns - external abap deploy config answers
*/
export function reconcileAnswers(answers: AbapDeployConfigAnswersInternal): AbapDeployConfigAnswers {
const reconciledAnswers: AbapDeployConfigAnswers = {};
export function reconcileAnswers(
answers: AbapDeployConfigAnswersInternal,
state: Partial<AbapDeployConfigAnswersInternal>
): AbapDeployConfigAnswers {
// Add dervied service answers to the answers object
answers = Object.assign(answers, state);

const reconciledAnswers: AbapDeployConfigAnswers = {
url: getUrlAnswer(answers, state.url),
package: getPackageAnswer(answers, state.package)
};

if (answers.destination) {
reconciledAnswers.destination = answers.destination;
}
Expand All @@ -239,16 +249,11 @@ export function reconcileAnswers(answers: AbapDeployConfigAnswersInternal): Abap
reconciledAnswers.url = answers.targetSystem;
}

const url = getUrlAnswer(answers);
if (url) {
reconciledAnswers.url = url;
if (answers.client || state.client) {
reconciledAnswers.client = answers.client || state.client;
}

if (answers.client || PromptState.abapDeployConfig.client) {
reconciledAnswers.client = answers.client || PromptState.abapDeployConfig.client;
}

if (answers.scp || PromptState.abapDeployConfig.scp) {
if (answers.scp || state.scp) {
reconciledAnswers.scp = true;
}

Expand All @@ -260,11 +265,6 @@ export function reconcileAnswers(answers: AbapDeployConfigAnswersInternal): Abap
reconciledAnswers.description = answers.description;
}

const packageAnswer = getPackageAnswer(answers);
if (packageAnswer) {
reconciledAnswers.package = packageAnswer;
}

const transportAnswer = getTransportAnswer(answers);
if (transportAnswer) {
reconciledAnswers.transport = transportAnswer;
Expand Down
2 changes: 2 additions & 0 deletions packages/abap-deploy-config-inquirer/test/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@ describe('index', () => {
});

const answers: AbapDeployConfigAnswersInternal = {
url: '',
targetSystem: 'https://mock.url.target1.com',
client: '000',
package: '',
ui5AbapRepo: 'mockRepo',
packageManual: 'mockPackage',
transportManual: 'mockTransport'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,22 +50,22 @@ describe('Test abap deploy config inquirer conditions', () => {

test('should not show scp question', async () => {
// 1 target not chosen
expect(showScpQuestion({})).toBe(false);
expect(showScpQuestion({ url: '', package: '' })).toBe(false);
// 2 url target chosen but no url provided
expect(showScpQuestion({ targetSystem: 'Url', url: '' })).toBe(false);
expect(showScpQuestion({ targetSystem: 'Url', url: '', package: '' })).toBe(false);

// 3 scp value has been retrieved from existing system
jest.spyOn(utils, 'findBackendSystemByUrl').mockReturnValue({
name: 'Target system 1',
url: 'http://saved.target.url',
client: '100'
});
expect(showScpQuestion({ url: 'http://saved.target.url' })).toBe(false);
expect(showScpQuestion({ url: 'http://saved.target.url', package: '' })).toBe(false);
});

test('should show scp question', async () => {
jest.spyOn(utils, 'findBackendSystemByUrl').mockReturnValue(undefined);
expect(showScpQuestion({ targetSystem: 'Url', url: 'http://new.target.url' })).toBe(true);
expect(showScpQuestion({ targetSystem: 'Url', url: 'http://new.target.url', package: '' })).toBe(true);
});

test('should show client choice question', () => {
Expand Down Expand Up @@ -128,7 +128,7 @@ describe('Test abap deploy config inquirer conditions', () => {
test('should show package input choice question', () => {
// cli
PromptState.isYUI = false;
expect(showPackageInputChoiceQuestion()).toBe(true);
expect(showPackageInputChoiceQuestion(true)).toBe(true);
});

test('should not show package input choice question', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,15 +73,15 @@ describe('helpers', () => {
});

it('should update prompt state url (destination)', () => {
updatePromptStateUrl({ destination: 'Dest1' }, mockDestinations);
updatePromptStateUrl({ url: '', package: '', destination: 'Dest1' }, mockDestinations);
expect(PromptState.abapDeployConfig.url).toBe('https://mock.url.dest1.com');
});
});

describe('getPackageChoices', () => {
it('should return package choices and empty message', async () => {
mockQueryPackages.mockResolvedValueOnce(['package1', 'package2']);
const result = await getPackageChoices(true, 'pack', {});
const result = await getPackageChoices(true, 'pack', { url: '', package: '' });
expect(result).toEqual({
packages: ['package1', 'package2'],
morePackageResultsMsg: ''
Expand All @@ -96,7 +96,7 @@ describe('helpers', () => {
}

mockQueryPackages.mockResolvedValueOnce(packages);
const result = await getPackageChoices(true, 'pack', {});
const result = await getPackageChoices(true, 'pack', { url: '', package: '' });
expect(result).toEqual({
packages,
morePackageResultsMsg: t('prompts.config.package.packageAutocomplete.sourceMessage', {
Expand All @@ -108,7 +108,11 @@ describe('helpers', () => {
it('should return package choices and have previous answer to the top', async () => {
mockQueryPackages.mockResolvedValueOnce(['package1', 'package2', 'package3']);

const result = await getPackageChoices(true, 'pack', { packageAutocomplete: 'package3' });
const result = await getPackageChoices(true, 'pack', {
url: '',
package: '',
packageAutocomplete: 'package3'
});
expect(result).toEqual({
packages: ['package3', 'package1', 'package2'],
morePackageResultsMsg: ''
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ describe('getAbapTargetPrompts', () => {
"filter": [Function],
"guiOptions": Object {
"breadcrumb": true,
"mandatory": true,
},
"message": "Destination",
"name": "destination",
Expand All @@ -65,6 +66,7 @@ describe('getAbapTargetPrompts', () => {
"default": [Function],
"guiOptions": Object {
"breadcrumb": "Target System",
"mandatory": true,
},
"message": "Select Target system",
"name": "targetSystem",
Expand Down
Loading

0 comments on commit d8ff746

Please sign in to comment.