Skip to content

Commit 19de12e

Browse files
authored
Merge pull request #158 from codefori/feature/local_server_component
Feature/local server component
2 parents 03b7f85 + 5988114 commit 19de12e

File tree

7 files changed

+108
-76
lines changed

7 files changed

+108
-76
lines changed

.vscodeignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,6 @@ vsc-extension-quickstart.md
1010
media/main.png
1111
node_modules
1212
src
13-
types
13+
types
14+
.github
15+
src/dsc.ts

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,5 @@ As of 0.3.0, the Db2 for i extension requires a server component. The component
2424
1. This project requires VS Code and Node.js.
2525
2. fork & clone repo
2626
3. `npm i`
27+
4. `npm run dsc` (to fetch the Server Component)
2728
4. 'Run Extension' from vscode debug.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -561,8 +561,9 @@
561561
"lint": "eslint .",
562562
"pretest": "npm run lint",
563563
"language:test": "vitest",
564+
"dsc": "mkdir -p dist && npx tsx src/dsc",
564565
"package": "vsce package",
565-
"vscode:prepublish": "webpack --mode production",
566+
"vscode:prepublish": "rm -rf dist && webpack --mode production && npm run dsc",
566567
"webpack": "webpack --mode development",
567568
"webpack-dev": "webpack --mode development --watch",
568569
"typings": "npx -p typescript tsc ./src/extension.ts --declaration --allowJs --emitDeclarationOnly --outDir types --esModuleInterop -t es2019 --moduleResolution node"

src/connection/SCVersion.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
2+
export const SERVER_VERSION_TAG = `v1.2.0`;
3+
export const SERVER_VERSION_FILE = `codeforiserver-1.2.0.jar`;

src/connection/serverComponent.ts

Lines changed: 45 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,13 @@
11
import { getInstance } from "../base";
22

33
import { Octokit } from "octokit";
4-
import fetch from 'node-fetch';
54

65
import { Config } from "../config";
76
import path from "path";
8-
import { OutputChannel, commands, window } from "vscode";
7+
import { OutputChannel, extensions, window } from "vscode";
98

10-
import { writeFile, unlink } from "fs/promises";
11-
import os from "os";
12-
13-
const octokit = new Octokit();
14-
15-
// During development, you can set the SERVER_VERSION in .vscode/launch.json
16-
// Otherwise, fall back to the working version
17-
const SERVER_VERSION = process.env[`SERVER_VERSION`] || `v1.2.0`;
9+
import { stat } from "fs/promises";
10+
import { SERVER_VERSION_FILE } from "./SCVersion";
1811

1912
const ExecutablePathDir = `$HOME/.vscode/`;
2013

@@ -90,79 +83,54 @@ export class ServerComponent {
9083
*/
9184
public static async checkForUpdate(): Promise<UpdateStatus> {
9285
let updateResult: UpdateStatus = UpdateStatus.NONE_AVAILABLE;
86+
87+
const extensionPath = extensions.getExtension(`halcyontechltd.vscode-db2i`).extensionPath;
9388
const instance = getInstance();
9489
const connection = instance.getConnection();
9590

96-
const owner = `ThePrez`;
97-
const repo = `CodeForIBMiServer`;
98-
9991
try {
100-
const result = await octokit.request(`GET /repos/{owner}/{repo}/releases/tags/${SERVER_VERSION}`, {
101-
owner,
102-
repo,
103-
headers: {
104-
'X-GitHub-Api-Version': '2022-11-28'
105-
}
106-
});
92+
const assetPath = path.join(extensionPath, `dist`, SERVER_VERSION_FILE);
93+
const assetExists = await exists(assetPath);
10794

108-
ServerComponent.writeOutput(JSON.stringify(result));
95+
ServerComponent.writeOutput(JSON.stringify({assetPath, assetExists}));
10996

110-
const newAsset = result.data.assets.find(asset => asset.name.endsWith(`.jar`));
111-
112-
if (newAsset) {
113-
const url = newAsset.browser_download_url;
114-
const basename = newAsset.name;
97+
if (assetExists) {
98+
const basename = SERVER_VERSION_FILE;
11599
const lastInstalledName = Config.getServerComponentName();
116100

117-
if (lastInstalledName !== basename || this.installed === false) {
118-
const updateQuestion = await window.showInformationMessage(
119-
`Database Extension update required`,
120-
{
121-
modal: true,
122-
detail: `An update to the database server component is required: ${basename}`
123-
},
124-
`Update`
125-
);
126-
127-
if (updateQuestion === `Update`) {
128-
// This means we're currently running a different version,
129-
// or maybe not at all (currentlyInstalled can be undefined)
130-
131-
// First, we need their home directory
132-
const commandResult = await connection.sendCommand({
133-
command: `echo ${ExecutablePathDir}`
134-
});
135-
136-
if (commandResult.code === 0 && commandResult.stderr === ``) {
137-
const remotePath = path.posix.join(commandResult.stdout, basename)
101+
ServerComponent.writeOutput(JSON.stringify({basename, lastInstalledName}));
138102

139-
const tempFile = path.join(os.tmpdir(), basename);
103+
if (lastInstalledName !== basename || this.installed === false) {
104+
// This means we're currently running a different version,
105+
// or maybe not at all (currentlyInstalled can be undefined)
140106

141-
await downloadFile(url, tempFile);
107+
// First, we need their home directory
108+
const commandResult = await connection.sendCommand({
109+
command: `echo ${ExecutablePathDir}`
110+
});
142111

143-
await connection.uploadFiles([{local: tempFile, remote: remotePath}]);
112+
if (commandResult.code === 0 && commandResult.stderr === ``) {
113+
const remotePath = path.posix.join(commandResult.stdout, basename);
144114

145-
// Clean up the temp file
146-
unlink(tempFile);
115+
ServerComponent.writeOutput(JSON.stringify({remotePath, ExecutablePathDir}));
147116

148-
await Config.setServerComponentName(basename);
117+
await connection.uploadFiles([{local: assetPath, remote: remotePath}]);
149118

150-
window.showInformationMessage(`Db2 for IBM i extension server component has been updated!`);
151-
this.installed = true;
152-
updateResult = UpdateStatus.JUST_UPDATED;
153-
154-
} else {
155-
updateResult = UpdateStatus.FAILED;
119+
await Config.setServerComponentName(basename);
156120

157-
this.writeOutput(JSON.stringify(commandResult));
158-
window.showErrorMessage(`Something went really wrong when trying to fetch your home directory.`).then(chosen => {
159-
if (chosen === `Show`) {
160-
this.outputChannel.show();
161-
}
162-
});
163-
}
121+
window.showInformationMessage(`Db2 for IBM i extension server component has been updated!`);
122+
this.installed = true;
123+
updateResult = UpdateStatus.JUST_UPDATED;
124+
164125
} else {
165-
updateResult = UpdateStatus.DECLINED_UPDATE;
126+
updateResult = UpdateStatus.FAILED;
127+
128+
this.writeOutput(JSON.stringify(commandResult));
129+
window.showErrorMessage(`Something went really wrong when trying to fetch your home directory.`).then(chosen => {
130+
if (chosen === `Show`) {
131+
this.outputChannel.show();
132+
}
133+
});
166134
}
167135

168136
} else {
@@ -172,9 +140,10 @@ export class ServerComponent {
172140

173141
} else {
174142
// Uh oh. A release was made by there's no jar file??
175-
ServerComponent.writeOutput('Unable to get file name from server component release');
143+
ServerComponent.writeOutput('Unable to get file name from server component release.');
176144
updateResult = UpdateStatus.NONE_AVAILABLE;
177145
}
146+
178147
} catch (e) {
179148
updateResult = UpdateStatus.FAILED;
180149
ServerComponent.writeOutput(JSON.stringify(e));
@@ -191,8 +160,11 @@ export class ServerComponent {
191160
}
192161
}
193162

194-
function downloadFile(url, outputPath) {
195-
return fetch(url)
196-
.then(x => x.arrayBuffer())
197-
.then(x => writeFile(outputPath, Buffer.from(x)));
198-
}
163+
async function exists(path: string) {
164+
try {
165+
await stat(path);
166+
return true;
167+
} catch (e) {
168+
return false;
169+
}
170+
}

src/dsc.ts

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import path from "path";
2+
3+
import fetch from "node-fetch";
4+
import { Octokit } from "octokit";
5+
import { writeFile } from "fs/promises";
6+
import { SERVER_VERSION_TAG } from "./connection/SCVersion";
7+
8+
async function work() {
9+
const octokit = new Octokit();
10+
11+
const owner = `ThePrez`;
12+
const repo = `CodeForIBMiServer`;
13+
14+
try {
15+
const result = await octokit.request(`GET /repos/{owner}/{repo}/releases/tags/${SERVER_VERSION_TAG}`, {
16+
owner,
17+
repo,
18+
headers: {
19+
'X-GitHub-Api-Version': '2022-11-28'
20+
}
21+
});
22+
23+
const newAsset = result.data.assets.find(asset => asset.name.endsWith(`.jar`));
24+
25+
if (newAsset) {
26+
console.log(`Asset found: ${newAsset.name}`);
27+
28+
const url = newAsset.browser_download_url;
29+
const basename = newAsset.name;
30+
31+
const dist = path.join(`.`, `dist`, basename);
32+
33+
await downloadFile(url, dist);
34+
35+
console.log(`Asset downloaded.`);
36+
37+
} else {
38+
console.log(`Release found but no asset found.`);
39+
}
40+
41+
42+
} catch (e) {
43+
console.log(e);
44+
}
45+
}
46+
47+
function downloadFile(url, outputPath) {
48+
return fetch(url)
49+
.then(x => x.arrayBuffer())
50+
.then(x => writeFile(outputPath, Buffer.from(x)));
51+
}
52+
53+
work();

src/extension.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export interface Db2i {
2727
// your extension is activated the very first time the command is executed
2828

2929
export function activate(context: vscode.ExtensionContext): Db2i {
30-
30+
3131
// Use the console to output diagnostic information (console.log) and errors (console.error)
3232
// This line of code will only be executed once when your extension is activated
3333
console.log(`Congratulations, your extension "vscode-db2i" is now active!`);

0 commit comments

Comments
 (0)