forked from LeetCode-OpenSource/vscode-leetcode
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathleetCodeExecutor.ts
140 lines (119 loc) · 6.23 KB
/
leetCodeExecutor.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
// Copyright (c) jdneo. All rights reserved.
// Licensed under the MIT license.
import * as cp from "child_process";
import * as fse from "fs-extra";
import * as path from "path";
import * as requireFromString from "require-from-string";
import * as vscode from "vscode";
import { Endpoint } from "./shared";
import { executeCommand, executeCommandWithProgress } from "./utils/cpUtils";
import { DialogOptions, openUrl } from "./utils/uiUtils";
import * as wsl from "./utils/wslUtils";
class LeetCodeExecutor {
private leetCodeRootPath: string;
private leetCodeRootPathInWsl: string;
constructor() {
this.leetCodeRootPath = path.join(__dirname, "..", "..", "node_modules", "leetcode-cli");
this.leetCodeRootPathInWsl = "";
}
public async getLeetCodeRootPath(): Promise<string> { // not wrapped by ""
if (wsl.useWsl()) {
if (!this.leetCodeRootPathInWsl) {
this.leetCodeRootPathInWsl = `${await wsl.toWslPath(this.leetCodeRootPath)}`;
}
return `${this.leetCodeRootPathInWsl}`;
}
return `${this.leetCodeRootPath}`;
}
public async getLeetCodeBinaryPath(): Promise<string> { // wrapped by ""
return `"${path.join(await this.getLeetCodeRootPath(), "bin", "leetcode")}"`;
}
public async meetRequirements(): Promise<boolean> {
try {
await this.executeCommandEx("node", ["-v"]);
} catch (error) {
const choice: vscode.MessageItem | undefined = await vscode.window.showErrorMessage(
"LeetCode extension needs Node.js installed in environment path",
DialogOptions.open,
);
if (choice === DialogOptions.open) {
openUrl("https://nodejs.org");
}
return false;
}
try { // Check company plugin
await this.executeCommandEx("node", [await this.getLeetCodeBinaryPath(), "plugin", "-e", "company"]);
} catch (error) { // Download company plugin and activate
await this.executeCommandEx("node", [await this.getLeetCodeBinaryPath(), "plugin", "-i", "company"]);
}
return true;
}
public async deleteCache(): Promise<string> {
return await this.executeCommandEx("node", [await this.getLeetCodeBinaryPath(), "cache", "-d"]);
}
public async getUserInfo(): Promise<string> {
return await this.executeCommandEx("node", [await this.getLeetCodeBinaryPath(), "user"]);
}
public async signOut(): Promise<string> {
return await await this.executeCommandEx("node", [await this.getLeetCodeBinaryPath(), "user", "-L"]);
}
public async listProblems(showLocked: boolean): Promise<string> {
return await this.executeCommandEx("node", showLocked ?
[await this.getLeetCodeBinaryPath(), "list"] :
[await this.getLeetCodeBinaryPath(), "list", "-q", "L"],
);
}
public async showProblem(id: string, language: string, outDir: string): Promise<string> {
return await this.executeCommandWithProgressEx("Fetching problem data...", "node", [await this.getLeetCodeBinaryPath(), "show", id, "-gx", "-l", language, "-o", `"${outDir}"`]);
}
public async listSessions(): Promise<string> {
return await this.executeCommandEx("node", [await this.getLeetCodeBinaryPath(), "session"]);
}
public async enableSession(name: string): Promise<string> {
return await this.executeCommandEx("node", [await this.getLeetCodeBinaryPath(), "session", "-e", name]);
}
public async createSession(name: string): Promise<string> {
return await this.executeCommandEx("node", [await this.getLeetCodeBinaryPath(), "session", "-c", name]);
}
public async submitSolution(filePath: string): Promise<string> {
return await this.executeCommandWithProgressEx("Submitting to LeetCode...", "node", [await this.getLeetCodeBinaryPath(), "submit", `"${filePath}"`]);
}
public async testSolution(filePath: string, testString?: string): Promise<string> {
if (testString) {
return await this.executeCommandWithProgressEx("Submitting to LeetCode...", "node", [await this.getLeetCodeBinaryPath(), "test", `"${filePath}"`, "-t", `${testString}`]);
}
return await this.executeCommandWithProgressEx("Submitting to LeetCode...", "node", [await this.getLeetCodeBinaryPath(), "test", `"${filePath}"`]);
}
public async switchEndpoint(endpoint: string): Promise<string> {
switch (endpoint) {
case Endpoint.LeetCodeCN:
return await this.executeCommandEx("node", [await this.getLeetCodeBinaryPath(), "plugin", "-e", "leetcode.cn"]);
case Endpoint.LeetCode:
default:
return await this.executeCommandEx("node", [await this.getLeetCodeBinaryPath(), "plugin", "-d", "leetcode.cn"]);
}
}
public async getCompaniesAndTags(): Promise<{ companies: { [key: string]: string[] }, tags: { [key: string]: string[] } }> {
// preprocess the plugin source
const companiesTagsPath: string = path.join(await leetCodeExecutor.getLeetCodeRootPath(), "lib", "plugins", "company.js");
const companiesTagsSrc: string = (await fse.readFile(companiesTagsPath, "utf8")).replace(
"module.exports = plugin",
"module.exports = { COMPONIES, TAGS }",
);
const { COMPONIES, TAGS } = requireFromString(companiesTagsSrc, companiesTagsPath);
return { companies: COMPONIES, tags: TAGS };
}
private async executeCommandEx(command: string, args: string[], options: cp.SpawnOptions = { shell: true }): Promise<string> {
if (wsl.useWsl()) {
return await executeCommand("wsl", [command].concat(args), options);
}
return await executeCommand(command, args, options);
}
private async executeCommandWithProgressEx(message: string, command: string, args: string[], options: cp.SpawnOptions = { shell: true }): Promise<string> {
if (wsl.useWsl()) {
return await executeCommandWithProgress(message, "wsl", [command].concat(args), options);
}
return await executeCommandWithProgress(message, command, args, options);
}
}
export const leetCodeExecutor: LeetCodeExecutor = new LeetCodeExecutor();