diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index 8bfca62e1c..04c687570d 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to the Zowe CLI package will be documented in this file. +## Recent Changes + +- Enhancement: Pass a `.zosattributes` file path for the download encoding format by adding the new --attributes flag to the `zowe zos-files upload` command.[#2322](https://github.com/zowe/zowe-cli/issues/2322) + ## `8.7.0` - Enhancement: Added --wait-for-active and --wait-for-output to download options on zosjobs. [#2328](https://github.com/zowe/zowe-cli/pull/2328) @@ -18,6 +22,7 @@ All notable changes to the Zowe CLI package will be documented in this file. - Enhancement: Added support for running applications on TSO/E address spaces. Start applications and receive/transmit messages using the new `tso start`, `tso receive` and `tso send` commands. [#2280](https://github.com/zowe/zowe-cli/pull/2280) + ## `8.4.0` - Enhancement: Added optional `--attributes` flag to `zowe zos-files upload file-to-uss` to allow passing a .zosattributes file path for upload encoding format. [#2319](https://github.com/zowe/zowe-cli/pull/2319) diff --git a/packages/cli/__tests__/zosfiles/__integration__/download/uss/__snapshots__/cli.files.download.uss.integration.test.ts.snap b/packages/cli/__tests__/zosfiles/__integration__/download/uss/__snapshots__/cli.files.download.uss.integration.test.ts.snap index 31c18dade7..c71e38ea3e 100644 --- a/packages/cli/__tests__/zosfiles/__integration__/download/uss/__snapshots__/cli.files.download.uss.integration.test.ts.snap +++ b/packages/cli/__tests__/zosfiles/__integration__/download/uss/__snapshots__/cli.files.download.uss.integration.test.ts.snap @@ -28,6 +28,10 @@ exports[`Download USS File should display the help 1`] = ` OPTIONS ------- + --attributes | --attrs (local file path) + + Path of an attributes file to control how files are downloaded. + --binary | -b (boolean) Download the file content in binary mode, which means that no data conversion is @@ -158,8 +162,8 @@ exports[`Download USS File should display the help 1`] = ` \\"success\\": true, \\"exitCode\\": 0, \\"message\\": \\"The help was constructed for command: uss-file.\\", - \\"stdout\\": \\"\\\\n COMMAND NAME\\\\n ------------\\\\n\\\\n uss-file | uf | uss\\\\n\\\\n DESCRIPTION\\\\n -----------\\\\n\\\\n Download content from a USS file to a local file on your PC.\\\\n\\\\n USAGE\\\\n -----\\\\n\\\\n zowe zos-files download uss-file [options]\\\\n\\\\n POSITIONAL ARGUMENTS\\\\n --------------------\\\\n\\\\n ussFileName\\\\t\\\\t (string)\\\\n\\\\n The name of the USS file you want to download\\\\n\\\\n OPTIONS\\\\n -------\\\\n\\\\n --binary | -b (boolean)\\\\n\\\\n Download the file content in binary mode, which means that no data conversion is\\\\n performed. The data transfer process returns each line as-is, without\\\\n translation. No delimiters are added between records.\\\\n\\\\n --encoding | --ec (string)\\\\n\\\\n Download the file content with encoding mode, which means that data conversion\\\\n is performed using the file encoding specified.\\\\n\\\\n --file | -f (string)\\\\n\\\\n The path to the local file where you want to download the content. When you omit\\\\n the option, the command generates a file name automatically for you.\\\\n\\\\n --response-timeout | --rto (number)\\\\n\\\\n The maximum amount of time in seconds the z/OSMF Files TSO servlet should run\\\\n before returning a response. Any request exceeding this amount of time will be\\\\n terminated and return an error. Allowed values: 5 - 600\\\\n\\\\n ZOSMF CONNECTION OPTIONS\\\\n ------------------------\\\\n\\\\n --host | -H (string)\\\\n\\\\n The z/OSMF server host name.\\\\n\\\\n --port | -P (number)\\\\n\\\\n The z/OSMF server port.\\\\n\\\\n Default value: 443\\\\n\\\\n --user | -u (string)\\\\n\\\\n Mainframe (z/OSMF) user name, which can be the same as your TSO login.\\\\n\\\\n --password | --pass | --pw (string)\\\\n\\\\n Mainframe (z/OSMF) password, which can be the same as your TSO password.\\\\n\\\\n --reject-unauthorized | --ru (boolean)\\\\n\\\\n Reject self-signed certificates.\\\\n\\\\n Default value: true\\\\n\\\\n --base-path | --bp (string)\\\\n\\\\n The base path for your API mediation layer instance. Specify this option to\\\\n prepend the base path to all z/OSMF resources when making REST requests. Do not\\\\n specify this option if you are not using an API mediation layer.\\\\n\\\\n --protocol (string)\\\\n\\\\n The protocol used (HTTP or HTTPS)\\\\n\\\\n Default value: https\\\\n Allowed values: http, https\\\\n\\\\n --cert-file (local file path)\\\\n\\\\n The file path to a certificate file to use for authentication\\\\n\\\\n --cert-key-file (local file path)\\\\n\\\\n The file path to a certificate key file to use for authentication\\\\n\\\\n PROFILE OPTIONS\\\\n ---------------\\\\n\\\\n --zosmf-profile | --zosmf-p (string)\\\\n\\\\n The name of a (zosmf) profile to load for this command execution.\\\\n\\\\n --base-profile | --base-p (string)\\\\n\\\\n The name of a (base) profile to load for this command execution.\\\\n\\\\n BASE CONNECTION OPTIONS\\\\n -----------------------\\\\n\\\\n --token-type | --tt (string)\\\\n\\\\n The type of token to get and use for the API. Omit this option to use the\\\\n default token type, which is provided by 'zowe auth login'.\\\\n\\\\n --token-value | --tv (string)\\\\n\\\\n The value of the token to pass to the API.\\\\n\\\\n GLOBAL OPTIONS\\\\n --------------\\\\n\\\\n --show-inputs-only (boolean)\\\\n\\\\n Show command inputs and do not run the command\\\\n\\\\n --response-format-json | --rfj (boolean)\\\\n\\\\n Produce JSON formatted data from a command\\\\n\\\\n --help | -h (boolean)\\\\n\\\\n Display help text\\\\n\\\\n --help-web | --hw (boolean)\\\\n\\\\n Display HTML help in browser\\\\n\\\\n EXAMPLES\\\\n --------\\\\n\\\\n - Download the file \\\\\\"/a/ibmuser/my_text.txt\\\\\\" to\\\\n ./my_text.txt:\\\\n\\\\n $ zowe zos-files download uss-file \\\\\\"/a/ibmuser/my_text.txt\\\\\\" -f ./my_text.txt\\\\n\\\\n - Download the file \\\\\\"/a/ibmuser/MyJava.class\\\\\\" to\\\\n \\\\\\"java/MyJava.class\\\\\\" in binary mode:\\\\n\\\\n $ zowe zos-files download uss-file \\\\\\"/a/ibmuser/MyJava.class\\\\\\" -b -f \\\\\\"java/MyJava.class\\\\\\"\\\\n\\\\n\\", + \\"stdout\\": \\"\\\\n COMMAND NAME\\\\n ------------\\\\n\\\\n uss-file | uf | uss\\\\n\\\\n DESCRIPTION\\\\n -----------\\\\n\\\\n Download content from a USS file to a local file on your PC.\\\\n\\\\n USAGE\\\\n -----\\\\n\\\\n zowe zos-files download uss-file [options]\\\\n\\\\n POSITIONAL ARGUMENTS\\\\n --------------------\\\\n\\\\n ussFileName\\\\t\\\\t (string)\\\\n\\\\n The name of the USS file you want to download\\\\n\\\\n OPTIONS\\\\n -------\\\\n\\\\n --attributes | --attrs (local file path)\\\\n\\\\n Path of an attributes file to control how files are downloaded.\\\\n\\\\n --binary | -b (boolean)\\\\n\\\\n Download the file content in binary mode, which means that no data conversion is\\\\n performed. The data transfer process returns each line as-is, without\\\\n translation. No delimiters are added between records.\\\\n\\\\n --encoding | --ec (string)\\\\n\\\\n Download the file content with encoding mode, which means that data conversion\\\\n is performed using the file encoding specified.\\\\n\\\\n --file | -f (string)\\\\n\\\\n The path to the local file where you want to download the content. When you omit\\\\n the option, the command generates a file name automatically for you.\\\\n\\\\n --response-timeout | --rto (number)\\\\n\\\\n The maximum amount of time in seconds the z/OSMF Files TSO servlet should run\\\\n before returning a response. Any request exceeding this amount of time will be\\\\n terminated and return an error. Allowed values: 5 - 600\\\\n\\\\n ZOSMF CONNECTION OPTIONS\\\\n ------------------------\\\\n\\\\n --host | -H (string)\\\\n\\\\n The z/OSMF server host name.\\\\n\\\\n --port | -P (number)\\\\n\\\\n The z/OSMF server port.\\\\n\\\\n Default value: 443\\\\n\\\\n --user | -u (string)\\\\n\\\\n Mainframe (z/OSMF) user name, which can be the same as your TSO login.\\\\n\\\\n --password | --pass | --pw (string)\\\\n\\\\n Mainframe (z/OSMF) password, which can be the same as your TSO password.\\\\n\\\\n --reject-unauthorized | --ru (boolean)\\\\n\\\\n Reject self-signed certificates.\\\\n\\\\n Default value: true\\\\n\\\\n --base-path | --bp (string)\\\\n\\\\n The base path for your API mediation layer instance. Specify this option to\\\\n prepend the base path to all z/OSMF resources when making REST requests. Do not\\\\n specify this option if you are not using an API mediation layer.\\\\n\\\\n --protocol (string)\\\\n\\\\n The protocol used (HTTP or HTTPS)\\\\n\\\\n Default value: https\\\\n Allowed values: http, https\\\\n\\\\n --cert-file (local file path)\\\\n\\\\n The file path to a certificate file to use for authentication\\\\n\\\\n --cert-key-file (local file path)\\\\n\\\\n The file path to a certificate key file to use for authentication\\\\n\\\\n PROFILE OPTIONS\\\\n ---------------\\\\n\\\\n --zosmf-profile | --zosmf-p (string)\\\\n\\\\n The name of a (zosmf) profile to load for this command execution.\\\\n\\\\n --base-profile | --base-p (string)\\\\n\\\\n The name of a (base) profile to load for this command execution.\\\\n\\\\n BASE CONNECTION OPTIONS\\\\n -----------------------\\\\n\\\\n --token-type | --tt (string)\\\\n\\\\n The type of token to get and use for the API. Omit this option to use the\\\\n default token type, which is provided by 'zowe auth login'.\\\\n\\\\n --token-value | --tv (string)\\\\n\\\\n The value of the token to pass to the API.\\\\n\\\\n GLOBAL OPTIONS\\\\n --------------\\\\n\\\\n --show-inputs-only (boolean)\\\\n\\\\n Show command inputs and do not run the command\\\\n\\\\n --response-format-json | --rfj (boolean)\\\\n\\\\n Produce JSON formatted data from a command\\\\n\\\\n --help | -h (boolean)\\\\n\\\\n Display help text\\\\n\\\\n --help-web | --hw (boolean)\\\\n\\\\n Display HTML help in browser\\\\n\\\\n EXAMPLES\\\\n --------\\\\n\\\\n - Download the file \\\\\\"/a/ibmuser/my_text.txt\\\\\\" to\\\\n ./my_text.txt:\\\\n\\\\n $ zowe zos-files download uss-file \\\\\\"/a/ibmuser/my_text.txt\\\\\\" -f ./my_text.txt\\\\n\\\\n - Download the file \\\\\\"/a/ibmuser/MyJava.class\\\\\\" to\\\\n \\\\\\"java/MyJava.class\\\\\\" in binary mode:\\\\n\\\\n $ zowe zos-files download uss-file \\\\\\"/a/ibmuser/MyJava.class\\\\\\" -b -f \\\\\\"java/MyJava.class\\\\\\"\\\\n\\\\n\\", \\"stderr\\": \\"\\", - \\"data\\": \\"\\\\n COMMAND NAME\\\\n ------------\\\\n\\\\n uss-file | uf | uss\\\\n\\\\n DESCRIPTION\\\\n -----------\\\\n\\\\n Download content from a USS file to a local file on your PC.\\\\n\\\\n USAGE\\\\n -----\\\\n\\\\n zowe zos-files download uss-file [options]\\\\n\\\\n POSITIONAL ARGUMENTS\\\\n --------------------\\\\n\\\\n ussFileName\\\\t\\\\t (string)\\\\n\\\\n The name of the USS file you want to download\\\\n\\\\n OPTIONS\\\\n -------\\\\n\\\\n --binary | -b (boolean)\\\\n\\\\n Download the file content in binary mode, which means that no data conversion is\\\\n performed. The data transfer process returns each line as-is, without\\\\n translation. No delimiters are added between records.\\\\n\\\\n --encoding | --ec (string)\\\\n\\\\n Download the file content with encoding mode, which means that data conversion\\\\n is performed using the file encoding specified.\\\\n\\\\n --file | -f (string)\\\\n\\\\n The path to the local file where you want to download the content. When you omit\\\\n the option, the command generates a file name automatically for you.\\\\n\\\\n --response-timeout | --rto (number)\\\\n\\\\n The maximum amount of time in seconds the z/OSMF Files TSO servlet should run\\\\n before returning a response. Any request exceeding this amount of time will be\\\\n terminated and return an error. Allowed values: 5 - 600\\\\n\\\\n ZOSMF CONNECTION OPTIONS\\\\n ------------------------\\\\n\\\\n --host | -H (string)\\\\n\\\\n The z/OSMF server host name.\\\\n\\\\n --port | -P (number)\\\\n\\\\n The z/OSMF server port.\\\\n\\\\n Default value: 443\\\\n\\\\n --user | -u (string)\\\\n\\\\n Mainframe (z/OSMF) user name, which can be the same as your TSO login.\\\\n\\\\n --password | --pass | --pw (string)\\\\n\\\\n Mainframe (z/OSMF) password, which can be the same as your TSO password.\\\\n\\\\n --reject-unauthorized | --ru (boolean)\\\\n\\\\n Reject self-signed certificates.\\\\n\\\\n Default value: true\\\\n\\\\n --base-path | --bp (string)\\\\n\\\\n The base path for your API mediation layer instance. Specify this option to\\\\n prepend the base path to all z/OSMF resources when making REST requests. Do not\\\\n specify this option if you are not using an API mediation layer.\\\\n\\\\n --protocol (string)\\\\n\\\\n The protocol used (HTTP or HTTPS)\\\\n\\\\n Default value: https\\\\n Allowed values: http, https\\\\n\\\\n --cert-file (local file path)\\\\n\\\\n The file path to a certificate file to use for authentication\\\\n\\\\n --cert-key-file (local file path)\\\\n\\\\n The file path to a certificate key file to use for authentication\\\\n\\\\n PROFILE OPTIONS\\\\n ---------------\\\\n\\\\n --zosmf-profile | --zosmf-p (string)\\\\n\\\\n The name of a (zosmf) profile to load for this command execution.\\\\n\\\\n --base-profile | --base-p (string)\\\\n\\\\n The name of a (base) profile to load for this command execution.\\\\n\\\\n BASE CONNECTION OPTIONS\\\\n -----------------------\\\\n\\\\n --token-type | --tt (string)\\\\n\\\\n The type of token to get and use for the API. Omit this option to use the\\\\n default token type, which is provided by 'zowe auth login'.\\\\n\\\\n --token-value | --tv (string)\\\\n\\\\n The value of the token to pass to the API.\\\\n\\\\n GLOBAL OPTIONS\\\\n --------------\\\\n\\\\n --show-inputs-only (boolean)\\\\n\\\\n Show command inputs and do not run the command\\\\n\\\\n --response-format-json | --rfj (boolean)\\\\n\\\\n Produce JSON formatted data from a command\\\\n\\\\n --help | -h (boolean)\\\\n\\\\n Display help text\\\\n\\\\n --help-web | --hw (boolean)\\\\n\\\\n Display HTML help in browser\\\\n\\\\n EXAMPLES\\\\n --------\\\\n\\\\n - Download the file \\\\\\"/a/ibmuser/my_text.txt\\\\\\" to\\\\n ./my_text.txt:\\\\n\\\\n $ zowe zos-files download uss-file \\\\\\"/a/ibmuser/my_text.txt\\\\\\" -f ./my_text.txt\\\\n\\\\n - Download the file \\\\\\"/a/ibmuser/MyJava.class\\\\\\" to\\\\n \\\\\\"java/MyJava.class\\\\\\" in binary mode:\\\\n\\\\n $ zowe zos-files download uss-file \\\\\\"/a/ibmuser/MyJava.class\\\\\\" -b -f \\\\\\"java/MyJava.class\\\\\\"\\\\n\\\\n\\" + \\"data\\": \\"\\\\n COMMAND NAME\\\\n ------------\\\\n\\\\n uss-file | uf | uss\\\\n\\\\n DESCRIPTION\\\\n -----------\\\\n\\\\n Download content from a USS file to a local file on your PC.\\\\n\\\\n USAGE\\\\n -----\\\\n\\\\n zowe zos-files download uss-file [options]\\\\n\\\\n POSITIONAL ARGUMENTS\\\\n --------------------\\\\n\\\\n ussFileName\\\\t\\\\t (string)\\\\n\\\\n The name of the USS file you want to download\\\\n\\\\n OPTIONS\\\\n -------\\\\n\\\\n --attributes | --attrs (local file path)\\\\n\\\\n Path of an attributes file to control how files are downloaded.\\\\n\\\\n --binary | -b (boolean)\\\\n\\\\n Download the file content in binary mode, which means that no data conversion is\\\\n performed. The data transfer process returns each line as-is, without\\\\n translation. No delimiters are added between records.\\\\n\\\\n --encoding | --ec (string)\\\\n\\\\n Download the file content with encoding mode, which means that data conversion\\\\n is performed using the file encoding specified.\\\\n\\\\n --file | -f (string)\\\\n\\\\n The path to the local file where you want to download the content. When you omit\\\\n the option, the command generates a file name automatically for you.\\\\n\\\\n --response-timeout | --rto (number)\\\\n\\\\n The maximum amount of time in seconds the z/OSMF Files TSO servlet should run\\\\n before returning a response. Any request exceeding this amount of time will be\\\\n terminated and return an error. Allowed values: 5 - 600\\\\n\\\\n ZOSMF CONNECTION OPTIONS\\\\n ------------------------\\\\n\\\\n --host | -H (string)\\\\n\\\\n The z/OSMF server host name.\\\\n\\\\n --port | -P (number)\\\\n\\\\n The z/OSMF server port.\\\\n\\\\n Default value: 443\\\\n\\\\n --user | -u (string)\\\\n\\\\n Mainframe (z/OSMF) user name, which can be the same as your TSO login.\\\\n\\\\n --password | --pass | --pw (string)\\\\n\\\\n Mainframe (z/OSMF) password, which can be the same as your TSO password.\\\\n\\\\n --reject-unauthorized | --ru (boolean)\\\\n\\\\n Reject self-signed certificates.\\\\n\\\\n Default value: true\\\\n\\\\n --base-path | --bp (string)\\\\n\\\\n The base path for your API mediation layer instance. Specify this option to\\\\n prepend the base path to all z/OSMF resources when making REST requests. Do not\\\\n specify this option if you are not using an API mediation layer.\\\\n\\\\n --protocol (string)\\\\n\\\\n The protocol used (HTTP or HTTPS)\\\\n\\\\n Default value: https\\\\n Allowed values: http, https\\\\n\\\\n --cert-file (local file path)\\\\n\\\\n The file path to a certificate file to use for authentication\\\\n\\\\n --cert-key-file (local file path)\\\\n\\\\n The file path to a certificate key file to use for authentication\\\\n\\\\n PROFILE OPTIONS\\\\n ---------------\\\\n\\\\n --zosmf-profile | --zosmf-p (string)\\\\n\\\\n The name of a (zosmf) profile to load for this command execution.\\\\n\\\\n --base-profile | --base-p (string)\\\\n\\\\n The name of a (base) profile to load for this command execution.\\\\n\\\\n BASE CONNECTION OPTIONS\\\\n -----------------------\\\\n\\\\n --token-type | --tt (string)\\\\n\\\\n The type of token to get and use for the API. Omit this option to use the\\\\n default token type, which is provided by 'zowe auth login'.\\\\n\\\\n --token-value | --tv (string)\\\\n\\\\n The value of the token to pass to the API.\\\\n\\\\n GLOBAL OPTIONS\\\\n --------------\\\\n\\\\n --show-inputs-only (boolean)\\\\n\\\\n Show command inputs and do not run the command\\\\n\\\\n --response-format-json | --rfj (boolean)\\\\n\\\\n Produce JSON formatted data from a command\\\\n\\\\n --help | -h (boolean)\\\\n\\\\n Display help text\\\\n\\\\n --help-web | --hw (boolean)\\\\n\\\\n Display HTML help in browser\\\\n\\\\n EXAMPLES\\\\n --------\\\\n\\\\n - Download the file \\\\\\"/a/ibmuser/my_text.txt\\\\\\" to\\\\n ./my_text.txt:\\\\n\\\\n $ zowe zos-files download uss-file \\\\\\"/a/ibmuser/my_text.txt\\\\\\" -f ./my_text.txt\\\\n\\\\n - Download the file \\\\\\"/a/ibmuser/MyJava.class\\\\\\" to\\\\n \\\\\\"java/MyJava.class\\\\\\" in binary mode:\\\\n\\\\n $ zowe zos-files download uss-file \\\\\\"/a/ibmuser/MyJava.class\\\\\\" -b -f \\\\\\"java/MyJava.class\\\\\\"\\\\n\\\\n\\" }" `; diff --git a/packages/cli/__tests__/zosfiles/__unit__/download/uss/__snapshots__/UssFile.definition.unit.test.ts.snap b/packages/cli/__tests__/zosfiles/__unit__/download/uss/__snapshots__/UssFile.definition.unit.test.ts.snap index be7b770bba..3b0b1caa3d 100644 --- a/packages/cli/__tests__/zosfiles/__unit__/download/uss/__snapshots__/UssFile.definition.unit.test.ts.snap +++ b/packages/cli/__tests__/zosfiles/__unit__/download/uss/__snapshots__/UssFile.definition.unit.test.ts.snap @@ -2,6 +2,18 @@ exports[`zos-files download uss-file command definition should not have changed 1`] = ` Array [ + Object { + "aliases": Array [ + "attrs", + ], + "conflictsWith": Array [ + "binary", + "record", + ], + "description": "Path of an attributes file to control how files are downloaded.", + "name": "attributes", + "type": "existingLocalFile", + }, Object { "aliases": Array [ "b", diff --git a/packages/cli/__tests__/zosjobs/__system__/download/cli.zos-jobs.download.output.system.test.ts b/packages/cli/__tests__/zosjobs/__system__/download/cli.zos-jobs.download.output.system.test.ts index c646971f07..d1be44eee1 100644 --- a/packages/cli/__tests__/zosjobs/__system__/download/cli.zos-jobs.download.output.system.test.ts +++ b/packages/cli/__tests__/zosjobs/__system__/download/cli.zos-jobs.download.output.system.test.ts @@ -14,8 +14,6 @@ import { ITestEnvironment } from "../../../../../../__tests__/__src__/environmen import { runCliScript } from "@zowe/cli-test-utils"; import { ITestPropertiesSchema } from "../../../../../../__tests__/__src__/properties/ITestPropertiesSchema"; import * as fs from "fs"; -import { Session } from "@zowe/imperative"; -import { GetJobs } from "@zowe/zos-jobs-for-zowe-sdk"; // Test Environment populated in the beforeAll(); let TEST_ENVIRONMENT: ITestEnvironment; @@ -49,14 +47,14 @@ describe("zos-jobs download output command", () => { it("should download a job and wait for it to reach output status", async () => { const response = runCliScript(__dirname + "/__scripts__/download-output/download_job_wait_for_output.sh", TEST_ENVIRONMENT, [IEFBR14_JCL]); - expect(response.stderr.toString()).toBe(""); - expect(response.status).toBe(0); + expect(response.stderr.toString()).toBe(""); + expect(response.status).toBe(0); }); it("should download a job and wait for it to reach active status", async () => { const response = runCliScript(__dirname + "/__scripts__/download-output/download_job_wait_for_active.sh", TEST_ENVIRONMENT, [IEFBR14_JCL]); - expect(response.stderr.toString()).toBe(""); - expect(response.status).toBe(0); + expect(response.stderr.toString()).toBe(""); + expect(response.status).toBe(0); }); }); describe("output", () => { diff --git a/packages/cli/src/zosfiles/download/uss/UssFile.definition.ts b/packages/cli/src/zosfiles/download/uss/UssFile.definition.ts index 80c5852a33..e06e1af84f 100644 --- a/packages/cli/src/zosfiles/download/uss/UssFile.definition.ts +++ b/packages/cli/src/zosfiles/download/uss/UssFile.definition.ts @@ -39,6 +39,7 @@ export const UssFileDefinition: ICommandDefinition = { } ], options: [ + DownloadOptions.attributes, DownloadOptions.file, DownloadOptions.binary, DownloadOptions.encoding diff --git a/packages/cli/src/zosfiles/download/uss/UssFile.handler.ts b/packages/cli/src/zosfiles/download/uss/UssFile.handler.ts index c62fb8ee3d..00b62c237b 100644 --- a/packages/cli/src/zosfiles/download/uss/UssFile.handler.ts +++ b/packages/cli/src/zosfiles/download/uss/UssFile.handler.ts @@ -11,27 +11,40 @@ import { ZosFilesBaseHandler } from "../../ZosFilesBase.handler"; import { AbstractSession, IHandlerParameters, ITaskWithStatus, TaskStage } from "@zowe/imperative"; -import { Download, IZosFilesResponse } from "@zowe/zos-files-for-zowe-sdk"; +import { Download, IDownloadOptions, IZosFilesResponse, ZosFilesAttributes } from "@zowe/zos-files-for-zowe-sdk"; /** * Handler to download an uss file * @export */ export default class UssFileHandler extends ZosFilesBaseHandler { - public async processWithSession(commandParameters: IHandlerParameters, session: AbstractSession): Promise { + public async processWithSession( + commandParameters: IHandlerParameters, + session: AbstractSession + ): Promise { const task: ITaskWithStatus = { percentComplete: 0, statusMessage: "Downloading USS file", - stageName: TaskStage.IN_PROGRESS + stageName: TaskStage.IN_PROGRESS, }; - commandParameters.response.progress.startBar({task}); - return Download.ussFile(session, commandParameters.arguments.ussFileName, { - binary: commandParameters.arguments.binary, - encoding: commandParameters.arguments.encoding, - file: commandParameters.arguments.file, - task, - responseTimeout: commandParameters.arguments.responseTimeout, - overwrite: commandParameters.arguments.overwrite - }); + commandParameters.response.progress.startBar({ task }); + + const attributes = ZosFilesAttributes.loadFromFile( + commandParameters.arguments.attributes + ); + + return Download.ussFile( + session, + commandParameters.arguments.ussFileName, + { + binary: commandParameters.arguments.binary, + encoding: commandParameters.arguments.encoding, + file: commandParameters.arguments.file, + task, + responseTimeout: commandParameters.arguments.responseTimeout, + overwrite: commandParameters.arguments.overwrite, + attributes, + } + ); } } diff --git a/packages/zosfiles/CHANGELOG.md b/packages/zosfiles/CHANGELOG.md index a7d879d22f..aa11973cd1 100644 --- a/packages/zosfiles/CHANGELOG.md +++ b/packages/zosfiles/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to the Zowe z/OS files SDK package will be documented in this file. +## Recent Changes + +- Enhancement: Allows for passing a `.zosattributues` file path for the download encoding format via the `--attributes` flag on the `zowe zos-files download` command [#2322](https://github.com/zowe/zowe-cli/issues/2322) + ## `8.6.2` - BugFix: Resolved issue where encoding argument was missing from `FileToUss.handler.ts` options object. [#2234](https://github.com/zowe/zowe-cli/pull/2334) @@ -9,7 +13,7 @@ All notable changes to the Zowe z/OS files SDK package will be documented in thi ## `8.4.0` -- Enhancement: Added optional `--attributes` flag to `zowe zos-files upload file-to-uss` to allow passing a .zosattributes file path for upload encoding format. [#2319] (https://github.com/zowe/zowe-cli/pull/2319) +- Enhancement: Added optional `--attributes` flag to `zowe zos-files upload file-to-uss` to allow passing a .zosattributes file path for upload encoding format. [#2319](https://github.com/zowe/zowe-cli/pull/2319) ## `8.2.0` diff --git a/packages/zosfiles/__tests__/__system__/methods/download/Download.system.test.ts b/packages/zosfiles/__tests__/__system__/methods/download/Download.system.test.ts index ecddd8231e..cdf3a05e71 100644 --- a/packages/zosfiles/__tests__/__system__/methods/download/Download.system.test.ts +++ b/packages/zosfiles/__tests__/__system__/methods/download/Download.system.test.ts @@ -24,7 +24,7 @@ import { IMountFsOptions, Mount, Unmount, - IUSSListOptions + IUSSListOptions, } from "../../../../src"; import { Imperative, IO, Session } from "@zowe/imperative"; import { inspect } from "util"; @@ -37,6 +37,7 @@ import { posix } from "path"; import { Shell } from "@zowe/zos-uss-for-zowe-sdk"; import { PassThrough } from "stream"; import { text } from "stream/consumers"; +import { runCliScript } from "@zowe/cli-test-utils"; const rimraf = require("rimraf").sync; const delayTime = 2000; @@ -1080,7 +1081,91 @@ describe.each([false, true])("Download Data Set - Encoded: %s", (encoded: boolea expect(fileContents).toEqual(testData); }); - + describe.each([false, true])( + "Download Data Set - Binary: %s", + (binary: boolean) => { + it("should upload and download file with correct encoding", async () => { + let response: any; + + // Upload binary or encoded file + const uploadFile: string = binary + ? "downloadEncodingCheck.txt" + : "downloadEncodingCheckBinary.txt"; + let downloadResponse: any; + let error: any; + + // Use text file as to get proper response from getRemoteEncoding() + const ussnameAsTxt = ussname + ".txt"; + try { + response = runCliScript( + __dirname + + `/__resources__/${ + binary + ? "upload_file_to_uss.sh" + : "upload_file_to_uss_binary.sh" + }`, + testEnvironment, + [ + defaultSystem.tso.account, + defaultSystem.zosmf.host, + defaultSystem.zosmf.port, + defaultSystem.zosmf.user, + defaultSystem.zosmf.password, + defaultSystem.zosmf.rejectUnauthorized, + __dirname + + "/__resources__/testfiles/" + + uploadFile, + ussnameAsTxt, + binary ? "1047" : true, + ] + ); + downloadResponse = runCliScript( + __dirname + "/__resources__/download_file.sh", + testEnvironment, + [ + defaultSystem.tso.account, + defaultSystem.zosmf.host, + defaultSystem.zosmf.port, + defaultSystem.zosmf.user, + defaultSystem.zosmf.password, + defaultSystem.zosmf.rejectUnauthorized, + ussnameAsTxt, + __dirname + + `/__resources__/${ + binary + ? ".zosattributes" + : ".zosattributes-binary" + }`, + ] + ); + } catch (err) { + error = err; + } + + expect(error).toBeFalsy(); + expect(response).toBeTruthy(); + expect(downloadResponse).toBeTruthy(); + + // Compare the downloaded contents to those uploaded + const fileContents = fs + .readFileSync( + `${testEnvironment.workingDir}/${posix.basename( + ussnameAsTxt + )}` + ) + .toString(); + expect(fileContents).toEqual( + fs + .readFileSync( + __dirname + + "/__resources__/testfiles/" + + uploadFile + ) + .toString() + ); + }); + } + ); // When requesting etag, z/OSMF has a limit on file size when it stops to return etag by default (>8mb) // We are passing X-IBM-Return-Etag to force z/OSMF to always return etag, but testing here for case where it would be optional it("should download a 10mb uss file and return Etag", async () => { diff --git a/packages/zosfiles/__tests__/__system__/methods/download/__resources__/.zosattributes b/packages/zosfiles/__tests__/__system__/methods/download/__resources__/.zosattributes new file mode 100644 index 0000000000..88a1b0f51f --- /dev/null +++ b/packages/zosfiles/__tests__/__system__/methods/download/__resources__/.zosattributes @@ -0,0 +1,5 @@ +*.json - +*.bin binary binary +*.jcl IBM-1047 IBM-1047 +*.md UTF-8 UTF-8 +*.txt UTF-8 IBM-1047 \ No newline at end of file diff --git a/packages/zosfiles/__tests__/__system__/methods/download/__resources__/.zosattributes-binary b/packages/zosfiles/__tests__/__system__/methods/download/__resources__/.zosattributes-binary new file mode 100644 index 0000000000..0f79a06bc2 --- /dev/null +++ b/packages/zosfiles/__tests__/__system__/methods/download/__resources__/.zosattributes-binary @@ -0,0 +1,5 @@ +*.json - +*.bin binary binary +*.jcl IBM-1047 IBM-1047 +*.md UTF-8 UTF-8 +*.txt binary binary \ No newline at end of file diff --git a/packages/zosfiles/__tests__/__system__/methods/download/__resources__/download_file.sh b/packages/zosfiles/__tests__/__system__/methods/download/__resources__/download_file.sh new file mode 100755 index 0000000000..d4f66bcb9a --- /dev/null +++ b/packages/zosfiles/__tests__/__system__/methods/download/__resources__/download_file.sh @@ -0,0 +1,12 @@ +#!/bin/bash +account=$1 +host=$2 +port=$3 +user=$4 +password=$5 +ru=$6 +fileToDownload=$7 +attributes=$8 + +zowe zos-files download uss "$fileToDownload" --attributes "$attributes" --host $host --port $port --user $user --password $password --ru $ru +exit $? \ No newline at end of file diff --git a/packages/zosfiles/__tests__/__system__/methods/download/__resources__/testfiles/downloadEncodingCheck.txt b/packages/zosfiles/__tests__/__system__/methods/download/__resources__/testfiles/downloadEncodingCheck.txt new file mode 100644 index 0000000000..e85d5b4528 --- /dev/null +++ b/packages/zosfiles/__tests__/__system__/methods/download/__resources__/testfiles/downloadEncodingCheck.txt @@ -0,0 +1 @@ +abcdefghijklmnopqrstuvwxyz \ No newline at end of file diff --git a/packages/zosfiles/__tests__/__system__/methods/download/__resources__/testfiles/downloadEncodingCheckBinary.txt b/packages/zosfiles/__tests__/__system__/methods/download/__resources__/testfiles/downloadEncodingCheckBinary.txt new file mode 100644 index 0000000000..385781092d --- /dev/null +++ b/packages/zosfiles/__tests__/__system__/methods/download/__resources__/testfiles/downloadEncodingCheckBinary.txt @@ -0,0 +1 @@ +[][][] \ No newline at end of file diff --git a/packages/zosfiles/__tests__/__system__/methods/download/__resources__/upload_file_to_uss.sh b/packages/zosfiles/__tests__/__system__/methods/download/__resources__/upload_file_to_uss.sh new file mode 100755 index 0000000000..fd823d3988 --- /dev/null +++ b/packages/zosfiles/__tests__/__system__/methods/download/__resources__/upload_file_to_uss.sh @@ -0,0 +1,13 @@ +#!/bin/bash +account=$1 +host=$2 +port=$3 +user=$4 +password=$5 +ru=$6 +inputFile=$7 +ussName=$8 +encoding=$9 + +zowe zos-files upload file-to-uss "$inputFile" "$ussName" --encoding $encoding --host $host --port $port --user $user --password $password --ru $ru +exit $? \ No newline at end of file diff --git a/packages/zosfiles/__tests__/__system__/methods/download/__resources__/upload_file_to_uss_binary.sh b/packages/zosfiles/__tests__/__system__/methods/download/__resources__/upload_file_to_uss_binary.sh new file mode 100755 index 0000000000..33fdf7a9cd --- /dev/null +++ b/packages/zosfiles/__tests__/__system__/methods/download/__resources__/upload_file_to_uss_binary.sh @@ -0,0 +1,13 @@ +#!/bin/bash +account=$1 +host=$2 +port=$3 +user=$4 +password=$5 +ru=$6 +inputFile=$7 +ussName=$8 +binary=$9 + +zowe zos-files upload file-to-uss "$inputFile" "$ussName" --binary $binary --host $host --port $port --user $user --password $password --ru $ru +exit $? \ No newline at end of file diff --git a/packages/zosfiles/__tests__/__unit__/methods/download/Download.unit.test.ts b/packages/zosfiles/__tests__/__unit__/methods/download/Download.unit.test.ts index 9d7af8b881..ce404abc48 100644 --- a/packages/zosfiles/__tests__/__unit__/methods/download/Download.unit.test.ts +++ b/packages/zosfiles/__tests__/__unit__/methods/download/Download.unit.test.ts @@ -2184,6 +2184,90 @@ describe("z/OS Files - Download", () => { expect(ioCreateDirSpy).not.toHaveBeenCalled(); expect(ioWriteStreamSpy).not.toHaveBeenCalled(); }); + it("should download uss file using .zosattributes file", async () => { + let response; + let caughtError; + const destination = localFileName; + const zosAttributes = Object.create(ZosFilesAttributes.prototype); + zosAttributes.attributes = new Map([ + ['*.json', { ignore: true }], + ['*.bin', { ignore: false, localEncoding: 'binary', remoteEncoding: 'binary' }], + ['*.jcl', { ignore: false, localEncoding: 'IBM-1047', remoteEncoding: 'IBM-1047' }], + ['*.md', { ignore: false, localEncoding: 'UTF-8', remoteEncoding: 'UTF-8' }], + ['*.txt', { ignore: false, localEncoding: 'UTF-8', remoteEncoding: 'IBM-1047' }] + ]); + try { + response = await Download.ussFile(dummySession, ussname, { attributes: zosAttributes }); + } catch (e) { + caughtError = e; + } + + const endpoint = path.posix.join(ZosFilesConstants.RESOURCE, ZosFilesConstants.RES_USS_FILES, encodeURIComponent(ussname.substring(1))); + + expect(caughtError).toBeUndefined(); + expect(response).toEqual({ + success: true, + commandResponse: util.format(ZosFilesMessages.ussFileDownloadedWithDestination.message, destination), + apiResponse: {} + }); + + expect(zosmfGetFullSpy).toHaveBeenCalledTimes(1); + expect(zosmfGetFullSpy).toHaveBeenCalledWith(dummySession, { + resource: endpoint, + reqHeaders: [{ "X-IBM-Data-Type": "text;fileEncoding=IBM-1047" }, ZosmfHeaders.ACCEPT_ENCODING, {"Content-Type": "UTF-8"}], + responseStream: fakeStream, + normalizeResponseNewLines: true, + task: undefined /* no progress task */ + }); + + expect(ioCreateDirSpy).toHaveBeenCalledTimes(1); + expect(ioCreateDirSpy).toHaveBeenCalledWith(destination); + + expect(ioWriteStreamSpy).toHaveBeenCalledTimes(1); + expect(ioWriteStreamSpy).toHaveBeenCalledWith(destination); + }); + it("should download uss file using .zosattributes file - binary", async () => { + let response; + let caughtError; + const destination = localFileName; + const zosAttributes = Object.create(ZosFilesAttributes.prototype); + zosAttributes.attributes = new Map([ + ['*.json', { ignore: true }], + ['*.bin', { ignore: false, localEncoding: 'binary', remoteEncoding: 'binary' }], + ['*.jcl', { ignore: false, localEncoding: 'IBM-1047', remoteEncoding: 'IBM-1047' }], + ['*.md', { ignore: false, localEncoding: 'UTF-8', remoteEncoding: 'UTF-8' }], + ['*.txt', { ignore: false, localEncoding: 'binary', remoteEncoding: 'binary' }] + ]); + try { + response = await Download.ussFile(dummySession, ussname, { attributes: zosAttributes }); + } catch (e) { + caughtError = e; + } + + const endpoint = path.posix.join(ZosFilesConstants.RESOURCE, ZosFilesConstants.RES_USS_FILES, encodeURIComponent(ussname.substring(1))); + + expect(caughtError).toBeUndefined(); + expect(response).toEqual({ + success: true, + commandResponse: util.format(ZosFilesMessages.ussFileDownloadedWithDestination.message, destination), + apiResponse: {} + }); + + expect(zosmfGetFullSpy).toHaveBeenCalledTimes(1); + expect(zosmfGetFullSpy).toHaveBeenCalledWith(dummySession, { + resource: endpoint, + reqHeaders: [{ "X-IBM-Data-Type": "binary" }], + responseStream: fakeStream, + normalizeResponseNewLines: false, + task: undefined /* no progress task */ + }); + + expect(ioCreateDirSpy).toHaveBeenCalledTimes(1); + expect(ioCreateDirSpy).toHaveBeenCalledWith(destination); + + expect(ioWriteStreamSpy).toHaveBeenCalledTimes(1); + expect(ioWriteStreamSpy).toHaveBeenCalledWith(destination); + }); }); describe("USS Directory", () => { diff --git a/packages/zosfiles/src/methods/download/Download.ts b/packages/zosfiles/src/methods/download/Download.ts index 5944f6b6ee..50091d156d 100644 --- a/packages/zosfiles/src/methods/download/Download.ts +++ b/packages/zosfiles/src/methods/download/Download.ts @@ -521,7 +521,13 @@ export class Download { const writeStream = options.stream ?? IO.createWriteStream(destination); - // If data type is not defined by user, check for USS tags + if(options.attributes) + { + options = { ...options, ...this.parseAttributeOptions(ussFileName,options)}; + if(options.binary) options.encoding = undefined; + } + + // If data type is not defined by user via encoding flag or attributes file, check for USS tags if (options.binary == null && options.encoding == null) { await Utilities.applyTaggedEncoding(session, ussFileName, options); } diff --git a/packages/zosfiles/src/methods/download/doc/IDownloadOptions.ts b/packages/zosfiles/src/methods/download/doc/IDownloadOptions.ts index 103c496d2b..076d7a5522 100644 --- a/packages/zosfiles/src/methods/download/doc/IDownloadOptions.ts +++ b/packages/zosfiles/src/methods/download/doc/IDownloadOptions.ts @@ -58,9 +58,13 @@ export interface IDownloadSingleOptions extends IGetOptions { overwrite?: boolean; /** - * Optional stream to read the file contents + * Optional stream to write the file contents */ stream?: Writable; + /** + * The ZosFilesAttributes instance describe upload attributes for the files and directories + */ + attributes?: ZosFilesAttributes; } /** diff --git a/packages/zosfiles/src/methods/upload/Upload.ts b/packages/zosfiles/src/methods/upload/Upload.ts index 13a53abef4..528150b961 100644 --- a/packages/zosfiles/src/methods/upload/Upload.ts +++ b/packages/zosfiles/src/methods/upload/Upload.ts @@ -877,7 +877,7 @@ export class Upload { } else if(options.filesMap?.fileNames.indexOf(path.basename(localPath)) > -1) { tempOptions.binary = options.filesMap.binary; - // Reset encoding to undefined if binary is true to avoid file tagging issues + // Reset encoding to undefined if binary is true to avoid file tagging issues if(tempOptions.binary) tempOptions.encoding = undefined; }