Skip to content

Commit 5ec4669

Browse files
authored
release: 0.1.0
[WIP] release-next
2 parents 2fb55a1 + 2f4cd09 commit 5ec4669

39 files changed

+1509
-810
lines changed

main/constants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,4 @@ export const NOT_REINSTALL_PACKAGES = ['npm'];
2727

2828
export const TAOBAO_NPM_REGISTRY = 'https://registry.npm.taobao.org';
2929
export const ALI_NPM_REGISTRY = 'https://registry.npm.alibaba-inc.com/';
30+
export const TAOBAO_NODE_MIRROR = 'https://npm.taobao.org/mirrors/node';

main/data/data.json

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
"title": "Git",
55
"name": "git",
66
"description": "分布式版本控制软件",
7+
"link": "https://git-scm.com/",
78
"icon": "https://img.alicdn.com/imgextra/i2/O1CN012cOEYH1QgKmtKX8Ju_!!6000000002005-2-tps-200-200.png",
89
"downloadUrl": "https://iceworks.oss-cn-hangzhou.aliyuncs.com/toolkit/packages/dmg/git-2.31.0-intel-universal-mavericks.dmg",
910
"version": "2.29.2",
@@ -15,6 +16,7 @@
1516
{
1617
"title": "Node.js (NVM)",
1718
"name": "node",
19+
"link": "https://nodejs.org/",
1820
"description": "基于 Chrome V8 引擎的 JavaScript 运行环境",
1921
"icon": "https://img.alicdn.com/imgextra/i1/O1CN01VNaknC1eqK2iyxCdG_!!6000000003922-2-tps-288-288.png",
2022
"shellName": "install-nvm.sh",
@@ -31,9 +33,10 @@
3133
"title": "Google Chrome",
3234
"name": "Google Chrome",
3335
"description": "强大、快速的网页浏览器",
36+
"link": "https://www.google.com/chrome/",
3437
"icon": "https://img.alicdn.com/imgextra/i2/O1CN01jRdeW91kg8w2eH4YR_!!6000000004712-0-tps-225-225.jpg",
35-
"downloadUrl": "",
36-
"version": "89.0.4389.114",
38+
"downloadUrl": "https://iceworks.oss-cn-hangzhou.aliyuncs.com/toolkit/packages/dmg/googlechrome.dmg",
39+
"version": null,
3740
"recommended": true,
3841
"isInternal": false,
3942
"type": "dmg",
@@ -43,9 +46,10 @@
4346
"title": "Visual Studio Code",
4447
"name": "Visual Studio Code",
4548
"description": "跨平台、轻量的代码编辑器",
49+
"link": "https://code.visualstudio.com/",
4650
"icon": "https://img.alicdn.com/imgextra/i4/O1CN01Jujm911lApTQ1ghkF_!!6000000004779-0-tps-225-225.jpg",
47-
"downloadUrl": "https://iceworks.oss-cn-hangzhou.aliyuncs.com/toolkit/packages/dmg/VSCode-darwin.zip",
48-
"version": "1.51.1",
51+
"downloadUrl": "https://iceworks.oss-cn-hangzhou.aliyuncs.com/toolkit/packages/dmg/VSCode-darwin-universal.zip",
52+
"version": null,
4953
"recommended": true,
5054
"isInternal": false,
5155
"type": "dmg",
@@ -55,6 +59,7 @@
5559
"title": "AppWorks Pack",
5660
"name": "iceworks-team.iceworks",
5761
"description": "基于 VS Code 的多端研发套件",
62+
"link": "https://marketplace.visualstudio.com/items?itemName=iceworks-team.iceworks",
5863
"icon": "https://img.alicdn.com/imgextra/i4/O1CN01fpoIOY26SKXzOtTrR_!!6000000007660-2-tps-500-500.png",
5964
"version": "1.0.0",
6065
"recommended": true,

main/data/shells/nvm-node-version.sh

Lines changed: 0 additions & 4 deletions
This file was deleted.

main/ipc/getBasePackagesInfo.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,9 @@ export default () => {
1515
// remove internal package when not in the ali internal
1616
return item.isInternal ? isAliInternal : true;
1717
});
18-
const packagesData = basePackages.map((basePackageInfo: IBasePackageInfo) => {
18+
const packagesData = await Promise.all(basePackages.map((basePackageInfo: IBasePackageInfo) => {
1919
return getPackageInfo(basePackageInfo);
20-
});
21-
20+
}));
2221
return packagesData;
2322
});
2423
};

main/ipc/getNodeInfo.ts

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as path from 'path';
22
import * as fse from 'fs-extra';
33
import { ipcMain } from 'electron';
44
import { IpcMainInvokeEvent } from 'electron/main';
5-
import getNodeManager from '../node';
5+
import getNodeVersions from '../utils/getNodeVersions';
66
import { getPackageInfo } from '../packageInfo';
77
import { IBasePackageInfo } from '../types';
88

@@ -12,14 +12,12 @@ export default () => {
1212
const data = await fse.readJSON(path.join(__dirname, '../data', 'data.json'));
1313
const { bases = [] }: { bases: IBasePackageInfo[] } = data;
1414
const nodeBasicInfo = bases.find((base: IBasePackageInfo) => base.name === 'node');
15-
const localNodeInfo = getPackageInfo(nodeBasicInfo);
15+
const nodeInfo = getPackageInfo(nodeBasicInfo);
1616

17-
return localNodeInfo;
17+
return nodeInfo;
1818
});
1919

20-
ipcMain.handle('get-node-versions-list', async (event: IpcMainInvokeEvent, managerName: string) => {
21-
const nodeManager = getNodeManager(managerName);
22-
const nodeVersionsList = await nodeManager.getNodeVersionsList();
23-
return nodeVersionsList;
20+
ipcMain.handle('get-node-versions', async (event: IpcMainInvokeEvent) => {
21+
return await getNodeVersions();
2422
});
2523
};

main/ipc/installBasePackages.ts

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { IPackageInfo } from '../types';
66
import { send as sendMainWindow } from '../window';
77
import killChannelChildProcess from '../utils/killChannelChildProcess';
88
import log from '../utils/log';
9+
import nodeCache from '../utils/nodeCache';
910

1011
const childProcessMap = new Map();
1112

@@ -26,8 +27,21 @@ export default () => {
2627
childProcess.send({ packagesList, installChannel, processChannel });
2728

2829
childProcess.on('message', ({ channel, data }: any) => {
29-
if (channel === processChannel && data.status === 'done') {
30-
killChannelChildProcess(childProcessMap, installChannel);
30+
if (channel === processChannel) {
31+
if (data.status === 'done') {
32+
killChannelChildProcess(childProcessMap, installChannel);
33+
}
34+
// save process data to cache
35+
const processCaches = nodeCache.get(channel) || [];
36+
const taskIndex = processCaches.findIndex((item) => item.currentIndex === data.currentIndex);
37+
if (taskIndex > -1) {
38+
// update the existed task process in cache
39+
processCaches.splice(taskIndex, 1, data);
40+
} else {
41+
// add task process to cache
42+
processCaches.push(data);
43+
}
44+
nodeCache.set(channel, processCaches);
3145
}
3246

3347
sendMainWindow(channel, data);
@@ -37,4 +51,23 @@ export default () => {
3751
ipcMain.handle('cancel-install-base-packages', (event: IpcMainInvokeEvent, installChannel: string) => {
3852
killChannelChildProcess(childProcessMap, installChannel);
3953
});
54+
55+
ipcMain.handle('get-base-packages-install-cache', (event: IpcMainInvokeEvent, { installChannel, processChannel }) => {
56+
const processCaches = nodeCache.get(processChannel);
57+
const installLogCaches = nodeCache.get(installChannel);
58+
59+
return { processCaches, installLogCaches };
60+
});
61+
62+
ipcMain.handle('clear-base-packages-install-cache', (event: IpcMainInvokeEvent, { installChannel, processChannel }) => {
63+
clearCache([installChannel, processChannel]);
64+
});
4065
};
66+
67+
function clearCache(cachesId: string[]) {
68+
if (Array.isArray(cachesId)) {
69+
cachesId.forEach((cacheId: string) => {
70+
nodeCache.set(cacheId, undefined);
71+
});
72+
}
73+
}

main/ipc/installNode.ts

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import { ipcMain } from 'electron';
44
import { IpcMainInvokeEvent } from 'electron/main';
55
import { send as sendMainWindow } from '../window';
66
import killChannelChildProcess from '../utils/killChannelChildProcess';
7+
import nodeCache from '../utils/nodeCache';
8+
import log from '../utils/log';
79

810
const childProcessMap = new Map();
911

@@ -24,7 +26,13 @@ export default () => {
2426
processChannel: string;
2527
},
2628
) => {
27-
const childProcess = child_process.fork(path.join(__dirname, '..', 'node/index'));
29+
let childProcess = childProcessMap.get(installChannel);
30+
if (childProcess) {
31+
log.info(`Channel ${installChannel} has an existed child process.`);
32+
return;
33+
}
34+
// fork a child process to install node
35+
childProcess = child_process.fork(path.join(__dirname, '..', 'node/index'));
2836
childProcessMap.set(installChannel, childProcess);
2937

3038
childProcess.send({
@@ -46,6 +54,17 @@ export default () => {
4654
// process.env.PATH: /usr/local/bin -> /Users/xxx/.nvm/versions/node/v14.15.0/bin:/usr/local/bin
4755
process.env.PATH = `${nodeEnvPath}${path.delimiter}${process.env.PATH}`;
4856
}
57+
// save process data to cache
58+
const processCaches = nodeCache.get(channel) || [];
59+
const taskIndex = processCaches.findIndex((item) => item.task === data.task);
60+
if (taskIndex > -1) {
61+
// update the existed task process in cache
62+
processCaches.splice(taskIndex, 1, data);
63+
} else {
64+
// add task process to cache
65+
processCaches.push(data);
66+
}
67+
nodeCache.set(channel, processCaches);
4968
}
5069
sendMainWindow(channel, data);
5170
});
@@ -54,4 +73,23 @@ export default () => {
5473
ipcMain.handle('cancel-install-node', (event: IpcMainInvokeEvent, installChannel: string) => {
5574
killChannelChildProcess(childProcessMap, installChannel);
5675
});
76+
77+
ipcMain.handle('get-node-install-cache', (event: IpcMainInvokeEvent, { installChannel, processChannel }) => {
78+
const processCaches = nodeCache.get(processChannel);
79+
const installLogCaches = nodeCache.get(installChannel);
80+
81+
return { processCaches, installLogCaches };
82+
});
83+
84+
ipcMain.handle('clear-node-install-cache', (event: IpcMainInvokeEvent, { installChannel, processChannel }) => {
85+
clearCache([installChannel, processChannel]);
86+
});
5787
};
88+
89+
function clearCache(cachesId: string[]) {
90+
if (Array.isArray(cachesId)) {
91+
cachesId.forEach((cacheId: string) => {
92+
nodeCache.set(cacheId, undefined);
93+
});
94+
}
95+
}

main/node/NvmManager.ts

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,36 @@
11
import * as path from 'path';
22
import * as execa from 'execa';
3+
import * as shell from 'shelljs';
34
import { INodeManager } from '../types';
45
import log from '../utils/log';
5-
import formatWhitespaceInPath from '../utils/formatWhitespaceInPath';
66
import formatNodeVersion from '../utils/formatNodeVersion';
77
import { NOT_REINSTALL_PACKAGES } from '../constants';
88
import getNpmRegistry from '../utils/getNpmRegistry';
9-
// eslint-disable-next-line import/order
10-
import stripAnsi = require('strip-ansi');
119

1210
class NvmManager implements INodeManager {
1311
channel: string;
1412

1513
std: string;
1614

15+
previousNpmPath: string;
16+
1717
globalNpmPackages: string[];
1818

1919
nodePath: string;
2020

2121
constructor(channel = '') {
2222
this.channel = channel;
2323
this.std = '';
24+
this.previousNpmPath = '';
2425
this.globalNpmPackages = [];
2526
this.nodePath = '';
2627
}
2728

2829
installNode = (version: string, reinstallGlobalDeps = true) => {
2930
if (reinstallGlobalDeps) {
30-
// collect the global npm packages
31-
const args: string[] = ['list', '-g', '--depth=0', '--json'];
32-
const { stdout } = execa.sync('npm', args);
33-
if (stdout) {
34-
const { dependencies = {} } = JSON.parse(stdout);
35-
const depNames = Object.keys(dependencies).filter((dep: string) => !NOT_REINSTALL_PACKAGES.includes(dep)) || [];
36-
37-
depNames.forEach((dep: string) => {
38-
const { version: depVersion } = dependencies[dep];
39-
this.globalNpmPackages.push(`${dep}@${depVersion}`);
40-
});
41-
}
31+
// get the previous npm path
32+
const { stdout } = shell.which('npm');
33+
this.previousNpmPath = stdout;
4234
}
4335
const formattedVersion = formatNodeVersion(version);
4436
const shFilePath = path.resolve(__dirname, '../data/shells', 'nvm-install-node.sh');
@@ -66,18 +58,9 @@ class NvmManager implements INodeManager {
6658
});
6759
};
6860

69-
async getNodeVersionsList() {
70-
const shFilePath = formatWhitespaceInPath(path.resolve(__dirname, '../data/shells', 'nvm-node-version.sh'));
71-
const { stdout } = await execa.command(`sh ${shFilePath}`);
72-
73-
return stdout
74-
.split('\n')
75-
.reverse()
76-
.map((version: string) => stripAnsi(version).trim());
77-
}
78-
7961
reinstallPackages = () => {
80-
return getNpmRegistry()
62+
return this.getGlobalNpmPackages()
63+
.then(() => getNpmRegistry())
8164
.then((npmRegistry) => {
8265
return new Promise((resolve, reject) => {
8366
const args = ['i', '-g', ...this.globalNpmPackages, '--registry', npmRegistry];
@@ -88,6 +71,7 @@ class NvmManager implements INodeManager {
8871
// Don't extend env because it will not use the current(new) npm to install package
8972
extendEnv: false,
9073
});
74+
9175
cp.stdout.on('data', this.listenFunc);
9276

9377
cp.stderr.on('data', this.listenFunc);
@@ -126,6 +110,22 @@ class NvmManager implements INodeManager {
126110
}
127111
return undefined;
128112
}
113+
114+
private async getGlobalNpmPackages() {
115+
if (!this.previousNpmPath) {
116+
throw new Error('Npm command was not Found.');
117+
}
118+
const { stdout } = await execa(this.previousNpmPath, ['list', '-g', '--depth=0', '--json']);
119+
if (stdout) {
120+
const { dependencies = {} } = JSON.parse(stdout);
121+
const depNames = Object.keys(dependencies).filter((dep: string) => !NOT_REINSTALL_PACKAGES.includes(dep)) || [];
122+
123+
depNames.forEach((dep: string) => {
124+
const { version: depVersion } = dependencies[dep];
125+
this.globalNpmPackages.push(`${dep}@${depVersion}`);
126+
});
127+
}
128+
}
129129
}
130130

131131
export default NvmManager;

main/packageInfo/IDEExtension/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@ const processor = {
66
VSCode: getVSCodeExtensionInfo,
77
};
88

9-
export default (basePackageInfo: IBasePackageInfo) => {
9+
export default async (basePackageInfo: IBasePackageInfo) => {
1010
const { name, options: { IDEType } } = basePackageInfo;
1111

1212
const getIDEExtensionInfoFunc = processor[IDEType];
1313
if (getIDEExtensionInfoFunc) {
14-
return getVSCodeExtensionInfo(name);
14+
return await getVSCodeExtensionInfo(name);
1515
}
1616
return DEFAULT_LOCAL_PACKAGE_INFO;
1717
};

main/packageInfo/IDEExtension/vscodeExtension.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@ import isCliInstalled from '../../utils/isCliInstalled';
33
import { VSCODE_CLI_COMAMND_NAME } from '../../constants';
44
import { ILocalPackageInfo } from '../../types';
55

6-
function getVSCodeExtensionInfo(name: string) {
6+
async function getVSCodeExtensionInfo(name: string) {
77
const extensionInfo: ILocalPackageInfo = {
88
versionStatus: 'uninstalled',
99
localVersion: null,
1010
};
1111
if (isCliInstalled(VSCODE_CLI_COMAMND_NAME)) {
12-
const { stdout } = execa.sync(
12+
const { stdout } = await execa(
1313
VSCODE_CLI_COMAMND_NAME,
1414
['--list-extensions', '--show-versions'],
1515
);

0 commit comments

Comments
 (0)