Skip to content
Snippets Groups Projects
Unverified Commit 5a87c8b7 authored by Michael Kriese's avatar Michael Kriese Committed by GitHub
Browse files

feat(presets): extract generic platform preset fetch (#6467)

parent a77d73f7
No related branches found
No related tags found
No related merge requests found
...@@ -86,7 +86,7 @@ Array [ ...@@ -86,7 +86,7 @@ Array [
] ]
`; `;
exports[`config/presets/github/index getPreset() should return undefined 1`] = ` exports[`config/presets/github/index getPreset() should throws not-found 1`] = `
Array [ Array [
Object { Object {
"headers": Object { "headers": Object {
......
import * as httpMock from '../../../../test/httpMock'; import * as httpMock from '../../../../test/httpMock';
import { getName, mocked } from '../../../../test/util'; import { getName, mocked } from '../../../../test/util';
import * as _hostRules from '../../../util/host-rules'; import * as _hostRules from '../../../util/host-rules';
import { PRESET_NOT_FOUND } from '../util';
import * as github from '.'; import * as github from '.';
jest.mock('../../../util/host-rules'); jest.mock('../../../util/host-rules');
const hostRules = mocked(_hostRules); const hostRules = mocked(_hostRules);
const githubApiHost = 'https://api.github.com/'; const githubApiHost = github.Endpoint;
const basePath = '/repos/some/repo/contents'; const basePath = '/repos/some/repo/contents';
describe(getName(__filename), () => { describe(getName(__filename), () => {
...@@ -30,7 +31,7 @@ describe(getName(__filename), () => { ...@@ -30,7 +31,7 @@ describe(getName(__filename), () => {
const res = await github.fetchJSONFile( const res = await github.fetchJSONFile(
'some/repo', 'some/repo',
'some-filename.json', 'some-filename.json',
'https://api.github.com/' githubApiHost
); );
expect(res).toMatchSnapshot(); expect(res).toMatchSnapshot();
expect(httpMock.getTrace()).toMatchSnapshot(); expect(httpMock.getTrace()).toMatchSnapshot();
...@@ -145,7 +146,7 @@ describe(getName(__filename), () => { ...@@ -145,7 +146,7 @@ describe(getName(__filename), () => {
expect(httpMock.getTrace()).toMatchSnapshot(); expect(httpMock.getTrace()).toMatchSnapshot();
}); });
it('should return undefined', async () => { it('should throws not-found', async () => {
httpMock httpMock
.scope(githubApiHost) .scope(githubApiHost)
.get(`${basePath}/somefile.json`) .get(`${basePath}/somefile.json`)
...@@ -155,11 +156,12 @@ describe(getName(__filename), () => { ...@@ -155,11 +156,12 @@ describe(getName(__filename), () => {
try { try {
global.appMode = true; global.appMode = true;
const content = await github.getPreset({ await expect(
github.getPreset({
packageName: 'some/repo', packageName: 'some/repo',
presetName: 'somefile/somename/somesubname', presetName: 'somefile/somename/somesubname',
}); })
expect(content).toBeUndefined(); ).rejects.toThrow(PRESET_NOT_FOUND);
} finally { } finally {
delete global.appMode; delete global.appMode;
} }
......
...@@ -2,8 +2,10 @@ import { PLATFORM_FAILURE } from '../../../constants/error-messages'; ...@@ -2,8 +2,10 @@ import { PLATFORM_FAILURE } from '../../../constants/error-messages';
import { PLATFORM_TYPE_GITHUB } from '../../../constants/platforms'; import { PLATFORM_TYPE_GITHUB } from '../../../constants/platforms';
import { logger } from '../../../logger'; import { logger } from '../../../logger';
import { Http, HttpOptions } from '../../../util/http'; import { Http, HttpOptions } from '../../../util/http';
import { ensureTrailingSlash } from '../../../util/url';
import { Preset, PresetConfig } from '../common'; import { Preset, PresetConfig } from '../common';
import { PRESET_DEP_NOT_FOUND, fetchPreset } from '../util';
export const Endpoint = 'https://api.github.com/';
const http = new Http(PLATFORM_TYPE_GITHUB); const http = new Http(PLATFORM_TYPE_GITHUB);
...@@ -32,7 +34,7 @@ export async function fetchJSONFile( ...@@ -32,7 +34,7 @@ export async function fetchJSONFile(
{ statusCode: err.statusCode }, { statusCode: err.statusCode },
`Failed to retrieve ${fileName} from repo` `Failed to retrieve ${fileName} from repo`
); );
throw new Error('dep not found'); throw new Error(PRESET_DEP_NOT_FOUND);
} }
try { try {
const content = Buffer.from(res.body.content, 'base64').toString(); const content = Buffer.from(res.body.content, 'base64').toString();
...@@ -46,39 +48,19 @@ export async function fetchJSONFile( ...@@ -46,39 +48,19 @@ export async function fetchJSONFile(
export async function getPresetFromEndpoint( export async function getPresetFromEndpoint(
pkgName: string, pkgName: string,
filePreset: string, filePreset: string,
endpoint = 'https://api.github.com/' endpoint = Endpoint
): Promise<Preset> { ): Promise<Preset> {
// eslint-disable-next-line no-param-reassign return fetchPreset({
endpoint = ensureTrailingSlash(endpoint); pkgName,
const [fileName, presetName, subPresetName] = filePreset.split('/'); filePreset,
let jsonContent: any; endpoint,
if (fileName === 'default') { fetch: fetchJSONFile,
try { });
jsonContent = await fetchJSONFile(pkgName, 'default.json', endpoint);
} catch (err) {
if (err.message !== 'dep not found') {
throw err;
}
logger.debug('default.json preset not found - trying renovate.json');
jsonContent = await fetchJSONFile(pkgName, 'renovate.json', endpoint);
}
} else {
jsonContent = await fetchJSONFile(pkgName, `${fileName}.json`, endpoint);
}
if (presetName) {
if (subPresetName) {
return jsonContent[presetName]
? jsonContent[presetName][subPresetName]
: undefined;
}
return jsonContent[presetName];
}
return jsonContent;
} }
export function getPreset({ export function getPreset({
packageName: pkgName, packageName: pkgName,
presetName = 'default', presetName = 'default',
}: PresetConfig): Promise<Preset> { }: PresetConfig): Promise<Preset> {
return getPresetFromEndpoint(pkgName, presetName); return getPresetFromEndpoint(pkgName, presetName, Endpoint);
} }
import { getName } from '../../../test/util';
import { Preset } from './common';
import {
FetchPresetConfig,
PRESET_DEP_NOT_FOUND,
PRESET_NOT_FOUND,
fetchPreset,
} from './util';
const config: FetchPresetConfig = {
pkgName: 'some/repo',
filePreset: 'default',
endpoint: 'endpoint',
fetch: undefined,
};
const fetch = jest.fn(() => Promise.resolve<Preset>({}));
describe(getName(__filename), () => {
beforeEach(() => {
fetch.mockReset();
});
it('works', async () => {
fetch.mockResolvedValue({ sub: { preset: { foo: true } } });
expect(await fetchPreset({ ...config, fetch })).toEqual({
sub: { preset: { foo: true } },
});
expect(
await fetchPreset({ ...config, filePreset: 'some/sub', fetch })
).toEqual({ preset: { foo: true } });
expect(
await fetchPreset({ ...config, filePreset: 'some/sub/preset', fetch })
).toEqual({ foo: true });
});
it('fails', async () => {
fetch.mockRejectedValueOnce(new Error('fails'));
await expect(fetchPreset({ ...config, fetch })).rejects.toThrow('fails');
});
it(PRESET_DEP_NOT_FOUND, async () => {
fetch.mockResolvedValueOnce(null);
await expect(fetchPreset({ ...config, fetch })).rejects.toThrow(
PRESET_DEP_NOT_FOUND
);
fetch.mockRejectedValueOnce(new Error(PRESET_DEP_NOT_FOUND));
fetch.mockRejectedValueOnce(new Error(PRESET_DEP_NOT_FOUND));
await expect(fetchPreset({ ...config, fetch })).rejects.toThrow(
PRESET_DEP_NOT_FOUND
);
});
it(PRESET_NOT_FOUND, async () => {
fetch.mockResolvedValueOnce({});
await expect(
fetchPreset({ ...config, filePreset: 'some/sub/preset', fetch })
).rejects.toThrow(PRESET_NOT_FOUND);
fetch.mockResolvedValueOnce({ sub: {} });
await expect(
fetchPreset({ ...config, filePreset: 'some/sub/preset', fetch })
).rejects.toThrow(PRESET_NOT_FOUND);
});
});
import { logger } from '../../logger';
import { ensureTrailingSlash } from '../../util/url';
import { Preset } from './common';
export const PRESET_DEP_NOT_FOUND = 'dep not found';
export const PRESET_NOT_FOUND = 'preset not found';
export type PresetFetcher = (
repo: string,
fileName: string,
endpoint: string
) => Promise<Preset>;
export type FetchPresetConfig = {
pkgName: string;
filePreset: string;
endpoint: string;
fetch: PresetFetcher;
};
export async function fetchPreset({
pkgName,
filePreset,
endpoint,
fetch,
}: FetchPresetConfig): Promise<Preset | undefined> {
// eslint-disable-next-line no-param-reassign
endpoint = ensureTrailingSlash(endpoint);
const [fileName, presetName, subPresetName] = filePreset.split('/');
let jsonContent: any | undefined;
if (fileName === 'default') {
try {
jsonContent = await fetch(pkgName, 'default.json', endpoint);
} catch (err) {
if (err.message !== PRESET_DEP_NOT_FOUND) {
throw err;
}
logger.debug('default.json preset not found - trying renovate.json');
jsonContent = await fetch(pkgName, 'renovate.json', endpoint);
}
} else {
jsonContent = await fetch(pkgName, `${fileName}.json`, endpoint);
}
if (!jsonContent) {
throw new Error(PRESET_DEP_NOT_FOUND);
}
if (presetName) {
const preset = jsonContent[presetName];
if (!preset) {
throw new Error(PRESET_NOT_FOUND);
}
if (subPresetName) {
const subPreset = preset[subPresetName];
if (!subPreset) {
throw new Error(PRESET_NOT_FOUND);
}
return subPreset;
}
return preset;
}
return jsonContent;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment