Skip to content
Open
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
716e1bc
feat: command for downloading all members of PDS to local directory
JWaters02 Feb 9, 2025
72877ab
Attempt on tests
JWaters02 Feb 14, 2025
5bb37c1
Merge remote-tracking branch 'JWaters02/main' into feat/download-ds
JWaters02 May 24, 2025
08de650
refactor: smarter attempt at downloadAllMembers
JWaters02 May 24, 2025
ab2535a
store download options in local storage
JWaters02 May 25, 2025
f87c6b5
WIP
JWaters02 Jun 5, 2025
7a9b90f
Merge remote-tracking branch 'origin/main' into feat/download-ds
JWaters02 Aug 15, 2025
42fcb20
wip: downloading
JWaters02 Aug 23, 2025
c4eaeb4
Merge remote-tracking branch 'origin/main' into feat/download-ds
JWaters02 Aug 23, 2025
7ea6ff2
wip: downloading
JWaters02 Aug 23, 2025
8eafadb
wip: downloading
JWaters02 Aug 24, 2025
d230ec0
wip: add downloadDataSet and move common quickpick to helper
JWaters02 Aug 24, 2025
116d596
refactor: reduce code duplication
JWaters02 Aug 24, 2025
2d2b5ac
Merge remote-tracking branch 'origin/main' into feat/download-ds
JWaters02 Aug 30, 2025
fa100fb
feat: download uss files/directories
JWaters02 Aug 30, 2025
5f81fc3
fix: count dir children recursively
JWaters02 Aug 30, 2025
17fc579
Merge remote-tracking branch 'origin/main' into feat/download-ds
JWaters02 Oct 4, 2025
a663383
Merge remote-tracking branch 'origin/main' into feat/download-ds
JWaters02 Oct 8, 2025
9c6c4ed
refactor: fallback to profile encoding
JWaters02 Oct 18, 2025
4a039fc
Merge remote-tracking branch 'origin/main' into feat/download-ds
JWaters02 Oct 18, 2025
ed79831
fix: implement downloadAllDatasets into FtpMvsApi
JWaters02 Oct 18, 2025
a003177
tests: update command count
JWaters02 Oct 18, 2025
11beac6
tests: all tests passing, ready for Download test cases
JWaters02 Oct 18, 2025
5c15080
tests: data set download functions tests
JWaters02 Oct 18, 2025
efb87ef
tests: uss download functions tests
JWaters02 Oct 19, 2025
e8bce59
tests: add USSUtils.unit.test.ts with coverage for existing & new funcs
JWaters02 Oct 19, 2025
e25d90f
tests: USSInit & DatasetInit coverage
JWaters02 Oct 19, 2025
03fa91e
tests: remove unused imports
JWaters02 Oct 19, 2025
a3de6fd
refactor: add downloadDirectory to IUss interface
JWaters02 Oct 19, 2025
cab987b
tests: add mvs/uss download api impl to ftp ext tests
JWaters02 Oct 19, 2025
5da1f2a
wip: add list opts support to uss dir download
JWaters02 Oct 19, 2025
9bf9a9d
refactor: uss dir download options
JWaters02 Oct 19, 2025
10a1ce7
refactor: handle download responses properly
JWaters02 Oct 20, 2025
6f636e2
Merge branch 'feat/download-uss-dir-opts' into feat/download-ds
JWaters02 Oct 20, 2025
a61fa6f
tests: fix tests and add new tests for the changes
JWaters02 Oct 20, 2025
a44a6ba
refactor: change context menu groupings
JWaters02 Oct 20, 2025
1b06aad
chore: prepublish
JWaters02 Oct 20, 2025
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
10 changes: 10 additions & 0 deletions packages/zowe-explorer-api/src/extend/MainframeInteraction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,16 @@ export namespace MainframeInteraction {
*/
getContents(dataSetName: string, options?: zosfiles.IDownloadSingleOptions): Promise<zosfiles.IZosFilesResponse>;

/**
* Retrieve all members of a partitioned data set and save them to a directory.
*
* @param {string} dataSetName
* @param {string} directoryPath
* @param {zosfiles.IDownloadOptions} [options]
* @returns {Promise<zosfiles.IZosFilesResponse>}
*/
downloadAllMembers(dataSetName: string, options?: zosfiles.IDownloadOptions): Promise<zosfiles.IZosFilesResponse>;

/**
* Uploads a given buffer as the contents of a file to a data set or member.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,13 @@ export namespace ZoweExplorerZosmf {
});
}

public downloadAllMembers(dataSetName: string, options?: zosfiles.IDownloadOptions): Promise<zosfiles.IZosFilesResponse> {
return zosfiles.Download.allMembers(this.getSession(), dataSetName, {
responseTimeout: this.profile?.profile?.responseTimeout,
...options,
});
}

public uploadFromBuffer(buffer: Buffer, dataSetName: string, options?: zosfiles.IUploadOptions): Promise<zosfiles.IZosFilesResponse> {
return zosfiles.Upload.bufferToDataSet(this.getSession(), buffer, dataSetName, {
responseTimeout: this.profile?.profile?.responseTimeout,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,10 @@ async function createGlobalMocks() {
"zowe.ds.uploadDialog",
"zowe.ds.uploadDialogWithEncoding",
"zowe.ds.deleteMember",
"zowe.ds.downloadDataset",
"zowe.ds.downloadAllDatasets",
"zowe.ds.downloadMember",
"zowe.ds.downloadAllMembers",
"zowe.ds.editDataSet",
"zowe.ds.editMember",
"zowe.ds.submitJcl",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3500,3 +3500,5 @@ describe("Dataset Actions Unit Tests - upload with encoding", () => {
getTreeViewMock.mockRestore();
});
});

describe("DatasetActions - downloading functions", () => {});
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,10 @@ describe("Test src/dataset/extension", () => {
name: "zowe.ds.uploadDialogWithEncoding",
mock: [{ spy: jest.spyOn(DatasetActions, "uploadDialogWithEncoding"), arg: [test.value, dsProvider] }],
},
{
name: "zowe.ds.downloadAllMembers",
mock: [{ spy: jest.spyOn(DatasetActions, "downloadAllMembers"), arg: [test.value] }],
},
{
name: "zowe.ds.deleteMember",
mock: [{ spy: jest.spyOn(DatasetActions, "deleteDatasetPrompt"), arg: [dsProvider, test.value] }],
Expand Down
72 changes: 36 additions & 36 deletions packages/zowe-explorer/l10n/bundle.l10n.json
Original file line number Diff line number Diff line change
Expand Up @@ -243,42 +243,6 @@
"Uploading USS files...": "Uploading USS files...",
"Error uploading files": "Error uploading files",
"Retrieving response from USS list API": "Retrieving response from USS list API",
"The 'move' function is not implemented for this USS API.": "The 'move' function is not implemented for this USS API.",
"Failed to move {0}/File path": {
"message": "Failed to move {0}",
"comment": [
"File path"
]
},
"Profile does not exist for this file.": "Profile does not exist for this file.",
"Saving USS file...": "Saving USS file...",
"Failed to rename {0}/File path": {
"message": "Failed to rename {0}",
"comment": [
"File path"
]
},
"Failed to delete {0}/File name": {
"message": "Failed to delete {0}",
"comment": [
"File name"
]
},
"No error details given": "No error details given",
"Error fetching destination {0} for paste action: {1}/USS pathError message": {
"message": "Error fetching destination {0} for paste action: {1}",
"comment": [
"USS path",
"Error message"
]
},
"Failed to copy {0} to {1}/Source pathDestination path": {
"message": "Failed to copy {0} to {1}",
"comment": [
"Source path",
"Destination path"
]
},
"Downloaded: {0}/Download time": {
"message": "Downloaded: {0}",
"comment": [
Expand Down Expand Up @@ -341,6 +305,42 @@
"initializeUSSFavorites.error.buttonRemove": "initializeUSSFavorites.error.buttonRemove",
"File does not exist. It may have been deleted.": "File does not exist. It may have been deleted.",
"Pulling from Mainframe...": "Pulling from Mainframe...",
"The 'move' function is not implemented for this USS API.": "The 'move' function is not implemented for this USS API.",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"The 'move' function is not implemented for this USS API.": "The 'move' function is not implemented for this USS API.",
"The 'Move' function is not implemented for this USS API.": "The 'move' function is not implemented for this USS API.",

"Failed to move {0}/File path": {
"message": "Failed to move {0}",
"comment": [
"File path"
]
},
"Profile does not exist for this file.": "Profile does not exist for this file.",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we say "A profile ... "?

"Saving USS file...": "Saving USS file...",
"Failed to rename {0}/File path": {
"message": "Failed to rename {0}",
"comment": [
"File path"
]
},
"Failed to delete {0}/File name": {
"message": "Failed to delete {0}",
"comment": [
"File name"
]
},
"No error details given": "No error details given",
"Error fetching destination {0} for paste action: {1}/USS pathError message": {
"message": "Error fetching destination {0} for paste action: {1}",
"comment": [
"USS path",
"Error message"
]
},
"Failed to copy {0} to {1}/Source pathDestination path": {
"message": "Failed to copy {0} to {1}",
"comment": [
"Source path",
"Destination path"
]
},
"{0} location/Node type": {
"message": "{0} location",
"comment": [
Expand Down
18 changes: 9 additions & 9 deletions packages/zowe-explorer/l10n/poeditor.json
Original file line number Diff line number Diff line change
Expand Up @@ -706,15 +706,6 @@
"Uploading USS files...": "",
"Error uploading files": "",
"Retrieving response from USS list API": "",
"The 'move' function is not implemented for this USS API.": "",
"Failed to move {0}": "",
"Profile does not exist for this file.": "",
"Saving USS file...": "",
"Failed to rename {0}": "",
"Failed to delete {0}": "",
"No error details given": "",
"Error fetching destination {0} for paste action: {1}": "",
"Failed to copy {0} to {1}": "",
"Downloaded: {0}": "",
"Encoding: {0}": "",
"Binary": "",
Expand All @@ -741,6 +732,15 @@
"initializeUSSFavorites.error.buttonRemove": "",
"File does not exist. It may have been deleted.": "",
"Pulling from Mainframe...": "",
"The 'move' function is not implemented for this USS API.": "",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"The 'move' function is not implemented for this USS API.": "",
"The 'Move' function is not implemented for this USS API.": "",

"Failed to move {0}": "",
"Profile does not exist for this file.": "",
"Saving USS file...": "",
"Failed to rename {0}": "",
"Failed to delete {0}": "",
"No error details given": "",
"Error fetching destination {0} for paste action: {1}": "",
"Failed to copy {0} to {1}": "",
"{0} location": "",
"Choose a location to create the {0}": "",
"Name of file or directory": "",
Expand Down
74 changes: 72 additions & 2 deletions packages/zowe-explorer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,21 @@
"title": "%uploadDialogWithEncoding%",
"category": "Zowe Explorer"
},
{
"command": "zowe.ds.downloadDataSet",
"title": "%downloadDataSet%",
"category": "Zowe Explorer"
},
{
"command": "zowe.ds.downloadMember",
"title": "%downloadMember%",
"category": "Zowe Explorer"
},
{
"command": "zowe.ds.downloadAllMembers",
"title": "%downloadAllMembers%",
"category": "Zowe Explorer"
},
{
"command": "zowe.ds.editDataSet",
"title": "%editDataSet%",
Expand Down Expand Up @@ -529,6 +544,16 @@
"title": "%uss.uploadDialogWithEncoding%",
"category": "Zowe Explorer"
},
{
"command": "zowe.uss.downloadFile",
"title": "%uss.downloadFile%",
"category": "Zowe Explorer"
},
{
"command": "zowe.uss.downloadDirectory",
"title": "%uss.downloadDirectory%",
"category": "Zowe Explorer"
},
{
"command": "zowe.uss.copyUssFile",
"title": "%copyFile%",
Expand Down Expand Up @@ -994,10 +1019,20 @@
"command": "zowe.uss.renameNode",
"group": "099_zowe_ussModification:@3"
},
{
"when": "view == zowe.uss.explorer && viewItem =~ /^textFile|binaryFile/ && !listMultiSelection",
"command": "zowe.uss.downloadFile",
"group": "099_zowe_ussModification:@5"
},
{
"when": "view == zowe.uss.explorer && viewItem =~ /^directory.*/ && !listMultiSelection",
"command": "zowe.uss.downloadDirectory",
"group": "099_zowe_ussModification:@5"
},
{
"when": "view == zowe.uss.explorer && viewItem =~ /^(?!(ussSession|favorite|.*_fav))/",
"command": "zowe.uss.deleteNode",
"group": "099_zowe_ussModification:@4"
"group": "099_zowe_ussModification:@7"
},
{
"when": "view == zowe.uss.explorer && viewItem =~ /^(?!.*_fav.*)ussSession.*/ && !listMultiSelection",
Expand Down Expand Up @@ -1229,6 +1264,21 @@
"command": "zowe.ds.renameDataSet",
"group": "099_zowe_dsModification@2"
},
{
"when": "view == zowe.ds.explorer && viewItem =~ /^ds.*/ && !listMultiSelection",
"command": "zowe.ds.downloadDataSet",
"group": "099_zowe_dsModification@3"
},
{
"when": "view == zowe.ds.explorer && viewItem =~ /^pds.*/ && !listMultiSelection",
"command": "zowe.ds.downloadAllMembers",
"group": "099_zowe_dsModification@3"
},
{
"when": "view == zowe.ds.explorer && viewItem =~ /^member.*/ && !listMultiSelection",
"command": "zowe.ds.downloadMember",
"group": "099_zowe_dsModification@3"
},
{
"when": "view == zowe.ds.explorer && viewItem =~ /^ds.*/",
"command": "zowe.ds.deleteDataset",
Expand Down Expand Up @@ -1602,6 +1652,14 @@
"command": "zowe.uss.uploadDialog",
"when": "never"
},
{
"command": "zowe.uss.downloadFile",
"when": "never"
},
{
"command": "zowe.uss.downloadDirectory",
"when": "never"
},
{
"command": "zowe.uss.copyUssFile",
"when": "never"
Expand Down Expand Up @@ -1714,6 +1772,18 @@
"command": "zowe.ds.sortBy",
"when": "never"
},
{
"command": "zowe.ds.downloadDataSet",
"when": "never"
},
{
"command": "zowe.ds.downloadAllMembers",
"when": "never"
},
{
"command": "zowe.ds.downloadMember",
"when": "never"
},
{
"command": "zowe.jobs.startPolling",
"when": "never"
Expand Down Expand Up @@ -2297,4 +2367,4 @@
}
}
}
}
}
7 changes: 6 additions & 1 deletion packages/zowe-explorer/package.nls.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@
"uss.uploadDialog": "Upload Files...",
"uss.uploadDialogBinary": "Upload Files (Binary)...",
"uss.uploadDialogWithEncoding": "Upload Files with Encoding...",
"uss.downloadFile": "Download File...",
"uss.downloadDirectory": "Download Directory...",
"uss.text": "Toggle Text",
"uss.filterBy": "Search by Directory",
"uss.cd": "Go Up One Level",
Expand Down Expand Up @@ -171,6 +173,9 @@
"jobs.filterBy": "Filter Jobs...",
"ds.filterBy": "Filter PDS Members...",
"ds.sortBy": "Sort PDS Members...",
"downloadDataSet": "Download Data Set...",
"downloadAllMembers": "Download All Members...",
"downloadMember": "Download Member...",
"issueUnixCmd": "Issue Unix Command",
"selectForCompare": "Select for Compare",
"copyName": "Copy Name",
Expand All @@ -187,4 +192,4 @@
"zowe.settings.displayReleaseNotes": "Should display the Zowe Explorer release notes after an update.",
"zowe.table.maxPinnedRows": "Maximum number of rows that can be pinned to the top of table views.",
"zowe.table.hidePinnedRowsWarning": "Hide the warning message when pinning many rows to table views."
}
}
3 changes: 2 additions & 1 deletion packages/zowe-explorer/src/configuration/Constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { imperative, PersistenceSchemaEnum } from "@zowe/zowe-explorer-api";
import type { Profiles } from "./Profiles";

export class Constants {
public static readonly COMMAND_COUNT = 122;
public static readonly COMMAND_COUNT = 126;
public static readonly MAX_SEARCH_HISTORY = 5;
public static readonly MAX_FILE_HISTORY = 10;
public static readonly MAX_DISPLAYED_DELETE_NAMES = 10;
Expand All @@ -25,6 +25,7 @@ export class Constants {
public static readonly STATUS_BAR_TIMEOUT_MS = 5000;
public static readonly ACTIVE_JOBS_POLLING_TIMEOUT_MS = 1000;
public static readonly MIN_WARN_ACTIVE_JOBS_TO_POLL = 10;
public static readonly MIN_WARN_DOWNLOAD_FILES = 100;
public static readonly CONTEXT_PREFIX = "_";
public static readonly FAV_SUFFIX = Constants.CONTEXT_PREFIX + "fav";
public static readonly HOME_SUFFIX = Constants.CONTEXT_PREFIX + "home";
Expand Down
18 changes: 18 additions & 0 deletions packages/zowe-explorer/src/configuration/Definitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,22 @@ export namespace Definitions {
caseSensitive?: boolean;
regex?: boolean;
};
export type DataSetDownloadOptions = {
overwrite?: boolean;
generateDirectory?: boolean;
preserveCase?: boolean;
binary?: boolean;
record?: boolean;
selectedPath?: vscode.Uri;
};
export type UssDownloadOptions = {
overwrite?: boolean;
generateDirectory?: boolean;
includeHidden?: boolean;
chooseEncoding?: boolean;
encoding?: ZosEncoding;
selectedPath?: vscode.Uri;
};
export type FavoriteData = {
profileName: string;
label: string;
Expand Down Expand Up @@ -157,5 +173,7 @@ export namespace Definitions {
V1_MIGRATION_STATUS = "zowe.v1MigrationStatus",
DS_SEARCH_OPTIONS = "zowe.dsSearchOptions",
DISPLAY_RELEASE_NOTES_VERSION = "zowe.displayReleaseNotes",
DS_DOWNLOAD_OPTIONS = "zowe.dsDownloadOptions",
USS_DOWNLOAD_OPTIONS = "zowe.ussDownloadOptions",
}
}
2 changes: 2 additions & 0 deletions packages/zowe-explorer/src/tools/ZoweLocalStorage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ export class LocalStorageAccess extends ZoweLocalStorage {
[Definitions.LocalStorageKey.ENCODING_HISTORY]: StorageAccessLevel.Read | StorageAccessLevel.Write,
[Definitions.LocalStorageKey.DS_SEARCH_OPTIONS]: StorageAccessLevel.Read | StorageAccessLevel.Write,
[Definitions.LocalStorageKey.DISPLAY_RELEASE_NOTES_VERSION]: StorageAccessLevel.Read | StorageAccessLevel.Write,
[Definitions.LocalStorageKey.DS_DOWNLOAD_OPTIONS]: StorageAccessLevel.Read | StorageAccessLevel.Write,
[Definitions.LocalStorageKey.USS_DOWNLOAD_OPTIONS]: StorageAccessLevel.Read | StorageAccessLevel.Write,
[PersistenceSchemaEnum.Dataset]: StorageAccessLevel.Read | StorageAccessLevel.Write,
[PersistenceSchemaEnum.USS]: StorageAccessLevel.Read | StorageAccessLevel.Write,
[PersistenceSchemaEnum.Job]: StorageAccessLevel.Read | StorageAccessLevel.Write,
Expand Down
Loading
Loading