UNPKG

renovate

Version:

Automated dependency updates. Flexible so you don't need to be.

262 lines • 8.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.parse = parse; const tslib_1 = require("tslib"); const good_enough_parser_1 = require("good-enough-parser"); const logger_1 = require("../../../logger"); const memCache = tslib_1.__importStar(require("../../../util/cache/memory")); const hash_1 = require("../../../util/hash"); const rules_1 = require("./rules"); function emptyCtx(source) { return { source, results: [], stack: [], }; } function currentFragment(ctx) { const deepestFragment = ctx.stack[ctx.stack.length - 1]; return deepestFragment; } function extractTreeValue(source, tree, offset) { if (tree.type === 'wrapped-tree') { const { endsWith } = tree; const to = endsWith.offset + endsWith.value.length; return source.slice(offset, to); } // istanbul ignore next return ''; } /** * Matches key-value pairs: * - `tag = "1.2.3"` * - `name = "foobar"` * - `deps = ["foo", "bar"]` * - ` * artifacts = [ maven.artifact( group = "com.example1", artifact = "foobar", version = "1.2.3", ) ] ` **/ const kwParams = good_enough_parser_1.query .sym((ctx, { value: recordKey }) => { return { ...ctx, recordKey }; }) .op('=') .alt( // string good_enough_parser_1.query.str((ctx, { offset, value }) => { const frag = currentFragment(ctx); if (frag.type === 'record' && ctx.recordKey) { const key = ctx.recordKey; frag.children[key] = { type: 'string', value, offset }; } return ctx; }), // array of strings or calls good_enough_parser_1.query.tree({ type: 'wrapped-tree', maxDepth: 1, startsWith: '[', endsWith: ']', preHandler: (ctx, tree) => { const parentRecord = currentFragment(ctx); if (parentRecord.type === 'record' && ctx.recordKey && tree.type === 'wrapped-tree') { const key = ctx.recordKey; parentRecord.children[key] = { type: 'array', value: '', offset: tree.startsWith.offset, children: [], }; } return ctx; }, search: good_enough_parser_1.query.alt(good_enough_parser_1.query.str((ctx, { value, offset }) => { const parentRecord = currentFragment(ctx); if (parentRecord.type === 'record' && ctx.recordKey) { const key = ctx.recordKey; const array = parentRecord.children[key]; if (array.type === 'array') { array.children.push({ type: 'string', value, offset }); } } return ctx; }), good_enough_parser_1.query .sym() .handler(recordStartHandler) .handler((ctx, { value, offset }) => { const ruleFragment = currentFragment(ctx); if (ruleFragment.type === 'record') { ruleFragment.children._function = { type: 'string', value, offset, }; } return ctx; }) .many(good_enough_parser_1.query.op('.').sym((ctx, { value }) => { const ruleFragment = currentFragment(ctx); if (ruleFragment.type === 'record' && ruleFragment.children._function) { ruleFragment.children._function.value += `.${value}`; } return ctx; }), 0, 3) .tree({ type: 'wrapped-tree', maxDepth: 1, startsWith: '(', endsWith: ')', search: good_enough_parser_1.query .opt(good_enough_parser_1.query .sym((ctx, { value: subRecordKey }) => ({ ...ctx, subRecordKey, })) .op('=')) .str((ctx, { value: subRecordValue, offset }) => { const argIndex = ctx.argIndex ?? 0; const subRecordKey = ctx.subRecordKey ?? argIndex.toString(); const ruleFragment = currentFragment(ctx); if (ruleFragment.type === 'record') { ruleFragment.children[subRecordKey] = { type: 'string', value: subRecordValue, offset, }; } delete ctx.subRecordKey; ctx.argIndex = argIndex + 1; return ctx; }), postHandler: (ctx, tree) => { delete ctx.argIndex; const callFrag = currentFragment(ctx); ctx.stack.pop(); if (callFrag.type === 'record' && tree.type === 'wrapped-tree') { callFrag.value = extractTreeValue(ctx.source, tree, callFrag.offset); const parentRecord = currentFragment(ctx); if (parentRecord.type === 'record' && ctx.recordKey) { const key = ctx.recordKey; const array = parentRecord.children[key]; if (array.type === 'array') { array.children.push(callFrag); } } } return ctx; }, })), postHandler: (ctx, tree) => { const parentRecord = currentFragment(ctx); if (parentRecord.type === 'record' && ctx.recordKey && tree.type === 'wrapped-tree') { const key = ctx.recordKey; const array = parentRecord.children[key]; if (array.type === 'array') { array.value = extractTreeValue(ctx.source, tree, array.offset); } } return ctx; }, })) .handler((ctx) => { delete ctx.recordKey; return ctx; }); /** * Matches rule signature: * `git_repository(......)` * ^^^^^^^^ * * @param search something to match inside parens */ function ruleCall(search) { return good_enough_parser_1.query.tree({ type: 'wrapped-tree', maxDepth: 1, search, postHandler: (ctx, tree) => { const frag = currentFragment(ctx); if (frag.type === 'record' && tree.type === 'wrapped-tree') { frag.value = extractTreeValue(ctx.source, tree, frag.offset); ctx.stack.pop(); ctx.results.push(frag); } return ctx; }, }); } function recordStartHandler(ctx, { offset }) { ctx.stack.push({ type: 'record', value: '', offset, children: {}, }); return ctx; } function ruleNameHandler(ctx, { value, offset }) { const ruleFragment = currentFragment(ctx); if (ruleFragment.type === 'record') { ruleFragment.children.rule = { type: 'string', value, offset }; } return ctx; } /** * Matches regular rules: * - `git_repository(...)` * - `_go_repository(...)` */ const regularRule = good_enough_parser_1.query .sym(rules_1.supportedRulesRegex, (ctx, token) => ruleNameHandler(recordStartHandler(ctx, token), token)) .join(ruleCall(kwParams)); /** * Matches "maybe"-form rules: * - `maybe(git_repository, ...)` * - `maybe(_go_repository, ...)` */ const maybeRule = good_enough_parser_1.query .sym('maybe', recordStartHandler) .join(ruleCall(good_enough_parser_1.query.alt(good_enough_parser_1.query.begin().sym(rules_1.supportedRulesRegex, ruleNameHandler).op(','), kwParams))); const rule = good_enough_parser_1.query.alt(maybeRule, regularRule); const query = good_enough_parser_1.query.tree({ type: 'root-tree', maxDepth: 16, search: rule, }); function getCacheKey(input) { const hashedInput = (0, hash_1.hash)(input); return `bazel-parser-${hashedInput}`; } const starlark = good_enough_parser_1.lang.createLang('starlark'); function parse(input, packageFile) { const cacheKey = getCacheKey(input); const cachedResult = memCache.get(cacheKey); // istanbul ignore if if (cachedResult === null || cachedResult) { return cachedResult; } let result = null; try { const parsedResult = starlark.query(input, query, emptyCtx(input)); if (parsedResult) { result = parsedResult.results; } } catch (err) /* istanbul ignore next */ { logger_1.logger.debug({ err, packageFile }, 'Bazel parsing error'); } memCache.set(cacheKey, result); return result; } //# sourceMappingURL=parser.js.map