diff --git a/changelog/209-fix.md b/changelog/209-fix.md new file mode 100644 index 00000000..d538ee71 --- /dev/null +++ b/changelog/209-fix.md @@ -0,0 +1,12 @@ +--- +type: fix +issue: 209 +audience: user +components: + - server +--- + +# Fix provided by 'git-version' + +Snage will now find the first matching tag instead of aborting the search if the +first tag doesn't match the version regex. diff --git a/eslint.yaml b/eslint.yaml index c61543be..f09cbbc1 100644 --- a/eslint.yaml +++ b/eslint.yaml @@ -29,6 +29,7 @@ rules: default-param-last: error no-loop-func: off arrow-body-style: [error, as-needed] + no-constant-condition: off unicorn/no-abusive-eslint-disable: error unicorn/no-array-instanceof: error diff --git a/packages/snage/src/provider/git-version.ts b/packages/snage/src/provider/git-version.ts index 7eab0b5c..c0e278ee 100644 --- a/packages/snage/src/provider/git-version.ts +++ b/packages/snage/src/provider/git-version.ts @@ -25,7 +25,6 @@ const getVersion = ( ): TE.TaskEither => pipe( getFirstTagContainingFile(file, versionRegex), - TE.map(O.map((tag) => extractVersion(tag, versionRegex))), TE.mapLeft((error): string => `provider error on field '${field.name}': ${error}`), TE.chainEitherK( O.fold( @@ -58,14 +57,31 @@ const fetchCommit = (directory: string, filename: string): TE.TaskEither typeof commit !== 'undefined' && commit !== '')) ); -const getTag = (directory: string, commit: string, versionRegex: string): TE.TaskEither> => - pipe( - tryExec(`git name-rev --tags --name-only "${commit}"`, {cwd: directory}), - TE.map((tag) => tag.trim()), - TE.map(O.fromPredicate((tag) => typeof tag !== 'undefined' && tag !== '' && tag !== 'undefined')), - TE.map(O.map((rawTag) => rawTag.replace(/[~^].*/, ''))), - TE.map(O.filter((tag) => RegExp(versionRegex).test(tag))) - ); +const getTag = + (directory: string, commit: string, versionRegex: string): TE.TaskEither> => + async (): Promise>> => { + const excludes: string[] = []; + while (true) { + const result = await pipe( + tryExec(`git name-rev --tags ${excludes.join(' ')} --name-only "${commit}"`, {cwd: directory}), + TE.map((tag) => tag.trim()) + )(); -const extractVersion = (tag: string, versionRegex: string): string => - tag.replace(RegExp(versionRegex), (match, version) => version); + if (E.isLeft(result)) { + return result; + } + const rawTag = result.right; + // name-rev returns the string undefined when there are no tags left + if (typeof rawTag === 'undefined' || rawTag === '' || rawTag === 'undefined') { + return E.right(O.none); + } + const tag = rawTag.replace(/[~^].*/, ''); + if (tag) { + const match = RegExp(versionRegex).exec(tag); + if (match) { + return E.right(O.some(match[1])); + } + excludes.push(`--exclude ${tag}`); + } + } + };