Skip to content

Commit

Permalink
fix(manager/devcontainer): parse with JSONC parser (#28914)
Browse files Browse the repository at this point in the history
  • Loading branch information
suzuki-shunsuke committed May 8, 2024
1 parent ff566cb commit ed4c2e6
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 2 deletions.
36 changes: 36 additions & 0 deletions lib/modules/manager/devcontainer/extract.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,42 @@ describe('modules/manager/devcontainer/extract', () => {
expect(result).toBeNull();
});

it('tests if JSONC can be parsed', () => {
// Arrange
const content = codeBlock(`
{
// hello
"features": {
"devcontainer.registry.renovate.com/test/features/first:1.2.3": {}
}
}`);
const extractConfig = {};
// Act
const result = extractPackageFile(
content,
'devcontainer.json',
extractConfig,
);

// Assert
expect(result).toEqual({
deps: [
{
autoReplaceStringTemplate:
'{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}',
currentDigest: undefined,
currentValue: '1.2.3',
datasource: 'docker',
depName: 'devcontainer.registry.renovate.com/test/features/first',
depType: 'feature',
pinDigests: false,
replaceString:
'devcontainer.registry.renovate.com/test/features/first:1.2.3',
},
],
});
});

it('returns feature image deps when only the features property is defined in dev container JSON file', () => {
// Arrange
const content = codeBlock(`
Expand Down
4 changes: 2 additions & 2 deletions lib/modules/manager/devcontainer/schema.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { z } from 'zod';
import { Json } from '../../../util/schema-utils';
import { Jsonc } from '../../../util/schema-utils';

export const DevContainerFile = Json.pipe(
export const DevContainerFile = Jsonc.pipe(
z.object({
image: z.string().optional(),
features: z.record(z.unknown()).optional(),
Expand Down
67 changes: 67 additions & 0 deletions lib/util/schema-utils.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { z } from 'zod';
import {
Json,
Json5,
Jsonc,
LooseArray,
LooseRecord,
MultidocYaml,
Expand Down Expand Up @@ -269,6 +270,72 @@ describe('util/schema-utils', () => {
});
});

describe('Jsonc', () => {
it('parses JSONC', () => {
const Schema = Jsonc.pipe(z.object({ foo: z.literal('bar') }));

expect(Schema.parse('{"foo": "bar"}')).toEqual({ foo: 'bar' });

expect(Schema.safeParse(42)).toMatchObject({
error: {
issues: [
{
message: 'Expected string, received number',
code: 'invalid_type',
expected: 'string',
received: 'number',
path: [],
},
],
},
success: false,
});

expect(Schema.safeParse('{"foo": "foo"}')).toMatchObject({
error: {
issues: [
{
message: 'Invalid literal value, expected "bar"',
code: 'invalid_literal',
expected: 'bar',
received: 'foo',
path: ['foo'],
},
],
},
success: false,
});

expect(Schema.safeParse('["foo", "bar"]')).toMatchObject({
error: {
issues: [
{
message: 'Expected object, received array',
code: 'invalid_type',
expected: 'object',
received: 'array',
path: [],
},
],
},
success: false,
});

expect(Schema.safeParse('{')).toMatchObject({
error: {
issues: [
{
message: 'Invalid JSONC',
code: 'custom',
path: [],
},
],
},
success: false,
});
});
});

describe('UtcDate', () => {
it('parses date', () => {
expect(UtcDate.parse('2020-04-04').toString()).toBe(
Expand Down
11 changes: 11 additions & 0 deletions lib/util/schema-utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import JSON5 from 'json5';
import * as JSONC from 'jsonc-parser';
import { DateTime } from 'luxon';
import type { JsonArray, JsonValue } from 'type-fest';
import { z } from 'zod';
Expand Down Expand Up @@ -215,6 +216,16 @@ export const Json5 = z.string().transform((str, ctx): JsonValue => {
}
});

export const Jsonc = z.string().transform((str, ctx): JsonValue => {
const errors: JSONC.ParseError[] = [];
const value = JSONC.parse(str, errors);
if (errors.length === 0) {
return value;
}
ctx.addIssue({ code: 'custom', message: 'Invalid JSONC' });
return z.NEVER;
});

export const UtcDate = z
.string({ description: 'ISO 8601 string' })
.transform((str, ctx): DateTime => {
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@
"json-stringify-pretty-compact": "3.0.0",
"json5": "2.2.3",
"jsonata": "2.0.4",
"jsonc-parser": "3.2.1",
"klona": "2.0.6",
"lru-cache": "10.2.2",
"luxon": "3.4.4",
Expand Down
3 changes: 3 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit ed4c2e6

Please sign in to comment.