regex 如何使用Ruby从Github存储库URL获取版本标记并返回最新的版本标记

bmp9r5qi  于 2023-01-21  发布在  Ruby
关注(0)|答案(1)|浏览(122)

我是第一次使用Ruby,我正在写一个脚本,通过检查Github存储库中的标签,该脚本应该返回可用的最新版本。该脚本应该只考虑格式为0.0.00.0v0.0.0的标签,排除所有其他标签,删除v(如果存在)。并只返回最近的标签。到目前为止,这是我工作的代码,在我的正则表达式中或者在我对版本排序的方式中(或者可能两者都有)有一些错误。我应该改变什么来达到预期的结果?

def find_latest_version(package_url)

    latest_version = ""
    version = `git ls-remote --tags --refs #{package_url} "*\.*\.*"`
    regex = /[vV]?[0-9][0-9.]*$|\/[0-9][0-9.]*$/
    split = version.split("\n")
    split.map {|s|
        a = s.split("/").last
        b = a.scan(regex).map {|a| a.gsub(/[vV]/, '')}
        latest_version = b.max_by{ |s| Gem::Version.new(s) }

    }
    latest_version
end
2wnc66cl

2wnc66cl1#

split是一个包含多个值的数组。然后调用split.map,它将遍历数组并对每个元素执行操作。
其中一个操作是latest_version = ...,这意味着对于数组中的每一个元素,你都在 * 重置 * latest_version的值,无论数组中的最后一个元素是什么,它最终都会定义latest_version的最终值,而这不是你想要的。
你也许可以使用类似这样的方法来实现你的目标:

# Set a regex that looks for:
# 1. v or V, optionally
# 2. one or more digits (e.g., 1 or 55)
# 3. a literal period and then one or more digits (e.g., 2 or 66)
# 4. a literal period and then one or more digits (e.g., 3 or 77), optionally
# This will match v1.2.3 or v1.2 or 1.2.3 or 1.2 or v10.1.2 or v10.1 or v10.1.20, etc.
# This will not match v1.2.3-alpha, for example
regex = /^[vV]?[0-9]+\.[0-9]+(\.[0-9]+)?$/

# Use the Rails repo as the sample as they have a ton of tags and a lot of variety
package_url = "https://github.com/rails/rails"

# Use a semantic variable name
git_versions = `git ls-remote --tags --refs #{package_url} "*\.*\.*"`

# Split the string by newlines
versions = git_versions.split("\n")

# Split each element by refs/tags/ and select the last element so that we get something like "v7.0.4" only 
versions = versions.map { |s| s.split('refs/tags/').last }

# Grab only the versions that match the regex, excluding things like "v6.0.2.rc2"
versions = versions.select { |s| s =~ regex }

# Remove all the v and Vs from the start of the version strings
versions = versions.map { |s| s.sub(/^[vV]/, '') }

# Convert all the strings to Gem::Version values
versions = versions.map { |s| Gem::Version.new(s) }

# Get the largest version
latest_version = versions.max

这段代码可以缩小很多,限制为数组的三次迭代,但从可读性的Angular 来看,这段代码并不出色:

regex = /^[vV]?[0-9]+\.[0-9]+(\.[0-9]+)?$/
package_url = "https://github.com/rails/rails"
git_versions = `git ls-remote --tags --refs #{package_url} "*\.*\.*"`
latest_version = git_versions.split("\n").map { |v| Gem::Version.create(v.split('refs/tags/').last.match(regex)&.[](0)&.sub(/^[vV]/, '')) }.compact.max
=> Gem::Version.new("7.0.4")

相关问题