UNPKG

snapshot-fs

Version:

Create a filesystem snapshot for use with memfs

156 lines 5.1 kB
#!/usr/bin/env node /* eslint-disable @typescript-eslint/unbound-method */ /** * Writes a DirectoryJSON object or snapshot (with --binary flag) to file. * * For use with memfs. * * @module snapshot-fs/cli * @see {@link https://npm.im/memfs} */ import nodeFs from 'node:fs'; import { mkdir, writeFile } from 'node:fs/promises'; import path from 'node:path'; import yargs from 'yargs'; import { hideBin } from 'yargs/helpers'; import { CBOR_KIND, CJSON_KIND, createCBORSnapshot, createCJSONSnapshot, createJSONSnapshot, exportSnapshot, JSON_KIND, } from './index.js'; const GROUP_OUTPUT = 'Output:'; const GROUP_INPUT = 'Input:'; async function main() { await yargs(hideBin(process.argv)) .version() .strict() .help() .scriptName('snapshot-fs') .epilog(`For more information, visit https://github.com/boneskull/snapshot-fs`) .options({ separator: { alias: 'sep', choices: ['posix', 'win32'], default: 'posix', describe: 'Path separator', global: true, group: GROUP_OUTPUT, }, }) .middleware((argv) => { argv.separator = argv.separator === 'posix' ? path.posix.sep : path.win32.sep; }) .command(['$0 [dest]', 'create [dest]'], 'Create memfs snapshot from filesystem', (yargs) => yargs .positional('dest', { coerce: path.resolve, describe: 'Path to output file', }) .options({ format: { alias: 'f', choices: [CBOR_KIND, CJSON_KIND, JSON_KIND], default: CJSON_KIND, describe: 'Snapshot format', group: GROUP_OUTPUT, nargs: 1, requiresArg: true, type: 'string', }, source: { alias: 's', coerce: path.resolve, default: process.cwd(), defaultDescription: '(current directory)', describe: 'File or directory to snapshot', group: GROUP_INPUT, nargs: 1, requiresArg: true, type: 'string', }, }), async ({ dest, format: kind, separator, source }) => { const pathSep = separator; if (kind === JSON_KIND) { console.error('[WARN] DirectoryJSON output is lossy and should be avoided'); } const output = kind === CBOR_KIND ? await createCBORSnapshot({ separator: pathSep, source, }) : kind === JSON_KIND ? await createJSONSnapshot({ separator: pathSep, source }) : await createCJSONSnapshot({ separator: pathSep, source }); if (dest) { await mkdir(path.dirname(dest), { recursive: true }); await writeFile(dest, output); console.error('[INFO] Wrote %s snapshot of %s to %s', kind.toUpperCase(), source, dest); } else { console.log(output); } }) .command('export <snapshot> [dest]', 'Export a JSON snapshot to the filesystem', (yargs) => yargs .positional('snapshot', { coerce: path.resolve, demandOption: true, describe: 'Path to snapshot file (CBOR/CJSON/DirectoryJSON)', }) .positional('dest', { coerce: path.resolve, default: process.cwd(), defaultDescription: 'Current working directory', describe: 'Destination directory', }) .options({ 'dry-run': { alias: 'D', description: 'Print what would be written to the filesystem', type: 'boolean', }, format: { alias: 'f', choices: [CBOR_KIND, CJSON_KIND, JSON_KIND], default: CJSON_KIND, describe: 'Snapshot format', nargs: 1, requiresArg: true, type: 'string', }, }), async ({ dest, dryRun, format: kind, snapshot }) => { const data = (await nodeFs.promises.readFile(snapshot)); switch (kind) { case CBOR_KIND: { await exportSnapshot(kind, data, { dest, dryRun, }); break; } case CJSON_KIND: { await exportSnapshot(kind, data, { dest, dryRun, }); break; } case JSON_KIND: { await exportSnapshot(kind, data, { dest, dryRun, }); break; } /* c8 ignore next */ default: { throw new TypeError('Invalid format'); } } if (!dryRun) { console.error('[INFO] Exported %s snapshot of %s to %s', kind.toUpperCase(), snapshot, dest); } }) .options({}) .parseAsync(); } main().catch((err) => { console.error(err); process.exitCode = 1; }); //# sourceMappingURL=cli.js.map