UNPKG

@sprucelabs/spruce-cli

Version:

Command line interface for building Spruce skills.

189 lines • 8.22 kB
#!/usr/bin/env node "use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const child_process_1 = require("child_process"); const spruce_skill_utils_1 = require("@sprucelabs/spruce-skill-utils"); const dotenv_1 = __importDefault(require("dotenv")); const TerminalInterface_1 = __importDefault(require("../interfaces/TerminalInterface")); const ImportService_1 = __importDefault(require("../services/ImportService")); const ServiceFactory_1 = __importDefault(require("../services/ServiceFactory")); const test_utility_1 = __importDefault(require("../tests/utilities/test.utility")); const graphicsInterface_types_1 = require("../types/graphicsInterface.types"); const duration_utility_1 = __importDefault(require("../utilities/duration.utility")); const FeatureFixture_1 = __importDefault(require("./fixtures/FeatureFixture")); const MercuryFixture_1 = __importDefault(require("./fixtures/MercuryFixture")); dotenv_1.default.config({ quiet: true }); const packageJsonContents = spruce_skill_utils_1.diskUtil.readFile(spruce_skill_utils_1.diskUtil.resolvePath(__dirname, '..', '..', 'package.json')); const packageJson = JSON.parse(packageJsonContents); const { testSkillCache } = packageJson; const testKeys = Object.keys(testSkillCache); let remaining = testKeys.length; const term = new TerminalInterface_1.default(__dirname, true); const start = new Date().getTime(); const testSkillsToCache = process.env.TEST_SKILLS_TO_CACHE === '*' ? undefined : process.env.TEST_SKILLS_TO_CACHE; const onlyInstall = testSkillsToCache?.split(',').map((t) => t.trim()); const shouldRunSequentially = !!process.argv.find((a) => a === '--shouldRunSequentially=true' || a === '--shouldRunSequentially'); const maxSimultaneous = parseInt(process.env.MAX_SIMULTANEOUS_SKILL_CACHERS ?? '10', 10); let totalSimultaneous = 0; let progressInterval; const doesSupportColor = TerminalInterface_1.default.doesSupportColor(); let didMessagesChange = true; async function run() { term.clear(); if (process.env.WILL_BUILD_CACHE_SCRIPT) { term.renderLine('Running will-build cache script'); if (process.env.CLEAN_CACHE_SCRIPT) { try { (0, child_process_1.execSync)(process.env.CLEAN_CACHE_SCRIPT); } catch { /* Empty */ } } (0, child_process_1.execSync)(process.env.WILL_BUILD_CACHE_SCRIPT); } term.renderHeadline(`Found ${testKeys.length} skills to cache.`); let messages = []; const render = async () => { if (didMessagesChange) { term.moveCursorTo(0, 6); for (const message of messages) { term.eraseLine(); term.renderLine(message[0], message[1]); } await term.stopLoading(); term.eraseLine(); term.renderLine(''); } didMessagesChange = false; await term.startLoading(`${`Building ${remaining} skill${dropInS(remaining)}`}. ${duration_utility_1.default.msToFriendly(getTimeSpent())}`); term.clearBelowCursor(); }; progressInterval = doesSupportColor && setInterval(render, 1000); function getTimeSpent() { const now = new Date().getTime(); const delta = now - start; return delta; } function renderLine(lineNum, message, effects) { if (doesSupportColor) { didMessagesChange = true; messages[lineNum] = [message, effects]; void render(); } else { console.log(message); } } function renderWarning(lineNum, message, effects) { if (doesSupportColor) { didMessagesChange = true; messages[lineNum] = [message, effects]; void render(); } else { console.log(message); } } if (doesSupportColor) { await term.startLoading(`Building ${remaining} remaining skill${dropInS(remaining)}...`); } if (shouldRunSequentially) { await Promise.all(testKeys.map((cacheKey, idx) => cacheOrSkip(idx, cacheKey))); } else { const promises = testKeys.map(async (cacheKey, idx) => { while (totalSimultaneous >= maxSimultaneous) { await new Promise((resolve) => setTimeout(resolve, 1000)); } totalSimultaneous++; await cacheOrSkip(idx, cacheKey); totalSimultaneous--; }); await Promise.all(promises); } await term.stopLoading(); term.renderLine(`Done! ${duration_utility_1.default.msToFriendly(getTimeSpent())}`); async function cacheOrSkip(lineNum, cacheKey) { const { cacheTracker, cwd, fixture, options } = setup(cacheKey); if (onlyInstall && onlyInstall.indexOf(cacheKey) === -1) { renderLine(lineNum, `Skipping '${cacheKey}'.`, [ graphicsInterface_types_1.GraphicsTextEffect.Yellow, ]); remaining--; } else if (cacheTracker[cacheKey] && spruce_skill_utils_1.diskUtil.doesDirExist(spruce_skill_utils_1.diskUtil.resolvePath(cwd, 'node_modules'))) { remaining--; renderLine(lineNum, `'${cacheKey}' already cached. Skipping...`, [ graphicsInterface_types_1.GraphicsTextEffect.Italic, ]); } else { await cache(lineNum, cwd, cacheKey, fixture, options); remaining--; } } function setup(cacheKey) { const options = testSkillCache[cacheKey]; const importCacheDir = test_utility_1.default.resolveTestDir('spruce-cli-import-cache'); ImportService_1.default.setCacheDir(importCacheDir); const serviceFactory = new ServiceFactory_1.default(); const cwd = test_utility_1.default.resolveTestDir(cacheKey); const mercuryFixture = new MercuryFixture_1.default(cwd, serviceFactory); const fixture = new FeatureFixture_1.default({ cwd, serviceFactory, ui: new TerminalInterface_1.default(cwd), shouldGenerateCacheIfMissing: true, apiClientFactory: mercuryFixture.getApiClientFactory(), }); const cacheTracker = fixture.loadCacheTracker(); return { cacheTracker, cwd, fixture, options }; } async function cache(lineNum, cwd, cacheKey, fixture, options) { if (spruce_skill_utils_1.diskUtil.doesDirExist(cwd)) { renderWarning(lineNum, `Found cached '${cacheKey}', but deleted it since it was not in the cache tracker...`, [graphicsInterface_types_1.GraphicsTextEffect.Italic]); spruce_skill_utils_1.diskUtil.deleteDir(cwd); } renderLine(lineNum, `Starting to build '${cacheKey}'...`, [ graphicsInterface_types_1.GraphicsTextEffect.Green, ]); try { await fixture.installFeatures(options, cacheKey); renderLine(lineNum, `Done caching '${cacheKey}'. ${remaining - 1} remaining (${duration_utility_1.default.msToFriendly(getTimeSpent())})...`, [graphicsInterface_types_1.GraphicsTextEffect.Green, graphicsInterface_types_1.GraphicsTextEffect.Bold]); } catch (err) { renderLine(lineNum, `Error caching '${cacheKey}'...`, [ graphicsInterface_types_1.GraphicsTextEffect.Red, graphicsInterface_types_1.GraphicsTextEffect.Bold, ]); renderLine(lineNum, `Error caching ${cacheKey}:\n\n${err.stack}`); } } } function dropInS(remaining) { return remaining === 1 ? '' : 's'; } void run() .then(() => { if (process.env.DID_BUILD_CACHE_SCRIPT) { term.renderLine('Running did-build cache script'); (0, child_process_1.execSync)(process.env.DID_BUILD_CACHE_SCRIPT); } if (progressInterval) { clearInterval(progressInterval); } }) .catch((err) => { term.renderError(err); if (progressInterval) { clearInterval(progressInterval); } }); //# sourceMappingURL=buildTestCache.js.map