Skip to content

Commit

Permalink
Merge pull request #2427 from zowe/duplicate-pds-members
Browse files Browse the repository at this point in the history
Identical member names - PDS enhancement
  • Loading branch information
t1m0thyj authored Feb 20, 2025
2 parents 9697faa + 0775bf4 commit b91b989
Show file tree
Hide file tree
Showing 13 changed files with 381 additions and 50 deletions.
7 changes: 6 additions & 1 deletion packages/cli/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
# Change Log
All notable changes to the Zowe CLI package will be documented in this file.


## Recent Changes

- BugFix: Users were not warned when copying partitioned data sets with identical member names. Now, the user is prompted to confirm before continuing the copy operation to avoid potential data loss. [#2349] (https://github.com/zowe/zowe-cli/issues/2349)

## `8.14.0`

- Enhancement: Added the ability to see secure properties when running `zowe config list` when the `ZOWE_SHOW_SECURE_ARGS` environment variable is set to `true`. [#2259](https://github.com/zowe/zowe-cli/issues/2259)
Expand Down Expand Up @@ -935,7 +940,7 @@ LTS Breaking: Removed the following previously deprecated items: [#1981](https:/

## `6.25.0`

- Enhancement: Added a `--replace` option to the `zowe zos-files copy data-set` command. Use this option if you want to replace like-named members in the target data set. [#808](https://github.com/zowe/zowe-cli/issues/808)
- Enhancement: Added a `--replace` option to the `zowe zos-files copy data-set` command. Use this option if you want to replace members with identical names in the target data set. [#808](https://github.com/zowe/zowe-cli/issues/808)
- Enhancement: Improved a cryptic error message that was shown if TSO address space failed to start for the `zowe zos-tso issue command` command. [#28](https://github.com/zowe/zowe-cli/issues/28)
- Bugfix: Removed "[object Object]" text that appeared in some error messages. The proper text "Imperative API Error" is now displayed. [#836](https://github.com/zowe/zowe-cli/pull/836)

Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ describe("DsHandler", () => {

},
response: {
console: { promptFn: jest.fn() }
console: { promptFn: jest.fn(), promptForIdenticalNamedMembers: jest.fn() }
}
};

Expand All @@ -68,7 +68,8 @@ describe("DsHandler", () => {
"replace": commandParameters.arguments.replace,
"responseTimeout": commandParameters.arguments.responseTimeout,
"safeReplace": commandParameters.arguments.safeReplace,
"promptFn": expect.any(Function)
"promptFn": expect.any(Function),
"promptForIdenticalNamedMembers": expect.any(Function)
}
);
expect(response).toBe(defaultReturn);
Expand Down Expand Up @@ -98,7 +99,7 @@ describe("DsHandler", () => {
responseTimeout
},
response: {
console: { promptFn: jest.fn() }
console: { promptFn: jest.fn(), promptForIdenticalNamedMembers: jest.fn() }
}
};

Expand All @@ -116,7 +117,8 @@ describe("DsHandler", () => {
"replace": commandParameters.arguments.replace,
"responseTimeout": commandParameters.arguments.responseTimeout,
"safeReplace": commandParameters.arguments.safeReplace,
"promptFn": expect.any(Function)
"promptFn": expect.any(Function),
"promptForIdenticalNamedMembers": expect.any(Function)
}
);
expect(response).toBe(defaultReturn);
Expand Down Expand Up @@ -162,7 +164,8 @@ describe("DsHandler", () => {
"replace": commandParameters.arguments.replace,
"responseTimeout": commandParameters.arguments.responseTimeout,
"safeReplace": commandParameters.arguments.safeReplace,
"promptFn": expect.any(Function)
"promptFn": expect.any(Function),
"promptForIdenticalNamedMembers": expect.any(Function)
}
);
expect(response).toBe(defaultReturn);
Expand Down Expand Up @@ -198,7 +201,7 @@ describe("DsHandler", () => {
const result = await promptFn(commandParameters.arguments.toDataSetName);

expect(promptMock).toHaveBeenCalledWith(
`The dataset '${toDataSetName}' exists on the target system. This copy will result in data loss.` +
`The dataset '${toDataSetName}' exists on the target system. This copy can result in data loss.` +
` Are you sure you want to continue? [y/N]: `
);
expect(result).toBe(true);
Expand Down Expand Up @@ -234,7 +237,79 @@ describe("DsHandler", () => {
const result = await promptFn(commandParameters.arguments.toDataSetName);

expect(promptMock).toHaveBeenCalledWith(
`The dataset '${toDataSetName}' exists on the target system. This copy will result in data loss.` +
`The dataset '${toDataSetName}' exists on the target system. This copy can result in data loss.` +
` Are you sure you want to continue? [y/N]: `
);
expect(result).toBe(false);
});
it("should prompt the user about duplicate member names and return true when input is 'y", async () => {
const handler = new DsHandler();

expect(handler).toBeInstanceOf(ZosFilesBaseHandler);
const fromDataSetName = "ABCD";
const toDataSetName = "EFGH";
const enq = "SHR";
const replace = false;
const safeReplace = false;
const responseTimeout: any = undefined;

const commandParameters: any = {
arguments: {
fromDataSetName,
toDataSetName,
enq,
replace,
safeReplace,
responseTimeout
},
response: {
console: { promptFn: jest.fn() }
}
};
const promptMock = jest.fn();
promptMock.mockResolvedValue("y");

const promptForDuplicates = (handler as any)["promptForIdenticalNamedMembers"]({ prompt: promptMock });
const result = await promptForDuplicates();

expect(promptMock).toHaveBeenCalledWith(
`The source and target data sets have identical member names. The contents of the target members will be overwritten.` +
` Are you sure you want to continue? [y/N]: `
);
expect(result).toBe(true);
});
it("should prompt the user about duplicate member names and return false when input is 'N'", async () => {
const handler = new DsHandler();

expect(handler).toBeInstanceOf(ZosFilesBaseHandler);
const fromDataSetName = "ABCD";
const toDataSetName = "EFGH";
const enq = "SHR";
const replace = false;
const safeReplace = false;
const responseTimeout: any = undefined;

const commandParameters: any = {
arguments: {
fromDataSetName,
toDataSetName,
enq,
replace,
safeReplace,
responseTimeout
},
response: {
console: { promptFn: jest.fn() }
}
};
const promptMock = jest.fn();
promptMock.mockResolvedValue("N");

const promptForDuplicates = (handler as any)["promptForIdenticalNamedMembers"]({ prompt: promptMock });
const result = await promptForDuplicates();

expect(promptMock).toHaveBeenCalledWith(
`The source and target data sets have identical member names. The contents of the target members will be overwritten.` +
` Are you sure you want to continue? [y/N]: `
);
expect(result).toBe(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Array [
"aliases": Array [
"rep",
],
"description": "Specify this option as true if you wish to replace like-named members in the target data set",
"description": "Specify this option as true if you wish to replace members with identical names in the target data set",
"name": "replace",
"type": "boolean",
},
Expand All @@ -15,7 +15,7 @@ Array [
"safe-rep",
"sr",
],
"description": "Specify this option as true if you wish to replace like-named members or the content of the target data set. This option will prompt to confirm.",
"description": "Specify this option as true if you wish to replace members with identical names or the content of the target data set. This option will prompt to confirm.",
"name": "safe-replace",
"type": "boolean",
},
Expand All @@ -41,7 +41,7 @@ Array [
"options": "\\"USER.FROM.SET(mem1)\\" \\"USER.TO.SET\\"",
},
Object {
"description": "Copy the data set named 'USER.FROM.SET' to the data set named 'USER.TO.SET' and replace like-named members",
"description": "Copy the data set named 'USER.FROM.SET' to the data set named 'USER.TO.SET' and replace members with identical names",
"options": "\\"USER.FROM.SET\\" \\"USER.TO.SET\\" --replace",
},
Object {
Expand Down
8 changes: 4 additions & 4 deletions packages/cli/src/zosfiles/-strings-/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,16 +196,16 @@ export default {
TODSNAME: "The name of the data set that you want to copy to"
},
OPTIONS: {
REPLACE: "Specify this option as true if you wish to replace like-named members in the target data set",
SAFE_REPLACE: "Specify this option as true if you wish to replace like-named members or the content of the target data set. " +
"This option will prompt to confirm."
REPLACE: "Specify this option as true if you wish to replace members with identical names in the target data set",
SAFE_REPLACE: "Specify this option as true if you wish to replace members with identical names or the " +
"content of the target data set. This option will prompt to confirm."
},
EXAMPLES: {
EX1: "Copy the data set named 'USER.FROM.SET' to the data set named 'USER.TO.SET'",
EX2: "Copy the data set member named 'USER.FROM.SET(MEM1)' to the data set member named 'USER.TO.SET(MEM2)'",
EX3: "Copy the data set named 'USER.FROM.SET' to the data set member named 'USER.TO.SET(MEM2)'",
EX4: "Copy the data set member named 'USER.FROM.SET(MEM1)' to the data set named 'USER.TO.SET'",
EX5: "Copy the data set named 'USER.FROM.SET' to the data set named 'USER.TO.SET' and replace like-named members",
EX5: "Copy the data set named 'USER.FROM.SET' to the data set named 'USER.TO.SET' and replace members with identical names",
EX6: "Copy the partitioned data set named 'TEST.PDS1' to the partitioned data set named 'TEST.PDS2'",
EX7: "Copy the partitioned data set named 'EXISTING.PDS' to a non-existent target 'NEW.PDS'"
}
Expand Down
15 changes: 13 additions & 2 deletions packages/cli/src/zosfiles/copy/ds/Ds.handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ export default class DsHandler extends ZosFilesBaseHandler {
replace: commandParameters.arguments.replace,
responseTimeout: commandParameters.arguments.responseTimeout,
safeReplace: commandParameters.arguments.safeReplace,
promptFn: this.promptForSafeReplace(commandParameters.response.console)
promptFn: this.promptForSafeReplace(commandParameters.response.console),
promptForIdenticalNamedMembers: this.promptForIdenticalNamedMembers(commandParameters.response.console)
};

return Copy.dataSet(session, toDataSet, options);
Expand All @@ -35,7 +36,17 @@ export default class DsHandler extends ZosFilesBaseHandler {
private promptForSafeReplace(console: IHandlerResponseConsoleApi) {
return async (targetDSN: string) => {
const answer: string = await console.prompt(
`The dataset '${targetDSN}' exists on the target system. This copy will result in data loss.` +
`The dataset '${targetDSN}' exists on the target system. This copy can result in data loss.` +
` Are you sure you want to continue? [y/N]: `
);
return answer != null && (answer.toLowerCase() === "y" || answer.toLowerCase() === "yes");
};
}

private promptForIdenticalNamedMembers(console: IHandlerResponseConsoleApi) {
return async() => {
const answer: string = await console.prompt (
`The source and target data sets have identical member names. The contents of the target members will be overwritten.` +
` Are you sure you want to continue? [y/N]: `
);
return answer != null && (answer.toLowerCase() === "y" || answer.toLowerCase() === "yes");
Expand Down
5 changes: 3 additions & 2 deletions packages/zosfiles/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@

All notable changes to the Zowe z/OS files SDK package will be documented in this file.

## Recent Changes
- BugFix: Users were not warned when copying partitioned data sets with identical member names. Now, the user is prompted to confirm before continuing the copy operation to avoid potential data loss. [#2349] (https://github.com/zowe/zowe-cli/issues/2349)

## `8.13.0`

- BugFix: The `Create.dataSetValidateOptions()` function now correctly handles data set creation when the `dsorg` attribute is set to `PS-L` by automatically updating the `dsntype` attribute to `LARGE`. [#2141](https://github.com/zowe/zowe-cli/issues/2141)
- BugFix: Fixed an issue in the `Copy.dataSetCrossLPAR()` function where the `spacu` attribute of the copied data set was always set to `TRK`, regardless of the source data set's attributes. [#2412](https://github.com/zowe/zowe-cli/issues/2412)
- BugFix: The `Copy.data.set` function now prompts the user to confirm before overwriting the contents of the target data set with the addition of the `--safe-replace` option. [#2369] (https://github.com/zowe/zowe-cli/issues/2369)

## `8.12.0`

## `8.12.0`
- Enhancement: The `Copy.dataset` function now creates a new data set if the entered target data set does not exist. [#2349](https://github.com/zowe/zowe-cli/issues/2349)
- Enhancement: Added the `maxLength` option to List SDK functions (`allMembers`, `dataSetsMatchingPattern`, `membersMatchingPattern`) to specify the maximum number of items to return. [#2409](https://github.com/zowe/zowe-cli/pull/2409)
Expand Down
Loading

0 comments on commit b91b989

Please sign in to comment.