diff --git a/test/config/npm/_fixtures/renovate-config-default.json b/lib/config/presets/__fixtures__/renovate-config-default.json similarity index 100% rename from test/config/npm/_fixtures/renovate-config-default.json rename to lib/config/presets/__fixtures__/renovate-config-default.json diff --git a/test/config/npm/_fixtures/renovate-config-group.json b/lib/config/presets/__fixtures__/renovate-config-group.json similarity index 100% rename from test/config/npm/_fixtures/renovate-config-group.json rename to lib/config/presets/__fixtures__/renovate-config-group.json diff --git a/test/config/npm/_fixtures/renovate-config-ikatyang.json b/lib/config/presets/__fixtures__/renovate-config-ikatyang.json similarity index 100% rename from test/config/npm/_fixtures/renovate-config-ikatyang.json rename to lib/config/presets/__fixtures__/renovate-config-ikatyang.json diff --git a/test/config/npm/_fixtures/renovate-config-monorepo.json b/lib/config/presets/__fixtures__/renovate-config-monorepo.json similarity index 100% rename from test/config/npm/_fixtures/renovate-config-monorepo.json rename to lib/config/presets/__fixtures__/renovate-config-monorepo.json diff --git a/test/config/npm/_fixtures/renovate-config-packages.json b/lib/config/presets/__fixtures__/renovate-config-packages.json similarity index 100% rename from test/config/npm/_fixtures/renovate-config-packages.json rename to lib/config/presets/__fixtures__/renovate-config-packages.json diff --git a/test/config/__snapshots__/presets.spec.ts.snap b/lib/config/presets/__snapshots__/index.spec.ts.snap similarity index 100% rename from test/config/__snapshots__/presets.spec.ts.snap rename to lib/config/presets/__snapshots__/index.spec.ts.snap diff --git a/lib/config/presets/__snapshots__/npm.spec.ts.snap b/lib/config/presets/__snapshots__/npm.spec.ts.snap new file mode 100644 index 0000000000000000000000000000000000000000..eb67bf320a745a276b4064596c08e889f2ef8751 --- /dev/null +++ b/lib/config/presets/__snapshots__/npm.spec.ts.snap @@ -0,0 +1,7 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`config/presets/npm should return preset 1`] = ` +Object { + "rangeStrategy": "auto", +} +`; diff --git a/lib/config/presets/common.ts b/lib/config/presets/common.ts new file mode 100644 index 0000000000000000000000000000000000000000..72ea53ca7134945f4f3fe96525baf774a674edbd --- /dev/null +++ b/lib/config/presets/common.ts @@ -0,0 +1,2 @@ +// TODO: Proper typing +export type Preset = any; diff --git a/lib/config/presets/github.spec.ts b/lib/config/presets/github.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..dac3a47c801f219afbdd7b716f386fdd2dda3ada --- /dev/null +++ b/lib/config/presets/github.spec.ts @@ -0,0 +1,70 @@ +import * as github from './github'; +import _got from '../../util/got'; +import * as _hostRules from '../../util/host-rules'; +import { PLATFORM_FAILURE } from '../../constants/error-messages'; + +jest.mock('../../platform/github/gh-got-wrapper'); +jest.mock('../../util/got'); +jest.mock('../../util/host-rules'); + +const got: any = _got; +const hostRules: any = _hostRules; + +describe('config/presets/github', () => { + beforeEach(() => global.renovateCache.rmAll()); + describe('getPreset()', () => { + it('passes up platform-failure', async () => { + got.mockImplementationOnce(() => { + throw new Error(PLATFORM_FAILURE); + }); + await expect(github.getPreset('some/repo')).rejects.toThrow( + PLATFORM_FAILURE + ); + }); + it('tries default then renovate', async () => { + got.mockImplementationOnce(() => { + throw new Error(); + }); + await expect(github.getPreset('some/repo')).rejects.toThrow(); + }); + it('throws if no content', async () => { + got.mockImplementationOnce(() => ({ + body: {}, + })); + await expect(github.getPreset('some/repo')).rejects.toThrow(); + }); + it('throws if fails to parse', async () => { + got.mockImplementationOnce(() => ({ + body: { + content: Buffer.from('not json').toString('base64'), + }, + })); + await expect(github.getPreset('some/repo')).rejects.toThrow(); + }); + it('should return default.json', async () => { + hostRules.find.mockReturnValueOnce({ token: 'abc' }); + got.mockImplementationOnce(() => ({ + body: { + content: Buffer.from('{"foo":"bar"}').toString('base64'), + }, + })); + const content = await github.getPreset('some/repo'); + expect(content).toEqual({ foo: 'bar' }); + }); + it('should return custom.json', async () => { + hostRules.find.mockReturnValueOnce({ token: 'abc' }); + got.mockImplementationOnce(() => ({ + body: { + content: Buffer.from('{"foo":"bar"}').toString('base64'), + }, + })); + try { + global.appMode = true; + const content = await github.getPreset('some/repo', 'custom'); + expect(content).toEqual({ foo: 'bar' }); + } finally { + delete global.appMode; + } + }); + }); +}); diff --git a/lib/config/presets/github.ts b/lib/config/presets/github.ts new file mode 100644 index 0000000000000000000000000000000000000000..34f82642a79df5bb60f6f1887e3721b3a49c377f --- /dev/null +++ b/lib/config/presets/github.ts @@ -0,0 +1,60 @@ +import { logger } from '../../logger'; +import { Preset } from './common'; +import got, { GotJSONOptions } from '../../util/got'; +import { PLATFORM_FAILURE } from '../../constants/error-messages'; +import { DATASOURCE_GITHUB } from '../../constants/data-binary-source'; + +async function fetchJSONFile(repo: string, fileName: string): Promise<Preset> { + const url = `https://api.github.com/repos/${repo}/contents/${fileName}`; + const opts: GotJSONOptions = { + headers: { + accept: global.appMode + ? 'application/vnd.github.machine-man-preview+json' + : 'application/vnd.github.v3+json', + }, + json: true, + hostType: DATASOURCE_GITHUB, + }; + let res: { body: { content: string } }; + try { + res = await got(url, opts); + } catch (err) { + if (err.message === PLATFORM_FAILURE) { + throw err; + } + logger.debug( + { statusCode: err.statusCodef }, + `Failed to retrieve ${fileName} from repo` + ); + throw new Error('dep not found'); + } + try { + const content = Buffer.from(res.body.content, 'base64').toString(); + const parsed = JSON.parse(content); + return parsed; + } catch (err) { + throw new Error('invalid preset JSON'); + } +} + +export async function getPreset( + pkgName: string, + presetName = 'default' +): Promise<Preset> { + if (presetName === 'default') { + try { + const defaultJson = await fetchJSONFile(pkgName, 'default.json'); + return defaultJson; + } catch (err) { + if (err.message === PLATFORM_FAILURE) { + throw err; + } + if (err.message === 'dep not found') { + logger.debug('default.json preset not found - trying renovate.json'); + return fetchJSONFile(pkgName, 'renovate.json'); + } + throw err; + } + } + return fetchJSONFile(pkgName, `${presetName}.json`); +} diff --git a/lib/config/presets/gitlab.spec.ts b/lib/config/presets/gitlab.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..6b4d3cdeb3869409ea484ff8af2dd5177d866e1f --- /dev/null +++ b/lib/config/presets/gitlab.spec.ts @@ -0,0 +1,52 @@ +import * as gitlab from './gitlab'; +import { api } from '../../platform/gitlab/gl-got-wrapper'; + +jest.mock('../../platform/gitlab/gl-got-wrapper'); +jest.mock('../../util/got'); + +const glGot: any = api.get; + +describe('config/presets/gitlab', () => { + beforeEach(() => { + global.repoCache = {}; + return global.renovateCache.rmAll(); + }); + describe('getPreset()', () => { + it('throws if non-default', async () => { + await expect( + gitlab.getPreset('some/repo', 'non-default') + ).rejects.toThrow(); + }); + it('throws if no content', async () => { + glGot.mockImplementationOnce(() => ({ + body: {}, + })); + await expect(gitlab.getPreset('some/repo')).rejects.toThrow(); + }); + it('throws if fails to parse', async () => { + glGot.mockImplementationOnce(() => ({ + body: { + content: Buffer.from('not json').toString('base64'), + }, + })); + await expect(gitlab.getPreset('some/repo')).rejects.toThrow(); + }); + it('should return the preset', async () => { + glGot.mockResolvedValueOnce({ + body: [ + { + name: 'master', + default: true, + }, + ], + }); + glGot.mockResolvedValueOnce({ + body: { + content: Buffer.from('{"foo":"bar"}').toString('base64'), + }, + }); + const content = await gitlab.getPreset('some/repo'); + expect(content).toEqual({ foo: 'bar' }); + }); + }); +}); diff --git a/lib/config/presets/gitlab.ts b/lib/config/presets/gitlab.ts new file mode 100644 index 0000000000000000000000000000000000000000..1b8cc1cc8ccc8338440a9302db2af13e439a0411 --- /dev/null +++ b/lib/config/presets/gitlab.ts @@ -0,0 +1,62 @@ +import { api } from '../../platform/gitlab/gl-got-wrapper'; +import { logger } from '../../logger'; +import { Preset } from './common'; + +const { get: glGot } = api; + +const GitLabApiUrl = 'https://gitlab.com/api/v4/projects'; + +async function getDefaultBranchName( + urlEncodedPkgName: string +): Promise<string> { + const branchesUrl = `${GitLabApiUrl}/${urlEncodedPkgName}/repository/branches`; + type GlBranch = { + default: boolean; + name: string; + }[]; + + const res = await glGot<GlBranch>(branchesUrl); + const branches = res.body; + let defautlBranchName = 'master'; + for (const branch of branches) { + if (branch.default) { + defautlBranchName = branch.name; + break; + } + } + + return defautlBranchName; +} + +export async function getPreset( + pkgName: string, + presetName = 'default' +): Promise<Preset> { + if (presetName !== 'default') { + // TODO: proper error contructor + throw new Error( + // { pkgName, presetName }, + 'Sub-preset names are not supported with Gitlab datasource' + ); + } + let res: string; + try { + const urlEncodedPkgName = encodeURIComponent(pkgName); + const defautlBranchName = await getDefaultBranchName(urlEncodedPkgName); + + const presetUrl = `${GitLabApiUrl}/${urlEncodedPkgName}/repository/files/renovate.json?ref=${defautlBranchName}`; + res = Buffer.from( + (await glGot(presetUrl)).body.content, + 'base64' + ).toString(); + } catch (err) { + logger.debug({ err }, 'Failed to retrieve renovate.json from repo'); + throw new Error('dep not found'); + } + try { + return JSON.parse(res); + } catch (err) /* istanbul ignore next */ { + logger.debug('Failed to parse renovate.json'); + throw new Error('invalid preset JSON'); + } +} diff --git a/test/config/presets.spec.ts b/lib/config/presets/index.spec.ts similarity index 95% rename from test/config/presets.spec.ts rename to lib/config/presets/index.spec.ts index cb3889c56cdd871115e5feb660aa0513734cc73d..f13552a01cb1e48280dda431a8742638e42708de 100644 --- a/test/config/presets.spec.ts +++ b/lib/config/presets/index.spec.ts @@ -1,13 +1,13 @@ -import * as _npm from '../../lib/datasource/npm'; -import * as presets from '../../lib/config/presets'; -import presetDefaults from './npm/_fixtures/renovate-config-default.json'; -import presetPackages from './npm/_fixtures/renovate-config-packages.json'; -import presetGroup from './npm/_fixtures/renovate-config-group.json'; -import presetMonorepo from './npm/_fixtures/renovate-config-monorepo.json'; -import presetIkatyang from './npm/_fixtures/renovate-config-ikatyang.json'; -import { RenovateConfig } from '../../lib/config'; +import * as _npm from './npm'; +import * as presets from '.'; +import presetDefaults from './__fixtures__/renovate-config-default.json'; +import presetPackages from './__fixtures__/renovate-config-packages.json'; +import presetGroup from './__fixtures__/renovate-config-group.json'; +import presetMonorepo from './__fixtures__/renovate-config-monorepo.json'; +import presetIkatyang from './__fixtures__/renovate-config-ikatyang.json'; +import { RenovateConfig } from '..'; -jest.mock('../../lib/datasource/npm'); +jest.mock('./npm'); const npm: any = _npm; diff --git a/lib/config/presets.ts b/lib/config/presets/index.ts similarity index 94% rename from lib/config/presets.ts rename to lib/config/presets/index.ts index 916bc1f9faad48f1d2e908a9c735b916c5f8f486..2092f55c8e8f632b72187bd5e46a2afed7b4b6ef 100644 --- a/lib/config/presets.ts +++ b/lib/config/presets/index.ts @@ -1,23 +1,23 @@ import is from '@sindresorhus/is'; -import { logger } from '../logger'; -import * as massage from './massage'; -import * as migration from './migration'; -import * as github from '../datasource/github'; -import * as npm from '../datasource/npm'; -import * as gitlab from '../datasource/gitlab'; -import { RenovateConfig } from './common'; -import { mergeChildConfig } from './utils'; -import { regEx } from '../util/regex'; +import { logger } from '../../logger'; +import * as massage from '../massage'; +import * as migration from '../migration'; +import * as github from './github'; +import * as npm from './npm'; +import * as gitlab from './gitlab'; +import { RenovateConfig } from '../common'; +import { mergeChildConfig } from '../utils'; +import { regEx } from '../../util/regex'; import { CONFIG_VALIDATION, DATASOURCE_FAILURE, PLATFORM_FAILURE, -} from '../constants/error-messages'; +} from '../../constants/error-messages'; import { DATASOURCE_GITHUB, DATASOURCE_GITLAB, DATASOURCE_NPM, -} from '../constants/data-binary-source'; +} from '../../constants/data-binary-source'; const datasources = { github, diff --git a/lib/config/presets/npm.spec.ts b/lib/config/presets/npm.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..fd441c911d6dc0f3bc1daa522412a3b9249f29df --- /dev/null +++ b/lib/config/presets/npm.spec.ts @@ -0,0 +1,121 @@ +import nock from 'nock'; +import * as npm from './npm'; + +jest.mock('registry-auth-token'); +jest.mock('delay'); + +describe('config/presets/npm', () => { + delete process.env.NPM_TOKEN; + beforeEach(() => { + jest.resetAllMocks(); + global.repoCache = {}; + global.trustLevel = 'low'; + nock.cleanAll(); + return global.renovateCache.rmAll(); + }); + afterEach(() => { + delete process.env.RENOVATE_CACHE_NPM_MINUTES; + }); + it('should throw if no package', async () => { + nock('https://registry.npmjs.org') + .get('/nopackage') + .reply(404); + await expect(npm.getPreset('nopackage', 'default')).rejects.toThrow( + /dep not found/ + ); + }); + it('should throw if no renovate-config', async () => { + const presetPackage = { + name: 'norenovateconfig', + versions: { + '0.0.1': { + foo: 1, + }, + '0.0.2': { + foo: 2, + deprecated: 'This is deprecated', + }, + }, + repository: { + type: 'git', + url: 'git://github.com/renovateapp/dummy.git', + }, + 'dist-tags': { + latest: '0.0.2', + }, + time: { + '0.0.1': '2018-05-06T07:21:53+02:00', + '0.0.2': '2018-05-07T07:21:53+02:00', + }, + }; + nock('https://registry.npmjs.org') + .get('/norenovateconfig') + .reply(200, presetPackage); + await expect(npm.getPreset('norenovateconfig', 'default')).rejects.toThrow( + /preset renovate-config not found/ + ); + }); + it('should throw if preset name not found', async () => { + const presetPackage = { + name: 'presetnamenotfound', + versions: { + '0.0.1': { + foo: 1, + }, + '0.0.2': { + foo: 2, + deprecated: 'This is deprecated', + 'renovate-config': { default: { rangeStrategy: 'auto' } }, + }, + }, + repository: { + type: 'git', + url: 'git://github.com/renovateapp/dummy.git', + }, + 'dist-tags': { + latest: '0.0.2', + }, + time: { + '0.0.1': '2018-05-06T07:21:53+02:00', + '0.0.2': '2018-05-07T07:21:53+02:00', + }, + }; + nock('https://registry.npmjs.org') + .get('/presetnamenotfound') + .reply(200, presetPackage); + await expect( + npm.getPreset('presetnamenotfound', 'missing') + ).rejects.toThrow(/preset not found/); + }); + it('should return preset', async () => { + const presetPackage = { + name: 'workingpreset', + versions: { + '0.0.1': { + foo: 1, + }, + '0.0.2': { + foo: 2, + deprecated: 'This is deprecated', + 'renovate-config': { default: { rangeStrategy: 'auto' } }, + }, + }, + repository: { + type: 'git', + url: 'https://github.com/renovateapp/dummy.git', + }, + 'dist-tags': { + latest: '0.0.2', + }, + time: { + '0.0.1': '2018-05-06T07:21:53+02:00', + '0.0.2': '2018-05-07T07:21:53+02:00', + }, + }; + nock('https://registry.npmjs.org') + .get('/workingpreset') + .reply(200, presetPackage); + const res = await npm.getPreset('workingpreset'); + expect(res).toMatchSnapshot(); + }); +}); diff --git a/lib/datasource/npm/presets.ts b/lib/config/presets/npm.ts similarity index 87% rename from lib/datasource/npm/presets.ts rename to lib/config/presets/npm.ts index 2ca515fc5c4b76be3148acc24070e5c16ac7416b..173e99033b95e8ebcb6af09243871079a148824a 100644 --- a/lib/datasource/npm/presets.ts +++ b/lib/config/presets/npm.ts @@ -1,6 +1,6 @@ import { logger } from '../../logger'; -import { getDependency } from './get'; -import { Preset } from '../common'; +import { getDependency } from '../../datasource/npm/get'; +import { Preset } from './common'; export async function getPreset( pkgName: string, diff --git a/lib/datasource/common.ts b/lib/datasource/common.ts index e97b71b71e02660f6e57d1875b2b72f0210dac2b..f7ad071248c26935ed9dd5f1901fe6cd6d7f55e3 100644 --- a/lib/datasource/common.ts +++ b/lib/datasource/common.ts @@ -44,12 +44,8 @@ export interface ReleaseResult { versions?: any; } -// TODO: Proper typing -export type Preset = any; - export interface Datasource { getDigest?(config: DigestConfig, newValue?: string): Promise<string | null>; - getPreset?(packageName: string, presetName?: string): Promise<Preset>; getPkgReleases(config: PkgReleaseConfig): Promise<ReleaseResult | null>; } diff --git a/lib/datasource/github/index.spec.ts b/lib/datasource/github/index.spec.ts index f990e856648e2d3b2da951d6732c928e04c8454d..6d9617ad3f6202ac9dd1dbb39b0cbb8b949698a1 100644 --- a/lib/datasource/github/index.spec.ts +++ b/lib/datasource/github/index.spec.ts @@ -1,15 +1,12 @@ import { api } from '../../platform/github/gh-got-wrapper'; import * as github from '.'; -import _got from '../../util/got'; import * as _hostRules from '../../util/host-rules'; -import { PLATFORM_FAILURE } from '../../constants/error-messages'; jest.mock('../../platform/github/gh-got-wrapper'); jest.mock('../../util/got'); jest.mock('../../util/host-rules'); -const got: any = _got; const ghGot: any = api.get; const hostRules: any = _hostRules; @@ -62,61 +59,6 @@ describe('datasource/github', () => { expect(res).toBeNull(); }); }); - describe('getPreset()', () => { - it('passes up platform-failure', async () => { - got.mockImplementationOnce(() => { - throw new Error(PLATFORM_FAILURE); - }); - await expect(github.getPreset('some/repo')).rejects.toThrow( - PLATFORM_FAILURE - ); - }); - it('tries default then renovate', async () => { - got.mockImplementationOnce(() => { - throw new Error(); - }); - await expect(github.getPreset('some/repo')).rejects.toThrow(); - }); - it('throws if no content', async () => { - got.mockImplementationOnce(() => ({ - body: {}, - })); - await expect(github.getPreset('some/repo')).rejects.toThrow(); - }); - it('throws if fails to parse', async () => { - got.mockImplementationOnce(() => ({ - body: { - content: Buffer.from('not json').toString('base64'), - }, - })); - await expect(github.getPreset('some/repo')).rejects.toThrow(); - }); - it('should return default.json', async () => { - hostRules.find.mockReturnValueOnce({ token: 'abc' }); - got.mockImplementationOnce(() => ({ - body: { - content: Buffer.from('{"foo":"bar"}').toString('base64'), - }, - })); - const content = await github.getPreset('some/repo'); - expect(content).toEqual({ foo: 'bar' }); - }); - it('should return custom.json', async () => { - hostRules.find.mockReturnValueOnce({ token: 'abc' }); - got.mockImplementationOnce(() => ({ - body: { - content: Buffer.from('{"foo":"bar"}').toString('base64'), - }, - })); - try { - global.appMode = true; - const content = await github.getPreset('some/repo', 'custom'); - expect(content).toEqual({ foo: 'bar' }); - } finally { - delete global.appMode; - } - }); - }); describe('getPkgReleases', () => { beforeAll(() => global.renovateCache.rmAll()); it('returns releases', async () => { diff --git a/lib/datasource/github/index.ts b/lib/datasource/github/index.ts index c72d5c07198d96706ccb99bbb1b7c30a9f5cd80c..be4be995e52ba53f4565eb1674fb13441aad9778 100644 --- a/lib/datasource/github/index.ts +++ b/lib/datasource/github/index.ts @@ -1,72 +1,9 @@ import { api } from '../../platform/github/gh-got-wrapper'; -import { - ReleaseResult, - PkgReleaseConfig, - Preset, - DigestConfig, -} from '../common'; +import { ReleaseResult, PkgReleaseConfig, DigestConfig } from '../common'; import { logger } from '../../logger'; -import got, { GotJSONOptions } from '../../util/got'; -import { PLATFORM_FAILURE } from '../../constants/error-messages'; -import { DATASOURCE_GITHUB } from '../../constants/data-binary-source'; const { get: ghGot } = api; -async function fetchJSONFile(repo: string, fileName: string): Promise<Preset> { - const url = `https://api.github.com/repos/${repo}/contents/${fileName}`; - const opts: GotJSONOptions = { - headers: { - accept: global.appMode - ? 'application/vnd.github.machine-man-preview+json' - : 'application/vnd.github.v3+json', - }, - json: true, - hostType: DATASOURCE_GITHUB, - }; - let res: { body: { content: string } }; - try { - res = await got(url, opts); - } catch (err) { - if (err.message === PLATFORM_FAILURE) { - throw err; - } - logger.debug( - { statusCode: err.statusCodef }, - `Failed to retrieve ${fileName} from repo` - ); - throw new Error('dep not found'); - } - try { - const content = Buffer.from(res.body.content, 'base64').toString(); - const parsed = JSON.parse(content); - return parsed; - } catch (err) { - throw new Error('invalid preset JSON'); - } -} - -export async function getPreset( - pkgName: string, - presetName = 'default' -): Promise<Preset> { - if (presetName === 'default') { - try { - const defaultJson = await fetchJSONFile(pkgName, 'default.json'); - return defaultJson; - } catch (err) { - if (err.message === PLATFORM_FAILURE) { - throw err; - } - if (err.message === 'dep not found') { - logger.debug('default.json preset not found - trying renovate.json'); - return fetchJSONFile(pkgName, 'renovate.json'); - } - throw err; - } - } - return fetchJSONFile(pkgName, `${presetName}.json`); -} - const cacheNamespace = 'datasource-github'; function getCacheKey(repo: string, type: string): string { return `${repo}:${type}`; diff --git a/lib/datasource/gitlab/index.spec.ts b/lib/datasource/gitlab/index.spec.ts index 46cff2e05a2adf32d21ee64c7303a9b3eb45a5f4..35092cddfe7f64d536bb4e0af099144fc551f6b7 100644 --- a/lib/datasource/gitlab/index.spec.ts +++ b/lib/datasource/gitlab/index.spec.ts @@ -11,44 +11,6 @@ describe('datasource/gitlab', () => { global.repoCache = {}; return global.renovateCache.rmAll(); }); - describe('getPreset()', () => { - it('throws if non-default', async () => { - await expect( - gitlab.getPreset('some/repo', 'non-default') - ).rejects.toThrow(); - }); - it('throws if no content', async () => { - glGot.mockImplementationOnce(() => ({ - body: {}, - })); - await expect(gitlab.getPreset('some/repo')).rejects.toThrow(); - }); - it('throws if fails to parse', async () => { - glGot.mockImplementationOnce(() => ({ - body: { - content: Buffer.from('not json').toString('base64'), - }, - })); - await expect(gitlab.getPreset('some/repo')).rejects.toThrow(); - }); - it('should return the preset', async () => { - glGot.mockResolvedValueOnce({ - body: [ - { - name: 'master', - default: true, - }, - ], - }); - glGot.mockResolvedValueOnce({ - body: { - content: Buffer.from('{"foo":"bar"}').toString('base64'), - }, - }); - const content = await gitlab.getPreset('some/repo'); - expect(content).toEqual({ foo: 'bar' }); - }); - }); describe('getPkgReleases', () => { beforeAll(() => global.renovateCache.rmAll()); it('returns releases', async () => { diff --git a/lib/datasource/gitlab/index.ts b/lib/datasource/gitlab/index.ts index 607719c41c74cf2c56c36b7e576be89661888636..53c25078d3aa1db362fefc5c3b4eb55f1de65384 100644 --- a/lib/datasource/gitlab/index.ts +++ b/lib/datasource/gitlab/index.ts @@ -1,67 +1,10 @@ import is from '@sindresorhus/is'; import { api } from '../../platform/gitlab/gl-got-wrapper'; import { logger } from '../../logger'; -import { PkgReleaseConfig, ReleaseResult, Preset } from '../common'; +import { PkgReleaseConfig, ReleaseResult } from '../common'; const { get: glGot } = api; -const GitLabApiUrl = 'https://gitlab.com/api/v4/projects'; - -async function getDefaultBranchName( - urlEncodedPkgName: string -): Promise<string> { - const branchesUrl = `${GitLabApiUrl}/${urlEncodedPkgName}/repository/branches`; - type GlBranch = { - default: boolean; - name: string; - }[]; - - const res = await glGot<GlBranch>(branchesUrl); - const branches = res.body; - let defautlBranchName = 'master'; - for (const branch of branches) { - if (branch.default) { - defautlBranchName = branch.name; - break; - } - } - - return defautlBranchName; -} - -export async function getPreset( - pkgName: string, - presetName = 'default' -): Promise<Preset> { - if (presetName !== 'default') { - // TODO: proper error contructor - throw new Error( - // { pkgName, presetName }, - 'Sub-preset names are not supported with Gitlab datasource' - ); - } - let res: string; - try { - const urlEncodedPkgName = encodeURIComponent(pkgName); - const defautlBranchName = await getDefaultBranchName(urlEncodedPkgName); - - const presetUrl = `${GitLabApiUrl}/${urlEncodedPkgName}/repository/files/renovate.json?ref=${defautlBranchName}`; - res = Buffer.from( - (await glGot(presetUrl)).body.content, - 'base64' - ).toString(); - } catch (err) { - logger.debug({ err }, 'Failed to retrieve renovate.json from repo'); - throw new Error('dep not found'); - } - try { - return JSON.parse(res); - } catch (err) /* istanbul ignore next */ { - logger.debug('Failed to parse renovate.json'); - throw new Error('invalid preset JSON'); - } -} - const cacheNamespace = 'datasource-gitlab'; function getCacheKey( depHost: string, diff --git a/lib/datasource/npm/__snapshots__/index.spec.ts.snap b/lib/datasource/npm/__snapshots__/index.spec.ts.snap index b87d89c58bd6dda825ec10526f6eee9afcef6c0c..99fc4368c2d02da3f20abb165272c6ad95c37a71 100644 --- a/lib/datasource/npm/__snapshots__/index.spec.ts.snap +++ b/lib/datasource/npm/__snapshots__/index.spec.ts.snap @@ -222,12 +222,6 @@ exports[`api/npm should return deprecated 2`] = ` Marking the latest version of an npm package as deprecated results in the entire package being considered deprecated, so contact the package author you think this is a mistake." `; -exports[`api/npm should return preset 1`] = ` -Object { - "rangeStrategy": "auto", -} -`; - exports[`api/npm should send an authorization header if provided 1`] = ` Object { "homepage": "https://github.com/renovateapp/dummy", diff --git a/lib/datasource/npm/index.spec.ts b/lib/datasource/npm/index.spec.ts index dc9b953272d8e0e27d7490743c7d782b94030118..6b146d9ea5d456efdf083cafb37e8be41a1da779 100644 --- a/lib/datasource/npm/index.spec.ts +++ b/lib/datasource/npm/index.spec.ts @@ -74,108 +74,6 @@ describe('api/npm', () => { expect(getRelease(res, '0.0.1').canBeUnpublished).toBe(false); expect(getRelease(res, '0.0.2').canBeUnpublished).toBe(false); }); - it('should throw if no package', async () => { - nock('https://registry.npmjs.org') - .get('/foobar') - .reply(404); - await expect(npm.getPreset('foobar', 'default')).rejects.toThrow( - /dep not found/ - ); - }); - it('should throw if no renovate-config', async () => { - const presetPackage = { - name: 'foobar', - versions: { - '0.0.1': { - foo: 1, - }, - '0.0.2': { - foo: 2, - deprecated: 'This is deprecated', - }, - }, - repository: { - type: 'git', - url: 'git://github.com/renovateapp/dummy.git', - }, - 'dist-tags': { - latest: '0.0.2', - }, - time: { - '0.0.1': '2018-05-06T07:21:53+02:00', - '0.0.2': '2018-05-07T07:21:53+02:00', - }, - }; - nock('https://registry.npmjs.org') - .get('/foobar') - .reply(200, presetPackage); - await expect(npm.getPreset('foobar', 'default')).rejects.toThrow( - /preset renovate-config not found/ - ); - }); - it('should throw if no preset name not found', async () => { - const presetPackage = { - name: 'foobar', - versions: { - '0.0.1': { - foo: 1, - }, - '0.0.2': { - foo: 2, - deprecated: 'This is deprecated', - 'renovate-config': { default: { rangeStrategy: 'auto' } }, - }, - }, - repository: { - type: 'git', - url: 'git://github.com/renovateapp/dummy.git', - }, - 'dist-tags': { - latest: '0.0.2', - }, - time: { - '0.0.1': '2018-05-06T07:21:53+02:00', - '0.0.2': '2018-05-07T07:21:53+02:00', - }, - }; - nock('https://registry.npmjs.org') - .get('/foobar') - .reply(200, presetPackage); - await expect(npm.getPreset('foobar', 'missing')).rejects.toThrow( - /preset not found/ - ); - }); - it('should return preset', async () => { - const presetPackage = { - name: 'foobar', - versions: { - '0.0.1': { - foo: 1, - }, - '0.0.2': { - foo: 2, - deprecated: 'This is deprecated', - 'renovate-config': { default: { rangeStrategy: 'auto' } }, - }, - }, - repository: { - type: 'git', - url: 'https://github.com/renovateapp/dummy.git', - }, - 'dist-tags': { - latest: '0.0.2', - }, - time: { - '0.0.1': '2018-05-06T07:21:53+02:00', - '0.0.2': '2018-05-07T07:21:53+02:00', - }, - }; - nock('https://registry.npmjs.org') - .get('/foobar') - .reply(200, presetPackage); - const res = await npm.getPreset('foobar'); - expect(res).toMatchSnapshot(); - }); it('should parse repo url', async () => { const pkg = { name: 'foobar', diff --git a/lib/datasource/npm/index.ts b/lib/datasource/npm/index.ts index c4fc281955210e20437ed86cc8667f73d788798f..8a90451a27ffc2e82eac9bedad69b740f00e76e9 100644 --- a/lib/datasource/npm/index.ts +++ b/lib/datasource/npm/index.ts @@ -1,4 +1,3 @@ export { resetMemCache, resetCache } from './get'; -export { getPreset } from './presets'; export { getPkgReleases } from './releases'; export { setNpmrc } from './npmrc'; diff --git a/lib/datasource/readme.md b/lib/datasource/readme.md index b585276252fb2dc6a101a5ac2d56ff033bfeee57..9715a45355b2d964ab3c80634c69695c972ba1c8 100644 --- a/lib/datasource/readme.md +++ b/lib/datasource/readme.md @@ -31,7 +31,3 @@ The `getDigest` function has two inputs: - `newValue`: the version or value to retrieve the digest for The `getDigest` function returns a string output representing the digest value. If none is found then a return value of `null` should be returned. - -### getPreset - -This function is supported by npm, github and gitlab for retrieving a Renovate preset. diff --git a/test/config/index.spec.ts b/test/config/index.spec.ts index 8a6e42e637a40b71d2956db17226b1e19a9f7618..b143200a74623cc6a69c835a08559678e656ae8f 100644 --- a/test/config/index.spec.ts +++ b/test/config/index.spec.ts @@ -1,7 +1,5 @@ import getArgv from './config/_fixtures/argv'; import { getConfig } from '../../lib/config/defaults'; -import * as _npm from '../../lib/datasource/npm'; -import presetDefaults from './npm/_fixtures/renovate-config-default.json'; jest.mock('../../lib/datasource/npm'); try { @@ -10,16 +8,8 @@ try { // file does not exist } -const npm: any = _npm; const defaultConfig = getConfig(); -npm.getPkgReleases = jest.fn(() => ({ - 'renovate-config': - presetDefaults.versions[presetDefaults['dist-tags'].latest][ - 'renovate-config' - ], -})); - describe('config/index', () => { describe('.parseConfigs(env, defaultArgv)', () => { let configParser: typeof import('../../lib/config');