diff --git a/package.json b/package.json index 5352d87e3d..0ff177482d 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,7 @@ "audit:public": "npm audit --registry https://registry.npmjs.org/", "bundle:webHelp": "cd packages/imperative/web-help && node build.js", "prepare": "husky install && npm run bundle:webHelp", - "package": "node scripts/bundleCliTgz.js" + "package": "lerna run prepublishOnly && node scripts/bundleCliTgz.js" }, "dependencies": {}, "devDependencies": { @@ -57,7 +57,7 @@ "chalk": "^4.1.0", "env-cmd": "^10.1.0", "eslint": "^8.22.0", - "eslint-plugin-deprecation": "^2.0.0", + "eslint-plugin-deprecation": "^2.0.0", "eslint-plugin-jest": "^26.8.0", "eslint-plugin-unused-imports": "^2.0.0", "fancy-log": "^1.3.3", diff --git a/packages/zosfiles/CHANGELOG.md b/packages/zosfiles/CHANGELOG.md index fe59a322f8..2cf27a597a 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 + +- BugFix: Fixed an issue with the `List.dataSetsMatchingPattern` method where migrated data sets could break fetching attributes for other data sets. [#2285](https://github.com/zowe/zowe-cli/issues/2285) + ## `7.28.3` - BugFix: Refactored code to reduce the use of deprecated functions to prepare for upcoming Node.js 22 support. [#2191](https://github.com/zowe/zowe-cli/issues/2191) diff --git a/packages/zosfiles/__tests__/__unit__/methods/list/List.unit.test.ts b/packages/zosfiles/__tests__/__unit__/methods/list/List.unit.test.ts index a8fc17ea6a..b5e8434626 100644 --- a/packages/zosfiles/__tests__/__unit__/methods/list/List.unit.test.ts +++ b/packages/zosfiles/__tests__/__unit__/methods/list/List.unit.test.ts @@ -1498,7 +1498,7 @@ describe("z/OS Files - List", () => { }); expect(listDataSetSpy).toHaveBeenCalledTimes(3); - expect(listDataSetSpy).toHaveBeenCalledWith(dummySession, dataSetPS.dsname, {attributes: true}); + expect(listDataSetSpy).toHaveBeenLastCalledWith(dummySession, dataSetPS.dsname, {attributes: true, maxLength: 1}); }); it("should handle an error when the exclude pattern is specified", async () => { diff --git a/packages/zosfiles/src/methods/list/List.ts b/packages/zosfiles/src/methods/list/List.ts index 10d8a29da0..51780935ac 100644 --- a/packages/zosfiles/src/methods/list/List.ts +++ b/packages/zosfiles/src/methods/list/List.ts @@ -389,7 +389,7 @@ export class List { listsInitiated++; } - return List.dataSet(session, dataSetObj.dsname, { attributes: true }).then( + return List.dataSet(session, dataSetObj.dsname, { attributes: true, maxLength: 1 }).then( (tempResponse) => { Object.assign(dataSetObj, tempResponse.apiResponse.items[0]); }, diff --git a/packages/zosjobs/CHANGELOG.md b/packages/zosjobs/CHANGELOG.md index 18cb80b765..8b18247d62 100644 --- a/packages/zosjobs/CHANGELOG.md +++ b/packages/zosjobs/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to the Zowe z/OS jobs SDK package will be documented in this file. +## Recent Changes + +- BugFix: Fixed error in `DownloadJobs.downloadSpoolContentCommon` method causing binary spool files to be corrupted by newline normalization. [#2282](https://github.com/zowe/zowe-cli/issues/2282) + ## `7.26.1` - BugFix: Fixed error in `DownloadJobs.downloadSpoolContentCommon` method when encoding parameter is not specified. [#2173](https://github.com/zowe/zowe-cli/pull/2173) diff --git a/packages/zosjobs/__tests__/__unit__/DownloadJobs.unit.test.ts b/packages/zosjobs/__tests__/__unit__/DownloadJobs.unit.test.ts index 9f8497ca1a..b38364adec 100644 --- a/packages/zosjobs/__tests__/__unit__/DownloadJobs.unit.test.ts +++ b/packages/zosjobs/__tests__/__unit__/DownloadJobs.unit.test.ts @@ -9,7 +9,7 @@ * */ -import { AbstractSession, ImperativeError, IO } from "@zowe/imperative"; +import { AbstractSession, Headers, ImperativeError, IO } from "@zowe/imperative"; import { DownloadJobs, GetJobs, IDownloadAllSpoolContentParms, IDownloadSpoolContentParms, IJobFile } from "../../src"; import { ZosmfRestClient } from "@zowe/core-for-zowe-sdk"; import { Writable } from "stream"; @@ -103,10 +103,7 @@ describe("DownloadJobs", () => { describe("downloadAllSpoolContentCommon", () => { it("should allow users to call downloadAllSpoolContentCommon with correct parameters", async () => { - let uri: string = ""; - ZosmfRestClient.getStreamed = jest.fn(async (session: AbstractSession, resource: string, reqHeaders?: any[]): Promise => { - uri = resource; - }); + const getStreamedSpy = jest.spyOn(ZosmfRestClient, "getStreamed"); const allSpoolParms: IDownloadAllSpoolContentParms = { jobid: fakeJobID, jobname: fakeJobName, @@ -120,14 +117,15 @@ describe("DownloadJobs", () => { expect(GetJobs.getSpoolFiles).toHaveBeenCalled(); expect(IO.createDirsSyncFromFilePath).toHaveBeenCalledWith(expectedFile); - expect(uri).not.toContain("fileEncoding"); + expect(getStreamedSpy).toHaveBeenCalledTimes(1); + const [_session, resource, reqHeaders, _responseStream, normalizeResponseNewLines] = getStreamedSpy.mock.calls[0]; + expect(resource).not.toContain("fileEncoding"); + expect(reqHeaders).toContain(Headers.TEXT_PLAIN_UTF8); + expect(normalizeResponseNewLines).toBe(true); }); it("should allow users to call downloadAllSpoolContentCommon with correct parameters and binary mode", async () => { - let uri: string = ""; - ZosmfRestClient.getStreamed = jest.fn(async (session: AbstractSession, resource: string, reqHeaders?: any[]): Promise => { - uri = resource; - }); + const getStreamedSpy = jest.spyOn(ZosmfRestClient, "getStreamed"); const allSpoolParms: IDownloadAllSpoolContentParms = { jobid: fakeJobID, jobname: fakeJobName, @@ -142,14 +140,14 @@ describe("DownloadJobs", () => { expect(GetJobs.getSpoolFiles).toHaveBeenCalled(); expect(IO.createDirsSyncFromFilePath).toHaveBeenCalledWith(expectedFile); - expect(uri).toContain("?mode=binary"); + expect(getStreamedSpy).toHaveBeenCalledTimes(1); + const [_session, resource, _reqHeaders, _responseStream, normalizeResponseNewLines] = getStreamedSpy.mock.calls[0]; + expect(resource).toContain("?mode=binary"); + expect(normalizeResponseNewLines).toBe(false); }); it("should allow users to call downloadAllSpoolContentCommon with correct parameters and record mode", async () => { - let uri: string = ""; - ZosmfRestClient.getStreamed = jest.fn(async (session: AbstractSession, resource: string, reqHeaders?: any[]): Promise => { - uri = resource; - }); + const getStreamedSpy = jest.spyOn(ZosmfRestClient, "getStreamed"); const allSpoolParms: IDownloadAllSpoolContentParms = { jobid: fakeJobID, jobname: fakeJobName, @@ -164,7 +162,10 @@ describe("DownloadJobs", () => { expect(GetJobs.getSpoolFiles).toHaveBeenCalled(); expect(IO.createDirsSyncFromFilePath).toHaveBeenCalledWith(expectedFile); - expect(uri).toContain("?mode=record"); + expect(getStreamedSpy).toHaveBeenCalledTimes(1); + const [_session, resource, _reqHeaders, _responseStream, normalizeResponseNewLines] = getStreamedSpy.mock.calls[0]; + expect(resource).toContain("?mode=record"); + expect(normalizeResponseNewLines).toBe(false); }); it("should allow users to call downloadAllSpoolContentCommon with a job containing duplicate step names", async () => { diff --git a/packages/zosjobs/src/DownloadJobs.ts b/packages/zosjobs/src/DownloadJobs.ts index 679ad2ad5a..6abe4fb528 100644 --- a/packages/zosjobs/src/DownloadJobs.ts +++ b/packages/zosjobs/src/DownloadJobs.ts @@ -127,8 +127,9 @@ export class DownloadJobs { } const writeStream = parms.stream ?? IO.createWriteStream(file); + const normalizeResponseNewLines = !(parms.binary || parms.record); await ZosmfRestClient.getStreamed(session, JobsConstants.RESOURCE + parameters, [Headers.TEXT_PLAIN_UTF8], writeStream, - true); + normalizeResponseNewLines); } /**