UNPKG

@struktoai/mirage-core

Version:

A Unified Virtual Filesystem For AI Agents

123 lines • 5.52 kB
// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. ========= // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // ========= Copyright 2026 @ Strukto.AI All Rights Reserved. ========= import { encodeText, utf8Locale } from "../../../shell/bytes.js"; import { specOf } from "../../spec/builtins.js"; import { FlagView } from "../../spec/flag_view.js"; import { IOResult, materialize } from "../../../io/types.js"; import { matcherSyntax, resolvePattern } from "../grep_pattern.js"; import { UsageError } from "../../errors.js"; import { GREP_STDIN_LABEL, STDIN_OPERAND } from "../utils/constants.js"; import { linkResolver } from "../utils/links.js"; import { operandLabel } from "../utils/stream.js"; import { decompressInputs } from "./decompress.js"; import { listingMode, maxCount } from "./grep.js"; import { exitCodeFor } from "../grep_scan.js"; import { openGrep, streamConfig, streamInput } from "../grep_stream.js"; import { OutputStream, closeQuietly, ensureStream } from "../../../io/stream.js"; import { closeStream } from "../../../rs/stream.js"; import { concat } from "../../../utils/bytes.js"; const ZGREP_NO_PATTERN = "zgrep: missing pattern; try `zgrep --help' for help"; function parseFlags(fl, neverMatch) { const [filesOnly, filesWithoutMatch] = listingMode(fl); const count = maxCount(fl); return { ignoreCase: fl.asBool('ignore_case'), invert: fl.asBool('invert_match'), countOnly: fl.asBool('count'), filesOnly, filesWithoutMatch, lineNumbers: fl.asBool('line_number'), byteOffsets: fl.asBool('byte_offset'), fixedString: fl.asBool('fixed_strings') && !neverMatch, syntax: matcherSyntax(fl), withFilename: fl.asBool('with_filename'), noFilename: fl.asBool('no_filename'), onlyMatching: fl.asBool('only_matching'), quiet: fl.asBool('quiet') && count !== 0, wholeWord: fl.asBool('word_regexp'), lineRegexp: fl.asBool('line_regexp'), maxCount: count, noMessages: false, recursive: false, afterContext: null, beforeContext: null, binaryMode: 'binary', filters: { fileGlobs: [], excludeDir: [], text: false }, }; } export async function zgrepGeneric(paths, texts, ctx, read, stat) { const fl = new FlagView(ctx.flags, specOf('zgrep')); const resolution = await resolvePattern('zgrep', texts, fl, read); if (resolution.error !== null) { return [null, new IOResult({ exitCode: 2, stderr: encodeText(resolution.error) })]; } if (resolution.pattern === null) { return [null, new IOResult({ exitCode: 2, stderr: encodeText(ZGREP_NO_PATTERN + '\n') })]; } let f; try { f = parseFlags(fl, resolution.neverMatch); } catch (err) { if (!(err instanceof UsageError)) throw err; return [null, new IOResult({ exitCode: 2, stderr: encodeText(err.message + '\n') })]; } const [stream, warnings] = await openGrep(streamConfig(f, resolution.neverMatch || f.maxCount === 0 ? null : resolution.pattern, utf8Locale(ctx.env))); const showFilename = f.withFilename || (paths.length > 1 && !f.noFilename); const resolver = linkResolver(ctx); const result = new IOResult({ exitCode: 1, stderr: warnings.length ? warnings : null }); async function* run() { let anyMatch = false; let failed = false; try { for (const p of paths.length > 0 ? paths : [STDIN_OPERAND]) { const [body, io] = await decompressInputs([p], read, { stdin: ctx.stdin, toStdout: true, force: true, quiet: true, ...(stat !== undefined ? { stat } : {}), resolver, }); const selected = new IOResult({ exitCode: 1 }); try { yield* streamInput(ensureStream(body ?? new Uint8Array()), stream, operandLabel(p, GREP_STDIN_LABEL), showFilename, selected, false, null, ctx.signal, true, p.rawPath); } finally { anyMatch ||= selected.exitCode === 0; failed ||= io.exitCode === 1 || selected.exitCode === 2; const diagnostic = concat([ await io.materializeStderr(), await selected.materializeStderr(), ]); if (diagnostic.length) result.stderr = concat([await materialize(result.stderr), diagnostic]); result.exitCode = exitCodeFor(anyMatch, failed, false); } } } finally { await closeStream(stream); } } return [ new OutputStream(run(), async () => { await closeStream(stream); await closeQuietly(ctx.stdin); }), result, ]; } //# sourceMappingURL=zgrep.js.map