Add bin and edit workflow
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 9s

This commit is contained in:
2026-09-16 13:11:16 -06:00
parent c8ac4fcae5
commit 4cee170d66
17576 changed files with 895740 additions and 2 deletions
@@ -0,0 +1,127 @@
# frozen_string_literal: true
require_relative "package"
module Bundler
class Resolver
class Base
attr_reader :packages, :requirements, :source_requirements, :locked_specs
def initialize(source_requirements, dependencies, base, platforms, options)
@explicit_unlocks = options.delete(:explicit_unlocks) || []
@source_requirements = source_requirements
@locked_specs = options[:locked_specs]
@base = base
@packages = Hash.new do |hash, name|
hash[name] = Package.new(name, platforms, **options)
end
@requirements = dependencies.filter_map do |dep|
dep_platforms = dep.gem_platforms(platforms)
# Dependencies scoped to external platforms are ignored
next if dep_platforms.empty?
name = dep.name
@packages[name] = Package.new(name, dep_platforms, **options.merge(dependency: dep))
dep
end
end
def [](name)
@base[name]
end
def delete(specs)
@base.delete(specs)
end
def get_package(name)
@packages[name]
end
# Gems the user named on a `bundle update GEM` / `bundle lock --update GEM`
# command line. These are the only ones meant to move off their locked
# version, so cooldown keeps applying to them while every other locked gem
# stays exempt.
def explicitly_unlocked?(name)
@explicit_unlocks.include?(name)
end
def base_requirements
@base_requirements ||= build_base_requirements
end
def unlock_names(names)
indirect_pins = indirect_pins(names)
if indirect_pins.any?
loosen_names(indirect_pins)
else
pins = pins(names)
if pins.any?
loosen_names(pins)
else
unrestrict_names(names)
end
end
end
def include_prereleases(names)
names.each do |name|
get_package(name).consider_prereleases!
end
end
def include_remote_specs(names)
names.each do |name|
get_package(name).consider_remote_versions!
end
end
private
def indirect_pins(names)
names.select {|name| @base_requirements[name].exact? && @requirements.none? {|dep| dep.name == name } }
end
def pins(names)
names.select {|name| @base_requirements[name].exact? }
end
def loosen_names(names)
names.each do |name|
version = @base_requirements[name].requirements.first[1]
@base_requirements[name] = Gem::Requirement.new(">= #{version}")
@base.delete_by_name(name)
end
end
def unrestrict_names(names)
names.each do |name|
@base_requirements.delete(name)
end
end
def build_base_requirements
base_requirements = {}
@base.each do |ls|
if ls.source_changed? && ls.source.specs.search(ls.name).empty?
raise GemNotFound, "Could not find gem '#{ls.name}' in #{ls.source}"
end
req = Gem::Requirement.new(ls.version)
base_requirements[ls.name] = req
end
base_requirements
end
end
end
end
@@ -0,0 +1,85 @@
# frozen_string_literal: true
require_relative "spec_group"
module Bundler
class Resolver
#
# This class is a PubGrub compatible "Version" class that takes Bundler
# resolution complexities into account.
#
# Each Resolver::Candidate has a underlying `Gem::Version` plus a set of
# platforms. For example, 1.1.0-x86_64-linux is a different resolution candidate
# from 1.1.0 (generic). This is because different platform variants of the
# same gem version can bring different dependencies, so they need to be
# considered separately.
#
# Some candidates may also keep some information explicitly about the
# package they refer to. These candidates are referred to as "canonical" and
# are used when materializing resolution results back into RubyGems
# specifications that can be installed, written to lockfiles, and so on.
#
class Candidate
include Comparable
attr_reader :version
def initialize(version, group: nil, priority: -1)
@spec_group = group || SpecGroup.new([])
@version = Gem::Version.new(version)
@priority = priority
end
def dependencies
@spec_group.dependencies
end
def to_specs(package, most_specific_locked_platform)
return [] if package.meta?
@spec_group.to_specs(package.force_ruby_platform?, most_specific_locked_platform)
end
def prerelease?
@version.prerelease?
end
def segments
@version.segments
end
def <=>(other)
return unless other.is_a?(self.class)
version_comparison = version <=> other.version
return version_comparison unless version_comparison.zero?
priority <=> other.priority
end
def ==(other)
return unless other.is_a?(self.class)
version == other.version && priority == other.priority
end
def eql?(other)
return unless other.is_a?(self.class)
version.eql?(other.version) && priority.eql?(other.priority)
end
def hash
[@version, @priority].hash
end
def to_s
@version.to_s
end
protected
attr_reader :priority
end
end
end
@@ -0,0 +1,15 @@
# frozen_string_literal: true
module Bundler
class Resolver
class Incompatibility < PubGrub::Incompatibility
attr_reader :extended_explanation
def initialize(terms, cause:, custom_explanation: nil, extended_explanation: nil)
@extended_explanation = extended_explanation
super(terms, cause: cause, custom_explanation: custom_explanation)
end
end
end
end
@@ -0,0 +1,95 @@
# frozen_string_literal: true
module Bundler
class Resolver
#
# Represents a gem being resolved, in a format PubGrub likes.
#
# The class holds the following information:
#
# * Platforms this gem will be resolved on.
# * The locked version of this gem resolution should favor (if any).
# * Whether the gem should be unlocked to its latest version.
# * The dependency explicit set in the Gemfile for this gem (if any).
#
class Package
attr_reader :name, :platforms, :dependency, :locked_version
def initialize(name, platforms, locked_specs:, unlock:, prerelease: false, prefer_local: false, dependency: nil, new_platforms: [])
@name = name
@platforms = platforms
@locked_version = locked_specs.version_for(name)
@unlock = unlock
@dependency = dependency || Dependency.new(name, @locked_version)
@platforms |= [Gem::Platform::RUBY] if @dependency.default_force_ruby_platform
@top_level = !dependency.nil?
@prerelease = @dependency.prerelease? || @locked_version&.prerelease? || prerelease ? :consider_first : :ignore
@prefer_local = prefer_local
@new_platforms = new_platforms
end
def platform_specs(specs)
platforms.map do |platform|
prefer_locked = @new_platforms.include?(platform) ? false : !unlock?
MatchPlatform.select_best_platform_match(specs, platform, prefer_locked: prefer_locked)
end
end
def to_s
@name.delete("\0")
end
def root?
false
end
def top_level?
@top_level
end
def meta?
@name.end_with?("\0")
end
def ==(other)
self.class == other.class && @name == other.name
end
def hash
@name.hash
end
def unlock?
@unlock == true || @unlock.include?(name)
end
def ignores_prereleases?
@prerelease == :ignore
end
def prerelease_specified?
@prerelease == :consider_first
end
def consider_prereleases!
@prerelease = :consider_last
end
def prefer_local?
@prefer_local
end
def consider_remote_versions!
@prefer_local = false
end
def force_ruby_platform?
@dependency.force_ruby_platform
end
def current_platform?
@dependency.current_platform?
end
end
end
end
@@ -0,0 +1,25 @@
# frozen_string_literal: true
require_relative "package"
module Bundler
class Resolver
#
# Represents the Gemfile from the resolver's perspective. It's the root
# package and Gemfile entries depend on it.
#
class Root < Package
def initialize(name)
@name = name
end
def meta?
true
end
def root?
true
end
end
end
end
@@ -0,0 +1,74 @@
# frozen_string_literal: true
module Bundler
class Resolver
class SpecGroup
attr_reader :specs
def initialize(specs)
@specs = specs
end
def empty?
@specs.empty?
end
def name
@name ||= exemplary_spec.name
end
def version
@version ||= exemplary_spec.version
end
def source
@source ||= exemplary_spec.source
end
def to_specs(force_ruby_platform, most_specific_locked_platform)
@specs.map do |s|
lazy_spec = LazySpecification.from_spec(s)
lazy_spec.force_ruby_platform = force_ruby_platform
lazy_spec.most_specific_locked_platform = most_specific_locked_platform
lazy_spec
end
end
def to_s
sorted_spec_names.join(", ")
end
def dependencies
@dependencies ||= @specs.flat_map(&:expanded_dependencies).uniq.sort
end
def ==(other)
sorted_spec_names == other.sorted_spec_names
end
def merge(other)
return false unless equivalent?(other)
@specs |= other.specs
true
end
protected
def sorted_spec_names
@specs.map(&:full_name).sort
end
private
def equivalent?(other)
name == other.name && version == other.version && source == other.source && dependencies == other.dependencies
end
def exemplary_spec
@specs.first
end
end
end
end
@@ -0,0 +1,43 @@
# frozen_string_literal: true
module Bundler
class Resolver
class Strategy
def initialize(source)
@source = source
@package_priority_cache = {}
end
def next_package_and_version(unsatisfied)
package, range = next_term_to_try_from(unsatisfied)
[package, most_preferred_version_of(package, range).first]
end
private
def next_term_to_try_from(unsatisfied)
unsatisfied.min_by do |package, range|
@package_priority_cache[[package, range]] ||= begin
matching_versions = @source.versions_for(package, range)
higher_versions = @source.versions_for(package, range.upper_invert)
[matching_versions.count <= 1 ? 0 : 1, higher_versions.count]
end
end
end
def most_preferred_version_of(package, range)
versions = @source.versions_for(package, range)
# Conditional avoids (among other things) calling
# sort_versions_by_preferred with the root package
if versions.size > 1
@source.sort_versions_by_preferred(package, versions)
else
versions
end
end
end
end
end