Skip to content

Commit 7d3a068

Browse files
sergiuilietemanbrcom
authored andcommitted
feat: Retrieve local copybooks if exists eclipse-che4zGH-327
1 parent 09b8016 commit 7d3a068

File tree

7 files changed

+256
-20
lines changed

7 files changed

+256
-20
lines changed

clients/cobol-lsp-vscode-extension/package.json

+8
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,14 @@
5555
{
5656
"command": "broadcom-cobol-lsp.cpy-manager.resolve-local-copybooks",
5757
"title": "Resolve Local Copybooks"
58+
},
59+
{
60+
"command": "broadcom-cobol-lsp.cpy-manager.resolve-git-copybooks",
61+
"title": "Resolve Local 2"
62+
},
63+
{
64+
"command": "broadcom-cobol-lsp.cpy-manager.resolve-git-copybooks-2",
65+
"title": "Get local copybooks"
5866
}
5967
],
6068
"languages": [

clients/cobol-lsp-vscode-extension/src/__tests__/LocalCopybookResolverTest.ts

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import * as path from "path";
1717
import {PATHS_LOCAL_KEY, SETTINGS_SECTION } from "../constants";
1818
import {LocalCopybookResolver} from "../services/settings/LocalCopybookResolver";
1919
import {SettingsUtils} from "../services/settings/util/SettingsUtils";
20+
import { URL } from "url";
2021

2122
const settingsParser: LocalCopybookResolver = new LocalCopybookResolver();
2223
const STAR_LOCATION = "*";
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/*
2+
* Copyright (c) 2020 Broadcom.
3+
* The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
4+
*
5+
* This program and the accompanying materials are made
6+
* available under the terms of the Eclipse Public License 2.0
7+
* which is available at https://www.eclipse.org/legal/epl-2.0/
8+
*
9+
* SPDX-License-Identifier: EPL-2.0
10+
*
11+
* Contributors:
12+
* Broadcom, Inc. - initial API and implementation
13+
*/
14+
15+
import * as fs from "fs";
16+
import * as path from "path";
17+
import { Prioritizer } from "../services/Prioritizer";
18+
import { SettingsUtils } from "../services/settings/util/SettingsUtils";
19+
20+
const prioritizer: Prioritizer = new Prioritizer();
21+
const FILENAME1: string = "test.cpy";
22+
const FILENAME2: string = "mama.cpy";
23+
const FILENAME3: string = "tata";
24+
let FILENAME_URI1: string = "";
25+
let FILENAME_URI2: string = "";
26+
let FILENAME_URI3: string = "";
27+
28+
beforeAll(() => {
29+
FILENAME_URI1 = createFile(FILENAME1);
30+
FILENAME_URI2 = createFile(FILENAME2);
31+
FILENAME_URI3 = createFile(FILENAME3);
32+
SettingsUtils.getWorkspacesURI = jest.fn().mockReturnValue(["file://"]);
33+
});
34+
35+
afterAll(() => {
36+
return deleteTempFile([FILENAME_URI1, FILENAME_URI2, FILENAME_URI3]);
37+
});
38+
39+
describe("ConfigurationSwitcher tests", () => {
40+
test("check if copybooks are present local", () => {
41+
prioritizer.checkCopybooksPresentLocal([FILENAME1, FILENAME2], [FILENAME_URI1, FILENAME_URI2, "./src"]);
42+
expect(prioritizer.getLocalCpyURI().length).toBe(2);
43+
});
44+
45+
test("copybook is found even without extension", () => {
46+
prioritizer.checkCopybooksPresentLocal([FILENAME3], [FILENAME_URI3]);
47+
expect(prioritizer.getLocalCpyURI().length).toBe(1);
48+
});
49+
});
50+
51+
describe("Negative scenario test", () => {
52+
test("Path is not provided and method should return empty list", () => {
53+
prioritizer.checkCopybooksPresentLocal([FILENAME1], []);
54+
expect(prioritizer.getLocalCpyURI().length).toBe(0);
55+
});
56+
});
57+
58+
function createFile(filename: string): string {
59+
fs.writeFile(path.join(__dirname, filename), "Some dummy content", err => {
60+
if (err) {
61+
return null;
62+
}
63+
});
64+
return path.resolve(__dirname, filename);
65+
}
66+
67+
function deleteTempFile(filenames: string[]) {
68+
filenames.forEach(filename => {
69+
const filePath: string = path.resolve(filename);
70+
if (fs.existsSync(filePath)) {
71+
fs.unlinkSync(filePath);
72+
}
73+
});
74+
}

clients/cobol-lsp-vscode-extension/src/extension.ts

+16-3
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import { changeDefaultZoweProfile } from "./commands/ChangeDefaultZoweProfile";
1717
import { editDatasetPaths } from "./commands/EditDatasetPaths";
1818
import { fetchCopybookCommand } from "./commands/FetchCopybookCommand";
1919
import { DEPENDENCIES_FOLDER, REASON_MSG } from "./constants";
20-
import { LANGUAGE_ID, SETTINGS_SECTION } from "./constants";
20+
import { LANGUAGE_ID, SETTINGS_SECTION, PATHS_LOCAL_KEY } from "./constants";
2121
import { CopybookFix } from "./services/CopybookFix";
2222
import { CopybooksCodeActionProvider } from "./services/CopybooksCodeActionProvider";
2323
import { CopybooksDownloader } from "./services/CopybooksDownloader";
@@ -31,16 +31,18 @@ import { ProfileService } from "./services/ProfileService";
3131
import {CopybookResolver} from "./services/settings/CopybookResolver";
3232
import {LocalCopybookResolver} from "./services/settings/LocalCopybookResolver";
3333
import { ZoweApi } from "./services/ZoweApi";
34+
import { Prioritizer } from "./services/Prioritizer";
3435

3536
export async function activate(context: vscode.ExtensionContext) {
3637
initializeSettings();
3738

3839
const zoweApi: ZoweApi = new ZoweApi();
3940
const profileService: ProfileService = new ProfileService(zoweApi);
4041
const copybookFix: CopybookFix = new CopybookFix();
42+
const prioritizer: Prioritizer = new Prioritizer();
4143
const copybooksPathGenerator: CopybooksPathGenerator = new CopybooksPathGenerator(profileService);
42-
const copyBooksDownloader: CopybooksDownloader = new CopybooksDownloader(copybookFix, zoweApi, profileService, copybooksPathGenerator);
43-
const languageClientService: LanguageClientService = new LanguageClientService(copybooksPathGenerator);
44+
const copyBooksDownloader: CopybooksDownloader = new CopybooksDownloader(copybookFix, zoweApi, profileService, copybooksPathGenerator, prioritizer);
45+
const languageClientService: LanguageClientService = new LanguageClientService(copybooksPathGenerator, prioritizer);
4446
const pathsService: PathsService = new PathsService();
4547
const copybookResolver: CopybookResolver = new LocalCopybookResolver();
4648

@@ -81,6 +83,17 @@ export async function activate(context: vscode.ExtensionContext) {
8183
resolveLocalCopybooks(copybookResolver);
8284
}));
8385

86+
//to be deleted after implementation
87+
context.subscriptions.push
88+
(vscode.commands.registerCommand("broadcom-cobol-lsp.cpy-manager.resolve-git-copybooks", () => {
89+
prioritizer.checkCopybooksPresentLocal(["DEMO1", "DEMO2"],
90+
vscode.workspace.getConfiguration(SETTINGS_SECTION).get(PATHS_LOCAL_KEY));
91+
}));
92+
93+
context.subscriptions.push
94+
(vscode.commands.registerCommand("broadcom-cobol-lsp.cpy-manager.resolve-git-copybooks-2", () => {
95+
vscode.window.showInformationMessage("My message: " + prioritizer.getLocalCpyURI());
96+
}));
8497

8598
context.subscriptions.push(languageClientService.start());
8699
context.subscriptions.push(initWorkspaceTracker(copyBooksDownloader));

clients/cobol-lsp-vscode-extension/src/services/CopybooksDownloader.ts

+63-14
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,12 @@
1414

1515
import * as fs from "fs";
1616
import * as vscode from "vscode";
17-
import { loadDepFile, DependenciesDesc } from "./DependencyService";
18-
import { DEPENDENCIES_FOLDER, PROCESS_DOWNLOAD_ERROR_MSG } from "../constants";
19-
import { CopybookFix } from "./CopybookFix";
17+
import { DEPENDENCIES_FOLDER, PROCESS_DOWNLOAD_ERROR_MSG, SETTINGS_SECTION, PATHS_LOCAL_KEY } from "../constants";
2018
import { CopybooksPathGenerator, createDatasetPath, createCopybookPath, checkWorkspace } from "./CopybooksPathGenerator";
19+
import { Prioritizer } from "./Prioritizer";
20+
import { CopybookFix } from "./CopybookFix";
2121
import { CopybookProfile, DownloadQueue } from "./DownloadQueue";
22+
import { loadDepFile, DependenciesDesc } from "./DependencyService";
2223
import { ProfileService } from "./ProfileService";
2324
import { ZoweApi } from "./ZoweApi";
2425

@@ -29,7 +30,8 @@ export class CopybooksDownloader implements vscode.Disposable {
2930
private resolver: CopybookFix,
3031
private zoweApi: ZoweApi,
3132
private profileService: ProfileService,
32-
private pathGenerator: CopybooksPathGenerator) { }
33+
private pathGenerator: CopybooksPathGenerator,
34+
private prioritizer: Prioritizer) { }
3335

3436
public async redownloadDependencies(message: string = "Redownload dependencies requested.") {
3537
(await vscode.workspace.findFiles(DEPENDENCIES_FOLDER + "/**/*.dep")).forEach(dep => {
@@ -39,9 +41,9 @@ export class CopybooksDownloader implements vscode.Disposable {
3941

4042
/**
4143
* @param copybooks array of copybooks names to download
44+
* @param programName analyzed COBOL file
4245
*/
4346
async downloadCopybooks(copybooks: string[], programName: string): Promise<void> {
44-
// TODO do it right
4547
const profile: string = await this.profileService.getProfile(programName);
4648
if (!profile) {
4749
return;
@@ -54,22 +56,25 @@ export class CopybooksDownloader implements vscode.Disposable {
5456
return;
5557
}
5658
const depDesc: DependenciesDesc = loadDepFile(depFileUri);
59+
60+
// TODO: REMOVE PROFILE OR ADD IT AFTER LOCAL CHECK
5761
const profile: string = await this.profileService.getProfile(depDesc.programName);
5862
if (!profile) {
5963
return;
6064
}
6165

62-
const missingCopybooks: string[] = await this.listMissingCopybooks(depDesc.copybooks, profile);
66+
this.prioritizer.checkCopybooksPresentLocal(depDesc.copybooks,
67+
vscode.workspace.getConfiguration(SETTINGS_SECTION).get(PATHS_LOCAL_KEY));
68+
const notLocalCpy: string[] = this.prioritizer.getNotLocalCpy();
69+
const localCpyExists: boolean = this.prioritizer.getLocalCpyURI().length > 0;
6370

64-
if (!message.length) {
65-
missingCopybooks.forEach(copybook => this.queue.push(copybook, profile));
66-
} else if (missingCopybooks.length > 0) {
67-
this.resolver.fixMissingDownloads(message, missingCopybooks, profile, {
68-
hasPaths: (await this.pathGenerator.listDatasets()).length > 0,
69-
hasProfiles: Object.keys(await this.profileService.listProfiles()).length > 1,
70-
});
71+
// message to be displayed should be adjusted according to the requirments
72+
if (localCpyExists) {
73+
// we can use the logic from continueDownloadFromMF in order to ask user if would like to use Zowe or no - TBD
74+
this.notifyUserIfCopyNotLocal("Some copybooks are not present locally", notLocalCpy.length > 0);
75+
} else {
76+
this.continueDownloadFromMF(notLocalCpy, depDesc.programName, message);
7177
}
72-
7378
}
7479

7580
public async start() {
@@ -121,6 +126,50 @@ export class CopybooksDownloader implements vscode.Disposable {
121126
this.queue.stop();
122127
}
123128

129+
/**
130+
* This method pushes missingCopybooks into the queue to be downloaded from MF
131+
* @param message message to be displayed
132+
* @param missingCopybooks copybooks which are not presented locally
133+
* @param profile Zowe connection profile
134+
*/
135+
private async resolveMissingCopybooksFromMF(message: string, missingCopybooks: string[], profile: string) {
136+
if (!message.length) {
137+
missingCopybooks.forEach(copybook => this.queue.push(copybook, profile));
138+
} else if (missingCopybooks.length > 0) {
139+
this.resolver.fixMissingDownloads(message, missingCopybooks, profile, {
140+
hasPaths: (await this.pathGenerator.listDatasets()).length > 0,
141+
hasProfiles: Object.keys(await this.profileService.listProfiles()).length > 1,
142+
});
143+
}
144+
}
145+
146+
/**
147+
* @param title message to be displayed
148+
* @param cpyNotLocal check if there are any copybooks unresolved locally
149+
*/
150+
private notifyUserIfCopyNotLocal(title: string, cpyNotLocal: boolean) {
151+
if (cpyNotLocal) { vscode.window.showErrorMessage(title); }
152+
}
153+
154+
/**
155+
* This method is implemented in order to create a smooth transition from local analyze to MF download
156+
* @param notLocalCpy copybooks not present in local workspace
157+
* @param programName analyzed COBOL file
158+
* @param message message to be displayed
159+
*/
160+
private async continueDownloadFromMF(notLocalCpy: string[], programName: string, message: string) {
161+
const action = await vscode.window.showErrorMessage("Do you wanna use Zowe?",
162+
"Yes", "Never");
163+
if (action === "Yes") {
164+
const profile: string = await this.profileService.getProfile(programName);
165+
if (!profile) {
166+
return;
167+
}
168+
const missingCopybooks: string[] = await this.listMissingCopybooks(notLocalCpy, profile);
169+
this.resolveMissingCopybooksFromMF(message, missingCopybooks, profile);
170+
}
171+
}
172+
124173
private async fetchCopybook(dataset: string, copybookProfile: CopybookProfile): Promise<boolean> {
125174
let members: string[] = [];
126175
try {

clients/cobol-lsp-vscode-extension/src/services/LanguageClientService.ts

+27-3
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,17 @@
1515
import * as fs from "fs";
1616
import * as net from "net";
1717
import * as vscode from "vscode";
18-
import { LANGUAGE_ID } from "../constants";
19-
import {CancellationToken, ConfigurationParams, ConfigurationRequest, LanguageClient, LanguageClientOptions, StreamInfo} from "vscode-languageclient";
18+
import { LANGUAGE_ID, PATHS_ZOWE, SETTINGS_SECTION } from "../constants";
19+
import { CancellationToken, ConfigurationParams, ConfigurationRequest, LanguageClient, LanguageClientOptions, StreamInfo} from "vscode-languageclient";
2020
import { ConfigurationWorkspaceMiddleware } from "vscode-languageclient/lib/configuration";
2121
import { CopybooksPathGenerator } from "./CopybooksPathGenerator";
2222
import { JavaCheck } from "./JavaCheck";
23+
import { Prioritizer } from "./Prioritizer";
2324

2425
export class LanguageClientService {
2526
private jarPath: string;
2627

27-
constructor(private copybooksPathGenerator: CopybooksPathGenerator) {
28+
constructor(private copybooksPathGenerator: CopybooksPathGenerator, private prioritizer: Prioritizer) {
2829
const ext = vscode.extensions.getExtension("BroadcomMFD.cobol-language-support");
2930
this.jarPath = `${ext.extensionPath}/server/lsp-service-cobol-${ext.packageJSON.version}.jar`;
3031
}
@@ -53,6 +54,24 @@ export class LanguageClientService {
5354
next: ConfigurationRequest.HandlerSignature) => {
5455

5556
// TODO if request params are right
57+
58+
// TODO after server modification this method return the local copybooks URI
59+
/*
60+
there should be logic here to check if user complete the zowe settings, than add
61+
calculated path to response object
62+
use checkMFSettings and this.copybooksPathGenerator.listUris()
63+
*/
64+
65+
/**
66+
* TODO
67+
* at initialize moment, check if there is a dependency file created for the open COBOL
68+
* file, if not send empty array, if yes call prioritizer.checkCopybooksPresentLocal
69+
* If the dependency file is not present at the initialize moment, the server after analyzing
70+
* the open file has to ask for settings in order to resolve the local copybooks
71+
*/
72+
73+
console.log(this.prioritizer.getLocalCpyURI());
74+
5675
return (await this.copybooksPathGenerator.listUris()).map(uri => uri.toString());
5776
// TODO else return next(params, token);
5877
};
@@ -65,6 +84,11 @@ export class LanguageClientService {
6584
middleware: { workspace: configurationMiddleware }
6685
};
6786
}
87+
88+
private checkMFSettings(): boolean {
89+
return vscode.workspace.getConfiguration(SETTINGS_SECTION).has(PATHS_ZOWE);
90+
}
91+
6892
private createServerOptions(jarPath: string) {
6993
const port = this.getLspPort();
7094
if (port) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
* Copyright (c) 2020 Broadcom.
3+
* The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
4+
*
5+
* This program and the accompanying materials are made
6+
* available under the terms of the Eclipse Public License 2.0
7+
* which is available at https://www.eclipse.org/legal/epl-2.0/
8+
*
9+
* SPDX-License-Identifier: EPL-2.0
10+
*
11+
* Contributors:
12+
* Broadcom, Inc. - initial API and implementation
13+
*/
14+
15+
import * as fs from "fs";
16+
import {URL} from "url";
17+
import {LocalCopybookResolver} from "./settings/LocalCopybookResolver";
18+
19+
export class Prioritizer {
20+
private settingsParser: LocalCopybookResolver = new LocalCopybookResolver();
21+
private localCpyURI: string[];
22+
private notLocalCpy: string[];
23+
24+
public setLocalCpyURI(localCpy: string[]) {
25+
this.localCpyURI = localCpy;
26+
}
27+
28+
public getLocalCpyURI(): string[] {
29+
return this.localCpyURI;
30+
}
31+
32+
public setNotLocalCpy(notLocalCpy: string[]) {
33+
this.notLocalCpy = notLocalCpy;
34+
}
35+
36+
public getNotLocalCpy(): string[] {
37+
return this.notLocalCpy;
38+
}
39+
40+
public checkCopybooksPresentLocal(copybooks: string[], listUri: string[]) {
41+
const resolvedUri: string[] = this.settingsParser.resolve(listUri);
42+
const copybooksPath: string[] = [];
43+
const notLocal: string[] = [];
44+
copybooks.forEach(copybook => {
45+
const copybookPath: string = this.copybookInLocal(copybook, resolvedUri);
46+
if (copybookPath) {
47+
copybooksPath.push(copybookPath);
48+
} else {
49+
notLocal.push(copybook);
50+
}
51+
});
52+
this.setNotLocalCpy(notLocal);
53+
this.setLocalCpyURI(copybooksPath);
54+
}
55+
56+
private copybookInLocal(copybook: string, resolvedUri: string[]): string {
57+
let finalUri: URL;
58+
resolvedUri.forEach(uri => {
59+
let url = new URL(uri);
60+
if (uri.includes(copybook) && fs.existsSync(url)) {
61+
finalUri = url;
62+
}
63+
});
64+
return finalUri ? finalUri.href : null;
65+
}
66+
67+
}

0 commit comments

Comments
 (0)