Begin the bulk script.
This commit is contained in:
parent
9761204fda
commit
f350e75ff5
|
@ -2,6 +2,7 @@
|
|||
|
||||
## Scripts
|
||||
|
||||
- [`bulk`]: bulk doer of things.
|
||||
- [`codium-extensions`]: save and install VS Codium extensions using their identifier.
|
||||
- [`copy-nixos-config`]: copies NixOS configuration from `$BAUKE_DIR/nix/<hostname>/` to `/etc/nixos/`.
|
||||
- [`desktop-wallpaper`]: desktop wallpaper changer.
|
||||
|
@ -11,6 +12,7 @@
|
|||
- [`simple-git-push`]: `git push` with extra semantics.
|
||||
- [`tauon-controls`]: remote control CLI for Tauon Music Box.
|
||||
|
||||
[`bulk`]: ./scripts/bulk/bulk.ts
|
||||
[`codium-extensions`]: ./scripts/codium-extensions.ts
|
||||
[`copy-nixos-config`]: ./scripts/copy-nixos-config.ts
|
||||
[`desktop-wallpaper`]: ./scripts/desktop-wallpaper.ts
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
#!/usr/bin/env zsh
|
||||
|
||||
deno run \
|
||||
--allow-read \
|
||||
--allow-run \
|
||||
"$BAUKE_DIR/scripts/bulk/bulk.ts" \
|
||||
"$@"
|
|
@ -0,0 +1,15 @@
|
|||
import { Command } from "https://deno.land/x/cliffy@v0.25.5/command/mod.ts";
|
||||
|
||||
import { runCommand } from "./run.ts";
|
||||
|
||||
async function main(): Promise<void> {
|
||||
await new Command()
|
||||
.name("bulk")
|
||||
.description("Bulk doer of things.")
|
||||
.command("run", runCommand)
|
||||
.parse(Deno.args);
|
||||
}
|
||||
|
||||
if (import.meta.main) {
|
||||
void main();
|
||||
}
|
|
@ -0,0 +1,146 @@
|
|||
import { Command } from "https://deno.land/x/cliffy@v0.25.5/command/mod.ts";
|
||||
import * as prompt from "https://deno.land/x/cliffy@v0.25.5/prompt/mod.ts";
|
||||
|
||||
export const runCommand = new Command()
|
||||
.name("run")
|
||||
.description("Run a command over a group of files and directories.")
|
||||
.option(
|
||||
"-d, --directory <directory:string>",
|
||||
"Directories to include files from.",
|
||||
{
|
||||
collect: true,
|
||||
required: true,
|
||||
},
|
||||
)
|
||||
.option(
|
||||
"--include-directories",
|
||||
"Include directories found inside the directories.",
|
||||
)
|
||||
.action(async ({ directory, includeDirectories }) => {
|
||||
await actionHandler({
|
||||
directories: directory,
|
||||
includeDirectories: includeDirectories ?? false,
|
||||
});
|
||||
});
|
||||
|
||||
async function actionHandler(
|
||||
options: {
|
||||
directories: string[];
|
||||
includeDirectories: boolean;
|
||||
},
|
||||
): Promise<void> {
|
||||
let command: string[] = [];
|
||||
const previousPromptArgs: Map<number, string> = new Map();
|
||||
const suggestedPromptArgs: Set<string> = new Set();
|
||||
const substituteMarkers = {
|
||||
absoluteFile: "$absoluteFile",
|
||||
filename: "$filename",
|
||||
};
|
||||
|
||||
for (const directory of options.directories) {
|
||||
console.log(`\n## Input for ${directory}`);
|
||||
const constructedCommands: string[][] = [];
|
||||
const prompts = await prompt.prompt([
|
||||
{
|
||||
type: prompt.List,
|
||||
name: "command",
|
||||
message: "Arguments of the command to run separated by comma",
|
||||
default: command,
|
||||
suggestions: Object.values(substituteMarkers),
|
||||
},
|
||||
{
|
||||
type: prompt.Confirm,
|
||||
name: "confirmCommands",
|
||||
message: "Manually approve each command invocation",
|
||||
default: true,
|
||||
},
|
||||
]);
|
||||
|
||||
command = prompts.command ?? command;
|
||||
for await (const file of Deno.readDir(directory)) {
|
||||
if (!options.includeDirectories && file.isDirectory) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const absoluteFile = await Deno.realPath(`${directory}/${file.name}`);
|
||||
const constructedCommand: string[] = [];
|
||||
let promptArgCount = 1;
|
||||
const substitutes = [
|
||||
[substituteMarkers.absoluteFile, absoluteFile],
|
||||
[substituteMarkers.filename, file.name],
|
||||
];
|
||||
|
||||
argumentLoop:
|
||||
for (const argument of command) {
|
||||
if (argument === "$prompt") {
|
||||
const { promptedArg } = await prompt.prompt([{
|
||||
type: prompt.Input,
|
||||
name: "promptedArg",
|
||||
message: `$prompt ${promptArgCount} for ${absoluteFile}`,
|
||||
default: previousPromptArgs.get(promptArgCount) ?? "",
|
||||
suggestions: Array.from(suggestedPromptArgs),
|
||||
}]);
|
||||
|
||||
previousPromptArgs.set(promptArgCount, promptedArg!);
|
||||
suggestedPromptArgs.add(promptedArg!);
|
||||
constructedCommand.push(promptedArg!);
|
||||
promptArgCount += 1;
|
||||
} else {
|
||||
for (const [marker, substitute] of substitutes) {
|
||||
if (argument === marker) {
|
||||
constructedCommand.push(substitute);
|
||||
continue argumentLoop;
|
||||
}
|
||||
}
|
||||
|
||||
constructedCommand.push(argument);
|
||||
}
|
||||
}
|
||||
|
||||
if (prompts.confirmCommands) {
|
||||
const { confirmedRun } = await prompt.prompt([
|
||||
{
|
||||
type: prompt.Confirm,
|
||||
name: "confirmedRun",
|
||||
message: `Run "${constructedCommand.join(" ")}"`,
|
||||
default: true,
|
||||
},
|
||||
]);
|
||||
|
||||
if (!confirmedRun) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
constructedCommands.push(constructedCommand);
|
||||
}
|
||||
|
||||
if (constructedCommands.length === 0) {
|
||||
console.log("\n No commands to run.");
|
||||
continue;
|
||||
}
|
||||
|
||||
console.log("\n## Commands");
|
||||
console.log(constructedCommands.map((c) => c.join(" ")).join("\n"));
|
||||
|
||||
const { confirmedRun } = await prompt.prompt([
|
||||
{
|
||||
type: prompt.Confirm,
|
||||
name: "confirmedRun",
|
||||
message: "Is this correct",
|
||||
default: true,
|
||||
},
|
||||
]);
|
||||
|
||||
if (!confirmedRun) {
|
||||
continue;
|
||||
}
|
||||
|
||||
console.log("\n## Output");
|
||||
for (const constructedCommand of constructedCommands) {
|
||||
await Deno.run({
|
||||
cmd: constructedCommand,
|
||||
}).status();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue