diff --git a/lib/datasource/git-tags/index.js b/lib/datasource/git-tags/index.js index 7d2e3ff0c721cefa25d0578a7eb8bb55c74419b6..cf8cd025bbef799974c7a420ab5d08f01ba1b558 100644 --- a/lib/datasource/git-tags/index.js +++ b/lib/datasource/git-tags/index.js @@ -1,41 +1,42 @@ -const { getRemoteInfo } = require('isomorphic-git'); +const simpleGit = require('simple-git/promise'); +const semver = require('../../versioning/semver'); const cacheNamespace = 'git-tags'; const cacheMinutes = 10; +// git will prompt for known hosts or passwords, unless we activate BatchMode +process.env.GIT_SSH_COMMAND = 'ssh -o BatchMode=yes'; + async function getPkgReleases({ lookupName }) { + const git = simpleGit(); try { const cachedResult = await renovateCache.get(cacheNamespace, lookupName); /* istanbul ignore next line */ if (cachedResult) return cachedResult; - const info = await getRemoteInfo({ - url: lookupName, - }); - if (info && info.refs && info.refs.tags) { - const tags = Object.keys(info.refs.tags); - const result = tags.reduce( - (accum, gitRef) => { - if (!/\^/.test(gitRef)) { - // exclude things like '1.2.3^{}' - const version = gitRef.replace(/^v(?=[0-9])/, ''); // 'v1.2.3' => '1.2.3' - accum.releases.push({ - version, - gitRef, - }); - } - return accum; - }, - { - sourceUrl: lookupName, - releases: [], - } - ); - await renovateCache.set(cacheNamespace, lookupName, result, cacheMinutes); - return result; - } + // fetch remote tags + const lsRemote = await git.listRemote([ + '--sort=-v:refname', + '--tags', + lookupName, + ]); + // extract valid tags from git ls-remote which looks like 'commithash\trefs/tags/1.2.3 + const tags = lsRemote + .replace(/^.+?refs\/tags\//gm, '') + .split('\n') + .filter(tag => semver.isVersion(tag)); + const result = { + sourceUrl: lookupName, + releases: tags.map(tag => ({ + version: semver.isValid(tag), + gitref: tag, + })), + }; + + await renovateCache.set(cacheNamespace, lookupName, result, cacheMinutes); + return result; } catch (e) { - logger.debug(`Error looking up for tags in ${lookupName}`); + logger.debug(`Error looking up tags in ${lookupName}`); } return null; } diff --git a/package.json b/package.json index ef18621b01778a4cad8ead0c060c0251d00f7dbf..eaaf1aa0f53d2852b1232490d9c0516dcfc7fbda 100644 --- a/package.json +++ b/package.json @@ -111,7 +111,6 @@ "handlebars": "4.1.2", "hasha": "5.0.0", "ini": "1.3.5", - "isomorphic-git": "0.55.2", "js-yaml": "3.13.1", "json-dup-key-validator": "1.0.2", "json-stringify-pretty-compact": "2.0.0", diff --git a/test/datasource/git-tags.spec.js b/test/datasource/git-tags.spec.js index d9b389e4f4538779f1abaabbf9f701daf0bced0c..829875bf9ba05d78bf796ef0dc900c08e3c565bf 100644 --- a/test/datasource/git-tags.spec.js +++ b/test/datasource/git-tags.spec.js @@ -1,42 +1,43 @@ -const { getRemoteInfo } = require('isomorphic-git'); +const simpleGit = require('simple-git/promise'); const { getPkgReleases } = require('../../lib/datasource/git-tags'); -jest.mock('isomorphic-git'); +jest.mock('simple-git/promise.js'); -const lookupName = 'vapor'; -const registryUrls = ['https://github.com/vapor/vapor.git']; -const registryUrlsAlt = ['https://github.com/vapor/vapor/']; +// const lookupName = 'vapor'; +const lookupName = 'https://github.com/example/example.git'; describe('datasource/git-tags', () => { beforeEach(() => global.renovateCache.rmAll()); describe('getPkgReleases', () => { it('returns nil if response is wrong', async () => { - getRemoteInfo.mockReturnValue(Promise.resolve(null)); - const versions = await getPkgReleases({ lookupName, registryUrls }); + simpleGit.mockReturnValue({ + listRemote() { + return Promise.resolve(null); + }, + }); + const versions = await getPkgReleases({ lookupName }); expect(versions).toEqual(null); }); it('returns nil if remote call throws exception', async () => { - getRemoteInfo.mockImplementation(() => { - throw new Error(); + simpleGit.mockReturnValue({ + listRemote() { + throw new Error(); + }, }); - const versions = await getPkgReleases({ lookupName, registryUrls }); + const versions = await getPkgReleases({ lookupName }); expect(versions).toEqual(null); }); it('returns versions filtered from tags', async () => { - getRemoteInfo.mockReturnValue( - Promise.resolve({ - refs: { - tags: { - '0.0.1': 'foo', - 'v0.0.2': 'bar', - 'v0.0.2^{}': 'baz', - }, - }, - }) - ); + simpleGit.mockReturnValue({ + listRemote() { + return Promise.resolve( + 'commithash1\trefs/tags/0.0.1\ncommithash2\trefs/tags/v0.0.2\ncommithash3\trefs/tags/v0.0.2^{}' + ); + }, + }); + const versions = await getPkgReleases({ lookupName, - registryUrls: registryUrlsAlt, }); const result = versions.releases.map(x => x.version).sort(); expect(result).toEqual(['0.0.1', '0.0.2']);