Skip to content

Commit

Permalink
Release 0.1.1 (#24)
Browse files Browse the repository at this point in the history
* 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)
  • Loading branch information
luhc228 authored Jul 6, 2021
1 parent 5ec4669 commit c5d93d8
Show file tree
Hide file tree
Showing 36 changed files with 2,501 additions and 1,474 deletions.
3 changes: 2 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ module.exports = getESLintConfig('react-ts', {
'react-hooks/exhaustive-deps': 0,
'@iceworks/best-practices/recommend-polyfill': 0,
'import/order': 1,
'no-param-reassign': 0
'no-param-reassign': 0,
'@typescript-eslint/no-require-imports': 0
},
});
28 changes: 28 additions & 0 deletions main/autoDownloader/AutoDownloader.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import * as path from 'path';
import * as fse from 'fs-extra';
import { TOOLKIT_PACKAGES_DIR } from '../constants';
import downloadFile from '../utils/downloadFile';
import log from '../utils/log';

class AutoDownloader {
async checkForDownloadAvailable(sourceFileName: string) {
const sourceFilePath = path.join(TOOLKIT_PACKAGES_DIR, sourceFileName);
const sourceFileExists = await fse.pathExists(sourceFilePath);
log.info(sourceFileExists ? `${sourceFileName} has already existed in ${sourceFilePath}` : `${sourceFileName} is available to download.`);
return !sourceFileExists;
}

async downloadPackage({ downloadUrl, sourceFileName }) {
await downloadFile(downloadUrl, TOOLKIT_PACKAGES_DIR, sourceFileName);
}

async start(data) {
const { sourceFileName } = data;
const downloadAvailable = await this.checkForDownloadAvailable(sourceFileName);
if (downloadAvailable) {
await this.downloadPackage(data);
}
}
}

export default AutoDownloader;
31 changes: 31 additions & 0 deletions main/autoDownloader/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { IBasePackageInfo, Platform } from '../types';
import store, { packagesDataKey } from '../store';
import getPackageFileName from '../utils/getPackageFileName';
import AutoDownloader from './AutoDownloader';

const packageTypes = ['bases'];

export async function autoDownloadPackages() {
const data = store.get(packagesDataKey);
// the packages which should be checked for available downloading
const packageDatas = [];

packageTypes.forEach((packageType: string) => {
const packagesInfo: IBasePackageInfo[] = data[packageType] || [];

for (const packageInfo of packagesInfo) {
const { downloadUrl, platforms } = packageInfo;
const currentPlatform = process.platform as Platform;
if (!downloadUrl || !platforms.includes(currentPlatform)) {
continue;
}
const packageFileName = getPackageFileName(packageInfo);
packageDatas.push({ sourceFileName: packageFileName, downloadUrl });
}
});

await Promise.all(packageDatas.map((packageData) => {
const autoDownloader = new AutoDownloader();
return autoDownloader.start(packageData);
}));
}
14 changes: 10 additions & 4 deletions main/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,23 @@ export const APPLICATIONS_DIR_PATH = '/Applications';

export const PACKAGE_JSON_FILE_NAME = 'package.json';

export const TOOLKIT_TMP_DIR = path.join(process.env.HOME, '.toolkit');
export const TOOLKIT_DIR = path.join(process.env.HOME, '.toolkit');
export const TOOLKIT_TMP_DIR = path.join(TOOLKIT_DIR, 'tmp');
export const TOOLKIT_PACKAGES_DIR = path.join(TOOLKIT_DIR, 'packages');

export const DEFAULT_LOCAL_PACKAGE_INFO: ILocalPackageInfo = {
localVersion: null,
localPath: null,
versionStatus: 'uninstalled',
};

export const VSCODE_CLI_COMAMND_NAME = 'code';
export const VSCODE_COMMAND_NAME = 'code';
export const VSCODE_NAME = 'Visual Studio Code';

export const INSTALL_COMMAND_PACKAGES = [
{
name: 'Visual Studio Code',
command: 'code',
name: VSCODE_NAME,
command: VSCODE_COMMAND_NAME,
commandRelativePath: './Contents/Resources/app/bin/code',
},
];
Expand All @@ -28,3 +31,6 @@ 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';

export const PROFILE_FILES = ['.bash_profile', '.bashrc', '.zshrc'];
export const DEFAULT_PROFILE_FILE = '.bash_profile';
40 changes: 29 additions & 11 deletions main/data/data.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@
"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",
"version": "2.31.0",
"recommended": true,
"isInternal": false,
"type": "cli",
"platform": "darwin"
"platforms": ["darwin"]
},
{
"title": "Node.js (NVM)",
Expand All @@ -24,7 +24,7 @@
"recommended": true,
"isInternal": false,
"type": "cli",
"platform": "darwin",
"platforms": ["darwin"],
"options": {
"managerName": "nvm"
}
Expand All @@ -40,7 +40,7 @@
"recommended": true,
"isInternal": false,
"type": "dmg",
"platform": "darwin"
"platforms": ["darwin"]
},
{
"title": "Visual Studio Code",
Expand All @@ -53,7 +53,7 @@
"recommended": true,
"isInternal": false,
"type": "dmg",
"platform": "darwin"
"platforms": ["darwin"]
},
{
"title": "AppWorks Pack",
Expand All @@ -67,18 +67,36 @@
"type": "IDEExtension",
"options": {
"IDEType": "VSCode"
}
},
"platforms": ["darwin", "win32"]
}
],
"apps": [
{
"title": "Google Chrome",
"name": "Google Chrome",
"description": "强大、快速的网页浏览器",
"icon": "https://img.alicdn.com/imgextra/i3/O1CN01cspie61ZOm8vgQfKl_!!6000000003185-55-tps-32-32.svg",
"downloadUrl": "",
"version": "89.0.4389.114",
"link": "https://www.google.com/chrome/",
"icon": "https://img.alicdn.com/imgextra/i2/O1CN01jRdeW91kg8w2eH4YR_!!6000000004712-0-tps-225-225.jpg",
"downloadUrl": "https://iceworks.oss-cn-hangzhou.aliyuncs.com/toolkit/packages/dmg/googlechrome.dmg",
"version": null,
"recommended": true,
"isInternal": false
"isInternal": false,
"type": "dmg",
"platforms": ["darwin"]
},
{
"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-universal.zip",
"version": null,
"recommended": true,
"isInternal": false,
"type": "dmg",
"platforms": ["darwin"]
}
],
"npmPackages": [
Expand Down Expand Up @@ -133,4 +151,4 @@
}
}
]
}
}
8 changes: 4 additions & 4 deletions main/data/shells/install-nvm.sh
Original file line number Diff line number Diff line change
Expand Up @@ -269,12 +269,12 @@ nvm_detect_profile() {

local DETECTED_PROFILE
DETECTED_PROFILE=''

if [ -n "${BASH_VERSION-}" ]; then
if [ -f "$HOME/.bashrc" ]; then
DETECTED_PROFILE="$HOME/.bashrc"
elif [ -f "$HOME/.bash_profile" ]; then
# execute order is: .bash_profile > .bashrc
if [ -f "$HOME/.bash_profile" ]; then
DETECTED_PROFILE="$HOME/.bash_profile"
elif [ -f "$HOME/.bashrc" ]; then
DETECTED_PROFILE="$HOME/.bashrc"
fi
elif [ -n "${ZSH_VERSION-}" ]; then
DETECTED_PROFILE="$HOME/.zshrc"
Expand Down
5 changes: 5 additions & 0 deletions main/data/shells/is-nvm-installed.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env bash

\. "$NVM_DIR/nvm.sh"

echo "$(command -v nvm 2>/dev/null)"
29 changes: 21 additions & 8 deletions main/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,35 @@ import modifyProcessEnv from './utils/modifyProcessEnv';
import { createWindow } from './window';
import handleIPC from './ipc';
import { checkForUpdates } from './utils/autoUpdater';
import getPackagesData from './utils/getPackagesData';
import { autoDownloadPackages } from './autoDownloader';
import store, { packagesDataKey } from './store';
import { recordDAU } from './recorder';

process.env.ELECTRON_DISABLE_SECURITY_WARNINGS = 'true';

app.whenReady().then(() => {
checkForUpdates();
app.whenReady()
.then(() => getPackagesData())
.then((packagesData) => {
store.set(packagesDataKey, packagesData);
})
.finally(() => {
modifyProcessEnv();

modifyProcessEnv();
createWindow();

createWindow();
handleIPC();

handleIPC();
checkForUpdates();

app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) createWindow();
autoDownloadPackages();

recordDAU();

app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) createWindow();
});
});
});

// Quit when all windows are closed.
app.on('window-all-closed', () => {
Expand Down
15 changes: 7 additions & 8 deletions main/ipc/getBasePackagesInfo.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
import * as path from 'path';
import * as fse from 'fs-extra';
import { ipcMain } from 'electron';
import { IBasePackageInfo } from '../types';
import { IBasePackageInfo, Platform } from '../types';
import { getPackageInfo } from '../packageInfo';
import checkIsAliInternal from '../utils/checkIsAliInternal';
import store, { packagesDataKey } from '../store';

export default () => {
ipcMain.handle('get-base-packages-info', async () => {
// TODO: get data.json from OSS and save it in the storage when app starts first
const data = await fse.readJSON(path.join(__dirname, '../data', 'data.json'));
const data = store.get(packagesDataKey);
const { bases = [] }: { bases: IBasePackageInfo[] } = data;
const isAliInternal = await checkIsAliInternal();
const basePackages = bases.filter((item) => {
// remove internal package when not in the ali internal
return item.isInternal ? isAliInternal : true;
const basePackages = bases.filter(({ isInternal, platforms }) => {
// 1. only return the package info in current platform
// 2. remove internal package when not in the ali internal
return platforms.includes(process.platform as Platform) && (isInternal ? isAliInternal : true);
});
const packagesData = await Promise.all(basePackages.map((basePackageInfo: IBasePackageInfo) => {
return getPackageInfo(basePackageInfo);
Expand Down
11 changes: 4 additions & 7 deletions main/ipc/getNodeInfo.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,20 @@
import * as path from 'path';
import * as fse from 'fs-extra';
import { ipcMain } from 'electron';
import { IpcMainInvokeEvent } from 'electron/main';
import getNodeVersions from '../utils/getNodeVersions';
import { getPackageInfo } from '../packageInfo';
import { IBasePackageInfo } from '../types';
import store, { packagesDataKey } from '../store';

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

return nodeInfo;
});

ipcMain.handle('get-node-versions', async (event: IpcMainInvokeEvent) => {
ipcMain.handle('get-node-versions', async () => {
return await getNodeVersions();
});
};
7 changes: 5 additions & 2 deletions main/ipc/installBasePackages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { send as sendMainWindow } from '../window';
import killChannelChildProcess from '../utils/killChannelChildProcess';
import log from '../utils/log';
import nodeCache from '../utils/nodeCache';
import store, { packagesDataKey } from '../store';

const childProcessMap = new Map();

Expand All @@ -23,8 +24,10 @@ export default () => {
// fork a child process to install package
childProcess = child_process.fork(path.join(__dirname, '..', 'packageInstaller/index'));
childProcessMap.set(installChannel, childProcess);

childProcess.send({ packagesList, installChannel, processChannel });
// After packing the Electron app, the electron module which the electron-store require, couldn't be found in childProcess.
// For more detail, see this PR: https://github.com/appworks-lab/toolkit/pull/41
const packagesData = store.get(packagesDataKey);
childProcess.send({ packagesList, packagesData, installChannel, processChannel });

childProcess.on('message', ({ channel, data }: any) => {
if (channel === processChannel) {
Expand Down
8 changes: 4 additions & 4 deletions main/packageInfo/IDEExtension/vscodeExtension.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import * as execa from 'execa';
import isCliInstalled from '../../utils/isCliInstalled';
import { VSCODE_CLI_COMAMND_NAME } from '../../constants';
import isCliInstalled from '../../utils/isCommandInstalled';
import { VSCODE_COMMAND_NAME } from '../../constants';
import { ILocalPackageInfo } from '../../types';

async function getVSCodeExtensionInfo(name: string) {
const extensionInfo: ILocalPackageInfo = {
versionStatus: 'uninstalled',
localVersion: null,
};
if (isCliInstalled(VSCODE_CLI_COMAMND_NAME)) {
if (isCliInstalled(VSCODE_COMMAND_NAME)) {
const { stdout } = await execa(
VSCODE_CLI_COMAMND_NAME,
VSCODE_COMMAND_NAME,
['--list-extensions', '--show-versions'],
);
if (stdout && typeof stdout === 'string') {
Expand Down
Loading

0 comments on commit c5d93d8

Please sign in to comment.