| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227 |
- import { checkCache, updateCache } from "./cache.js";
- import {
- createTrackedObject,
- fileExists,
- readFilesByGlob,
- removeBasePaths,
- removeCwd,
- replaceFileExtension,
- getValueAtPath
- } from "./util/index.js";
- import path from "path";
- import process from "node:process";
- import { getLogger } from "./logging.js";
- export async function getConfig() {
- const args = process.argv.slice(2);
- const defaultPath = path.join(process.cwd(), "rhedyn.config.js");
- const findConfigPath = (args, index = 0) => {
- if (index >= args.length) {
- return defaultPath;
- }
- if (
- (args[index] === "-c" || args[index] === "--config") &&
- index + 1 < args.length
- ) {
- return path.resolve(args[index + 1]);
- }
- return findConfigPath(args, index + 1);
- };
- const configPath = findConfigPath(args);
- const configFileExists = await fileExists(configPath);
- if (configFileExists) {
- try {
- const config = await import(configPath);
- return config.default || config;
- } catch (err) {
- console.error(`Error reading config file at ${configPath}:`, err);
- throw new Error("Failed reading config file");
- }
- } else {
- return;
- }
- }
- async function runTask({ meta, config, jobId }) {
- const log = getLogger(
- config.logLevel ? config.logLevel : meta.opts.logLevel,
- jobId
- );
- log.trace(`meta: ${JSON.stringify(meta, null, 2)}`);
- log.trace(`config: ${JSON.stringify(config, null, 2)}`);
- const stateObject = {
- meta,
- config
- };
- const cache =
- meta.opts.cacheDir && !config.skipCache
- ? await checkCache(jobId, stateObject, meta.opts)
- : { disabled: true, reason: "Cache disabled" };
- if (cache && cache.hit) {
- log.debug(`Loaded cache for ${jobId}: ${cache.filePath}`);
- return { ...cache.taskResult, fromCache: true };
- }
- log.debug(`Cache miss for ${jobId} (${cache.reason})`);
- const state = meta.opts.cacheDir
- ? createTrackedObject(stateObject)
- : { proxy: stateObject };
- const {
- detail = {},
- paths = [],
- deps: processorDeps,
- ref
- } = await config.processor(state.proxy);
- const taskResult = {
- detail,
- paths: paths.map(fileOutputPath =>
- fileOutputPath.replace(meta.opts.outDir, "")
- ),
- ref
- };
- log.debug(`Wrote ${taskResult.paths.length} files for ${jobId}`);
- if (cache && !cache.disabled) {
- log.debug(`Updating cache for ${jobId}: ${cache.filePath}`);
- const processorPathDeps = processorDeps?.paths || [];
- const processorStateDeps = processorDeps?.state || [];
- const configPathDeps = config.deps?.paths || [];
- const configStateDeps = config.deps?.state || [];
- const stateSelectors = config.stateSelectors || [];
- await updateCache(
- meta.opts.cacheDir,
- jobId,
- removeCwd(
- [...configPathDeps, ...processorPathDeps, config?.filePath].filter(
- item => !!item
- )
- ),
- [
- ...configStateDeps,
- ...stateSelectors,
- ...processorStateDeps,
- ...(state?.accessed || [])
- ].filter(item => !!item),
- taskResult,
- cache.updates,
- meta.opts.includeStateValues
- );
- }
- return taskResult;
- }
- async function expandFileTask(patternsToInclude, config, meta) {
- const filesToProcess = await readFilesByGlob(patternsToInclude);
- const pathsToStrip = config.stripPaths || [];
- const outputDir = config.outputDir || "";
- return await Promise.all(
- filesToProcess.map(async filePath => {
- const fileOutputPath = path.join(
- meta.opts.outDir,
- outputDir,
- replaceFileExtension(
- removeBasePaths(pathsToStrip, filePath),
- config.outputFileExtension
- )
- );
- const fileOutputDir = path.dirname(fileOutputPath);
- const jobConfig = {
- ...config,
- filePath,
- fileOutputDir,
- fileOutputPath
- };
- return runTask({
- meta,
- config: jobConfig,
- jobId: `${config.name} @ ${filePath}`
- });
- })
- );
- }
- async function expandStateTask(stateToExpand, config, meta) {
- const stateToProcess = stateToExpand
- .map(property => {
- const values = getValueAtPath(meta, property);
- const expandedValues = Array.isArray(values)
- ? values
- : Object.values(values);
- return expandedValues.map((value, index) => ({ property, index, value }));
- })
- .flat();
- return await Promise.all(
- stateToProcess.map(async stateJob => {
- const jobConfig = {
- ...config,
- ...stateJob.value.detail
- };
- return runTask({
- meta,
- config: jobConfig,
- jobId: `${config.name} @ ${stateJob.property}:${stateJob.index}`
- });
- })
- );
- }
- export async function expandAndRunTask(meta, config) {
- const includes = meta.opts?.include?.[config.name] || [];
- const patternsToInclude = [...(config?.inputFiles || []), ...includes];
- if (patternsToInclude.length) {
- return expandFileTask(patternsToInclude, config, meta);
- }
- if (config.stateSelectors) {
- return expandStateTask(config.stateSelectors, config, meta);
- }
- const jobId = config.jobId || config.name;
- const taskResult = await runTask({ meta, config, jobId });
- return [taskResult];
- }
- export async function processTask(meta, task) {
- const log = getLogger(meta.opts.logLevel, task.name);
- const startTime = performance.now();
- const taskResult = await expandAndRunTask(meta, task);
- const cached = taskResult.filter(taskResult => taskResult.fromCache);
- const processed = taskResult.filter(taskResult => !taskResult.fromCache);
- const resources = taskResult.reduce(
- (obj, tResult) => (tResult.ref ? { ...obj, [tResult.ref]: tResult } : obj),
- {}
- );
- const endTime = performance.now();
- const timeTaken = endTime - startTime;
- const hrTime =
- timeTaken > 1000
- ? `${Number.parseFloat(timeTaken / 1000).toFixed(2)}s`
- : `${Number.parseFloat(timeTaken).toFixed(2)}ms`;
- const filesWritten = processed.reduce(
- (acc, cur) => acc + cur.paths.length,
- 0
- );
- log.info(
- `written: ${filesWritten} | processed: ${processed.length} | from cache: ${
- cached.length
- } | ${hrTime}`
- );
- return {
- name: task.name,
- taskResult,
- cached,
- processed,
- resources,
- filesWritten
- };
- }
|