diff options
Diffstat (limited to 'app/finders/repositories/previous_tag_finder.rb')
-rw-r--r-- | app/finders/repositories/previous_tag_finder.rb | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/app/finders/repositories/previous_tag_finder.rb b/app/finders/repositories/previous_tag_finder.rb new file mode 100644 index 00000000000..150a6332c29 --- /dev/null +++ b/app/finders/repositories/previous_tag_finder.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +module Repositories + # A finder class for getting the tag of the last release before a given + # version. + # + # Imagine a project with the following tags: + # + # * v1.0.0 + # * v1.1.0 + # * v2.0.0 + # + # If the version supplied is 2.1.0, the tag returned will be v2.0.0. And when + # the version is 1.1.1, or 1.2.0, the returned tag will be v1.1.0. + # + # This finder expects that all tags to consider meet the following + # requirements: + # + # * They start with the letter "v" + # * They use semantic versioning for the tag format + # + # Tags not meeting these requirements are ignored. + class PreviousTagFinder + TAG_REGEX = /\Av(?<version>#{Gitlab::Regex.unbounded_semver_regex})\z/.freeze + + def initialize(project) + @project = project + end + + def execute(new_version) + tags = {} + versions = [new_version] + + @project.repository.tags.each do |tag| + matches = tag.name.match(TAG_REGEX) + + next unless matches + + version = matches[:version] + tags[version] = tag + versions << version + end + + VersionSorter.sort!(versions) + + index = versions.index(new_version) + + tags[versions[index - 1]] if index&.positive? + end + end +end |