diff --git a/src/configuration.ts b/src/configuration.ts index 5f5c580..dbe653f 100644 --- a/src/configuration.ts +++ b/src/configuration.ts @@ -38,7 +38,8 @@ export interface Extractor extends Transformer { export interface TagResolver { method: string // semver, sort - filter?: Regex // the regex to filter the tags + filter?: Regex // the regex to filter the tags, prior to sorting + transformer?: Transformer // transforms the tag name using the regex, run after the filter } export const DefaultConfiguration: Configuration = { @@ -71,7 +72,8 @@ export const DefaultConfiguration: Configuration = { tag_resolver: { // defines the logic on how to resolve the previous tag, only relevant if `fromTag` is not specified method: 'semver', // defines which method to use, by default it will use `semver` (dropping all non matching tags). Alternative `sort` is also available. - filter: undefined // filter out all tags not matching the regex + filter: undefined, // filter out all tags not matching the regex + transformer: undefined // transforms the tag name using the regex, run after the filter }, base_branches: [] // target branches for the merged PR ignoring PRs with different target branch, by default it will get all PRs } diff --git a/src/tags.ts b/src/tags.ts index 7d47b96..5bdf7e7 100755 --- a/src/tags.ts +++ b/src/tags.ts @@ -5,6 +5,7 @@ import {Octokit, RestEndpointMethodTypes} from '@octokit/rest' import {SemVer} from 'semver' import {TagResolver} from './configuration' import {createCommandManager} from './gitHelper' +import {RegexTransformer, validateTransformer} from './transform' export interface TagResult { from: TagInfo | null @@ -16,6 +17,10 @@ export interface TagInfo { commit: string } +export interface SortableTagInfo extends TagInfo { + tmp: string +} + export class Tags { constructor(private octokit: Octokit) {} @@ -114,8 +119,35 @@ export class Tags { maxTagsToFetch: number, tagResolver: TagResolver ): Promise { - const filteredTags = filterTags(await this.getTags(owner, repo, maxTagsToFetch), tagResolver) - const tags = sortTags(filteredTags, tagResolver) + // filter out tags not matching the specified filter + const filteredTags = filterTags( + // retrieve the tags from the API + await this.getTags(owner, repo, maxTagsToFetch), + tagResolver + ) + + // check if a transformer was defined + const tagTransformer = validateTransformer(tagResolver.transformer) + + let transformedTags: TagInfo[] + if (tagTransformer != null) { + transformedTags = transformTags(filteredTags, tagTransformer) + } else { + transformedTags = filteredTags + } + + let tags = sortTags(transformedTags, tagResolver) + + if (tagTransformer != null) { + // restore the original name, after sorting + tags = filteredTags.map(function (tag) { + if (tag.hasOwnProperty('tmp')) { + return {name: (tag as SortableTagInfo).tmp, commit: tag.commit} + } else { + return tag + } + }) + } let resultToTag: TagInfo | null let resultFromTag: TagInfo | null @@ -209,6 +241,26 @@ export function filterTags( } } +/** + * Helper function to transform the tag name given the transformer + */ +function transformTags( + tags: TagInfo[], + transformer: RegexTransformer +): TagInfo[] { + return tags.map(function (tag) { + if (transformer.pattern) { + return { + tmp: tag.name, // remember the original name + name: tag.name.replace(transformer.pattern, transformer.target), + commit: tag.commit + } + } else { + return tag + } + }) +} + /* Sorts an array of tags as shown below: diff --git a/src/transform.ts b/src/transform.ts index ad8b485..b0408db 100644 --- a/src/transform.ts +++ b/src/transform.ts @@ -293,7 +293,7 @@ function validateTransformers( }) } -function validateTransformer( +export function validateTransformer( transformer?: Transformer ): RegexTransformer | null { if (transformer === undefined) { @@ -359,7 +359,7 @@ function extractValues( return null } -interface RegexTransformer { +export interface RegexTransformer { pattern: RegExp | null target: string onProperty?: 'title' | 'author' | 'milestone' | 'body' | undefined