mirror of
https://github.com/renovatebot/renovate.git
synced 2025-01-12 15:06:27 +00:00
refactor(bazel): Simplify parser output structure (#18270)
This commit is contained in:
parent
8b9259b0e9
commit
f2d85c16cd
3 changed files with 135 additions and 161 deletions
|
@ -1,8 +1,7 @@
|
|||
import { logger } from '../../../logger';
|
||||
import type { PackageDependency, PackageFile } from '../types';
|
||||
import { parse } from './parser';
|
||||
import { extractDepFromFragment } from './rules';
|
||||
import type { ArrayFragment } from './types';
|
||||
import type { RecordFragment } from './types';
|
||||
|
||||
export function extractPackageFile(
|
||||
content: string,
|
||||
|
@ -10,19 +9,13 @@ export function extractPackageFile(
|
|||
): PackageFile | null {
|
||||
const deps: PackageDependency[] = [];
|
||||
|
||||
let parsed: ArrayFragment | null = null;
|
||||
try {
|
||||
parsed = parse(content);
|
||||
} catch (err) /* istanbul ignore next */ {
|
||||
logger.debug({ err, packageFile }, 'Bazel parsing error');
|
||||
}
|
||||
|
||||
if (!parsed) {
|
||||
const fragments: RecordFragment[] | null = parse(content, packageFile);
|
||||
if (!fragments) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (let idx = 0; idx < parsed.children.length; idx += 1) {
|
||||
const fragment = parsed.children[idx];
|
||||
for (let idx = 0; idx < fragments.length; idx += 1) {
|
||||
const fragment = fragments[idx];
|
||||
|
||||
const dep = extractDepFromFragment(fragment);
|
||||
if (!dep) {
|
||||
|
|
|
@ -9,42 +9,36 @@ describe('modules/manager/bazel/parser', () => {
|
|||
|
||||
const res = parse(input);
|
||||
|
||||
expect(res).toEqual({
|
||||
type: 'array',
|
||||
value:
|
||||
'go_repository(name = "foo")\nmaybe(go_repository, name = "bar", deps = ["baz", "qux"])',
|
||||
offset: 0,
|
||||
children: [
|
||||
{
|
||||
type: 'record',
|
||||
value: 'go_repository(name = "foo")',
|
||||
offset: 0,
|
||||
children: {
|
||||
rule: { type: 'string', value: 'go_repository', offset: 0 },
|
||||
name: { type: 'string', value: 'foo', offset: 22 },
|
||||
expect(res).toEqual([
|
||||
{
|
||||
type: 'record',
|
||||
value: 'go_repository(name = "foo")',
|
||||
offset: 0,
|
||||
children: {
|
||||
rule: { type: 'string', value: 'go_repository', offset: 0 },
|
||||
name: { type: 'string', value: 'foo', offset: 22 },
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'record',
|
||||
value: 'maybe(go_repository, name = "bar", deps = ["baz", "qux"])',
|
||||
offset: 28,
|
||||
children: {
|
||||
rule: { type: 'string', value: 'go_repository', offset: 34 },
|
||||
name: { type: 'string', value: 'bar', offset: 57 },
|
||||
deps: {
|
||||
type: 'array',
|
||||
value: '["baz", "qux"]',
|
||||
offset: 70,
|
||||
children: [
|
||||
{ type: 'string', value: 'baz', offset: 72 },
|
||||
{ type: 'string', value: 'qux', offset: 79 },
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'record',
|
||||
value: 'maybe(go_repository, name = "bar", deps = ["baz", "qux"])',
|
||||
offset: 28,
|
||||
children: {
|
||||
rule: { type: 'string', value: 'go_repository', offset: 34 },
|
||||
name: { type: 'string', value: 'bar', offset: 57 },
|
||||
deps: {
|
||||
type: 'array',
|
||||
value: '["baz", "qux"]',
|
||||
offset: 70,
|
||||
children: [
|
||||
{ type: 'string', value: 'baz', offset: 72 },
|
||||
{ type: 'string', value: 'qux', offset: 79 },
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
expect(extract(res!)).toMatchObject([
|
||||
},
|
||||
]);
|
||||
expect(res?.map(extract)).toMatchObject([
|
||||
{ rule: 'go_repository', name: 'foo' },
|
||||
{ rule: 'go_repository', name: 'bar', deps: ['baz', 'qux'] },
|
||||
]);
|
||||
|
@ -66,45 +60,44 @@ describe('modules/manager/bazel/parser', () => {
|
|||
|
||||
const res = parse(input);
|
||||
|
||||
expect(res).toMatchObject({
|
||||
children: [
|
||||
{
|
||||
children: {
|
||||
rule: { value: 'http_archive' },
|
||||
name: { value: 'aspect_rules_js' },
|
||||
sha256: {
|
||||
value:
|
||||
'db9f446752fe4100320cf8487e8fd476b9af0adf6b99b601bcfd70b289bb0598',
|
||||
},
|
||||
strip_prefix: { value: 'rules_js-1.1.2' },
|
||||
url: {
|
||||
value:
|
||||
'https://github.com/aspect-build/rules_js/archive/refs/tags/v1.1.2.tar.gz',
|
||||
},
|
||||
expect(res).toMatchObject([
|
||||
{
|
||||
children: {
|
||||
rule: { value: 'http_archive' },
|
||||
name: { value: 'aspect_rules_js' },
|
||||
sha256: {
|
||||
value:
|
||||
'db9f446752fe4100320cf8487e8fd476b9af0adf6b99b601bcfd70b289bb0598',
|
||||
},
|
||||
strip_prefix: { value: 'rules_js-1.1.2' },
|
||||
url: {
|
||||
value:
|
||||
'https://github.com/aspect-build/rules_js/archive/refs/tags/v1.1.2.tar.gz',
|
||||
},
|
||||
},
|
||||
{
|
||||
children: {
|
||||
rule: { value: 'http_archive' },
|
||||
name: { value: 'rules_nodejs' },
|
||||
sha256: {
|
||||
value:
|
||||
'5aef09ed3279aa01d5c928e3beb248f9ad32dde6aafe6373a8c994c3ce643064',
|
||||
},
|
||||
urls: {
|
||||
type: 'array',
|
||||
children: [
|
||||
{
|
||||
value:
|
||||
'https://github.com/bazelbuild/rules_nodejs/releases/download/5.5.3/rules_nodejs-core-5.5.3.tar.gz',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
children: {
|
||||
rule: { value: 'http_archive' },
|
||||
name: { value: 'rules_nodejs' },
|
||||
sha256: {
|
||||
value:
|
||||
'5aef09ed3279aa01d5c928e3beb248f9ad32dde6aafe6373a8c994c3ce643064',
|
||||
},
|
||||
urls: {
|
||||
type: 'array',
|
||||
children: [
|
||||
{
|
||||
value:
|
||||
'https://github.com/bazelbuild/rules_nodejs/releases/download/5.5.3/rules_nodejs-core-5.5.3.tar.gz',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
expect(extract(res!)).toMatchObject([
|
||||
},
|
||||
]);
|
||||
|
||||
expect(res?.map(extract)).toMatchObject([
|
||||
{
|
||||
rule: 'http_archive',
|
||||
name: 'aspect_rules_js',
|
||||
|
@ -134,25 +127,24 @@ describe('modules/manager/bazel/parser', () => {
|
|||
|
||||
const res = parse(input);
|
||||
|
||||
expect(res).toMatchObject({
|
||||
children: [
|
||||
{
|
||||
children: {
|
||||
name: { value: 'rules_nodejs' },
|
||||
rule: { value: 'http_archive' },
|
||||
sha256: {
|
||||
value:
|
||||
'5aef09ed3279aa01d5c928e3beb248f9ad32dde6aafe6373a8c994c3ce643064',
|
||||
},
|
||||
url: {
|
||||
value:
|
||||
'https://github.com/bazelbuild/rules_nodejs/releases/download/5.5.3/rules_nodejs-core-5.5.3.tar.gz',
|
||||
},
|
||||
expect(res).toMatchObject([
|
||||
{
|
||||
children: {
|
||||
name: { value: 'rules_nodejs' },
|
||||
rule: { value: 'http_archive' },
|
||||
sha256: {
|
||||
value:
|
||||
'5aef09ed3279aa01d5c928e3beb248f9ad32dde6aafe6373a8c994c3ce643064',
|
||||
},
|
||||
url: {
|
||||
value:
|
||||
'https://github.com/bazelbuild/rules_nodejs/releases/download/5.5.3/rules_nodejs-core-5.5.3.tar.gz',
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
expect(extract(res!)).toMatchObject([
|
||||
},
|
||||
]);
|
||||
|
||||
expect(res?.map(extract)).toMatchObject([
|
||||
{
|
||||
rule: 'http_archive',
|
||||
name: 'rules_nodejs',
|
||||
|
@ -176,37 +168,35 @@ describe('modules/manager/bazel/parser', () => {
|
|||
|
||||
const res = parse(input);
|
||||
|
||||
expect(res).toMatchObject({
|
||||
children: [
|
||||
{
|
||||
children: {
|
||||
name: { value: 'bazel_toolchains' },
|
||||
rule: { value: 'http_archive' },
|
||||
sha256: {
|
||||
value:
|
||||
'4b1468b254a572dbe134cc1fd7c6eab1618a72acd339749ea343bd8f55c3b7eb',
|
||||
},
|
||||
strip_prefix: {
|
||||
value:
|
||||
'bazel-toolchains-d665ccfa3e9c90fa789671bf4ef5f7c19c5715c4',
|
||||
},
|
||||
urls: {
|
||||
children: [
|
||||
{
|
||||
value:
|
||||
'https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/d665ccfa3e9c90fa789671bf4ef5f7c19c5715c4.tar.gz',
|
||||
},
|
||||
{
|
||||
value:
|
||||
'https://github.com/bazelbuild/bazel-toolchains/archive/d665ccfa3e9c90fa789671bf4ef5f7c19c5715c4.tar.gz',
|
||||
},
|
||||
],
|
||||
},
|
||||
expect(res).toMatchObject([
|
||||
{
|
||||
children: {
|
||||
name: { value: 'bazel_toolchains' },
|
||||
rule: { value: 'http_archive' },
|
||||
sha256: {
|
||||
value:
|
||||
'4b1468b254a572dbe134cc1fd7c6eab1618a72acd339749ea343bd8f55c3b7eb',
|
||||
},
|
||||
strip_prefix: {
|
||||
value: 'bazel-toolchains-d665ccfa3e9c90fa789671bf4ef5f7c19c5715c4',
|
||||
},
|
||||
urls: {
|
||||
children: [
|
||||
{
|
||||
value:
|
||||
'https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/d665ccfa3e9c90fa789671bf4ef5f7c19c5715c4.tar.gz',
|
||||
},
|
||||
{
|
||||
value:
|
||||
'https://github.com/bazelbuild/bazel-toolchains/archive/d665ccfa3e9c90fa789671bf4ef5f7c19c5715c4.tar.gz',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
expect(extract(res!)).toMatchObject([
|
||||
},
|
||||
]);
|
||||
|
||||
expect(res?.map(extract)).toMatchObject([
|
||||
{
|
||||
name: 'bazel_toolchains',
|
||||
rule: 'http_archive',
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import { lang, lexer, parser, query as q } from 'good-enough-parser';
|
||||
import hasha from 'hasha';
|
||||
import { logger } from '../../../logger';
|
||||
import * as memCache from '../../../util/cache/memory';
|
||||
import { supportedRulesRegex } from './rules/index';
|
||||
import type {
|
||||
ArrayFragment,
|
||||
Fragment,
|
||||
FragmentData,
|
||||
NestedFragment,
|
||||
|
@ -12,6 +12,7 @@ import type {
|
|||
|
||||
interface Ctx {
|
||||
readonly source: string;
|
||||
results: RecordFragment[];
|
||||
stack: NestedFragment[];
|
||||
recordKey?: string;
|
||||
}
|
||||
|
@ -19,14 +20,8 @@ interface Ctx {
|
|||
function emptyCtx(source: string): Ctx {
|
||||
return {
|
||||
source,
|
||||
stack: [
|
||||
{
|
||||
type: 'array',
|
||||
value: source,
|
||||
offset: 0,
|
||||
children: [],
|
||||
},
|
||||
],
|
||||
results: [],
|
||||
stack: [],
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -139,12 +134,8 @@ function ruleCall(search: q.QueryBuilder<Ctx>): q.QueryBuilder<Ctx> {
|
|||
const frag = currentFragment(ctx);
|
||||
if (frag.type === 'record' && tree.type === 'wrapped-tree') {
|
||||
frag.value = extractTreeValue(ctx.source, tree, frag.offset);
|
||||
}
|
||||
|
||||
ctx.stack.pop();
|
||||
const parentFrag = currentFragment(ctx);
|
||||
if (parentFrag.type === 'array') {
|
||||
parentFrag.children.push(frag);
|
||||
ctx.stack.pop();
|
||||
ctx.results.push(frag);
|
||||
}
|
||||
|
||||
return ctx;
|
||||
|
@ -152,17 +143,13 @@ function ruleCall(search: q.QueryBuilder<Ctx>): q.QueryBuilder<Ctx> {
|
|||
});
|
||||
}
|
||||
|
||||
function ruleStartHandler(ctx: Ctx, { value, offset }: lexer.Token): Ctx {
|
||||
const parentFragment = currentFragment(ctx);
|
||||
if (parentFragment.type === 'array') {
|
||||
ctx.stack.push({
|
||||
type: 'record',
|
||||
value: '',
|
||||
offset,
|
||||
children: {},
|
||||
});
|
||||
}
|
||||
|
||||
function ruleStartHandler(ctx: Ctx, { offset }: lexer.Token): Ctx {
|
||||
ctx.stack.push({
|
||||
type: 'record',
|
||||
value: '',
|
||||
offset,
|
||||
children: {},
|
||||
});
|
||||
return ctx;
|
||||
}
|
||||
|
||||
|
@ -217,22 +204,26 @@ function getCacheKey(input: string): string {
|
|||
|
||||
const starlark = lang.createLang('starlark');
|
||||
|
||||
export function parse(input: string): ArrayFragment | null {
|
||||
export function parse(
|
||||
input: string,
|
||||
packageFile?: string
|
||||
): RecordFragment[] | null {
|
||||
const cacheKey = getCacheKey(input);
|
||||
|
||||
const cachedResult = memCache.get<ArrayFragment | null>(cacheKey);
|
||||
const cachedResult = memCache.get<RecordFragment[] | null>(cacheKey);
|
||||
// istanbul ignore if
|
||||
if (cachedResult === null || cachedResult) {
|
||||
return cachedResult;
|
||||
}
|
||||
|
||||
let result: ArrayFragment | null = null;
|
||||
const parsedResult = starlark.query(input, query, emptyCtx(input));
|
||||
if (parsedResult) {
|
||||
const rootFragment = parsedResult.stack[0];
|
||||
if (rootFragment.type === 'array') {
|
||||
result = rootFragment;
|
||||
let result: RecordFragment[] | null = null;
|
||||
try {
|
||||
const parsedResult = starlark.query(input, query, emptyCtx(input));
|
||||
if (parsedResult) {
|
||||
result = parsedResult.results;
|
||||
}
|
||||
} catch (err) /* istanbul ignore next */ {
|
||||
logger.debug({ err, packageFile }, 'Bazel parsing error');
|
||||
}
|
||||
|
||||
memCache.set(cacheKey, result);
|
||||
|
|
Loading…
Reference in a new issue