From 9db682ff33aec8b446f724d12bf357883c87a5a5 Mon Sep 17 00:00:00 2001 From: James P Date: Wed, 20 Mar 2024 11:40:39 -0500 Subject: [PATCH] Added make-listing script --- package.json | 3 ++ scripts/make-listing.js | 98 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100755 scripts/make-listing.js diff --git a/package.json b/package.json index f09935ceb..80894b86b 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,9 @@ "node", "storage" ], + "bin": { + "make-listing": "./scripts/make-listing.js" + }, "type": "module", "homepage": "https://github.com/browser-fs/core", "author": "John Vilk ", diff --git a/scripts/make-listing.js b/scripts/make-listing.js new file mode 100755 index 000000000..0f171099a --- /dev/null +++ b/scripts/make-listing.js @@ -0,0 +1,98 @@ +#!/usr/bin/env node +import { parseArgs } from 'util'; +import { statSync, readdirSync, writeFileSync } from 'fs'; +import { join } from 'path/posix'; +import { resolve } from 'path'; + +const { + values: options, + positionals: [root], +} = parseArgs({ + options: { + help: { short: 'h', type: 'boolean', default: false }, + ignore: { short: 'i', type: 'string', multiple: true, default: [] }, + output: { short: 'o', type: 'string', default: 'listing.json' }, + quiet: { short: 'q', type: 'boolean', default: false }, + verbose: { type: 'boolean', default: false }, + }, + allowPositionals: true, + strict: true, +}); + +if (options.help) { + console.log(`make-index [...options] + path: The path to create a listing for + + options: + --help, -h: Outputs this help message + --output, -o : Path to the output file. Defaults to listing. + --quiet, -q: Do not output messages about individual files + --verbose: Output verbose messages + --ignore, -i : Ignores files which match . Can be passed multiple times. + `); + process.exit(); +} + +if (options.quiet && options.verbose) { + console.log('Can not use both --verbose and --quiet.'); + process.exit(); +} + +function pathToPosix(path) { + return path.replaceAll('\\', '/'); +} + +const colors = { + reset: 0, + black: 30, + red: 31, + green: 32, + yellow: 33, + blue: 34, + magenta: 35, + cyan: 36, + white: 37, + bright_black: 90, + bright_red: 91, + bright_green: 92, + bright_yellow: 93, + bright_blue: 94, + bright_magenta: 95, + bright_cyan: 96, + bright_white: 97, +}; + +function color(color, text) { + return `\x1b[${colors[color]}m${text}\x1b[0m`; +} + +function makeListing(path, seen = new Set()) { + try { + const stats = statSync(path); + + if (stats.isFile()) { + return null; + } + + let entries = {}; + for (const file of readdirSync(path)) { + const full = join(path, file); + if (options.ignore.some(pattern => full.match(pattern))) { + if (!options.quiet) console.log(`${color('yellow', 'skip')} ${full}`); + continue; + } + + entries[file] = makeListing(full, seen); + } + return entries; + } catch (e) { + if (!options.quiet) { + console.log(`${color('red', 'fail')} ${path}: ${e.message}`); + } + } +} + +const listing = makeListing(pathToPosix(root)); +if (!options.quiet) console.log('Generated listing for ' + pathToPosix(resolve(root))); + +writeFileSync(options.output, JSON.stringify(listing));