Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion doc/apis.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
| Delete migrated data set | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Rename data set | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Rename data set member | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Copy data set | ✅ | ❌ | ✅ | | | | |
| Copy data set | ✅ | ❌ | ✅ | | | | |
| Compress data set | ➖ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ |
| Search data sets | 🚧 <sup>4</sup> | ❌ | 🚧 <sup>4</sup> | ❌ | ✅ | ❌ | ❌ |
| Invoke AMS (VSAM) | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ➖ |
Expand Down
3 changes: 2 additions & 1 deletion native/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ All notable changes to the native code for "zowe-native-proto" are documented in

Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file.

## `0.4.0`
## Recent Changes

- `c`: Exposed `copyDataset` over JSON-RPC with the same arguments as `zowex data-set copy` (`fromDataset` / `toDataset` map to `source` / `target`). Copy execution remains the existing `zds_copy_dsn` implementation; response includes `success` and optional `targetCreated` / `memberCreated`.
- `c`: Added `zowex uss issue` command and the `unixCommand` RPC for executing USS shell commands using `spawn()` with `_BPX_SHAREAS=YES` for efficient same-address-space execution. [#867](https://github.com/zowe/zowe-native-proto/pull/867)
- `c`: Fixed an issue where submitting JCL from the VS Code editor with CRLF line endings caused job submission errors. [#882](https://github.com/zowe/zowe-native-proto/pull/882)
- `c`: Fixed an issue where VSAM index or data components returned `*VSAM*` for the volume serial. Now, an accurate volume serial is returned for both component types. [#864](https://github.com/zowe/zowe-native-proto/pull/864)
Expand Down
5 changes: 5 additions & 0 deletions native/c/commands/ds.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -980,12 +980,16 @@ int handle_data_set_copy(InvocationContext &context)
return RTNCD_FAILURE;
}

const auto result = obj();
result->set("success", boolean(true));
if (options.target_created)
{
result->set("targetCreated", boolean(true));
context.output_stream() << "New data set '" << target << "' created and copied from '" << source << "'" << std::endl;
}
else if (options.member_created)
{
result->set("memberCreated", boolean(true));
context.output_stream() << "New member '" << target << "' created and copied from '" << source << "'" << std::endl;
}
else if (options.delete_target_members)
Expand All @@ -1000,6 +1004,7 @@ int handle_data_set_copy(InvocationContext &context)
{
context.output_stream() << "Data set '" << source << "' copied to '" << target << "'" << std::endl;
}
context.set_object(result);
return RTNCD_SUCCESS;
}

Expand Down
1 change: 1 addition & 0 deletions native/c/commands/ds.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,6 @@ int handle_data_set_compress(InvocationContext &result);
int handle_data_set_create_member(InvocationContext &result);
int handle_data_set_rename(InvocationContext &result);
int handle_rename_member(InvocationContext &result);
int handle_data_set_copy(InvocationContext &result);
void register_commands(parser::Command &root_command);
} // namespace ds
6 changes: 6 additions & 0 deletions native/c/server/rpc_commands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,12 @@ void register_ds_commands(CommandDispatcher &dispatcher)
.handle_fifo("stream", "pipe-path", FifoMode::PUT));
dispatcher.register_command("renameDataset", create_ds_builder(ds::handle_data_set_rename).validate<RenameDatasetRequest, RenameDatasetResponse>());
dispatcher.register_command("renameMember", create_ds_builder(ds::handle_rename_member).validate<RenameMemberRequest, RenameMemberResponse>());
dispatcher.register_command("copyDataset",
CommandBuilder(ds::handle_data_set_copy)
.validate<CopyDatasetRequest, CopyDatasetResponse>()
.rename_arg("fromDataset", "source")
.rename_arg("toDataset", "target")
.rename_arg("deleteTargetMembers", "delete-target-members"));
Comment thread
ATorrise marked this conversation as resolved.
}

void register_job_commands(CommandDispatcher &dispatcher)
Expand Down
22 changes: 15 additions & 7 deletions native/c/server/schemas/requests.hpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
/**
* This program and the accompanying materials are made available under the terms of the
* Eclipse Public License v2.0 which accompanies this distribution, and is available at
Expand Down Expand Up @@ -93,11 +93,11 @@

struct ReadDatasetRequest {};
ZJSON_SCHEMA(ReadDatasetRequest,
FIELD_OPTIONAL(stream, ANY),
FIELD_OPTIONAL(encoding, STRING),
FIELD_OPTIONAL(localEncoding, STRING),
FIELD_OPTIONAL(volume, STRING),
FIELD_REQUIRED(dsname, STRING)
FIELD_REQUIRED(dsname, STRING),
FIELD_OPTIONAL(stream, ANY)
);

struct RestoreDatasetRequest {};
Expand All @@ -107,13 +107,21 @@

struct WriteDatasetRequest {};
ZJSON_SCHEMA(WriteDatasetRequest,
FIELD_OPTIONAL(stream, ANY),
FIELD_OPTIONAL(encoding, STRING),
FIELD_OPTIONAL(localEncoding, STRING),
FIELD_OPTIONAL(etag, STRING),
FIELD_OPTIONAL(volume, STRING),
FIELD_REQUIRED(dsname, STRING),
FIELD_OPTIONAL(data, STRING)
FIELD_OPTIONAL(data, STRING),
FIELD_OPTIONAL(stream, ANY)
);

struct CopyDatasetRequest {};
ZJSON_SCHEMA(CopyDatasetRequest,
FIELD_REQUIRED(fromDataset, STRING),
FIELD_REQUIRED(toDataset, STRING),
FIELD_OPTIONAL(replace, BOOL),
FIELD_OPTIONAL(deleteTargetMembers, BOOL)
);

struct CancelJobRequest {};
Expand Down Expand Up @@ -253,20 +261,20 @@

struct ReadFileRequest {};
ZJSON_SCHEMA(ReadFileRequest,
FIELD_OPTIONAL(stream, ANY),
FIELD_OPTIONAL(encoding, STRING),
FIELD_OPTIONAL(localEncoding, STRING),
FIELD_REQUIRED(fspath, STRING)
FIELD_REQUIRED(fspath, STRING),
FIELD_OPTIONAL(stream, ANY)
);

struct WriteFileRequest {};
ZJSON_SCHEMA(WriteFileRequest,
FIELD_OPTIONAL(stream, ANY),
FIELD_OPTIONAL(encoding, STRING),
FIELD_OPTIONAL(localEncoding, STRING),
FIELD_OPTIONAL(etag, STRING),
FIELD_REQUIRED(fspath, STRING),
FIELD_OPTIONAL(data, STRING),
FIELD_OPTIONAL(stream, ANY),
FIELD_OPTIONAL(contentLen, NUMBER)
);

Expand Down
7 changes: 7 additions & 0 deletions native/c/server/schemas/responses.hpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
/**
* This program and the accompanying materials are made available under the terms of the
* Eclipse Public License v2.0 which accompanies this distribution, and is available at
Expand Down Expand Up @@ -163,6 +163,13 @@
FIELD_OPTIONAL(truncationWarning, STRING)
);

struct CopyDatasetResponse {};
ZJSON_SCHEMA(CopyDatasetResponse,
FIELD_REQUIRED(success, BOOL),
FIELD_OPTIONAL(targetCreated, BOOL),
FIELD_OPTIONAL(memberCreated, BOOL)
);

struct CancelJobResponse {};
ZJSON_SCHEMA(CancelJobResponse,
FIELD_REQUIRED(success, BOOL)
Expand Down
4 changes: 3 additions & 1 deletion packages/cli/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ All notable changes to the Client code for "zowe-native-proto-cli" are documente

Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file.

## `0.4.0`
## Recent Changes
- Added `zssh copy data-set` command to copy data sets and members with optional `--replace` and `--delete-target-members`. Supports PDS-to-PDS, member-to-member, and sequential-to-sequential copies. Note: RECFM=U data sets are not supported. [#778](https://github.com/zowe/zowe-native-proto/pull/778)

## `0.4.0`
- Added an `--attributes` flag to list ISPF statistics for member attributes. [#630](https://github.com/zowe/zowe-native-proto/issues/630)
- Added the `zssh uss copy` command to the CLI. [#379](https://github.com/zowe/zowe-native-proto/pull/379).
- Updated `stream` fields to match new requirements from the SDK. [#548](https://github.com/zowe/zowe-native-proto/issues/548)
Expand Down
34 changes: 34 additions & 0 deletions packages/cli/src/copy/Copy.definition.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
* This program and the accompanying materials are made available under the terms of the
* Eclipse Public License v2.0 which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-v20.html
*
* SPDX-License-Identifier: EPL-2.0
*
* Copyright Contributors to the Zowe Project.
*
*/

import type { ICommandDefinition } from "@zowe/imperative";
import { SshSession } from "@zowe/zos-uss-for-zowe-sdk";
import { Constants } from "../Constants";
import { CopyDataSetDefinition } from "./data-set/DataSet.definition";

const CopyDefinition: ICommandDefinition = {
name: "copy",
aliases: ["cp"],
summary: "Copy data sets and members",
description: "Copy a data set or member to another data set or member",
type: "group",
children: [CopyDataSetDefinition],
passOn: [
{
property: "options",
value: [...SshSession.SSH_CONNECTION_OPTIONS, Constants.OPT_SERVER_PATH],
merge: true,
ignoreNodes: [{ type: "group" }],
},
],
};

export = CopyDefinition;
81 changes: 81 additions & 0 deletions packages/cli/src/copy/data-set/DataSet.definition.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/**
* This program and the accompanying materials are made available under the terms of the
* Eclipse Public License v2.0 which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-v20.html
*
* SPDX-License-Identifier: EPL-2.0
*
* Copyright Contributors to the Zowe Project.
*
*/

import type { ICommandDefinition } from "@zowe/imperative";

export const CopyDataSetDefinition: ICommandDefinition = {
handler: `${__dirname}/DataSet.handler`,
description:
"Copy a data set or member to another data set or member. " +
"Supports PDS-to-PDS, member-to-member, and sequential-to-sequential copies. " +
"Note: RECFM=U data sets are not supported.",
type: "command",
name: "data-set",
aliases: ["ds"],
summary: "Copy a data set",
examples: [
{
description: "Copy a sequential data set to a new sequential data set",
options: '"ibmuser.source.seq" "ibmuser.target.seq"',
},
{
description: "Copy a PDS to a new PDS (copies all members)",
options: '"ibmuser.source.pds" "ibmuser.target.pds"',
},
{
description: "Copy a single member to another PDS",
options: '"ibmuser.source.pds(member)" "ibmuser.target.pds(member)"',
},
{
description: "Copy a PDS and replace existing members in the target",
options: '"ibmuser.source.pds" "ibmuser.target.pds" --replace',
},
{
description: "Copy a PDS and delete all target members before copying (makes target match source exactly)",
options: '"ibmuser.source.pds" "ibmuser.target.pds" --delete-target-members',
},
],
positionals: [
{
name: "fromDataset",
description: "The source data set to copy from (can include member name in parentheses)",
type: "string",
required: true,
},
{
name: "toDataset",
description: "The target data set to copy to (can include member name in parentheses)",
type: "string",
required: true,
},
],
options: [
{
name: "replace",
aliases: ["r"],
description:
"Replace existing data. For PDS-to-PDS: replaces matching members, preserves target-only members. " +
"For sequential or member-to-member: overwrites the target.",
type: "boolean",
defaultValue: false,
},
{
name: "delete-target-members",
aliases: ["d"],
description:
"Delete all members from target PDS before copying (PDS-to-PDS copy only). " +
"Makes the target match the source exactly.",
type: "boolean",
defaultValue: false,
},
],
profile: { optional: ["ssh"] },
};
54 changes: 54 additions & 0 deletions packages/cli/src/copy/data-set/DataSet.handler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/**
* This program and the accompanying materials are made available under the terms of the
* Eclipse Public License v2.0 which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-v20.html
*
* SPDX-License-Identifier: EPL-2.0
*
* Copyright Contributors to the Zowe Project.
*
*/

import type { IHandlerParameters } from "@zowe/imperative";
import type { ds, ZSshClient } from "zowe-native-proto-sdk";
import { SshBaseHandler } from "../../SshBaseHandler";

export default class CopyDataSetHandler extends SshBaseHandler {
public async processWithClient(params: IHandlerParameters, client: ZSshClient): Promise<ds.CopyDatasetResponse> {
const fromDataset = params.arguments.fromDataset;
const toDataset = params.arguments.toDataset;
const replace = params.arguments.replace ?? false;
const deleteTargetMembers = params.arguments.deleteTargetMembers ?? false;

const response = await client.ds.copyDataset({ fromDataset, toDataset, replace, deleteTargetMembers });

let dsMessage: string;
if (response.success) {
if (response.targetCreated) {
dsMessage = `Data set "${toDataset}" created and copied from "${fromDataset}"`;
} else if (deleteTargetMembers) {
dsMessage = `Target members deleted and data set "${toDataset}" replaced with contents of "${fromDataset}"`;
} else if (replace) {
dsMessage = `Data set "${toDataset}" updated with contents of "${fromDataset}"`;
} else {
dsMessage = `Data set "${fromDataset}" copied to "${toDataset}"`;
}
} else {
const r = response as ds.CopyDatasetResponse & { stderr?: string; message?: string };

Check warning on line 37 in packages/cli/src/copy/data-set/DataSet.handler.ts

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

This assertion is unnecessary since it does not change the type of the expression.

See more on https://sonarcloud.io/project/issues?id=zowe_zowe-native-proto&issues=AZ1uFI7YrNumCMcW_zlz&open=AZ1uFI7YrNumCMcW_zlz&pullRequest=920
const detail = r.stderr?.trim() || r.message?.trim();
Comment thread
ATorrise marked this conversation as resolved.
dsMessage = detail
? `Copy failed: "${fromDataset}" to "${toDataset}": ${detail}`
: `Copy failed: "${fromDataset}" to "${toDataset}"`;
}

params.response.data.setMessage(dsMessage);
params.response.data.setObj(response);
if (response.success) {
params.response.console.log(dsMessage);
} else {
params.response.console.error(dsMessage);
params.response.data.setExitCode(1);
}
return response;
}
}
Loading
Loading