From 76e98e2ce1b352f476e7fb20c64f2553193ca8fb Mon Sep 17 00:00:00 2001 From: zFernand0 <37381190+zFernand0@users.noreply.github.com> Date: Thu, 30 Nov 2023 19:13:17 +0000 Subject: [PATCH 1/3] feat(imperative): Enhance to allow for `ProfileInfo.updateProperty` to allow for `forceUpdate`s Signed-off-by: zFernand0 <37381190+zFernand0@users.noreply.github.com> --- packages/imperative/CHANGELOG.md | 4 +++ .../ProfileInfo.TeamConfig.unit.test.ts | 35 +++++++++++++++++-- .../imperative/src/config/src/ProfileInfo.ts | 7 ++++ .../config/src/doc/IProfInfoUpdatePropOpts.ts | 7 ++++ 4 files changed, 51 insertions(+), 2 deletions(-) diff --git a/packages/imperative/CHANGELOG.md b/packages/imperative/CHANGELOG.md index 7dbc271cb1..d11fdb7b11 100644 --- a/packages/imperative/CHANGELOG.md +++ b/packages/imperative/CHANGELOG.md @@ -335,6 +335,10 @@ that would be used if a command were executed. - BugFix: Fixed incorrect description for untyped profiles in team config files. [zowe/zowe-cli#1303](https://github.com/zowe/zowe-cli/issues/1303) - **Next Breaking**: Schema files created or updated with the above changes are not backward compatible with older versions of Imperative. +## Recent Changes + +- Enhancement: Added the ability to `forceUpdate` a property using the `ProfileInfo.updateProperty` method. [zowe-explorer#2493](https://github.com/zowe/vscode-extension-for-zowe/issues/2493) + ## `5.0.0-next.202203222132` - BugFix: Reverted unintentional breaking change that prevented `DefaultCredentialManager` from finding Keytar outside of calling CLI's node_modules folder. diff --git a/packages/imperative/src/config/__tests__/ProfileInfo.TeamConfig.unit.test.ts b/packages/imperative/src/config/__tests__/ProfileInfo.TeamConfig.unit.test.ts index 1042b5a537..c003154afb 100644 --- a/packages/imperative/src/config/__tests__/ProfileInfo.TeamConfig.unit.test.ts +++ b/packages/imperative/src/config/__tests__/ProfileInfo.TeamConfig.unit.test.ts @@ -25,6 +25,7 @@ import { AbstractSession, SessConstants } from "../../rest"; import { ConfigAutoStore } from "../src/ConfigAutoStore"; import { ImperativeConfig } from "../../utilities/src/ImperativeConfig"; import { ImperativeError } from "../../error"; +import { IProfInfoUpdatePropOpts } from "../src/doc/IProfInfoUpdatePropOpts"; const testAppNm = "ProfInfoApp"; const testEnvPrefix = testAppNm.toUpperCase(); @@ -1009,6 +1010,36 @@ describe("TeamConfig ProfileInfo tests", () => { expect(updateKnownPropertySpy).toHaveBeenCalledWith({ ...profileOptions, mergedArgs: {}, osLocInfo: undefined }); }); + it("should succeed forceUpdating a property even if the jsonLoc points somewhere else", async () => { + const profInfo = createNewProfInfo(teamProjDir); + await profInfo.readProfilesFromDisk(); + const mergedArgs = { + knownArgs: [{ + argName: "rejectUnauthorized", + argLoc: { jsonLoc: "profiles.base_glob.properties.rejectUnauthorized" } + }] + }; + jest.spyOn(profInfo as any, "mergeArgsForProfile").mockReturnValue(mergedArgs); + const updateKnownPropertySpy = jest.spyOn(profInfo as any, "updateKnownProperty").mockResolvedValue(true); + const profileOptions: IProfInfoUpdatePropOpts = { + profileName: "LPAR4", + profileType: "dummy", + property: "rejectUnauthorized", + value: true, + forceUpdate: true + }; + let caughtError; + try { + await profInfo.updateProperty(profileOptions); + } catch (error) { + caughtError = error; + } + expect(caughtError).toBeUndefined(); + expect(mergedArgs.knownArgs[0].argLoc.jsonLoc).toEqual("profiles.LPAR4.properties.rejectUnauthorized"); + const osLocInfo = { global: false, user: false, name: "LPAR4", path: path.join(teamProjDir, `${testAppNm}.config.json`) }; + expect(updateKnownPropertySpy).toHaveBeenCalledWith({ ...profileOptions, mergedArgs, osLocInfo }); + }); + it("should attempt to store session config properties without adding profile types to the loadedConfig", async () => { const profInfo = createNewProfInfo(teamProjDir); await profInfo.readProfilesFromDisk(); @@ -1153,11 +1184,11 @@ describe("TeamConfig ProfileInfo tests", () => { await profInfo.readProfilesFromDisk(); const prof = profInfo.mergeArgsForProfile(profInfo.getAllProfiles("dummy")[0]); - await profInfo.updateProperty({profileName: 'LPAR4', property: "someProperty", value: "example.com", profileType: "dummy"}); + await profInfo.updateProperty({ profileName: 'LPAR4', property: "someProperty", value: "example.com", profileType: "dummy" }); const afterUpdate = profInfo.mergeArgsForProfile(profInfo.getAllProfiles("dummy")[0]); expect(afterUpdate.knownArgs.find(v => v.argName === 'someProperty')?.argValue).toBe('example.com'); - await profInfo.removeKnownProperty({mergedArgs: afterUpdate, property: 'someProperty'}); + await profInfo.removeKnownProperty({ mergedArgs: afterUpdate, property: 'someProperty' }); const afterRemove = profInfo.mergeArgsForProfile(profInfo.getAllProfiles("dummy")[0]); expect(afterRemove.knownArgs.find(v => v.argName === 'someProperty')).toBeUndefined(); diff --git a/packages/imperative/src/config/src/ProfileInfo.ts b/packages/imperative/src/config/src/ProfileInfo.ts index 6d15c63a3e..99c6c155ee 100644 --- a/packages/imperative/src/config/src/ProfileInfo.ts +++ b/packages/imperative/src/config/src/ProfileInfo.ts @@ -201,6 +201,13 @@ export class ProfileInfo { } const mergedArgs = this.mergeArgsForProfile(desiredProfile, { getSecureVals: false }); + if (options.forceUpdate && this.usingTeamConfig) { + const knownProperty = mergedArgs.knownArgs.find((v => v.argName === options.property)); + const profPath = this.getTeamConfig().api.profiles.getProfilePathFromName(options.profileName); + if (!knownProperty.argLoc.jsonLoc.startsWith(profPath)) { + knownProperty.argLoc.jsonLoc = `${profPath}.properties.${options.property}`; + } + } if (!(await this.updateKnownProperty({ ...options, mergedArgs, osLocInfo: this.getOsLocInfo(desiredProfile)?.[0] }))) { if (this.usingTeamConfig) { // Check to see if loadedConfig already contains the schema for the specified profile type diff --git a/packages/imperative/src/config/src/doc/IProfInfoUpdatePropOpts.ts b/packages/imperative/src/config/src/doc/IProfInfoUpdatePropOpts.ts index 1c39c7b381..4ab1afce17 100644 --- a/packages/imperative/src/config/src/doc/IProfInfoUpdatePropOpts.ts +++ b/packages/imperative/src/config/src/doc/IProfInfoUpdatePropOpts.ts @@ -26,6 +26,13 @@ export interface IProfInfoUpdatePropOpts extends IProfInfoUpdatePropCommonOpts { * Name of the active profile */ profileName: string; + + /** + * Force the update to the profile specified even if the property comes from somehwere else + * Example: Token Value could be in the base profile and not in the service profile specified + * and the programmer has the intention of storing the token in the service profile + */ + forceUpdate?: boolean } /** From 2f807ee34c3db98e28551fadbaecd7f1dd704a73 Mon Sep 17 00:00:00 2001 From: Fernando Rijo Cedeno <37381190+zFernand0@users.noreply.github.com> Date: Fri, 1 Dec 2023 10:14:57 -0500 Subject: [PATCH 2/3] Update packages/imperative/src/config/src/ProfileInfo.ts Nice catch! Thank you, @traeok Co-authored-by: Trae Yelovich Signed-off-by: Fernando Rijo Cedeno <37381190+zFernand0@users.noreply.github.com> --- packages/imperative/src/config/src/ProfileInfo.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/imperative/src/config/src/ProfileInfo.ts b/packages/imperative/src/config/src/ProfileInfo.ts index 99c6c155ee..161a9aaf89 100644 --- a/packages/imperative/src/config/src/ProfileInfo.ts +++ b/packages/imperative/src/config/src/ProfileInfo.ts @@ -204,7 +204,7 @@ export class ProfileInfo { if (options.forceUpdate && this.usingTeamConfig) { const knownProperty = mergedArgs.knownArgs.find((v => v.argName === options.property)); const profPath = this.getTeamConfig().api.profiles.getProfilePathFromName(options.profileName); - if (!knownProperty.argLoc.jsonLoc.startsWith(profPath)) { + if (!knownProperty?.argLoc.jsonLoc.startsWith(profPath)) { knownProperty.argLoc.jsonLoc = `${profPath}.properties.${options.property}`; } } From 7dd5a40561cefa316c00acabdf725e2eebd0cefe Mon Sep 17 00:00:00 2001 From: zFernand0 <37381190+zFernand0@users.noreply.github.com> Date: Fri, 8 Dec 2023 13:13:46 +0000 Subject: [PATCH 3/3] update typedoc Signed-off-by: zFernand0 <37381190+zFernand0@users.noreply.github.com> --- .../src/config/src/doc/IProfInfoUpdatePropOpts.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/imperative/src/config/src/doc/IProfInfoUpdatePropOpts.ts b/packages/imperative/src/config/src/doc/IProfInfoUpdatePropOpts.ts index 4ab1afce17..17f3f7f332 100644 --- a/packages/imperative/src/config/src/doc/IProfInfoUpdatePropOpts.ts +++ b/packages/imperative/src/config/src/doc/IProfInfoUpdatePropOpts.ts @@ -29,8 +29,11 @@ export interface IProfInfoUpdatePropOpts extends IProfInfoUpdatePropCommonOpts { /** * Force the update to the profile specified even if the property comes from somehwere else - * Example: Token Value could be in the base profile and not in the service profile specified - * and the programmer has the intention of storing the token in the service profile + * @example Token Value could be in the base profile (not in the service profile specified) + * and the programmer has the intention of storing the token in the service profile + * @default false When the property is not specified, the updateProperty method follows current + * procedure of updating the property in the known jsonLoc (e.g. base profile). Otherwise, + * the updateProperty method updates the specified profile name-type combination. */ forceUpdate?: boolean }