Skip to content

Commit a9db92f

Browse files
martinemdehsbt
authored andcommitted
[rubygems/rubygems] Add gem sources --prepend and --append for finer source control
--append adds a source to the end, moving it to the end if it already exists. --prepend adds or moves a source to the beginning. This allows idempotent sorting of gem sources without removing and adding. rubygems/rubygems@d9a0567c65
1 parent 41ffd1b commit a9db92f

File tree

4 files changed

+582
-10
lines changed

4 files changed

+582
-10
lines changed

lib/rubygems/commands/sources_command.rb

Lines changed: 79 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,14 @@ def initialize
1818
options[:add] = value
1919
end
2020

21+
add_option "--append SOURCE_URI", "Append source (can be used multiple times)" do |value, options|
22+
options[:append] = value
23+
end
24+
25+
add_option "-p", "--prepend SOURCE_URI", "Prepend source (can be used multiple times)" do |value, options|
26+
options[:prepend] = value
27+
end
28+
2129
add_option "-l", "--list", "List sources" do |value, options|
2230
options[:list] = value
2331
end
@@ -26,8 +34,7 @@ def initialize
2634
options[:remove] = value
2735
end
2836

29-
add_option "-c", "--clear-all",
30-
"Remove all sources (clear the cache)" do |value, options|
37+
add_option "-c", "--clear-all", "Remove all sources (clear the cache)" do |value, options|
3138
options[:clear_all] = value
3239
end
3340

@@ -68,6 +75,60 @@ def add_source(source_uri) # :nodoc:
6875
end
6976
end
7077

78+
def append_source(source_uri) # :nodoc:
79+
check_rubygems_https source_uri
80+
81+
source = Gem::Source.new source_uri
82+
83+
check_typo_squatting(source)
84+
85+
begin
86+
source.load_specs :released
87+
was_present = Gem.sources.include?(source)
88+
Gem.sources.append source
89+
Gem.configuration.write
90+
91+
if was_present
92+
say "#{source_uri} moved to end of sources"
93+
else
94+
say "#{source_uri} added to sources"
95+
end
96+
rescue Gem::URI::Error, ArgumentError
97+
say "#{source_uri} is not a URI"
98+
terminate_interaction 1
99+
rescue Gem::RemoteFetcher::FetchError => e
100+
say "Error fetching #{Gem::Uri.redact(source.uri)}:\n\t#{e.message}"
101+
terminate_interaction 1
102+
end
103+
end
104+
105+
def prepend_source(source_uri) # :nodoc:
106+
check_rubygems_https source_uri
107+
108+
source = Gem::Source.new source_uri
109+
110+
check_typo_squatting(source)
111+
112+
begin
113+
source.load_specs :released
114+
was_present = Gem.sources.include?(source)
115+
Gem.sources.prepend source
116+
Gem.configuration.write
117+
118+
if was_present
119+
say "#{source_uri} moved to top of sources"
120+
else
121+
say "#{source_uri} added to sources"
122+
end
123+
rescue Gem::URI::Error, ArgumentError
124+
say "#{source_uri} is not a URI"
125+
terminate_interaction 1
126+
rescue Gem::RemoteFetcher::FetchError => e
127+
say "Error fetching #{Gem::Uri.redact(source.uri)}:\n\t#{e.message}"
128+
terminate_interaction 1
129+
end
130+
end
131+
71132
def check_typo_squatting(source)
72133
if source.typo_squatting?("rubygems.org")
73134
question = <<-QUESTION.chomp
@@ -147,14 +208,20 @@ def description # :nodoc:
147208
of them in your list. https://rubygems.org is recommended as it brings the
148209
protections of an SSL connection to gem downloads.
149210
150-
To add a source use the --add argument:
211+
To add a private gem source use the --prepend argument to insert it before
212+
the default source. This is usually the best place for private gem sources:
151213
152-
$ gem sources --add https://my.private.source
214+
$ gem sources --prepend https://my.private.source
153215
https://my.private.source added to sources
154216
155217
RubyGems will check to see if gems can be installed from the source given
156218
before it is added.
157219
220+
To add or move a source after all other sources, use --append:
221+
222+
$ gem sources --append https://rubygems.org
223+
https://rubygems.org moved to end of sources
224+
158225
To remove a source use the --remove argument:
159226
160227
$ gem sources --remove https://my.private.source/
@@ -182,6 +249,8 @@ def list # :nodoc:
182249

183250
def list? # :nodoc:
184251
!(options[:add] ||
252+
options[:prepend] ||
253+
options[:append] ||
185254
options[:clear_all] ||
186255
options[:remove] ||
187256
options[:update])
@@ -190,11 +259,13 @@ def list? # :nodoc:
190259
def execute
191260
clear_all if options[:clear_all]
192261

193-
source_uri = options[:add]
194-
add_source source_uri if source_uri
262+
add_source options[:add] if options[:add]
263+
264+
prepend_source options[:prepend] if options[:prepend]
265+
266+
append_source options[:append] if options[:append]
195267

196-
source_uri = options[:remove]
197-
remove_source source_uri if source_uri
268+
remove_source options[:remove] if options[:remove]
198269

199270
update if options[:update]
200271

lib/rubygems/source_list.rb

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,42 @@ def <<(obj)
5959
src
6060
end
6161

62+
##
63+
# Prepends +obj+ to the beginning of the source list which may be a Gem::Source, Gem::URI or URI
64+
# Moves +obj+ to the beginning of the list if already present.
65+
# String.
66+
67+
def prepend(obj)
68+
src = case obj
69+
when Gem::Source
70+
obj
71+
else
72+
Gem::Source.new(obj)
73+
end
74+
75+
@sources.delete(src) if @sources.include?(src)
76+
@sources.unshift(src)
77+
src
78+
end
79+
80+
##
81+
# Appends +obj+ to the end of the source list, moving it if already present.
82+
# +obj+ may be a Gem::Source, Gem::URI or URI String.
83+
# Moves +obj+ to the end of the list if already present.
84+
85+
def append(obj)
86+
src = case obj
87+
when Gem::Source
88+
obj
89+
else
90+
Gem::Source.new(obj)
91+
end
92+
93+
@sources.delete(src) if @sources.include?(src)
94+
@sources << src
95+
src
96+
end
97+
6298
##
6399
# Replaces this SourceList with the sources in +other+ See #<< for
64100
# acceptable items in +other+.

0 commit comments

Comments
 (0)