UNPKG

@struktoai/mirage-core

Version:

A Unified Virtual Filesystem For AI Agents

247 lines • 11.8 kB
import type { CommandFnResult, Context } from '../../../config.ts'; import type { FlagView } from '../../../spec/flag_view.ts'; import { type GitError } from './errors.ts'; import { PathSpec } from '../../../../types.ts'; import type { Files } from '../../../../workspace/files.ts'; export declare const STDOUT = "stdout"; export declare const STDERR = "stderr"; export declare const MARKER = "--"; /** * Where repository discovery begins for this invocation. * * `-C` changes directory before anything else happens, git's own reading of the * option. It needs no separate session-cwd fact: the option is declared with a * `'.'` default, and a PATH default lands as if typed, so an absent `-C` * resolves to the session cwd and a relative `-C build` is already absolute by * the time it arrives. * * Keep the PathSpec until the directory walk is checked. Repository-relative * pathspec matching uses its virtual spelling after that check. * * @param fl spec-validated view over the leaf's flag bag */ export declare function startPoint(fl: FlagView): PathSpec; /** * The revision operand a verb was given, or git's own default. * * @param texts positional text operands * @param fallback what an absent operand means */ export declare function revisionArg(texts: readonly string[], fallback?: string): string; /** * The words a `--` on the line marked as operands, not options. * * `--` is exactly how a caller names a file whose name begins with a dash, and * git says so in every synopsis that ends `[--] [<pathspec>...]`: `git rm * -draft` is a refused switch and `git rm -- -draft` removes the file. The * parser consumes the marker, so the words themselves are what carries the fact * forward, read back off the verbatim argv the record already holds. * * A set is enough. A dash word before the marker was read as an option and * never reached the operands, so a word that is here and also spelled earlier on * the line is still the escaped one. * * @param argv the line's verbatim tokens after the head word, subcommand words * included */ export declare function escaped(argv: readonly string[]): Set<string>; /** * The operands before a `--` on the line and the ones after it. * * `git diff A B -- docs` reads what comes before the marker as revisions and * what follows as pathspecs, whatever either looks like. Every word after the * marker is an operand, so they are the tail of the operands, as many as the * verbatim argv holds past it. * * @param texts positional text operands, as typed * @param argv the line's verbatim tokens after the head word, subcommand words * included */ export declare function splitMarked(texts: readonly string[], argv: readonly string[]): [string[], string[]]; /** * The first operand that is really an option this build lacks. * * A verb taking a revision accepts free text, so every flag mirage does not * declare reaches it as one. Resolving it as a revision is the wrong answer * twice over: it fails, and it fails saying the repository has no such commit, * when what happened is that mirage has no such flag. Found here, before any * object is read, so the refusal names the real problem. * * Unless the caller said otherwise. A word after `--` is an operand by the * caller's own instruction whatever it starts with, so it is never read as an * option here; see `escaped`, which is where the marker survives the parser. * * Which side of the marker an operand fell on says nothing about what it * *means* here. `diff`, `show`, `diff-tree` and the walks (`log`, `rev-list`, * `shortlog`) read what follows the marker as pathspecs (`splitMarked`). * * @param texts positional text operands, as typed * @param marked operands a `--` on the line escaped * @param known the verb's one-letter switches, which narrow a refused cluster to * its first unknown letter the way parse-options does; absent names the whole * word */ export declare function offending(texts: readonly string[], marked?: ReadonlySet<string>, known?: ReadonlySet<string>): string | null; /** * The first operand that is really an option, once `-h` is out. * * `-h` asks for the verb's usage block, which git prints on stdout for most * verbs and on stderr for a few (`diff`); every other word is the caller's to * refuse in the verb's own words. See `offending` for which words count. * * @param ctx the line's context, carrying its leaf * @param texts positional text operands, as typed * @param helpStream where `-h` puts the usage block * @throws UsageError the line asked for the usage block */ export declare function optionOperand(ctx: Context, texts: readonly string[], helpStream?: typeof STDOUT | typeof STDERR): string | null; /** * Where `-h` puts the usage block for a verb that takes it as help only alone. * * `rev-list`, `rev-parse` and `diff-tree` print it on stdout, exiting 0, when * `-h` is their one word, and beside anything else on stderr as a refusal, * exiting 129 (git 2.56). * * @param ctx the line's context, carrying its leaf * @param texts the verb's positional text operands */ export declare function loneHelp(ctx: Context, texts: readonly string[]): typeof STDOUT | typeof STDERR; /** * Refuse an operand that is really an option, as an unrecognized argument. * * For the verbs git words without a usage block (`log`, `show`, `reflog`), * whose refusal names the whole word (git 2.50.1). * * @param ctx the line's context, carrying its leaf * @param texts positional text operands, as typed * @param helpStream where `-h` puts the usage block */ export declare function checkOperands(ctx: Context, texts: readonly string[], helpStream?: typeof STDOUT | typeof STDERR): void; /** * The verb's usage block, as parse-options prints it. * * @param ctx the line's context, carrying its leaf */ export declare function verbUsage(ctx: Context): string; /** * Refuse an operand that is really an option, as parse-options does. * * The verbs built on parse-options (`status`, `add`, `branch`, `commit` and * most others) name an unknown option or switch and follow it with the usage * block, refuse a boolean handed a value on one line, and print the usage block * on stdout for `-h`; see `gitOptionRefusal`. Measured on git 2.50.1. * * @param ctx the line's context, carrying its leaf * @param texts positional text operands, as typed */ export declare function checkSwitches(ctx: Context, texts: readonly string[]): void; /** * The one-letter switches the leaf declares, without their dash. * * Read off the spec the line was parsed against, so the set is the verb's * own and never a copy of it; empty where no executor built the record. * * @param ctx the line's context, carrying its leaf */ export declare function switches(ctx: Context): ReadonlySet<string>; /** * The part of a dash word parse-options would refuse. * * git reads a short cluster letter by letter, consumes the ones the verb * declares and stops at the first it does not, so `git mv -nx` says `x' and * `git mv -draft` says `d' (git 2.50.1); a verb that declares no switch at * all (`reset`) still names the first letter. A long option is refused as * typed, and so is a cluster for a verb that hands over no set: log, show * and diff word the whole argument. * * @param text the dash word as the user spelled it * @param known the verb's one-letter switches, absent for a verb that * refuses the word whole */ export declare function offendingSwitch(text: string, known: ReadonlySet<string> | undefined): string; /** * The session's files, which every verb reads and writes through. Only a leaf * called directly, outside a workspace, has none; git words that the way it * words a bare repository. Mirrors Python's `require_vfs`. */ export declare function requireVfs(ctx: Context): Files; /** * Render a git error: `<prefix>: <message>`, on its own stream. * * git uses 128 for a fatal, which is neither the dispatcher's usage exit (2) nor * its generic handler-error exit (1), so leaves return the code rather than * throwing into the catch-all. A refused option carries its own prefix and code * instead, which is git's own split, and a refusal that is really a report * ("nothing to commit") carries no prefix and goes to stdout. * * * An error carrying a `report` puts that on stdout beside the stderr line, * because git writes some refusals to both streams at once: `<path>: needs * merge` is the diagnosis and "you need to resolve your current index first" is * the refusal. * * @param exc the error to render */ export declare function fatal(exc: GitError): CommandFnResult; /** * A config boolean read the way git's config callbacks read one. * * Every occurrence is parsed and the last one wins, so a value git cannot read * fails even when a later line would have read fine. A value is * `true`/`yes`/`on` or `false`/`no`/`off` in any case, empty for false, or an * integer for whether it is nonzero (pinned against git 2.54). * * @param values every value the variable takes, in file order; a bare name * arrives as `true` * @param key the variable, section and name lowercased * @param fallback the answer when the variable is unset */ export declare function gitBool(values: readonly string[], key: string, fallback: boolean): boolean; /** * A config boolean as git reads it: `true`/`yes`/`on` or `false`/`no`/`off` * in any case, empty for false, or an integer for whether it is nonzero; null * for anything else, which each caller answers in its own way. * * @param value the value as typed or as the config spells it */ export declare function maybeBool(value: string): boolean | null; /** * One `[section "name"]` block the way git's config writer spells it. * * The subsection escapes `"` and `\`; a value escapes those plus newline and * tab, and is quoted when it starts or ends with a space or holds `;` or `#`. * A branch may be named `a"b` or `a#b`, and either one written raw reads back * as a different name (pinned against git 2.50.1). * * @param section the section, e.g. `branch` * @param name the subsection, e.g. the branch name * @param pairs variables and values, in order */ export declare function configSection(section: string, name: string, pairs: readonly (readonly [string, string])[]): string; /** * A config's text with every block for `section.name` taken out. * * `git branch -d` drops the deleted branch's settings this way, so a branch * made again under the same name starts with no upstream rather than with two. * A header names the block the way git matches it, * spelled exactly: `[branch "x"]` with its escapes, or the older `[branch.x]`. * `[Branch "x"]` and `[branch.X]` are left, as git leaves them, and a line * opening with `[` ends a block (pinned against git 2.50.1). * * With `keys` only those variables leave the blocks, and a block they leave * holding no variable leaves with them, header and all, as * `git branch --delete-merged` clears an upstream (git 2.56.0). A variable * sharing its header's line leaves the header behind. * * A value continued onto the next line by a trailing backslash is followed, so * a continuation that opens with `[` is still part of the block. git 2.50.1 * reads it as a header there and leaves the rest of the block behind, which it * then refuses as a bad config line; mirage keeps the file readable instead. * * @param text the config file's contents * @param section the section as git writes it, e.g. `branch` * @param name the subsection, e.g. the branch name * @param keys the variables to take out, lowercase; null takes the whole block */ export declare function withoutSection(text: string, section: string, name: string, keys?: ReadonlySet<string> | null): string; //# sourceMappingURL=util.d.ts.map