Skip to content

Commit c5d93d8

Browse files
authored
Release 0.1.1 (#24)
* chore: version * fix: icon size * fix: icon file size * Feat: record DAU (#25) * fix: stdout match (#38) * fix: fail to install nvm (#29) * Fix: fail to install code to path (#37) * Feat: auto download package (#31) * Fix: vscode cli command not found (#36) * fix: nvm has installed but actually not installed (#39) * fix: managerVersion not found (#40) * Fix: electron not found in prod env (#41)
1 parent 5ec4669 commit c5d93d8

36 files changed

+2501
-1474
lines changed

.eslintrc.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ module.exports = getESLintConfig('react-ts', {
77
'react-hooks/exhaustive-deps': 0,
88
'@iceworks/best-practices/recommend-polyfill': 0,
99
'import/order': 1,
10-
'no-param-reassign': 0
10+
'no-param-reassign': 0,
11+
'@typescript-eslint/no-require-imports': 0
1112
},
1213
});
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import * as path from 'path';
2+
import * as fse from 'fs-extra';
3+
import { TOOLKIT_PACKAGES_DIR } from '../constants';
4+
import downloadFile from '../utils/downloadFile';
5+
import log from '../utils/log';
6+
7+
class AutoDownloader {
8+
async checkForDownloadAvailable(sourceFileName: string) {
9+
const sourceFilePath = path.join(TOOLKIT_PACKAGES_DIR, sourceFileName);
10+
const sourceFileExists = await fse.pathExists(sourceFilePath);
11+
log.info(sourceFileExists ? `${sourceFileName} has already existed in ${sourceFilePath}` : `${sourceFileName} is available to download.`);
12+
return !sourceFileExists;
13+
}
14+
15+
async downloadPackage({ downloadUrl, sourceFileName }) {
16+
await downloadFile(downloadUrl, TOOLKIT_PACKAGES_DIR, sourceFileName);
17+
}
18+
19+
async start(data) {
20+
const { sourceFileName } = data;
21+
const downloadAvailable = await this.checkForDownloadAvailable(sourceFileName);
22+
if (downloadAvailable) {
23+
await this.downloadPackage(data);
24+
}
25+
}
26+
}
27+
28+
export default AutoDownloader;

main/autoDownloader/index.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { IBasePackageInfo, Platform } from '../types';
2+
import store, { packagesDataKey } from '../store';
3+
import getPackageFileName from '../utils/getPackageFileName';
4+
import AutoDownloader from './AutoDownloader';
5+
6+
const packageTypes = ['bases'];
7+
8+
export async function autoDownloadPackages() {
9+
const data = store.get(packagesDataKey);
10+
// the packages which should be checked for available downloading
11+
const packageDatas = [];
12+
13+
packageTypes.forEach((packageType: string) => {
14+
const packagesInfo: IBasePackageInfo[] = data[packageType] || [];
15+
16+
for (const packageInfo of packagesInfo) {
17+
const { downloadUrl, platforms } = packageInfo;
18+
const currentPlatform = process.platform as Platform;
19+
if (!downloadUrl || !platforms.includes(currentPlatform)) {
20+
continue;
21+
}
22+
const packageFileName = getPackageFileName(packageInfo);
23+
packageDatas.push({ sourceFileName: packageFileName, downloadUrl });
24+
}
25+
});
26+
27+
await Promise.all(packageDatas.map((packageData) => {
28+
const autoDownloader = new AutoDownloader();
29+
return autoDownloader.start(packageData);
30+
}));
31+
}

main/constants.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,23 @@ export const APPLICATIONS_DIR_PATH = '/Applications';
55

66
export const PACKAGE_JSON_FILE_NAME = 'package.json';
77

8-
export const TOOLKIT_TMP_DIR = path.join(process.env.HOME, '.toolkit');
8+
export const TOOLKIT_DIR = path.join(process.env.HOME, '.toolkit');
9+
export const TOOLKIT_TMP_DIR = path.join(TOOLKIT_DIR, 'tmp');
10+
export const TOOLKIT_PACKAGES_DIR = path.join(TOOLKIT_DIR, 'packages');
911

1012
export const DEFAULT_LOCAL_PACKAGE_INFO: ILocalPackageInfo = {
1113
localVersion: null,
1214
localPath: null,
1315
versionStatus: 'uninstalled',
1416
};
1517

16-
export const VSCODE_CLI_COMAMND_NAME = 'code';
18+
export const VSCODE_COMMAND_NAME = 'code';
19+
export const VSCODE_NAME = 'Visual Studio Code';
1720

1821
export const INSTALL_COMMAND_PACKAGES = [
1922
{
20-
name: 'Visual Studio Code',
21-
command: 'code',
23+
name: VSCODE_NAME,
24+
command: VSCODE_COMMAND_NAME,
2225
commandRelativePath: './Contents/Resources/app/bin/code',
2326
},
2427
];
@@ -28,3 +31,6 @@ export const NOT_REINSTALL_PACKAGES = ['npm'];
2831
export const TAOBAO_NPM_REGISTRY = 'https://registry.npm.taobao.org';
2932
export const ALI_NPM_REGISTRY = 'https://registry.npm.alibaba-inc.com/';
3033
export const TAOBAO_NODE_MIRROR = 'https://npm.taobao.org/mirrors/node';
34+
35+
export const PROFILE_FILES = ['.bash_profile', '.bashrc', '.zshrc'];
36+
export const DEFAULT_PROFILE_FILE = '.bash_profile';

main/data/data.json

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@
77
"link": "https://git-scm.com/",
88
"icon": "https://img.alicdn.com/imgextra/i2/O1CN012cOEYH1QgKmtKX8Ju_!!6000000002005-2-tps-200-200.png",
99
"downloadUrl": "https://iceworks.oss-cn-hangzhou.aliyuncs.com/toolkit/packages/dmg/git-2.31.0-intel-universal-mavericks.dmg",
10-
"version": "2.29.2",
10+
"version": "2.31.0",
1111
"recommended": true,
1212
"isInternal": false,
1313
"type": "cli",
14-
"platform": "darwin"
14+
"platforms": ["darwin"]
1515
},
1616
{
1717
"title": "Node.js (NVM)",
@@ -24,7 +24,7 @@
2424
"recommended": true,
2525
"isInternal": false,
2626
"type": "cli",
27-
"platform": "darwin",
27+
"platforms": ["darwin"],
2828
"options": {
2929
"managerName": "nvm"
3030
}
@@ -40,7 +40,7 @@
4040
"recommended": true,
4141
"isInternal": false,
4242
"type": "dmg",
43-
"platform": "darwin"
43+
"platforms": ["darwin"]
4444
},
4545
{
4646
"title": "Visual Studio Code",
@@ -53,7 +53,7 @@
5353
"recommended": true,
5454
"isInternal": false,
5555
"type": "dmg",
56-
"platform": "darwin"
56+
"platforms": ["darwin"]
5757
},
5858
{
5959
"title": "AppWorks Pack",
@@ -67,18 +67,36 @@
6767
"type": "IDEExtension",
6868
"options": {
6969
"IDEType": "VSCode"
70-
}
70+
},
71+
"platforms": ["darwin", "win32"]
7172
}
7273
],
7374
"apps": [
7475
{
76+
"title": "Google Chrome",
7577
"name": "Google Chrome",
7678
"description": "强大、快速的网页浏览器",
77-
"icon": "https://img.alicdn.com/imgextra/i3/O1CN01cspie61ZOm8vgQfKl_!!6000000003185-55-tps-32-32.svg",
78-
"downloadUrl": "",
79-
"version": "89.0.4389.114",
79+
"link": "https://www.google.com/chrome/",
80+
"icon": "https://img.alicdn.com/imgextra/i2/O1CN01jRdeW91kg8w2eH4YR_!!6000000004712-0-tps-225-225.jpg",
81+
"downloadUrl": "https://iceworks.oss-cn-hangzhou.aliyuncs.com/toolkit/packages/dmg/googlechrome.dmg",
82+
"version": null,
8083
"recommended": true,
81-
"isInternal": false
84+
"isInternal": false,
85+
"type": "dmg",
86+
"platforms": ["darwin"]
87+
},
88+
{
89+
"title": "Visual Studio Code",
90+
"name": "Visual Studio Code",
91+
"description": "跨平台、轻量的代码编辑器",
92+
"link": "https://code.visualstudio.com/",
93+
"icon": "https://img.alicdn.com/imgextra/i4/O1CN01Jujm911lApTQ1ghkF_!!6000000004779-0-tps-225-225.jpg",
94+
"downloadUrl": "https://iceworks.oss-cn-hangzhou.aliyuncs.com/toolkit/packages/dmg/VSCode-darwin-universal.zip",
95+
"version": null,
96+
"recommended": true,
97+
"isInternal": false,
98+
"type": "dmg",
99+
"platforms": ["darwin"]
82100
}
83101
],
84102
"npmPackages": [
@@ -133,4 +151,4 @@
133151
}
134152
}
135153
]
136-
}
154+
}

main/data/shells/install-nvm.sh

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -269,12 +269,12 @@ nvm_detect_profile() {
269269

270270
local DETECTED_PROFILE
271271
DETECTED_PROFILE=''
272-
273272
if [ -n "${BASH_VERSION-}" ]; then
274-
if [ -f "$HOME/.bashrc" ]; then
275-
DETECTED_PROFILE="$HOME/.bashrc"
276-
elif [ -f "$HOME/.bash_profile" ]; then
273+
# execute order is: .bash_profile > .bashrc
274+
if [ -f "$HOME/.bash_profile" ]; then
277275
DETECTED_PROFILE="$HOME/.bash_profile"
276+
elif [ -f "$HOME/.bashrc" ]; then
277+
DETECTED_PROFILE="$HOME/.bashrc"
278278
fi
279279
elif [ -n "${ZSH_VERSION-}" ]; then
280280
DETECTED_PROFILE="$HOME/.zshrc"
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#!/usr/bin/env bash
2+
3+
\. "$NVM_DIR/nvm.sh"
4+
5+
echo "$(command -v nvm 2>/dev/null)"

main/index.ts

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,35 @@ import modifyProcessEnv from './utils/modifyProcessEnv';
33
import { createWindow } from './window';
44
import handleIPC from './ipc';
55
import { checkForUpdates } from './utils/autoUpdater';
6+
import getPackagesData from './utils/getPackagesData';
7+
import { autoDownloadPackages } from './autoDownloader';
8+
import store, { packagesDataKey } from './store';
9+
import { recordDAU } from './recorder';
610

711
process.env.ELECTRON_DISABLE_SECURITY_WARNINGS = 'true';
812

9-
app.whenReady().then(() => {
10-
checkForUpdates();
13+
app.whenReady()
14+
.then(() => getPackagesData())
15+
.then((packagesData) => {
16+
store.set(packagesDataKey, packagesData);
17+
})
18+
.finally(() => {
19+
modifyProcessEnv();
1120

12-
modifyProcessEnv();
21+
createWindow();
1322

14-
createWindow();
23+
handleIPC();
1524

16-
handleIPC();
25+
checkForUpdates();
1726

18-
app.on('activate', () => {
19-
if (BrowserWindow.getAllWindows().length === 0) createWindow();
27+
autoDownloadPackages();
28+
29+
recordDAU();
30+
31+
app.on('activate', () => {
32+
if (BrowserWindow.getAllWindows().length === 0) createWindow();
33+
});
2034
});
21-
});
2235

2336
// Quit when all windows are closed.
2437
app.on('window-all-closed', () => {

main/ipc/getBasePackagesInfo.ts

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,18 @@
1-
import * as path from 'path';
2-
import * as fse from 'fs-extra';
31
import { ipcMain } from 'electron';
4-
import { IBasePackageInfo } from '../types';
2+
import { IBasePackageInfo, Platform } from '../types';
53
import { getPackageInfo } from '../packageInfo';
64
import checkIsAliInternal from '../utils/checkIsAliInternal';
5+
import store, { packagesDataKey } from '../store';
76

87
export default () => {
98
ipcMain.handle('get-base-packages-info', async () => {
10-
// TODO: get data.json from OSS and save it in the storage when app starts first
11-
const data = await fse.readJSON(path.join(__dirname, '../data', 'data.json'));
9+
const data = store.get(packagesDataKey);
1210
const { bases = [] }: { bases: IBasePackageInfo[] } = data;
1311
const isAliInternal = await checkIsAliInternal();
14-
const basePackages = bases.filter((item) => {
15-
// remove internal package when not in the ali internal
16-
return item.isInternal ? isAliInternal : true;
12+
const basePackages = bases.filter(({ isInternal, platforms }) => {
13+
// 1. only return the package info in current platform
14+
// 2. remove internal package when not in the ali internal
15+
return platforms.includes(process.platform as Platform) && (isInternal ? isAliInternal : true);
1716
});
1817
const packagesData = await Promise.all(basePackages.map((basePackageInfo: IBasePackageInfo) => {
1918
return getPackageInfo(basePackageInfo);

main/ipc/getNodeInfo.ts

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,20 @@
1-
import * as path from 'path';
2-
import * as fse from 'fs-extra';
31
import { ipcMain } from 'electron';
4-
import { IpcMainInvokeEvent } from 'electron/main';
52
import getNodeVersions from '../utils/getNodeVersions';
63
import { getPackageInfo } from '../packageInfo';
74
import { IBasePackageInfo } from '../types';
5+
import store, { packagesDataKey } from '../store';
86

97
export default () => {
10-
ipcMain.handle('get-node-info', async () => {
11-
// TODO: get data.json from OSS and save it in the storage when app starts first
12-
const data = await fse.readJSON(path.join(__dirname, '../data', 'data.json'));
8+
ipcMain.handle('get-node-info', () => {
9+
const data = store.get(packagesDataKey);
1310
const { bases = [] }: { bases: IBasePackageInfo[] } = data;
1411
const nodeBasicInfo = bases.find((base: IBasePackageInfo) => base.name === 'node');
1512
const nodeInfo = getPackageInfo(nodeBasicInfo);
1613

1714
return nodeInfo;
1815
});
1916

20-
ipcMain.handle('get-node-versions', async (event: IpcMainInvokeEvent) => {
17+
ipcMain.handle('get-node-versions', async () => {
2118
return await getNodeVersions();
2219
});
2320
};

0 commit comments

Comments
 (0)