Skip to content

Commit

Permalink
Merge branch 'next' into rnd/table-view
Browse files Browse the repository at this point in the history
Signed-off-by: Trae Yelovich <[email protected]>
  • Loading branch information
traeok committed Jul 30, 2024
2 parents 6bdd24d + 2950dfa commit c61b832
Show file tree
Hide file tree
Showing 58 changed files with 1,038 additions and 559 deletions.
Binary file removed docs/images/ZE-Configuration.gif
Binary file not shown.
Binary file removed docs/images/ZE-CreateDelete.gif
Binary file not shown.
Binary file removed docs/images/ZE-Jobs-Issue-TSO-Command.gif
Binary file not shown.
Binary file removed docs/images/ZE-Settings.jpg
Binary file not shown.
Binary file removed docs/images/ZE-allocate-like.gif
Binary file not shown.
Binary file modified docs/images/ZE-copy-member.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed docs/images/ZE-copy.gif
Binary file not shown.
Binary file removed docs/images/ZE-del-pds-member.gif
Binary file not shown.
Binary file removed docs/images/ZE-delete-ds2.gif
Binary file not shown.
Binary file removed docs/images/ZE-download-edit.gif
Binary file not shown.
Binary file modified docs/images/ZE-edit-upload.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed docs/images/ZE-editUSS.gif
Binary file not shown.
Binary file removed docs/images/ZE-jobs-download-spool.gif
Binary file not shown.
Binary file removed docs/images/ZE-jobs-get-jcl.gif
Binary file not shown.
Binary file removed docs/images/ZE-mult-profiles.gif
Binary file not shown.
Binary file modified docs/images/ZE-multiple-search.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed docs/images/ZE-newProfiles.gif
Binary file not shown.
Binary file removed docs/images/ZE-path.gif
Binary file not shown.
Binary file removed docs/images/ZE-profile-api.gif
Binary file not shown.
Binary file removed docs/images/ZE-profile-links.gif
Binary file not shown.
Binary file removed docs/images/ZE-profile2.gif
Binary file not shown.
Binary file removed docs/images/ZE-refresh-all.gif
Binary file not shown.
Binary file removed docs/images/ZE-refreshUSS.gif
Binary file not shown.
Binary file modified docs/images/ZE-safe-save.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/images/ZE-submit-jcl.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/images/ze-access-multiple-profiles-simultaneously.gif
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@
"rimraf": "^3.0.2",
"terser-webpack-plugin": "^5.3.10",
"ts-jest": "^29.0.3",
"tsconfig-paths-webpack-plugin": "^4.1.0",
"tsx": "^4.9.3",
"typescript": "^5.3.3",
"webpack": "^5.89.0",
Expand All @@ -74,6 +73,6 @@
"test:parallel": "pnpm -r --parallel --color test",
"package": "pnpm -r --sequential package",
"preinstall": "npx only-allow pnpm",
"update-sdks": "pnpm -r update \"@zowe/*@next\" \"!@zowe/zowe-explorer-api\""
"update-sdks": "pnpm -r update \"@zowe/*@next\" \"!@zowe/zowe-explorer-api\" \"!@zowe/zos-ftp-for-zowe-cli\""
}
}
3 changes: 3 additions & 0 deletions packages/zowe-explorer-api/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,15 @@ All notable changes to the "zowe-explorer-api" extension will be documented in t
- Updated the `ProfilesCache.getProfiles` method to return empty list instead of undefined when there are no profiles. [#2947](https://github.com/zowe/zowe-explorer-vscode/pull/2947)
- Added PEM certificate support as an authentication method for logging into the API ML. [#2621](https://github.com/zowe/zowe-explorer-vscode/issues/2621)
- Deprecated the `getUSSDocumentFilePath` function on the `IZoweTreeNode` interface as Zowe Explorer no longer uses the local file system for storing USS files. **No replacement is planned**; please access data from tree nodes using their [resource URIs](https://github.com/zowe/zowe-explorer-vscode/wiki/FileSystemProvider#operations-for-extenders) instead. [#2968](https://github.com/zowe/zowe-explorer-vscode/pull/2968)
- **Next Breaking:** Changed `ProfilesCache.convertV1ProfToConfig` method to be a static method that requires `ProfileInfo` instance as a parameter.

### Bug fixes

- Fixed an issue where the `onProfilesUpdate` event did not fire after secure credentials were updated. [#2822](https://github.com/zowe/zowe-explorer-vscode/issues/2822)
- Fixed an issue where `ProfilesCache` may return missing or incorrect profile values when multiple extensions call it during activation. [#2831](https://github.com/zowe/zowe-explorer-vscode/issues/2831)
- Removed `handlebars` dependency in favor of `mustache` for technical currency purposes. [#2975](https://github.com/zowe/zowe-explorer-vscode/pull/2975)
- Update Zowe SDKs to `8.0.0-next.202407051717` for technical currency. [#2918](https://github.com/zowe/zowe-explorer-vscode/issues/2918)
- Fixed an issue where the `ZoweVsCodeExtension.updateCredentials` method could remove credentials from session when input prompt was cancelled. [#3009](https://github.com/zowe/zowe-explorer-vscode/pull/3009)

## `3.0.0-next.202404242037`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import * as path from "path";
import * as fs from "fs";
import * as imperative from "@zowe/imperative";
import { ProfilesCache } from "../../../src/profiles/ProfilesCache";
import { FileManagement, ZoweExplorerApi } from "../../../src";
import { FileManagement, Types } from "../../../src";

jest.mock("fs");

Expand Down Expand Up @@ -141,6 +141,7 @@ describe("ProfilesCache", () => {

it("getProfileInfo should initialize ProfileInfo API", async () => {
const existsSync = jest.spyOn(fs, "existsSync").mockImplementation();
jest.spyOn(FileManagement, "getZoweDir").mockReturnValue(fakeZoweDir);
const profInfo = await new ProfilesCache(fakeLogger as unknown as imperative.Logger, __dirname).getProfileInfo();
expect(readProfilesFromDiskSpy).toHaveBeenCalledTimes(1);
expect(defaultCredMgrWithKeytarSpy).toHaveBeenCalledTimes(1);
Expand Down Expand Up @@ -260,7 +261,7 @@ describe("ProfilesCache", () => {
it("should refresh profile data for multiple profile types", async () => {
const profCache = new ProfilesCache({ ...fakeLogger, error: mockLogError } as unknown as imperative.Logger);
const getProfInfoSpy = jest.spyOn(profCache, "getProfileInfo").mockResolvedValue(createProfInfoMock([lpar1Profile, zftpProfile]));
await profCache.refresh(fakeApiRegister as unknown as ZoweExplorerApi.IApiRegisterClient);
await profCache.refresh(fakeApiRegister as unknown as Types.IApiRegisterClient);
expect(profCache.allProfiles.length).toEqual(2);
expect(profCache.allProfiles[0]).toMatchObject(lpar1Profile);
expect(profCache.allProfiles[1]).toMatchObject(zftpProfile);
Expand All @@ -273,7 +274,7 @@ describe("ProfilesCache", () => {
jest.spyOn(profCache, "getProfileInfo").mockResolvedValue(
createProfInfoMock([lpar1ProfileWithToken, lpar2ProfileWithToken, baseProfileWithToken])
);
await profCache.refresh(fakeApiRegister as unknown as ZoweExplorerApi.IApiRegisterClient);
await profCache.refresh(fakeApiRegister as unknown as Types.IApiRegisterClient);
expect(profCache.allProfiles.length).toEqual(3);
expect(profCache.allProfiles[0]).toMatchObject(lpar1ProfileWithToken);
expect(profCache.allProfiles[1]).toMatchObject(lpar2Profile); // without token
Expand All @@ -288,7 +289,7 @@ describe("ProfilesCache", () => {
jest.spyOn(profCache, "getProfileInfo").mockImplementation(() => {
throw fakeError;
});
await profCache.refresh(fakeApiRegister as unknown as ZoweExplorerApi.IApiRegisterClient);
await profCache.refresh(fakeApiRegister as unknown as Types.IApiRegisterClient);
expect(profCache.allProfiles.length).toEqual(0);
expect(profCache.getAllTypes().length).toEqual(0);
expect(mockLogError).toHaveBeenCalledWith(fakeError);
Expand Down Expand Up @@ -438,55 +439,48 @@ describe("ProfilesCache", () => {
});

describe("convertV1ProfToConfig", () => {
Object.defineProperty(FileManagement, "getZoweDir", { value: jest.fn().mockReturnValue(fakeZoweDir), configurable: true });
Object.defineProperty(ProfilesCache, "addToConfigArray", { value: jest.fn(), configurable: true });
Object.defineProperty(fs, "renameSync", { value: jest.fn(), configurable: true });
Object.defineProperty(ProfilesCache, "getConfigArray", { value: jest.fn(), configurable: true });
it("Should convert v1 profiles to config file", async () => {
const profCache = new ProfilesCache(fakeLogger as unknown as imperative.Logger);
jest.spyOn(imperative.ConfigBuilder, "convert").mockImplementationOnce(() => {
const profInfo = createProfInfoMock([lpar1Profile]);
jest.spyOn(imperative.ConvertV1Profiles, "convert").mockImplementationOnce(() => {
return {
profilesConverted: { zosmf: ["profile1"] },
profilesFailed: {},
config: {},
} as any;
});
await expect(profCache.convertV1ProfToConfig()).resolves.not.toThrow();
await expect(ProfilesCache.convertV1ProfToConfig(profInfo)).resolves.not.toThrow();
});
it("Should convert v1 profiles to config file with profilesFailed", async () => {
const profCache = new ProfilesCache(fakeLogger as unknown as imperative.Logger);
jest.spyOn(imperative.ConfigBuilder, "convert").mockImplementationOnce(() => {
const profInfo = createProfInfoMock([lpar1Profile]);
jest.spyOn(imperative.ConvertV1Profiles, "convert").mockImplementationOnce(() => {
return {
profilesConverted: {},
profilesFailed: [{ name: ["profile2"], types: "zosmf", error: "Error converting" }],
config: {},
} as any;
});
await expect(profCache.convertV1ProfToConfig()).resolves.not.toThrow();
await expect(ProfilesCache.convertV1ProfToConfig(profInfo)).resolves.not.toThrow();
});
it("Should convert v1 profiles to config even if rename of profiles directory fails", async () => {
Object.defineProperty(fs, "renameSync", {
value: jest.fn().mockImplementation(() => {
throw new Error("Error renaming file");
}),
configurable: true,
jest.spyOn(fs, "renameSync").mockImplementationOnce(() => {
throw new Error("Error renaming file");
});
const profCache = new ProfilesCache(fakeLogger as unknown as imperative.Logger);
jest.spyOn(imperative.ConfigBuilder, "convert").mockImplementationOnce(() => {
const profInfo = createProfInfoMock([lpar1Profile]);
jest.spyOn(imperative.ConvertV1Profiles, "convert").mockImplementationOnce(() => {
return {
profilesConverted: {},
profilesFailed: [{ name: ["profile2"], types: "zosmf", error: "Error converting" }],
config: {},
} as any;
});
await expect(profCache.convertV1ProfToConfig()).resolves.not.toThrow();
await expect(ProfilesCache.convertV1ProfToConfig(profInfo)).resolves.not.toThrow();
});
it("Should reject if error thrown other than renaming profiles directory", async () => {
const profCache = new ProfilesCache(fakeLogger as unknown as imperative.Logger);
jest.spyOn(imperative.ConfigBuilder, "convert").mockImplementationOnce(() => {
const profInfo = createProfInfoMock([lpar1Profile]);
jest.spyOn(imperative.ConvertV1Profiles, "convert").mockImplementationOnce(() => {
throw new Error("Error converting config");
});
await expect(profCache.convertV1ProfToConfig()).rejects.toThrow("Error converting config");
await expect(ProfilesCache.convertV1ProfToConfig(profInfo)).rejects.toThrow("Error converting config");
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -467,10 +467,11 @@ describe("ZoweVsCodeExtension", () => {
});

it("should do nothing if user input is cancelled", async () => {
const fakeProfile = { user: "fakeUser", password: "fakePass" };
const mockUpdateProperty = jest.fn();
jest.spyOn(ZoweVsCodeExtension as any, "profilesCache", "get").mockReturnValue({
getLoadedProfConfig: jest.fn().mockReturnValue({
profile: {},
profile: fakeProfile,
}),
getProfileInfo: jest.fn().mockReturnValue({
isSecured: jest.fn().mockReturnValue(true),
Expand All @@ -479,17 +480,23 @@ describe("ZoweVsCodeExtension", () => {
refresh: jest.fn(),
});
const showInputBoxSpy = jest.spyOn(Gui, "showInputBox").mockResolvedValueOnce(undefined);
const profileLoaded = await ZoweVsCodeExtension.updateCredentials(promptCredsOptions, undefined as unknown as Types.IApiRegisterClient);
const profileLoaded = await ZoweVsCodeExtension.updateCredentials(
{ ...promptCredsOptions, rePrompt: true },
undefined as unknown as Types.IApiRegisterClient
);
expect(profileLoaded).toBeUndefined();
expect(showInputBoxSpy).toHaveBeenCalledTimes(1);
expect(mockUpdateProperty).toHaveBeenCalledTimes(0);
expect(fakeProfile.user).toBeDefined();
expect(fakeProfile.password).toBeDefined();
});

it("should do nothing if password input is cancelled", async () => {
const fakeProfile = { user: "fakeUser", password: "fakePass" };
const mockUpdateProperty = jest.fn();
jest.spyOn(ZoweVsCodeExtension as any, "profilesCache", "get").mockReturnValue({
getLoadedProfConfig: jest.fn().mockReturnValue({
profile: {},
profile: fakeProfile,
}),
getProfileInfo: jest.fn().mockReturnValue({
isSecured: jest.fn().mockReturnValue(true),
Expand All @@ -498,10 +505,15 @@ describe("ZoweVsCodeExtension", () => {
refresh: jest.fn(),
});
const showInputBoxSpy = jest.spyOn(Gui, "showInputBox").mockResolvedValueOnce("fakeUser").mockResolvedValueOnce(undefined);
const profileLoaded = await ZoweVsCodeExtension.updateCredentials(promptCredsOptions, undefined as unknown as Types.IApiRegisterClient);
const profileLoaded = await ZoweVsCodeExtension.updateCredentials(
{ ...promptCredsOptions, rePrompt: true },
undefined as unknown as Types.IApiRegisterClient
);
expect(profileLoaded).toBeUndefined();
expect(showInputBoxSpy).toHaveBeenCalledTimes(2);
expect(mockUpdateProperty).toHaveBeenCalledTimes(0);
expect(fakeProfile.user).toBeDefined();
expect(fakeProfile.password).toBeDefined();
});

it("should do nothing if profile and sessionName args are not provided", async () => {
Expand Down
24 changes: 15 additions & 9 deletions packages/zowe-explorer-api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@
"provenance": true
},
"main": "lib/index.js",
"exports": {
".": {
"@zowe:bundler": "./src/index.ts",
"default": "./lib/index.js"
}
},
"files": [
"lib"
],
Expand All @@ -22,15 +28,15 @@
},
"dependencies": {
"@types/vscode": "^1.53.2",
"@zowe/core-for-zowe-sdk": "8.0.0-next.202404032038",
"@zowe/imperative": "8.0.0-next.202404032038",
"@zowe/secrets-for-zowe-sdk": "8.0.0-next.202404032038",
"@zowe/zos-console-for-zowe-sdk": "8.0.0-next.202404032038",
"@zowe/zos-files-for-zowe-sdk": "8.0.0-next.202404032038",
"@zowe/zos-jobs-for-zowe-sdk": "8.0.0-next.202404032038",
"@zowe/zos-tso-for-zowe-sdk": "8.0.0-next.202404032038",
"@zowe/zos-uss-for-zowe-sdk": "8.0.0-next.202404032038",
"@zowe/zosmf-for-zowe-sdk": "8.0.0-next.202404032038",
"@zowe/core-for-zowe-sdk": "8.0.0-next.202407051717",
"@zowe/imperative": "8.0.0-next.202407051717",
"@zowe/secrets-for-zowe-sdk": "8.0.0-next.202407051717",
"@zowe/zos-console-for-zowe-sdk": "8.0.0-next.202407051717",
"@zowe/zos-files-for-zowe-sdk": "8.0.0-next.202407051717",
"@zowe/zos-jobs-for-zowe-sdk": "8.0.0-next.202407051717",
"@zowe/zos-tso-for-zowe-sdk": "8.0.0-next.202407051717",
"@zowe/zos-uss-for-zowe-sdk": "8.0.0-next.202407051717",
"@zowe/zosmf-for-zowe-sdk": "8.0.0-next.202407051717",
"deep-object-diff": "^1.1.9",
"mustache": "^4.2.0",
"preact": "^10.16.0",
Expand Down
18 changes: 0 additions & 18 deletions packages/zowe-explorer-api/src/globals/Interfaces.ts

This file was deleted.

1 change: 0 additions & 1 deletion packages/zowe-explorer-api/src/globals/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,3 @@
export * from "./Constants";
export * from "./Gui";
export * from "./GuiOptions";
export * from "./Interfaces";
52 changes: 6 additions & 46 deletions packages/zowe-explorer-api/src/profiles/ProfilesCache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,13 @@
*
*/

import * as path from "path";
import * as fs from "fs";
import * as imperative from "@zowe/imperative";
import type { IRegisterClient } from "../extend/IRegisterClient";
import { FileManagement } from "../utils";
import { Validation } from "./Validation";
import { ZeApiConvertResponse } from "../globals";
import { ZosmfProfile } from "@zowe/zosmf-for-zowe-sdk";
import { ZosTsoProfile } from "@zowe/zos-tso-for-zowe-sdk";
import { ZosUssProfile } from "@zowe/zos-uss-for-zowe-sdk";
import { ProfileConstants } from "@zowe/core-for-zowe-sdk";

export class ProfilesCache {
public profilesForValidation: Validation.IValidationProfile[] = [];
Expand Down Expand Up @@ -354,48 +350,12 @@ export class ProfilesCache {
};
}

public async convertV1ProfToConfig(): Promise<ZeApiConvertResponse> {
const successMsg: string[] = [];
const warningMsg: string[] = [];
const zoweDir = FileManagement.getZoweDir();
const profilesPath = path.join(zoweDir, "profiles");
const oldProfilesPath = `${profilesPath.replace(/[\\/]$/, "")}-old`;
const convertResult = await imperative.ConfigBuilder.convert(profilesPath);
for (const [k, v] of Object.entries(convertResult.profilesConverted)) {
successMsg.push(`Converted ${k} profile: ${v.join(", ")}\n`);
}
if (convertResult.profilesFailed.length > 0) {
warningMsg.push(`Failed to convert ${convertResult.profilesFailed.length} profile(s). See details below\n`);
for (const { name, type, error } of convertResult.profilesFailed) {
if (name != null) {
warningMsg.push(`Failed to load ${type} profile "${name}":\n${String(error)}\n`);
} else {
warningMsg.push(`Failed to find default ${type} profile:\n${String(error)}\n`);
}
}
}
const teamConfig = await imperative.Config.load("zowe", {
homeDir: zoweDir,
projectDir: false,
});
teamConfig.api.layers.activate(false, true);
teamConfig.api.layers.merge(convertResult.config);
const knownCliConfig: imperative.ICommandProfileTypeConfiguration[] = this.getCoreProfileTypes();
knownCliConfig.push(ProfileConstants.BaseProfile);
this.addToConfigArray(knownCliConfig);
teamConfig.setSchema(imperative.ConfigSchema.buildSchema(this.getConfigArray()));
await teamConfig.save();
try {
fs.renameSync(profilesPath, oldProfilesPath);
} catch (error) {
warningMsg.push(`Failed to rename profiles directory to ${oldProfilesPath}:\n ${String(error)}`);
}
successMsg.push(`Your new profiles have been saved to ${teamConfig.layerActive().path}.\n`);
return {
success: String(successMsg.join("")),
warnings: String(warningMsg.join("")),
convertResult,
};
public static async convertV1ProfToConfig(
profileInfo: imperative.ProfileInfo,
deleteV1Profs: boolean = false
): Promise<imperative.IConvertV1ProfResult> {
const convertResult = await imperative.ConvertV1Profiles.convert({ deleteV1Profs, profileInfo });
return convertResult;
}

protected getCoreProfileTypes(): imperative.IProfileTypeConfiguration[] {
Expand Down
6 changes: 3 additions & 3 deletions packages/zowe-explorer-api/src/vscode/ZoweVsCodeExtension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,6 @@ export class ZoweVsCodeExtension {
value: newUser,
...(options.userInputBoxOptions ?? {}),
});
options.session.user = newUser;
}
if (!newUser || (options.rePrompt && newUser === "")) {
return undefined;
Expand All @@ -307,13 +306,14 @@ export class ZoweVsCodeExtension {
value: newPass,
...(options.passwordInputBoxOptions ?? {}),
});
options.session.password = newPass;
}
if (!newPass || (options.rePrompt && newPass === "")) {
return undefined;
}

return [newUser.trim(), newPass.trim()];
options.session.user = newUser.trim();
options.session.password = newPass.trim();
return [options.session.user, options.session.password];
}

private static async promptCertificate(options: PromptCredentialsOptions.CertificateOptions): Promise<void> {
Expand Down
Loading

0 comments on commit c61b832

Please sign in to comment.