mirror of
https://github.com/dependabot/fetch-metadata.git
synced 2026-03-12 18:07:12 -04:00
Handle branch names containing hyphen separators
This commit is contained in:
25
dist/index.js
generated
vendored
25
dist/index.js
generated
vendored
@@ -10089,6 +10089,27 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
exports.calculateUpdateType = exports.parse = void 0;
|
||||
const YAML = __importStar(__nccwpck_require__(4083));
|
||||
function branchNameToDirectoryName(chunks, delimiter, updatedDependencies) {
|
||||
// We can always slice after the first 2 pieces, because they will always contain "dependabot" followed by the name
|
||||
// of the package ecosystem. e.g. "dependabot/npm_and_yarn".
|
||||
const sliceStart = 2;
|
||||
let sliceEnd = chunks.length;
|
||||
// If the delimiter is "-", we assume the last piece of the branch name is a version number.
|
||||
if (delimiter === '-') {
|
||||
sliceEnd -= 1;
|
||||
}
|
||||
// If there is more than 1 dependency name being updated, we assume 1 piece of the branch name will be "and".
|
||||
if (updatedDependencies.length > 1) {
|
||||
sliceEnd -= 1;
|
||||
}
|
||||
updatedDependencies.forEach(dependency => {
|
||||
// After replacing "/" in the dependency name with the delimiter, which could also be "/", we count how many pieces
|
||||
// the dependency name would split into by the delimiter, and slicing that amount off the end of the branch name.
|
||||
// e.g. "@types/twilio-video" and a delimiter of "-" would show up in the branch name as "types-twilio-video".
|
||||
sliceEnd -= dependency['dependency-name'].replace('/', delimiter).split(delimiter).length;
|
||||
});
|
||||
return `/${chunks.slice(sliceStart, sliceEnd).join('/')}`;
|
||||
}
|
||||
function parse(commitMessage, body, branchName, mainBranch, lookup, getScore) {
|
||||
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
@@ -10108,12 +10129,12 @@ function parse(commitMessage, body, branchName, mainBranch, lookup, getScore) {
|
||||
const next = (_f = (_e = bumpFragment === null || bumpFragment === void 0 ? void 0 : bumpFragment.groups) === null || _e === void 0 ? void 0 : _e.to) !== null && _f !== void 0 ? _f : ((_h = (_g = updateFragment === null || updateFragment === void 0 ? void 0 : updateFragment.groups) === null || _g === void 0 ? void 0 : _g.to) !== null && _h !== void 0 ? _h : '');
|
||||
const dependencyGroup = (_k = (_j = groupName === null || groupName === void 0 ? void 0 : groupName.groups) === null || _j === void 0 ? void 0 : _j.name) !== null && _k !== void 0 ? _k : '';
|
||||
if (data['updated-dependencies']) {
|
||||
const dirname = branchNameToDirectoryName(chunks, delim, data['updated-dependencies']);
|
||||
return yield Promise.all(data['updated-dependencies'].map((dependency, index) => __awaiter(this, void 0, void 0, function* () {
|
||||
const dirname = `/${chunks.slice(2, -1 * (1 + (dependency['dependency-name'].match(/\//g) || []).length)).join(delim) || ''}`;
|
||||
const lastVersion = index === 0 ? prev : '';
|
||||
const nextVersion = index === 0 ? next : '';
|
||||
const updateType = dependency['update-type'] || calculateUpdateType(lastVersion, nextVersion);
|
||||
return Object.assign({ dependencyName: dependency['dependency-name'], dependencyType: dependency['dependency-type'], updateType, directory: dirname, packageEcosystem: chunks[1], targetBranch: mainBranch, prevVersion: lastVersion, newVersion: nextVersion, compatScore: yield scoreFn(dependency['dependency-name'], lastVersion, nextVersion, chunks[1]), maintainerChanges: newMaintainer, dependencyGroup: dependencyGroup }, yield lookupFn(dependency['dependency-name'], lastVersion, dirname));
|
||||
return Object.assign({ dependencyName: dependency['dependency-name'], dependencyType: dependency['dependency-type'], updateType, directory: dirname, packageEcosystem: chunks[1], targetBranch: mainBranch, prevVersion: lastVersion, newVersion: nextVersion, compatScore: yield scoreFn(dependency['dependency-name'], lastVersion, nextVersion, chunks[1]), maintainerChanges: newMaintainer, dependencyGroup }, yield lookupFn(dependency['dependency-name'], lastVersion, dirname));
|
||||
})));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ test('it supports multiple dependencies within a single fragment', async () => {
|
||||
return Promise.resolve(0)
|
||||
}
|
||||
|
||||
const updatedDependencies = await updateMetadata.parse(commitMessage, body, 'dependabot/nuget/api/main/coffee-rails', 'main', getAlert, getScore)
|
||||
const updatedDependencies = await updateMetadata.parse(commitMessage, body, 'dependabot/nuget/api/main/coffee-rails/and/coffeescript', 'main', getAlert, getScore)
|
||||
|
||||
expect(updatedDependencies).toHaveLength(2)
|
||||
|
||||
@@ -299,6 +299,105 @@ test('it properly handles dependencies which contain slashes', async () => {
|
||||
expect(updatedDependencies[0].dependencyGroup).toEqual('')
|
||||
})
|
||||
|
||||
test('it handles branch names with hyphen separator', async () => {
|
||||
const commitMessage =
|
||||
'- [Release notes](https://github.com/fsevents/fsevents/releases)\n' +
|
||||
'- [Commits](fsevents/fsevents@v1.2.9...v1.2.13)\n' +
|
||||
'\n' +
|
||||
'---\n' +
|
||||
'updated-dependencies:\n' +
|
||||
'- dependency-name: fsevents\n' +
|
||||
' dependency-type: indirect\n' +
|
||||
'...\n' +
|
||||
'\n' +
|
||||
'Signed-off-by: dependabot[bot] <support@github.com>'
|
||||
|
||||
const getAlert = async () => Promise.resolve({ alertState: '', ghsaId: '', cvss: 0 })
|
||||
const getScore = async () => Promise.resolve(0)
|
||||
const updatedDependencies = await updateMetadata.parse(commitMessage, '', 'dependabot-npm_and_yarn-fsevents-1.2.13', 'master', getAlert, getScore)
|
||||
|
||||
expect(updatedDependencies[0].directory).toEqual('/')
|
||||
})
|
||||
|
||||
test('it handles branch names with hyphen separator and manifest files in nested directories', async () => {
|
||||
const commitMessage =
|
||||
'- [Release notes](https://github.com/fsevents/fsevents/releases)\n' +
|
||||
'- [Commits](fsevents/fsevents@v1.2.9...v1.2.13)\n' +
|
||||
'\n' +
|
||||
'---\n' +
|
||||
'updated-dependencies:\n' +
|
||||
'- dependency-name: fsevents\n' +
|
||||
' dependency-type: indirect\n' +
|
||||
'...\n' +
|
||||
'\n' +
|
||||
'Signed-off-by: dependabot[bot] <support@github.com>'
|
||||
|
||||
const getAlert = async () => Promise.resolve({ alertState: '', ghsaId: '', cvss: 0 })
|
||||
const getScore = async () => Promise.resolve(0)
|
||||
const updatedDependencies = await updateMetadata.parse(commitMessage, '', 'dependabot-npm_and_yarn-nested-nested-fsevents-1.2.13', 'master', getAlert, getScore)
|
||||
|
||||
expect(updatedDependencies[0].directory).toEqual('/nested/nested')
|
||||
})
|
||||
|
||||
test('it handles branch names with hyphen separator and dependency names with forward slashes', async () => {
|
||||
const commitMessage =
|
||||
'- [Release notes](https://github.com/composer/composer/releases)\n' +
|
||||
'- [Changelog](https://github.com/composer/composer/blob/main/CHANGELOG.md)\n' +
|
||||
'- [Commits](composer/composer@1.10.26...2.6.5)\n' +
|
||||
'\n' +
|
||||
'---\n' +
|
||||
'updated-dependencies:\n' +
|
||||
'- dependency-name: composer/composer\n' +
|
||||
' dependency-type: indirect\n' +
|
||||
'...\n' +
|
||||
'\n' +
|
||||
'Signed-off-by: dependabot[bot] <support@github.com>'
|
||||
|
||||
const getAlert = async () => Promise.resolve({ alertState: '', ghsaId: '', cvss: 0 })
|
||||
const getScore = async () => Promise.resolve(0)
|
||||
const updatedDependencies = await updateMetadata.parse(commitMessage, '', 'dependabot-composer-composer-composer-2.6.5', 'master', getAlert, getScore)
|
||||
|
||||
expect(updatedDependencies[0].directory).toEqual('/')
|
||||
})
|
||||
|
||||
test('it handles branch names with hyphen separator and multiple dependencies', async () => {
|
||||
const commitMessage =
|
||||
'Updates `twilio-video` from 2.7.0 to 2.28.1\n' +
|
||||
'- [Release notes](https://github.com/twilio/twilio-video.js/releases)\n' +
|
||||
'- [Changelog](https://github.com/twilio/twilio-video.js/blob/master/CHANGELOG.md)\n' +
|
||||
'- [Commits](twilio/twilio-video.js@2.7.0...2.28.1)\n' +
|
||||
'\n' +
|
||||
'Updates `@types/twilio-video` from 2.7.0 to 2.11.0\n' +
|
||||
'- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)\n' +
|
||||
'- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/twilio-video)\n' +
|
||||
'\n' +
|
||||
'---\n' +
|
||||
'updated-dependencies:\n' +
|
||||
'- dependency-name: twilio-video\n' +
|
||||
' dependency-type: direct:production\n' +
|
||||
' update-type: version-update:semver-minor\n' +
|
||||
'- dependency-name: "@types/twilio-video"\n' +
|
||||
' dependency-type: direct:development\n' +
|
||||
' update-type: version-update:semver-minor\n' +
|
||||
'...\n' +
|
||||
'\n' +
|
||||
'Signed-off-by: dependabot[bot] <support@github.com>'
|
||||
|
||||
const getAlert = async () => Promise.resolve({ alertState: '', ghsaId: '', cvss: 0 })
|
||||
const getScore = async () => Promise.resolve(0)
|
||||
|
||||
const updatedDependencies = await updateMetadata.parse(
|
||||
commitMessage,
|
||||
'',
|
||||
'dependabot-npm_and_yarn-twilio-video-and-types-twilio-video-2.28.1',
|
||||
'master',
|
||||
getAlert,
|
||||
getScore
|
||||
)
|
||||
|
||||
expect(updatedDependencies[0].directory).toEqual('/')
|
||||
})
|
||||
|
||||
test('calculateUpdateType should handle all paths', () => {
|
||||
expect(updateMetadata.calculateUpdateType('', '')).toEqual('')
|
||||
expect(updateMetadata.calculateUpdateType('', '1')).toEqual('')
|
||||
|
||||
@@ -28,6 +28,32 @@ export interface scoreLookup {
|
||||
(dependencyName: string, previousVersion: string, newVersion: string, ecosystem: string): Promise<number>;
|
||||
}
|
||||
|
||||
function branchNameToDirectoryName (chunks: string[], delimiter: string, updatedDependencies: any): string {
|
||||
// We can always slice after the first 2 pieces, because they will always contain "dependabot" followed by the name
|
||||
// of the package ecosystem. e.g. "dependabot/npm_and_yarn".
|
||||
const sliceStart = 2
|
||||
let sliceEnd = chunks.length
|
||||
|
||||
// If the delimiter is "-", we assume the last piece of the branch name is a version number.
|
||||
if (delimiter === '-') {
|
||||
sliceEnd -= 1
|
||||
}
|
||||
|
||||
// If there is more than 1 dependency name being updated, we assume 1 piece of the branch name will be "and".
|
||||
if (updatedDependencies.length > 1) {
|
||||
sliceEnd -= 1
|
||||
}
|
||||
|
||||
updatedDependencies.forEach(dependency => {
|
||||
// After replacing "/" in the dependency name with the delimiter, which could also be "/", we count how many pieces
|
||||
// the dependency name would split into by the delimiter, and slicing that amount off the end of the branch name.
|
||||
// e.g. "@types/twilio-video" and a delimiter of "-" would show up in the branch name as "types-twilio-video".
|
||||
sliceEnd -= dependency['dependency-name'].replace('/', delimiter).split(delimiter).length
|
||||
})
|
||||
|
||||
return `/${chunks.slice(sliceStart, sliceEnd).join('/')}`
|
||||
}
|
||||
|
||||
export async function parse (commitMessage: string, body: string, branchName: string, mainBranch: string, lookup?: alertLookup, getScore?: scoreLookup): Promise<Array<updatedDependency>> {
|
||||
const bumpFragment = commitMessage.match(/^Bumps .* from (?<from>v?\d[^ ]*) to (?<to>v?\d[^ ]*)\.$/m)
|
||||
const updateFragment = commitMessage.match(/^Update .* requirement from \S*? ?(?<from>v?\d\S*) to \S*? ?(?<to>v?\d\S*)$/m)
|
||||
@@ -48,8 +74,9 @@ export async function parse (commitMessage: string, body: string, branchName: st
|
||||
const dependencyGroup = groupName?.groups?.name ?? ''
|
||||
|
||||
if (data['updated-dependencies']) {
|
||||
const dirname = branchNameToDirectoryName(chunks, delim, data['updated-dependencies'])
|
||||
|
||||
return await Promise.all(data['updated-dependencies'].map(async (dependency, index) => {
|
||||
const dirname = `/${chunks.slice(2, -1 * (1 + (dependency['dependency-name'].match(/\//g) || []).length)).join(delim) || ''}`
|
||||
const lastVersion = index === 0 ? prev : ''
|
||||
const nextVersion = index === 0 ? next : ''
|
||||
const updateType = dependency['update-type'] || calculateUpdateType(lastVersion, nextVersion)
|
||||
@@ -64,7 +91,7 @@ export async function parse (commitMessage: string, body: string, branchName: st
|
||||
newVersion: nextVersion,
|
||||
compatScore: await scoreFn(dependency['dependency-name'], lastVersion, nextVersion, chunks[1]),
|
||||
maintainerChanges: newMaintainer,
|
||||
dependencyGroup: dependencyGroup,
|
||||
dependencyGroup,
|
||||
...await lookupFn(dependency['dependency-name'], lastVersion, dirname)
|
||||
}
|
||||
}))
|
||||
|
||||
@@ -93,4 +93,5 @@ require('yargs')(hideBin(process.argv))
|
||||
})
|
||||
.demandCommand(1)
|
||||
.help()
|
||||
.strict()
|
||||
.argv
|
||||
|
||||
@@ -415,7 +415,7 @@ test('if there are multiple dependencies, it summarizes them', async () => {
|
||||
const mockAlert = { alertState: '', ghsaId: '', cvss: 0 }
|
||||
|
||||
jest.spyOn(core, 'getInput').mockReturnValue('mock-token')
|
||||
jest.spyOn(util, 'getBranchNames').mockReturnValue({ headName: 'dependabot/npm_and_yarn/api/main/feature1', baseName: 'trunk' })
|
||||
jest.spyOn(util, 'getBranchNames').mockReturnValue({ headName: 'dependabot/npm_and_yarn/api/main/coffee-rails/and/coffeescript', baseName: 'trunk' })
|
||||
jest.spyOn(dependabotCommits, 'getMessage').mockImplementation(jest.fn(
|
||||
() => Promise.resolve(mockCommitMessage)
|
||||
))
|
||||
|
||||
Reference in New Issue
Block a user