UNPKG

xdc-npm

Version:

xnpm 命令行客户端

179 lines (154 loc) 4.53 kB
/** ! * Copyright(c) cnpmjs.org and other contributors. * MIT Licensed * * Authors: * fengmk2 <fengmk2@gmail.com> (http://fengmk2.com) * dead_horse <dead_horse@qq.com> (http://deadhorse.me) */ require('colors'); const debug = require('debug')('xnpm:origin'); const match = require('auto-correct'); const spawn = require('cross-spawn'); const fs = require('fs'); const path = require('path'); const config = require('./config'); const parseArgv = require('./parse_argv'); const binaryMirrorConfig = require('binary-mirror-config').china; const program = parseArgv(); const rawArgs = program.rawArgs.slice(2); const args = []; let isInstall = false; const isWin = /^win/.test(process.platform); let hasCNPM = false; for (let i = 0; i < rawArgs.length; i++) { let arg = rawArgs[i]; if (arg[0] !== '-') { arg = correct(arg); if (arg === 'tnpm') { arg = '@tencent/tnpm'; console.log('redirect from `tnpm` to `@tencent/tnpm`'); } if (i === 0 && (arg === 'i' || arg === 'install')) { isInstall = true; } if (arg === '@tencent/tnpm') { hasCNPM = true; } } args.push(arg); } const CWD = process.cwd(); if (program.userconfig && !fs.existsSync(program.userconfig)) { // make sure userconfig exists // or it will throw: npm ERR! Error: default value must be string or number fs.writeFileSync(program.userconfig, 'email =\n'); } args.unshift(`--registry=${program.registry}`); args.unshift(`--cache=${program.cache}`); args.unshift('--no-audit'); if (program.disturl) { args.unshift(`--disturl=${program.disturl}`); } if (program.userconfig) { args.unshift(`--userconfig=${program.userconfig}`); } if (program.proxy) { // 默认用代理实现 args.unshift(`--proxy=${program.proxy}`); } else { args.unshift(`--proxy=${config.proxy}`); } function getBinaryMirrorsFromConfig() { const result = {}; for (const binName in binaryMirrorConfig) { const hostInfo = binaryMirrorConfig[binName]; const tnpmMirrorUrl = replaceWithTnpmMirror(hostInfo.host); if (tnpmMirrorUrl && Object.keys(hostInfo).length === 1) { result[binName] = tnpmMirrorUrl; } } return result; } // 各种二进制包的参数 // https://github.com/cnpm/binary-mirror-config/blob/master/package.json const binaryMirrors = Object.assign(getBinaryMirrorsFromConfig(), { debug: `${config.mirrorsUrl}/node-inspector/`, profiler: `${config.mirrorsUrl}/node-inspector/`, node_sqlite3: `${config.mirrorsUrl}/`, grpc_node: `${config.mirrorsUrl}/`, fse: `${config.mirrorsUrl}/fsevents/`, }); for (const binName in binaryMirrors) { args.unshift(`--${binName}_binary_host_mirror=${binaryMirrors[binName]}`); } function finxnpmBin() { if (isWin && isInstall && hasCNPM) { // windows在用tnpm安装tnpm的时候,不能自己覆盖自己 return path.join(path.dirname(process.execPath), 'npm'); } return path.join(__dirname, 'node_modules', '.bin', 'npm'); } const npmBin = finxnpmBin(); debug('%s %s', npmBin, args.join(' ')); // 只有能被成功替换的才是能被使用的 mirror url,否则不要使用 function replaceWithTnpmMirror(url) { if (!url) { return ''; } if (url.indexOf('https://cdn.npm.taobao.org') > -1) { return url.replace('https://cdn.npm.taobao.org', config.taobaoNpmCdnUrl); } if (url.indexOf('https://npm.taobao.org/mirrors') > -1) { return url.replace('https://npm.taobao.org/mirrors', config.mirrorsUrl); } return ''; } // 环境变量 function getEnvFromConfig() { const result = {}; for (const k in binaryMirrorConfig.ENVS) { const v = binaryMirrorConfig.ENVS[k]; const tnpmMirrorUrl = replaceWithTnpmMirror(v); if (tnpmMirrorUrl) { result[k] = tnpmMirrorUrl; } } return result; } const env = getEnvFromConfig(); for (const k in process.env) { env[k] = process.env[k]; } // https://github.com/lovell/sharp/blob/master/install/libvips.js env.SHARP_DIST_BASE_URL = `${config.taobaoNpmCdnUrl}/dist/sharp-libvips/`; const npm = spawn(npmBin, args, { env, cwd: CWD, stdio: [ process.stdin, process.stdout, process.stderr, ], }); npm.on('exit', (code, signal) => { process.exit(code); }); /** * correct command * @return {[type]} [description] */ function correct(command) { const cmds = [ 'install', 'publish', 'adduser', 'author', 'config', 'unpublish', ]; for (let i = 0; i < cmds.length; i++) { if (match(command, cmds[i])) { return cmds[i]; } } return command; }