-v raises the CLI's log level per repeat; -q prints only fatal errors (closes #212)
check / check (push) Waiting to run
check / check (push) Waiting to run
Every line quak prints on stderr now goes through one log, in src/cli-log.ts, at one of six levels. The default, info, prints what quak printed before. -v adds each retry and the start and end of each refresh and ML data fetch; -vv adds each request with its result. -q prints only the line a failing command exits with, and is refused with -v. Both are program options. withRetry reports retries through a new onRetry, and ApiClient reports requests through a new onRequest; the CLI logs what they report. --json now changes stdout only, so backup and --json runs log their progress on stderr. Model: opus-5-5
This commit is contained in:
+40
-8
@@ -2,8 +2,9 @@
|
||||
|
||||
import { stdout, stderr } from "node:process";
|
||||
import { input, password } from "@inquirer/prompts";
|
||||
import { Command } from "commander";
|
||||
import { Command, Option } from "commander";
|
||||
import envPaths from "env-paths";
|
||||
import { logLevel, logRequests, stderrLog, type Log } from "../src/cli-log.js";
|
||||
import { init } from "../src/crypto/index.js";
|
||||
import {
|
||||
type CliContext,
|
||||
@@ -29,6 +30,9 @@ const paths = envPaths("quak", { suffix: "" });
|
||||
|
||||
const program = new Command();
|
||||
|
||||
// Program options, so they are taken before or after any command's name.
|
||||
// `-v` counts its repeats, the way commander's documentation counts a repeated
|
||||
// option.
|
||||
program
|
||||
.name("quak")
|
||||
.description("CLI for the Ente end-to-end encrypted photo service")
|
||||
@@ -37,21 +41,46 @@ program
|
||||
"--cache-dir <path>",
|
||||
"Directory for the local metadata/content cache " +
|
||||
"(default: the per-user cache directory)",
|
||||
);
|
||||
)
|
||||
.option(
|
||||
"-v, --verbose",
|
||||
"Log more on stderr: debug lines with -v, trace lines too with -vv",
|
||||
(_value: string, previous: number) => previous + 1,
|
||||
0,
|
||||
)
|
||||
.addOption(
|
||||
new Option(
|
||||
"-q, --quiet",
|
||||
"Print nothing on stderr but the error a failing command exits with",
|
||||
).conflicts("verbose"),
|
||||
)
|
||||
.configureHelp({ showGlobalOptions: true });
|
||||
|
||||
interface ProgramOptions {
|
||||
cacheDir?: string;
|
||||
verbose: number;
|
||||
quiet?: boolean;
|
||||
}
|
||||
|
||||
// The log for this run, at the level `-v` and `-q` ask for.
|
||||
const log = (): Log => {
|
||||
const { verbose, quiet } = program.opts<ProgramOptions>();
|
||||
return stderrLog(stderr, logLevel(verbose, quiet ?? false));
|
||||
};
|
||||
|
||||
const context = (): CliContext => ({
|
||||
stdout,
|
||||
stderr,
|
||||
log: log(),
|
||||
sessionDir: paths.data,
|
||||
cacheDir: program.opts<{ cacheDir?: string }>().cacheDir,
|
||||
loadSession,
|
||||
login: (opts) => Client.login(opts),
|
||||
cacheDir: program.opts<ProgramOptions>().cacheDir,
|
||||
loadSession: (path) => loadSession(path, logRequests(log())),
|
||||
login: (opts) => Client.login({ ...opts, apiOptions: logRequests(log()) }),
|
||||
prompt: (message) => input({ message }),
|
||||
promptSecret: (message) => password({ message, mask: true }),
|
||||
});
|
||||
|
||||
const run = (command: Promise<number>): Promise<void> =>
|
||||
runCommand(command, stdout, stderr, (code) => process.exit(code));
|
||||
runCommand(command, stdout, stderr, log(), (code) => process.exit(code));
|
||||
|
||||
program
|
||||
.command("login")
|
||||
@@ -143,7 +172,10 @@ program
|
||||
{
|
||||
...context(),
|
||||
loadSession: (path) =>
|
||||
loadSession(path, { retry: UNATTENDED_RETRY_OPTIONS }),
|
||||
loadSession(
|
||||
path,
|
||||
logRequests(log(), UNATTENDED_RETRY_OPTIONS),
|
||||
),
|
||||
},
|
||||
dir,
|
||||
opts,
|
||||
|
||||
Reference in New Issue
Block a user