Initial project outline
- package.json (ESM, bin entry) - bin/delta-backup.js — entrypoint - lib/args.js — CLI arg parsing via Node parseArgs - lib/config.js — config file merging + required path guards - lib/spawn.js — safe process spawning (no shell strings) - lib/state.js — sequence number + phase state management - lib/backends/zstd.js — zstd delta backend - lib/backends/index.js — backend registry - lib/commands/run.js — full run skeleton (phases 1-3 wired, 4-6 stubbed) - lib/commands/status.js — status command
This commit is contained in:
43
lib/config.js
Normal file
43
lib/config.js
Normal file
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* Config loading — merges JSON config file with CLI args.
|
||||
* CLI args always win. Required paths are validated here.
|
||||
*/
|
||||
import { readFile } from 'fs/promises';
|
||||
|
||||
const REQUIRED_PATHS = ['source', 'prev', 'pend', 'deltas'];
|
||||
const DEFAULTS = {
|
||||
backend: 'zstd',
|
||||
};
|
||||
|
||||
export async function loadConfig(args) {
|
||||
let fileConfig = {};
|
||||
|
||||
if (args.config) {
|
||||
try {
|
||||
const raw = await readFile(args.config, 'utf8');
|
||||
fileConfig = JSON.parse(raw);
|
||||
} catch (err) {
|
||||
console.error(`Error reading config file ${args.config}: ${err.message}`);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// CLI args override file config, file config overrides defaults
|
||||
const config = { ...DEFAULTS, ...fileConfig, ...filterDefined(args) };
|
||||
|
||||
// Guard: refuse to run if any required path is missing
|
||||
if (config.command === 'run') {
|
||||
const missing = REQUIRED_PATHS.filter(k => !config[k]);
|
||||
if (missing.length > 0) {
|
||||
console.error(`Error: missing required options: ${missing.map(k => `--${k}`).join(', ')}`);
|
||||
console.error('Provide them as CLI flags or in a --config JSON file.');
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
function filterDefined(obj) {
|
||||
return Object.fromEntries(Object.entries(obj).filter(([, v]) => v !== undefined));
|
||||
}
|
||||
Reference in New Issue
Block a user