Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ module.exports = getESLintConfig('react-ts', {
'@iceworks/best-practices/recommend-polyfill': 0,
'import/order': 1,
'no-param-reassign': 0,
'@typescript-eslint/no-require-imports': 0
'@typescript-eslint/no-require-imports': 0,
'no-await-in-loop': 0
},
});
16 changes: 10 additions & 6 deletions main/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export const PACKAGE_JSON_FILE_NAME = 'package.json';
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 TOOLKIT_USER_GIT_CONFIG_DIR = path.join(TOOLKIT_DIR, 'git');

export const DEFAULT_LOCAL_PACKAGE_INFO: ILocalPackageInfo = {
localVersion: null,
Expand All @@ -25,12 +26,15 @@ export const INSTALL_COMMAND_PACKAGES = [
commandRelativePath: './Contents/Resources/app/bin/code',
},
];

export const NOT_REINSTALL_PACKAGES = ['npm'];

export const NOT_REINSTALL_DEPENDENCIES = ['npm'];
// bash profile
export const PROFILE_FILES = ['.bash_profile', '.bashrc', '.zshrc'];
export const DEFAULT_PROFILE_FILE = '.bash_profile';
// npm
export const NPMRC_PATH = path.join(process.env[(process.platform === 'win32') ? 'USERPROFILE' : 'HOME'], '.npmrc');
export const NPM_REGISTRY = 'https://registry.npmjs.org/';
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';
// git
export const GLOBAL_GITCONFIG_PATH = path.join(process.env[(process.platform === 'win32') ? 'USERPROFILE' : 'HOME'], '.gitconfig');
5 changes: 5 additions & 0 deletions main/data/data.json
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,11 @@
"registry": "https://registry.npmjs.org/",
"isInternal": false
},
{
"name": "yarn",
"registry": "https://registry.yarnpkg.com/",
"isInternal": false
},
{
"name": "taobao",
"registry": "https://registry.npm.taobao.org/",
Expand Down
187 changes: 187 additions & 0 deletions main/git/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
import * as path from 'path';
import ini = require('ini');
import * as fse from 'fs-extra';
import * as globby from 'globby';
import { IAddUserConfig, IUserConfig } from '../types/git';
import { GLOBAL_GITCONFIG_PATH, TOOLKIT_USER_GIT_CONFIG_DIR } from '../constants';
import log from '../utils/log';
import {
updateSSHConfig,
getSSHConfig,
removeSSHConfig,
addSSHConfig,
} from './ssh';

const USER_GIT_CONFIG_FILENAME_PREFIX = '.gitconfig-';
const IGNORE_CONFIG_KEYS = ['gitDir'];

export async function getGlobalGitConfig() {
const globalGitConfig = await parseGitConfig(GLOBAL_GITCONFIG_PATH);
log.info('get-global-git-config', globalGitConfig);
return globalGitConfig;
}

export async function updateGlobalGitConfig(gitConfig: object) {
log.info('update-global-git-config', gitConfig);
await writeGitConfig(GLOBAL_GITCONFIG_PATH, gitConfig);
}

export async function getExistedUserGitConfigNames() {
const filenames = await getUserGitConfigFilenames();
return filenames.map((filename: string) => filename.replace(USER_GIT_CONFIG_FILENAME_PREFIX, ''));
}

/**
* get user git config list
*/
export async function getUserGitConfigs(): Promise<IUserConfig[]> {
const gitConfigFilenames = await getUserGitConfigFilenames();
const userGitDirs = await getUserGitDirs();

const userGitConfigs = [];
for (const gitConfigFilename of gitConfigFilenames) {
const configPath = path.join(TOOLKIT_USER_GIT_CONFIG_DIR, gitConfigFilename);
if (!fse.pathExistsSync(configPath)) {
continue;
}
const gitConfig = await parseGitConfig(configPath);
const filename = path.basename(configPath);
const configName = filename.replace(USER_GIT_CONFIG_FILENAME_PREFIX, '');
const { SSHPublicKey } = await getSSHConfig(configName);
userGitConfigs.push({
...gitConfig,
SSHPublicKey,
configName,
gitDirs: userGitDirs[configPath] || [],
});
}

return userGitConfigs;
}

export async function addUserGitConfig(userGitConfig: IAddUserConfig) {
const { configName, user: { name: userName, hostName } } = userGitConfig;
const gitConfigPath = getGitConfigPath(configName);

checkUserGitConfigExists(configName, gitConfigPath);

await fse.createFile(gitConfigPath);
// do not save the configName to the gitconfig file
delete userGitConfig.configName;
await writeGitConfig(gitConfigPath, userGitConfig);
await addSSHConfig({ hostName, configName, userName });
}

export async function updateUserGitConfig(gitConfig: any, configName: string) {
const { user = {} } = gitConfig;
const { name: userName = '', hostName = '' } = user;
await updateSSHConfig(configName, hostName, userName);

IGNORE_CONFIG_KEYS.forEach((key) => {
delete gitConfig[key];
});
// save to ~/.toolkit/git/.gitconfig-${configName}
const gitConfigPath = `${path.join(TOOLKIT_USER_GIT_CONFIG_DIR, `${USER_GIT_CONFIG_FILENAME_PREFIX}${configName}`)}`;
await writeGitConfig(gitConfigPath, gitConfig);

log.info('update-user-git-config', configName, gitConfig);
}

async function getUserGitDirs() {
const globalGitConfig = await getGlobalGitConfig();

const userGitDirs = {};

const configKeys = Object.keys(globalGitConfig);

for (const configKey of configKeys) {
const { path: gitConfigPath } = globalGitConfig[configKey];
if (!gitConfigPath) {
continue;
}
if (!userGitDirs[gitConfigPath]) {
userGitDirs[gitConfigPath] = [];
}
const gitDir = configKey.replace(/includeIf "gitdir:(.*)"/, (match, p1) => p1);
userGitDirs[gitConfigPath].push(gitDir);
}

return userGitDirs;
}

export async function updateUserGitDir(
originGitDir: string,
currentGitDir: string,
configName: string,
) {
const globalGitConfig = await parseGitConfig(GLOBAL_GITCONFIG_PATH);

const originIncludeIfKey = `includeIf "gitdir:${originGitDir}"`;
const currentIncludeIfKey = `includeIf "gitdir:${currentGitDir}"`;

delete globalGitConfig[originIncludeIfKey];
const gitConfigPath = getGitConfigPath(configName);
globalGitConfig[currentIncludeIfKey] = { path: gitConfigPath };
await writeGitConfig(GLOBAL_GITCONFIG_PATH, globalGitConfig);

log.info('update-user-git-dir: ', currentIncludeIfKey, globalGitConfig[currentIncludeIfKey]);
}

export async function removeUserGitDir(gitDir: string, configName: string) {
const gitConfigPath = getGitConfigPath(configName);
const globalGitConfig = await parseGitConfig(GLOBAL_GITCONFIG_PATH);

const includeIfKey = `includeIf "gitdir:${gitDir}"`;
const includeIfValue = globalGitConfig[includeIfKey];
if (includeIfValue && includeIfValue.path === gitConfigPath) {
delete globalGitConfig[includeIfKey];
await writeGitConfig(GLOBAL_GITCONFIG_PATH, globalGitConfig);
log.info('remove-user-git-dir: ', includeIfKey, gitConfigPath);
} else {
const error = new Error(`Can not remove ${gitDir}. The ${includeIfValue} is not found.`);
log.error(error);
throw error;
}
}

export async function removeUserGitConfig(configName: string, gitDirs = []) {
await removeSSHConfig(configName);

for (const gitDir of gitDirs) {
await removeUserGitDir(gitDir, configName);
}

// remove the gitconfig file
const gitConfigPath = getGitConfigPath(configName);
await fse.remove(gitConfigPath);
}

async function parseGitConfig(gitConfigPath: string) {
const gitConfigContent = await fse.readFile(gitConfigPath, 'utf-8');
return ini.parse(gitConfigContent);
}

async function writeGitConfig(gitConfigPath: string, config: object) {
await fse.writeFile(gitConfigPath, ini.stringify(config));
log.info('write-git-config', config);
}

function checkUserGitConfigExists(configName: string, gitConfigPath: string) {
if (fse.pathExistsSync(gitConfigPath)) {
const err = new Error(`${configName} config has existed,please use other config name.`);
err.name = 'add-user-git-config';
log.error(err);
throw err;
}
}

async function getUserGitConfigFilenames() {
return await globby([`${USER_GIT_CONFIG_FILENAME_PREFIX}*`], { cwd: TOOLKIT_USER_GIT_CONFIG_DIR, dot: true });
}

/**
* get absolute git config path in ~/.toolkit/git/
*/
function getGitConfigPath(configName: string) {
return path.join(TOOLKIT_USER_GIT_CONFIG_DIR, `${USER_GIT_CONFIG_FILENAME_PREFIX}${configName}`);
}
2 changes: 2 additions & 0 deletions main/git/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './config';
export * from './ssh';
Loading