Skip to content

Commit

Permalink
release: 0.1.0
Browse files Browse the repository at this point in the history
[WIP] release-next
  • Loading branch information
alvinhui authored Jun 3, 2021
2 parents 2fb55a1 + 2f4cd09 commit 5ec4669
Show file tree
Hide file tree
Showing 39 changed files with 1,509 additions and 810 deletions.
1 change: 1 addition & 0 deletions main/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,4 @@ export const NOT_REINSTALL_PACKAGES = ['npm'];

export const TAOBAO_NPM_REGISTRY = 'https://registry.npm.taobao.org';
export const ALI_NPM_REGISTRY = 'https://registry.npm.alibaba-inc.com/';
export const TAOBAO_NODE_MIRROR = 'https://npm.taobao.org/mirrors/node';
13 changes: 9 additions & 4 deletions main/data/data.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"title": "Git",
"name": "git",
"description": "分布式版本控制软件",
"link": "https://git-scm.com/",
"icon": "https://img.alicdn.com/imgextra/i2/O1CN012cOEYH1QgKmtKX8Ju_!!6000000002005-2-tps-200-200.png",
"downloadUrl": "https://iceworks.oss-cn-hangzhou.aliyuncs.com/toolkit/packages/dmg/git-2.31.0-intel-universal-mavericks.dmg",
"version": "2.29.2",
Expand All @@ -15,6 +16,7 @@
{
"title": "Node.js (NVM)",
"name": "node",
"link": "https://nodejs.org/",
"description": "基于 Chrome V8 引擎的 JavaScript 运行环境",
"icon": "https://img.alicdn.com/imgextra/i1/O1CN01VNaknC1eqK2iyxCdG_!!6000000003922-2-tps-288-288.png",
"shellName": "install-nvm.sh",
Expand All @@ -31,9 +33,10 @@
"title": "Google Chrome",
"name": "Google Chrome",
"description": "强大、快速的网页浏览器",
"link": "https://www.google.com/chrome/",
"icon": "https://img.alicdn.com/imgextra/i2/O1CN01jRdeW91kg8w2eH4YR_!!6000000004712-0-tps-225-225.jpg",
"downloadUrl": "",
"version": "89.0.4389.114",
"downloadUrl": "https://iceworks.oss-cn-hangzhou.aliyuncs.com/toolkit/packages/dmg/googlechrome.dmg",
"version": null,
"recommended": true,
"isInternal": false,
"type": "dmg",
Expand All @@ -43,9 +46,10 @@
"title": "Visual Studio Code",
"name": "Visual Studio Code",
"description": "跨平台、轻量的代码编辑器",
"link": "https://code.visualstudio.com/",
"icon": "https://img.alicdn.com/imgextra/i4/O1CN01Jujm911lApTQ1ghkF_!!6000000004779-0-tps-225-225.jpg",
"downloadUrl": "https://iceworks.oss-cn-hangzhou.aliyuncs.com/toolkit/packages/dmg/VSCode-darwin.zip",
"version": "1.51.1",
"downloadUrl": "https://iceworks.oss-cn-hangzhou.aliyuncs.com/toolkit/packages/dmg/VSCode-darwin-universal.zip",
"version": null,
"recommended": true,
"isInternal": false,
"type": "dmg",
Expand All @@ -55,6 +59,7 @@
"title": "AppWorks Pack",
"name": "iceworks-team.iceworks",
"description": "基于 VS Code 的多端研发套件",
"link": "https://marketplace.visualstudio.com/items?itemName=iceworks-team.iceworks",
"icon": "https://img.alicdn.com/imgextra/i4/O1CN01fpoIOY26SKXzOtTrR_!!6000000007660-2-tps-500-500.png",
"version": "1.0.0",
"recommended": true,
Expand Down
4 changes: 0 additions & 4 deletions main/data/shells/nvm-node-version.sh

This file was deleted.

5 changes: 2 additions & 3 deletions main/ipc/getBasePackagesInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,9 @@ export default () => {
// remove internal package when not in the ali internal
return item.isInternal ? isAliInternal : true;
});
const packagesData = basePackages.map((basePackageInfo: IBasePackageInfo) => {
const packagesData = await Promise.all(basePackages.map((basePackageInfo: IBasePackageInfo) => {
return getPackageInfo(basePackageInfo);
});

}));
return packagesData;
});
};
12 changes: 5 additions & 7 deletions main/ipc/getNodeInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as path from 'path';
import * as fse from 'fs-extra';
import { ipcMain } from 'electron';
import { IpcMainInvokeEvent } from 'electron/main';
import getNodeManager from '../node';
import getNodeVersions from '../utils/getNodeVersions';
import { getPackageInfo } from '../packageInfo';
import { IBasePackageInfo } from '../types';

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

return localNodeInfo;
return nodeInfo;
});

ipcMain.handle('get-node-versions-list', async (event: IpcMainInvokeEvent, managerName: string) => {
const nodeManager = getNodeManager(managerName);
const nodeVersionsList = await nodeManager.getNodeVersionsList();
return nodeVersionsList;
ipcMain.handle('get-node-versions', async (event: IpcMainInvokeEvent) => {
return await getNodeVersions();
});
};
37 changes: 35 additions & 2 deletions main/ipc/installBasePackages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { IPackageInfo } from '../types';
import { send as sendMainWindow } from '../window';
import killChannelChildProcess from '../utils/killChannelChildProcess';
import log from '../utils/log';
import nodeCache from '../utils/nodeCache';

const childProcessMap = new Map();

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

childProcess.on('message', ({ channel, data }: any) => {
if (channel === processChannel && data.status === 'done') {
killChannelChildProcess(childProcessMap, installChannel);
if (channel === processChannel) {
if (data.status === 'done') {
killChannelChildProcess(childProcessMap, installChannel);
}
// save process data to cache
const processCaches = nodeCache.get(channel) || [];
const taskIndex = processCaches.findIndex((item) => item.currentIndex === data.currentIndex);
if (taskIndex > -1) {
// update the existed task process in cache
processCaches.splice(taskIndex, 1, data);
} else {
// add task process to cache
processCaches.push(data);
}
nodeCache.set(channel, processCaches);
}

sendMainWindow(channel, data);
Expand All @@ -37,4 +51,23 @@ export default () => {
ipcMain.handle('cancel-install-base-packages', (event: IpcMainInvokeEvent, installChannel: string) => {
killChannelChildProcess(childProcessMap, installChannel);
});

ipcMain.handle('get-base-packages-install-cache', (event: IpcMainInvokeEvent, { installChannel, processChannel }) => {
const processCaches = nodeCache.get(processChannel);
const installLogCaches = nodeCache.get(installChannel);

return { processCaches, installLogCaches };
});

ipcMain.handle('clear-base-packages-install-cache', (event: IpcMainInvokeEvent, { installChannel, processChannel }) => {
clearCache([installChannel, processChannel]);
});
};

function clearCache(cachesId: string[]) {
if (Array.isArray(cachesId)) {
cachesId.forEach((cacheId: string) => {
nodeCache.set(cacheId, undefined);
});
}
}
40 changes: 39 additions & 1 deletion main/ipc/installNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { ipcMain } from 'electron';
import { IpcMainInvokeEvent } from 'electron/main';
import { send as sendMainWindow } from '../window';
import killChannelChildProcess from '../utils/killChannelChildProcess';
import nodeCache from '../utils/nodeCache';
import log from '../utils/log';

const childProcessMap = new Map();

Expand All @@ -24,7 +26,13 @@ export default () => {
processChannel: string;
},
) => {
const childProcess = child_process.fork(path.join(__dirname, '..', 'node/index'));
let childProcess = childProcessMap.get(installChannel);
if (childProcess) {
log.info(`Channel ${installChannel} has an existed child process.`);
return;
}
// fork a child process to install node
childProcess = child_process.fork(path.join(__dirname, '..', 'node/index'));
childProcessMap.set(installChannel, childProcess);

childProcess.send({
Expand All @@ -46,6 +54,17 @@ export default () => {
// process.env.PATH: /usr/local/bin -> /Users/xxx/.nvm/versions/node/v14.15.0/bin:/usr/local/bin
process.env.PATH = `${nodeEnvPath}${path.delimiter}${process.env.PATH}`;
}
// save process data to cache
const processCaches = nodeCache.get(channel) || [];
const taskIndex = processCaches.findIndex((item) => item.task === data.task);
if (taskIndex > -1) {
// update the existed task process in cache
processCaches.splice(taskIndex, 1, data);
} else {
// add task process to cache
processCaches.push(data);
}
nodeCache.set(channel, processCaches);
}
sendMainWindow(channel, data);
});
Expand All @@ -54,4 +73,23 @@ export default () => {
ipcMain.handle('cancel-install-node', (event: IpcMainInvokeEvent, installChannel: string) => {
killChannelChildProcess(childProcessMap, installChannel);
});

ipcMain.handle('get-node-install-cache', (event: IpcMainInvokeEvent, { installChannel, processChannel }) => {
const processCaches = nodeCache.get(processChannel);
const installLogCaches = nodeCache.get(installChannel);

return { processCaches, installLogCaches };
});

ipcMain.handle('clear-node-install-cache', (event: IpcMainInvokeEvent, { installChannel, processChannel }) => {
clearCache([installChannel, processChannel]);
});
};

function clearCache(cachesId: string[]) {
if (Array.isArray(cachesId)) {
cachesId.forEach((cacheId: string) => {
nodeCache.set(cacheId, undefined);
});
}
}
52 changes: 26 additions & 26 deletions main/node/NvmManager.ts
Original file line number Diff line number Diff line change
@@ -1,44 +1,36 @@
import * as path from 'path';
import * as execa from 'execa';
import * as shell from 'shelljs';
import { INodeManager } from '../types';
import log from '../utils/log';
import formatWhitespaceInPath from '../utils/formatWhitespaceInPath';
import formatNodeVersion from '../utils/formatNodeVersion';
import { NOT_REINSTALL_PACKAGES } from '../constants';
import getNpmRegistry from '../utils/getNpmRegistry';
// eslint-disable-next-line import/order
import stripAnsi = require('strip-ansi');

class NvmManager implements INodeManager {
channel: string;

std: string;

previousNpmPath: string;

globalNpmPackages: string[];

nodePath: string;

constructor(channel = '') {
this.channel = channel;
this.std = '';
this.previousNpmPath = '';
this.globalNpmPackages = [];
this.nodePath = '';
}

installNode = (version: string, reinstallGlobalDeps = true) => {
if (reinstallGlobalDeps) {
// collect the global npm packages
const args: string[] = ['list', '-g', '--depth=0', '--json'];
const { stdout } = execa.sync('npm', args);
if (stdout) {
const { dependencies = {} } = JSON.parse(stdout);
const depNames = Object.keys(dependencies).filter((dep: string) => !NOT_REINSTALL_PACKAGES.includes(dep)) || [];

depNames.forEach((dep: string) => {
const { version: depVersion } = dependencies[dep];
this.globalNpmPackages.push(`${dep}@${depVersion}`);
});
}
// get the previous npm path
const { stdout } = shell.which('npm');
this.previousNpmPath = stdout;
}
const formattedVersion = formatNodeVersion(version);
const shFilePath = path.resolve(__dirname, '../data/shells', 'nvm-install-node.sh');
Expand Down Expand Up @@ -66,18 +58,9 @@ class NvmManager implements INodeManager {
});
};

async getNodeVersionsList() {
const shFilePath = formatWhitespaceInPath(path.resolve(__dirname, '../data/shells', 'nvm-node-version.sh'));
const { stdout } = await execa.command(`sh ${shFilePath}`);

return stdout
.split('\n')
.reverse()
.map((version: string) => stripAnsi(version).trim());
}

reinstallPackages = () => {
return getNpmRegistry()
return this.getGlobalNpmPackages()
.then(() => getNpmRegistry())
.then((npmRegistry) => {
return new Promise((resolve, reject) => {
const args = ['i', '-g', ...this.globalNpmPackages, '--registry', npmRegistry];
Expand All @@ -88,6 +71,7 @@ class NvmManager implements INodeManager {
// Don't extend env because it will not use the current(new) npm to install package
extendEnv: false,
});

cp.stdout.on('data', this.listenFunc);

cp.stderr.on('data', this.listenFunc);
Expand Down Expand Up @@ -126,6 +110,22 @@ class NvmManager implements INodeManager {
}
return undefined;
}

private async getGlobalNpmPackages() {
if (!this.previousNpmPath) {
throw new Error('Npm command was not Found.');
}
const { stdout } = await execa(this.previousNpmPath, ['list', '-g', '--depth=0', '--json']);
if (stdout) {
const { dependencies = {} } = JSON.parse(stdout);
const depNames = Object.keys(dependencies).filter((dep: string) => !NOT_REINSTALL_PACKAGES.includes(dep)) || [];

depNames.forEach((dep: string) => {
const { version: depVersion } = dependencies[dep];
this.globalNpmPackages.push(`${dep}@${depVersion}`);
});
}
}
}

export default NvmManager;
4 changes: 2 additions & 2 deletions main/packageInfo/IDEExtension/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ const processor = {
VSCode: getVSCodeExtensionInfo,
};

export default (basePackageInfo: IBasePackageInfo) => {
export default async (basePackageInfo: IBasePackageInfo) => {
const { name, options: { IDEType } } = basePackageInfo;

const getIDEExtensionInfoFunc = processor[IDEType];
if (getIDEExtensionInfoFunc) {
return getVSCodeExtensionInfo(name);
return await getVSCodeExtensionInfo(name);
}
return DEFAULT_LOCAL_PACKAGE_INFO;
};
4 changes: 2 additions & 2 deletions main/packageInfo/IDEExtension/vscodeExtension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ import isCliInstalled from '../../utils/isCliInstalled';
import { VSCODE_CLI_COMAMND_NAME } from '../../constants';
import { ILocalPackageInfo } from '../../types';

function getVSCodeExtensionInfo(name: string) {
async function getVSCodeExtensionInfo(name: string) {
const extensionInfo: ILocalPackageInfo = {
versionStatus: 'uninstalled',
localVersion: null,
};
if (isCliInstalled(VSCODE_CLI_COMAMND_NAME)) {
const { stdout } = execa.sync(
const { stdout } = await execa(
VSCODE_CLI_COMAMND_NAME,
['--list-extensions', '--show-versions'],
);
Expand Down
4 changes: 2 additions & 2 deletions main/packageInfo/cli/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { DEFAULT_LOCAL_PACKAGE_INFO } from '../../constants';
import getVersionStatus from '../../utils/getVersionStatus';
import log from '../../utils/log';

function getLocalCliInfo(name: string, latestVersion: string | null) {
async function getLocalCliInfo(name: string, latestVersion: string | null) {
const localCliInfo = { ...DEFAULT_LOCAL_PACKAGE_INFO };
// get the local path of cli
try {
Expand All @@ -20,7 +20,7 @@ function getLocalCliInfo(name: string, latestVersion: string | null) {
}
// get cli version
try {
const { stdout: cliVersion } = execa.sync(
const { stdout: cliVersion } = await execa(
localCliInfo.localPath,
['--version'],
{ shell: true },
Expand Down
8 changes: 3 additions & 5 deletions main/packageInfo/cli/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,9 @@ const processor = {
node: getLocalNodeInfo,
};

export default (basePackageInfo: IBasePackageInfo) => {
export default async (basePackageInfo: IBasePackageInfo) => {
const { name, version, options } = basePackageInfo;
const getLocalInfoFunc = processor[name];
if (getLocalInfoFunc) {
return getLocalInfoFunc(name, version, options);
}
return getLocalCliInfo(name, version);

return getLocalInfoFunc ? await getLocalInfoFunc(name, version, options) : await getLocalCliInfo(name, version);
};
Loading

0 comments on commit 5ec4669

Please sign in to comment.