From c0524320da95821488d490f1cf7f786b39259bd2 Mon Sep 17 00:00:00 2001 From: "Zed A. Shaw" Date: Fri, 23 Dec 2022 17:35:16 +0700 Subject: [PATCH] Documenting builderator.js and cleaned it up. --- lib/builderator.js | 93 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 70 insertions(+), 23 deletions(-) diff --git a/lib/builderator.js b/lib/builderator.js index 0e81081..7b6bcff 100644 --- a/lib/builderator.js +++ b/lib/builderator.js @@ -1,3 +1,8 @@ +/* + Useful system level functions for use in build commands. It's mostly things like + detecting if two files changed, doing globs on Windows and Unix, and various + file operations that you need. + */ import fg from "fast-glob"; import fs from "fs"; import assert from "assert"; @@ -6,7 +11,12 @@ import Path from "path"; import { execSync } from "child_process"; /* - Fixes some common problems with fast-glob on windows. + Fixes some common problems with `fast-glob` on windows. I removes + leading "C:\" from paths and replaces all of the `\\` with `/`. + + __BUG__: This obviously won't work if you're on a different drive than C:. + + + `path string` -- The path/glob pattern to use. */ export const glob = (path) => { if(process.platform === "win32") { @@ -19,6 +29,17 @@ export const glob = (path) => { } } +/* + Detects if two files have changed. This is used to avoid + writing or working on files that don't need it, similar + to the Unix make utility. + + ___FOOTGUN___: It uses the stat.mtimeMs which may or may not be + the most reliable way to detect differences. + + + `source string` -- The source path. + + `target string` -- The target path. + */ export const changed = (source, target) => { // we want the source to error if it doesn't exist const s_stat = fs.statSync(source); @@ -28,7 +49,11 @@ export const changed = (source, target) => { return !t_stat || s_stat.mtimeMs > t_stat.mtimeMs; } -/* Makes a directory recursively. */ +/* + Makes a directory recursively, kind of like `mkdir -p`. + + + `dir string` -- The full path to the final directory to create. + */ export const mkdir = (dir) => { if(!fs.existsSync(dir)) { log.debug(`making dir ${dir}`); @@ -37,13 +62,8 @@ export const mkdir = (dir) => { } /* - Given any path to a file, makes sure all its directories are in place. - - Example: - - ```javascript - console.log("PRINT"); - ``` + Given any path to a file, makes sure all its directories are in place. This will + only the directory to the file, and then calls `mkdir` on it to create the path. - `param string` -- path to file */ @@ -52,7 +72,14 @@ export const mkdir_to = (target) => { mkdir(dirs.dir); } -/* Convenience function that makes sure the dir is there then writes the data. */ +/* + Convenience function that makes sure the dir is there then writes the data. + It's a combination of `mkdir_to` and `fs.writeFileSync` and exists because + these two operations are so common. + + + `target string` -- Path to the file to write. + + `data string|buffer|etc.` -- Anything that `fs.writeFileSync` can take as file contents. + */ export const write = (target, data) => { mkdir_to(target); fs.writeFileSync(target, data); @@ -61,7 +88,12 @@ export const write = (target, data) => { /* Like write but does an OS copy after making the target dir. When given a filter it will give the filter function the arguments, let it return contents, - then write those instead of a copy. + then write those instead of a copy. This will create the target file's path + with `mkdir_to`. + + + `src string` -- Source file path. + + `dest string` -- Destination path. + + `filter cb(src, dest, raw_data)` -- A function that can modify the data before it's written. */ export const copy = (src, dest, filter=null) => { mkdir_to(dest); @@ -70,7 +102,8 @@ export const copy = (src, dest, filter=null) => { try { let raw_data = fs.readFileSync(src); let data = filter(src, dest, raw_data); - write(dest, data); + + fs.writeFileSync(dest, data); } catch (error) { log.error(error, "Problem with filter write in copy"); } @@ -79,6 +112,12 @@ export const copy = (src, dest, filter=null) => { } } +/* + Removes a file, optionally ignoring any errors. + + + `file_name string` -- The path to the file to remove. + + `ignore boolean (false)` -- Whether to ignore errors removing the file. + */ export const rm = (file_name, ignore=false) => { log.warn("Deleting file", file_name); try { @@ -93,27 +132,35 @@ export const rm = (file_name, ignore=false) => { } } -export const index_rollup = (src_index, target_index, contents, key) => { - let index = JSON.parse(fs.readFileSync(src_index)); - - index[key] = glob(contents).map(f => JSON.parse(fs.readFileSync(f))); - assert(index[key] !== undefined, `Attempt to load contents into ${key} for ${src_index} failed with undefined.`); - - write(target_index, JSON.stringify(index)); - - return index; -} +/* + Executes a command, and mostly just logs the command then run + execSync with the same options. + + `cmd string` -- Command to run. + + `opts Object` -- Options for `execSync`. + */ export const exec = (cmd, opts) => { log.info(`EXEC ${cmd}`); return execSync(cmd, opts); } +/* + Similar to `exec` but it is _interactive_ because it reroutes this process's stderr, + stdout, and stdin to the process. If you find you can't ctrl-c then use this. The + options set are: + + ``` + {stdio: [process.stdout, process.stderr, process.stdin]} + ``` + + + `cmd string` -- The command to run. + + `opts Object` -- Additional options to set for the exec command. + */ export const exec_i = (cmd, opts={}) => { return exec(cmd, {stdio: [process.stdout, process.stderr, process.stdin], ...opts}); } export default { - index_rollup, rm, exec, changed, mkdir, mkdir_to, write, copy, exec_i, glob + rm, exec, changed, mkdir, mkdir_to, write, copy, exec_i, glob }