import * as ora from "ora"; import * as fse from "fs-extra"; import * as inquirer from "inquirer"; import * as SearchCheckbox from "inquirer-search-checkbox"; import Git from "./Git"; import { getPackages } from "./parse"; import { printWarn, printInfo } from "./index"; import { HOME_DIR, lastBuiltEntryCache } from "../CacheData"; inquirer.registerPrompt("SearchCheckbox", SearchCheckbox); const CACHE_FILE = `./${HOME_DIR}/auto-entry`; const git = new Git(); const ALL_KEY = ""; const AUTO_KEY = "auto"; const LAST_KEY = ""; export async function updateAutoEntry() { const latestCommit = await git.getLatestCommit(); const files = await git.getFilesByCommits([latestCommit]); if (files.length === 1 && files[0].includes("auto-entry")) { // prevent useless cycle commit return; } fse.writeFile(CACHE_FILE, latestCommit, "utf8").then(async () => { const msg = "Auto update ezpack auto-entry"; await git.add(CACHE_FILE); await git.commit(msg); git.push().catch(e => { printWarn(`${msg} fail.`); }); }); } function getAutoEntry(): string { fse.ensureFileSync(CACHE_FILE); return fse.readFileSync(CACHE_FILE, "utf8").replace("\n", ""); } async function autoSelectEntry( entry: { [index: string]: string[]; }, rootPath: string ) { const allPackageMap: { [index: string]: object; } = {}; const entryKeyList = Object.keys(entry); const spinner = ora("Finding entries..."); spinner.start(); return Promise.all( Object.keys(entry).map(k => { const item = entry[k]; let entryFile: string | string[] = item; if (Array.isArray(item)) { entryFile = item.reverse()[0]; } allPackageMap[k] = {}; return getPackages(allPackageMap[k], entryFile as string, rootPath); }) ).then(async packages => { const saveCommit = getAutoEntry(); const latestCommit = await git.getLatestCommit(); spinner.stop(); if (saveCommit && saveCommit !== latestCommit) { const files = await git.getFilesByCommitRange(saveCommit, latestCommit); const changeKeyList = entryKeyList.filter(k => files.some(file => allPackageMap[k][file])); if (changeKeyList.length > 0) { console.log("Below entries will be built: "); changeKeyList.forEach(k => { console.log(" - " + k); }); console.log(); return changeKeyList.reduce((obj, k) => { obj[k] = entry[k]; return obj; }, {}); } return null; } return null; }); } export async function getEntryByKey(key: string[], entry: any, rootPath: string) { if (key.includes(ALL_KEY)) { return Promise.resolve(entry); } else if (key.includes(AUTO_KEY)) { return await autoSelectEntry(entry, rootPath); } else if (key.includes(LAST_KEY)) { const lastEntry = lastBuiltEntryCache.getEntry(); if (lastEntry.length === 0) { return Promise.resolve(null); } else { key = lastBuiltEntryCache.getEntry(); printInfo(`Building entry: ${key.join(", ")}`); } } lastBuiltEntryCache.refreshEntry(key); const outputEntry = key.reduce(function(pValue, cValue) { if (typeof entry[cValue] !== "undefined") { pValue[cValue] = entry[cValue]; } return pValue; }, {}); return Promise.resolve(outputEntry); } export async function readCustomEntry(entry, rootPath: string, auto?: boolean) { if (Array.isArray(entry)) { // 数组entry直接返回; return entry; } let keys = [ALL_KEY, LAST_KEY].concat(Object.keys(entry)); const answers = await inquirer.prompt([ { type: "SearchCheckbox", name: "key", message: `Select your webpack entry (${keys.length})`, choices: keys.map(name => ({ name })), pageSize: 6, validate: function(answer) { if (answer.length < 1) { return "You must choose at least one entry."; } return true; } } ]); return getEntryByKey(answers.key, entry, rootPath); }