UNPKG

rigjs

Version:

A multi-repos dev tool based on yarn and git.Rigjs is intended to be the simplest way to develop,share and deliver codes between different developers or different projects.

205 lines (187 loc) 5.77 kB
import {Dep} from '@/classes/dependencies/Dep'; import fsHelper from '@/utils/fsHelper'; import objectHelper from '@/utils/objectHelper'; import print from '@/print'; import shell from 'shelljs'; import semver from 'semver'; import compareVersions from 'compare-versions' import os from "os"; const JSON5 = require('json5'); interface RigConfigJSON5 { dependencies: { [name: string]: Dep; }; share:{ [name: string]: string | string[]; }; } class RigConfig { dependencies: { [name: string]: Dep; } = {}; isLegacy = false; share: { [name: string]: string | string[]; } = {}; constructor(rigConfig: RigConfigJSON5 | Dep[]) { if (Array.isArray(rigConfig)) { //旧版配置 this.isLegacy = true; const depArrLegacy = rigConfig as Dep[]; for (let depLegacy of depArrLegacy) { const dep = new Dep(depLegacy); this.dependencies[dep.name] = dep; } } else { for (let rigName in rigConfig.dependencies) { this.dependencies[rigName] = new Dep({...rigConfig.dependencies[rigName], name: rigName}) } this.share = rigConfig.share; } } /** * createFromCWD 从当前工作目录创建config对象 * @returns {RigConfig} */ static createFromCWD() { const configJSON5 = fsHelper.readConfig(); return new RigConfig(configJSON5); } /** * createFromPath 从absolute path中创建config对象 * @param {string} path * @returns {RigConfig} */ static createFromPath(path: string) { const configJSON5 = fsHelper.readConfig(path); return new RigConfig(configJSON5); } validate() { print.info(`rig validating rig-dependencies...`); for (let key in this.dependencies) { const ret = this.dependencies[key].validate(); if (!ret) { throw new Error(`rig validating:${this.dependencies[key]} is invalid`); } } } /** * 检查依赖的之间的依赖(仅包含rig管理下的依赖) * */ validateDeps() { print.info(`rig validating dependencies' requirements`); let valid = true; for (let rigName in this.dependencies) { const rigDep = this.dependencies[rigName]; let pkgStr: string; try { if (rigDep.dev) { // pkgStr = fsHelper.readPkgStrInRepo(rigName); print.info(`${rigName} is in deleloping.Skip Validating.`); continue; } else { let cmd = `git fetch ${rigDep.source} refs/tags/${rigDep.version} && git show FETCH_HEAD:package.json`; if (os.platform() === 'win32') { print.info(`skip on windows`); return; // cmd = `echo (git fetch ${rigDep.source} refs/tags/${rigDep.version}) -and (git show FETCH_HEAD:package.json)`; } print.info(`validateDeps:${cmd}`); let showPackageProcess = shell.exec(cmd, {silent: true} ); pkgStr = showPackageProcess.stdout.trim(); } pkgStr = pkgStr.replace('-and', ''); console.log(pkgStr) const pkg = JSON.parse(pkgStr); console.log(pkg); //获取rig依赖 if (pkg.rig) { const pkgRig = pkg.rig; //遍历rig依赖 Object.keys(pkgRig).forEach(key => { //获取该rig依赖的要求的版本范围 let max = ''; let min = ''; if (Array.isArray(pkgRig[key])) { //使用数组的情况 if (pkgRig[key].length == 0) { //依赖该库,但是无版本要求 } else if (pkgRig[key].length == 1) { min = semver.valid(pkgRig[key][0]) || ''; } else if (pkgRig[key].length == 2) { min = semver.valid(pkgRig[key][0]) || ''; max = semver.valid(pkgRig[key][1]) || ''; } else { print.error(`invalid array ${JSON.stringify([key])}`); valid = false; } } else { //使用字典的情况 min = pkgRig[key]['min'] || ''; max = pkgRig[key]['max'] || ''; } //从rigJson5获取该依赖的版本号 const dep = this.dependencies[key] print.info(`checking requirements of ${rigName}: ${key}[${min},${max}]`); if (dep) { if (dep.dev) { valid = true; } else { if (min) { if (!dep.version) throw new Error(`${dep.name}'s version is invalid:${dep.version}`) valid = compareVersions(dep.version, min) >= 0; } if (max) { if (!dep.version) throw new Error(`${dep.name}'s version is invalid:${dep.version}`) valid = compareVersions(dep.version, max) <= 0 } if (!valid) { throw new Error(`${rigName} requires ${key}[${min},${max}],but ${key} is ${dep.version}!`); } } } else { print.error(`${key}[${min},${max}] is required`); valid = false; } }) } } catch (e) { // @ts-ignore throw new Error(`rig validateDeps:${rigDep.source} failed:${e.message},${pkgStr}`); } } } toString() { return JSON5.stringify(this, null, 2); } overwrite(overwritePath: string = '') { overwritePath ? fsHelper.writeConfig(this, overwritePath) : fsHelper.writeConfig({ dependencies: this.dependencies }); } checkDepExists(name: string) { return Object.keys(this.dependencies).find((key) => { return name === key; }) == name; } setDependencyToDev(name: string) { this.setDependenciesToDev(name); } setDependenciesToDev(names: string | string[]) { let nameArr = []; if (Array.isArray(names)) { nameArr.push(...names); } else { nameArr.push(names); } nameArr.forEach(name => { this.dependencies[name].dev = true; this.dependencies[name] = objectHelper.sortKeys(this.dependencies[name]); }); } findOrUpsertDep(name: string, dep: Dep) { if (this.checkDepExists(name)) { this.dependencies[name].dev = true; } else { this.dependencies[name] = dep; } this.dependencies[name] = objectHelper.sortKeys(this.dependencies[name]); } } export default RigConfig;