1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273
|
# frozen_string_literal: true
module Bundler
class SourceList
attr_reader :path_sources,
:git_sources,
:plugin_sources,
:global_path_source,
:metadata_source
def global_rubygems_source
@global_rubygems_source ||= rubygems_aggregate_class.new("allow_local" => true)
end
def initialize
@path_sources = []
@git_sources = []
@plugin_sources = []
@global_rubygems_source = nil
@global_path_source = nil
@rubygems_sources = []
@metadata_source = Source::Metadata.new
@merged_gem_lockfile_sections = false
@local_mode = true
end
def merged_gem_lockfile_sections?
@merged_gem_lockfile_sections
end
def merged_gem_lockfile_sections!(replacement_source)
@merged_gem_lockfile_sections = true
@global_rubygems_source = replacement_source
end
def aggregate_global_source?
global_rubygems_source.multiple_remotes?
end
def implicit_global_source?
global_rubygems_source.no_remotes?
end
def add_path_source(options = {})
if options["gemspec"]
add_source_to_list Source::Gemspec.new(options), path_sources
else
path_source = add_source_to_list Source::Path.new(options), path_sources
@global_path_source ||= path_source if options["global"]
path_source
end
end
def add_git_source(options = {})
add_source_to_list(Source::Git.new(options), git_sources).tap do |source|
warn_on_git_protocol(source)
end
end
def add_rubygems_source(options = {})
new_source = Source::Rubygems.new(options)
return @global_rubygems_source if @global_rubygems_source == new_source
add_source_to_list new_source, @rubygems_sources
end
def add_plugin_source(source, options = {})
add_source_to_list Plugin.source(source).new(options), @plugin_sources
end
def add_global_rubygems_remote(uri)
global_rubygems_source.add_remote(uri)
global_rubygems_source
end
def local_mode?
@local_mode
end
def default_source
global_path_source || global_rubygems_source
end
def rubygems_sources
non_global_rubygems_sources + [global_rubygems_source]
end
def non_global_rubygems_sources
@rubygems_sources
end
def rubygems_remotes
rubygems_sources.flat_map(&:remotes).uniq
end
def all_sources
path_sources + git_sources + plugin_sources + rubygems_sources + [metadata_source]
end
def non_default_explicit_sources
all_sources - [default_source, metadata_source]
end
def get(source)
source_list_for(source).find {|s| equivalent_source?(source, s) }
end
def lock_sources
lock_other_sources + lock_rubygems_sources
end
def lock_other_sources
(path_sources + git_sources + plugin_sources).sort_by(&:identifier)
end
def lock_rubygems_sources
if merged_gem_lockfile_sections?
[combine_rubygems_sources]
else
rubygems_sources.sort_by(&:identifier)
end
end
# Returns true if there are changes
def replace_sources!(replacement_sources)
return false if replacement_sources.empty?
@rubygems_sources, @path_sources, @git_sources, @plugin_sources = map_sources(replacement_sources)
@global_rubygems_source = global_replacement_source(replacement_sources)
different_sources?(lock_sources, replacement_sources)
end
# Returns true if there are changes
def expired_sources?(replacement_sources)
return false if replacement_sources.empty?
lock_sources = dup_with_replaced_sources(replacement_sources).lock_sources
different_sources?(lock_sources, replacement_sources)
end
def prefer_local!
all_sources.each(&:prefer_local!)
end
def local_only!
all_sources.each(&:local_only!)
end
def local!
all_sources.each(&:local!)
end
def cached!
all_sources.each(&:cached!)
end
def remote!
@local_mode = false
all_sources.each(&:remote!)
end
private
def dup_with_replaced_sources(replacement_sources)
new_source_list = dup
new_source_list.replace_sources!(replacement_sources)
new_source_list
end
def map_sources(replacement_sources)
rubygems = @rubygems_sources.map do |source|
replace_rubygems_source(replacement_sources, source)
end
git, plugin = [@git_sources, @plugin_sources].map do |sources|
sources.map do |source|
replace_source(replacement_sources, source)
end
end
path = @path_sources.map do |source|
replace_path_source(replacement_sources, source)
end
[rubygems, path, git, plugin]
end
def global_replacement_source(replacement_sources)
replace_rubygems_source(replacement_sources, global_rubygems_source, &:local!)
end
def replace_rubygems_source(replacement_sources, gemfile_source)
replace_source(replacement_sources, gemfile_source) do |replacement_source|
# locked sources never include credentials so always prefer remotes from the gemfile
replacement_source.remotes = gemfile_source.remotes
yield replacement_source if block_given?
replacement_source
end
end
def replace_source(replacement_sources, gemfile_source)
replacement_source = replacement_sources.find {|s| s == gemfile_source }
return gemfile_source unless replacement_source
replacement_source = yield(replacement_source) if block_given?
replacement_source
end
def replace_path_source(replacement_sources, gemfile_source)
replace_source(replacement_sources, gemfile_source) do |replacement_source|
if gemfile_source.is_a?(Source::Gemspec)
gemfile_source.checksum_store = replacement_source.checksum_store
gemfile_source
else
replacement_source
end
end
end
def different_sources?(lock_sources, replacement_sources)
!equivalent_sources?(lock_sources, replacement_sources)
end
def rubygems_aggregate_class
Source::Rubygems
end
def add_source_to_list(source, list)
list.unshift(source).uniq!
source
end
def source_list_for(source)
case source
when Source::Git then git_sources
when Source::Path then path_sources
when Source::Rubygems then rubygems_sources
when Plugin::API::Source then plugin_sources
else raise ArgumentError, "Invalid source: #{source.inspect}"
end
end
def combine_rubygems_sources
Source::Rubygems.new("remotes" => rubygems_remotes)
end
def warn_on_git_protocol(source)
return if Bundler.settings["git.allow_insecure"]
if /^git\:/.match?(source.uri)
Bundler.ui.warn "The git source `#{source.uri}` uses the `git` protocol, " \
"which transmits data without encryption. Disable this warning with " \
"`bundle config set --local git.allow_insecure true`, or switch to the `https` " \
"protocol to keep your data secure."
end
end
def equivalent_sources?(lock_sources, replacement_sources)
lock_sources.sort_by(&:identifier) == replacement_sources.sort_by(&:identifier)
end
def equivalent_source?(source, other_source)
source == other_source
end
end
end
|