UNPKG

@eagleoutice/flowr-dev

Version:

Static Dataflow Analyzer and Program Slicer for the R Programming Language

125 lines 7.09 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.signatureCommand = exports.signatureSubcommandNames = void 0; exports.replSignatureCompleter = replSignatureCompleter; const ansi_1 = require("../../../util/text/ansi"); const args_1 = require("../../../util/text/args"); const query_1 = require("../../../queries/query"); const signature_query_format_1 = require("../../../queries/catalog/signature-query/signature-query-format"); const query_print_1 = require("../../../queries/query-print"); const sigdb_download_1 = require("../../../project/sigdb/sigdb-download"); const config_1 = require("../../../config"); const retriever_1 = require("../../../r-bridge/retriever"); const signature_query_executor_1 = require("../../../queries/catalog/signature-query/signature-query-executor"); /** treat the whole line as arguments, no R code to separate */ function parseArgs(line) { return { rCode: undefined, remaining: (0, args_1.splitAtEscapeSensitive)(line) }; } /** the (possibly space-containing) path/argument remainder passed to a subcommand */ function joinArgs(args) { return args.filter(a => a.length > 0).join(' ').trim(); } function printHelp(output) { const f = output.formatter; output.stdout((0, ansi_1.bold)('Signature Database', f) + (0, ansi_1.italic)(' (inspect and extend the databases that resolve library()/`::` calls)', f)); output.stdout(''); output.stdout(` ${(0, ansi_1.bold)(':signature query', f)} ${(0, ansi_1.italic)('[<package>[@<version>][::<function>] [<function>]] [--param <name>] [--required <n>]', f)}`); output.stdout(` ${(0, ansi_1.italic)('inspect the database -- identical to :query @signature; with no package it summarizes the loaded databases and per-shard load state (run :signature query help for the full syntax)', f)}`); output.stdout(` ${(0, ansi_1.bold)(':signature add', f)} ${(0, ansi_1.italic)('<path-to-.sigs.ndjson|.br|.manifest.json>', f)}`); output.stdout(` ${(0, ansi_1.italic)('mount an additional signature database/source (dictionaries + shards); takes precedence over the bundle', f)}`); output.stdout(` ${(0, ansi_1.bold)(':signature download', f)} ${(0, ansi_1.italic)('[<version>]', f)}`); output.stdout(` ${(0, ansi_1.italic)('download the full-history database (all CRAN versions) from the release and mount it', f)}`); } /** `:signature query ...` -- inspect the database (identical to the signature query run via `:query`) */ async function runQuery(output, analyzer, args) { const parsed = signature_query_format_1.SignatureQueryDefinition.fromLine(output, args, analyzer.flowrConfig).query; const queries = parsed ? (Array.isArray(parsed) ? parsed : [parsed]) : []; if (queries.length === 0) { return; // e.g. `:signature query help` already printed the usage guide } const start = Date.now(); const results = await (0, query_1.executeQueries)({ analyzer }, queries); output.stdout(await (0, query_print_1.asciiSummaryOfQueryResult)(output.formatter, Date.now() - start, results, analyzer, queries)); } /** `:signature add <path>` -- mount an additional signature database/source (takes precedence over the bundle) */ async function runAdd(output, analyzer, rest) { const f = output.formatter; const source = joinArgs(rest); if (!source) { output.stderr(`Usage: ${(0, ansi_1.italic)(':signature add <path-to-.sigs.ndjson|.br|.manifest.json>', f)}`); return; } await analyzer.context().deps.addDatabaseSource(source); analyzer.reset(); output.stdout(`Mounted signature source ${(0, ansi_1.bold)(source, f)} (takes precedence over the bundled default).`); output.stdout((0, ansi_1.italic)('Inspect it with :signature query.', f)); } /** `:signature download [<version>]` -- fetch the full-history database from the release and mount it */ async function runDownload(output, analyzer, rest) { const f = output.formatter; const sigdb = analyzer.flowrConfig.solver.sigdb; try { const { dir, manifest, files } = await (0, sigdb_download_1.downloadFullSigDb)({ version: rest.find(a => a.length > 0), repo: sigdb.downloadRepo, onProgress: msg => output.stdout((0, ansi_1.italic)(` ${msg}`, f)) }); output.stdout(`Downloaded ${(0, ansi_1.bold)(String(files.length), f)} file(s) to ${(0, ansi_1.bold)(dir, f)}.`); if (manifest) { await analyzer.context().deps.addDatabaseSource(manifest); analyzer.reset(); output.stdout(`Mounted ${(0, ansi_1.bold)(manifest, f)}.`); } try { output.stdout(`Recorded in ${(0, ansi_1.bold)((0, config_1.persistSigDbPathToGlobalConfig)(dir), f)}; loads automatically on the next startup.`); } catch (e) { output.stderr((0, ansi_1.italic)(`Could not update global config (${e.message}); add ${dir} to solver.sigdb.additionalPaths manually.`, f)); } } catch (e) { output.stderr(`Download failed: ${e.message}`); } } /** every `:signature` subcommand keyed by name -- the single source driving both dispatch and completion */ const signatureSubcommands = { query: runQuery, add: runAdd, download: runDownload, help: output => printHelp(output), }; /** the `:signature` subcommand names, offered as completions for its first argument */ exports.signatureSubcommandNames = Object.keys(signatureSubcommands); /** completes `:signature`: its subcommands, then a file path for `add` (query args are freeform names) */ function replSignatureCompleter(splitLine, startingNewArg) { const subArgs = splitLine.slice(1).map(s => s.trim()).filter(s => s.length > 0); const inSubArgs = subArgs.length >= 2 || (subArgs.length === 1 && startingNewArg); if (!inSubArgs) { return { completions: exports.signatureSubcommandNames.map(s => s + ' ') }; } if (subArgs[0] === 'add') { return { completions: [retriever_1.fileProtocol] }; } if (subArgs[0] === 'query') { return (0, signature_query_executor_1.signatureQueryCompleter)(subArgs.slice(1), startingNewArg); } return { completions: [] }; } exports.signatureCommand = { description: 'Inspect and extend the signature database: `query` (identical to :query @signature), `add <path>` to mount another database/source, `download` to fetch the full-history database.', isCodeCommand: true, usageExample: ':signature <query|add|download> ...', aliases: ['sig'], script: false, argsParser: parseArgs, fn: async ({ output, analyzer, remainingArgs }) => { const [sub = 'help', ...rest] = remainingArgs.filter(a => a.length > 0); const handler = signatureSubcommands[sub]; if (!handler) { output.stderr(`Unknown subcommand ${(0, ansi_1.bold)(sub, output.formatter)}. Use ${(0, ansi_1.italic)(':signature help', output.formatter)}.`); return; } await handler(output, analyzer, rest); } }; //# sourceMappingURL=repl-signature.js.map