mirror of
https://gh.wpcy.net/https://github.com/discourse/discourse.git
synced 2026-05-04 00:20:20 +08:00
There are two issues addressed by this PR: We log an error to console when a git hash is passed to Discourse#has_needed_version?. This isn't correct. We should just return false. We only check that the commit hash is in the repo, we don't check that it's actually an ancestor in the current tree. So you'd see the feature even if you're on a branch that doesn't have it.
130 lines
3.8 KiB
Ruby
130 lines
3.8 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module Discourse
|
|
VERSION_REGEXP = /\A\d+\.\d+\.\d+(\.beta\d+)?\z/
|
|
VERSION_COMPATIBILITY_FILENAME = ".discourse-compatibility"
|
|
# work around reloader
|
|
unless defined?(::Discourse::VERSION)
|
|
module VERSION #:nodoc:
|
|
# Use the `version_bump:*` rake tasks to update this value
|
|
STRING = "3.6.0.beta1-dev"
|
|
|
|
PARTS = STRING.split(".")
|
|
private_constant :PARTS
|
|
|
|
MAJOR = PARTS[0].to_i
|
|
MINOR = PARTS[1].to_i
|
|
TINY = PARTS[2].to_i
|
|
PRE = PARTS[3]&.split("-", 2)&.[](0)
|
|
DEV = PARTS[3]&.split("-", 2)&.[](1)
|
|
end
|
|
end
|
|
|
|
class InvalidVersionListError < StandardError
|
|
end
|
|
|
|
def self.has_needed_version?(current, needed)
|
|
Gem::Version.new(current) >= Gem::Version.new(needed)
|
|
rescue ArgumentError
|
|
false
|
|
end
|
|
|
|
# lookup an external resource (theme/plugin)'s best compatible version
|
|
# compatible resource files are YAML, in the format:
|
|
# `discourse_version: plugin/theme git reference.` For example:
|
|
# 2.5.0.beta6: c4a6c17
|
|
# 2.5.0.beta4: d1d2d3f
|
|
# 2.5.0.beta2: bbffee
|
|
# 2.4.4.beta6: some-other-branch-ref
|
|
# 2.4.2.beta1: v1-tag
|
|
def self.find_compatible_resource(version_list, target_version = ::Discourse::VERSION::STRING)
|
|
return if version_list.blank?
|
|
|
|
begin
|
|
version_list = YAML.safe_load(version_list)
|
|
rescue Psych::SyntaxError, Psych::DisallowedClass => e
|
|
end
|
|
|
|
raise InvalidVersionListError unless version_list.is_a?(Hash)
|
|
|
|
version_list =
|
|
version_list
|
|
.transform_keys do |v|
|
|
Gem::Requirement.parse(v)
|
|
rescue Gem::Requirement::BadRequirementError => e
|
|
raise InvalidVersionListError, "Invalid version specifier: #{v}"
|
|
end
|
|
.sort_by do |parsed_requirement, _|
|
|
operator, version = parsed_requirement
|
|
[version, operator == "<" ? 0 : 1]
|
|
end
|
|
|
|
parsed_target_version = Gem::Version.new(target_version)
|
|
|
|
lowest_matching_entry =
|
|
version_list.find do |parsed_requirement, target|
|
|
req_operator, req_version = parsed_requirement
|
|
req_operator = "<=" if req_operator == "="
|
|
|
|
if !%w[<= <].include?(req_operator)
|
|
raise InvalidVersionListError,
|
|
"Invalid version specifier operator for '#{req_operator} #{req_version}'. Operator must be one of <= or <"
|
|
end
|
|
|
|
resolved_requirement = Gem::Requirement.new("#{req_operator} #{req_version}")
|
|
resolved_requirement.satisfied_by?(parsed_target_version)
|
|
end
|
|
|
|
return if lowest_matching_entry.nil?
|
|
|
|
checkout_version = lowest_matching_entry[1]
|
|
|
|
begin
|
|
Discourse::Utils.execute_command "git",
|
|
"check-ref-format",
|
|
"--allow-onelevel",
|
|
checkout_version
|
|
rescue RuntimeError
|
|
raise InvalidVersionListError, "Invalid ref name: #{checkout_version}"
|
|
end
|
|
|
|
checkout_version
|
|
end
|
|
|
|
# Find a compatible resource from a git repo
|
|
def self.find_compatible_git_resource(path)
|
|
return unless File.directory?("#{path}/.git")
|
|
|
|
tree_info =
|
|
Discourse::Utils.execute_command(
|
|
"git",
|
|
"-C",
|
|
path,
|
|
"ls-tree",
|
|
"-l",
|
|
"HEAD",
|
|
Discourse::VERSION_COMPATIBILITY_FILENAME,
|
|
)
|
|
blob_size = tree_info.split[3].to_i
|
|
|
|
if blob_size > Discourse::MAX_METADATA_FILE_SIZE
|
|
$stderr.puts "#{Discourse::VERSION_COMPATIBILITY_FILENAME} file in #{path} too big"
|
|
return
|
|
end
|
|
|
|
compat_resource =
|
|
Discourse::Utils.execute_command(
|
|
"git",
|
|
"-C",
|
|
path,
|
|
"show",
|
|
"HEAD@{upstream}:#{Discourse::VERSION_COMPATIBILITY_FILENAME}",
|
|
)
|
|
|
|
Discourse.find_compatible_resource(compat_resource)
|
|
rescue InvalidVersionListError => e
|
|
$stderr.puts "Invalid version list in #{path}"
|
|
rescue Discourse::Utils::CommandError => e
|
|
nil
|
|
end
|
|
end
|