rubygems-update 2.6.8 → 2.6.9

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of rubygems-update might be problematic. Click here for more details.

Files changed (96) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +9 -6
  3. data/CODE_OF_CONDUCT.md +36 -33
  4. data/History.txt +16 -0
  5. data/Manifest.txt +5 -3
  6. data/Rakefile +5 -0
  7. data/bundler/CHANGELOG.md +72 -0
  8. data/bundler/DEVELOPMENT.md +2 -2
  9. data/bundler/README.md +5 -0
  10. data/bundler/lib/bundler.rb +1 -1
  11. data/bundler/lib/bundler/cli.rb +42 -29
  12. data/bundler/lib/bundler/cli/common.rb +17 -0
  13. data/bundler/lib/bundler/cli/exec.rb +6 -0
  14. data/bundler/lib/bundler/cli/gem.rb +16 -3
  15. data/bundler/lib/bundler/cli/install.rb +7 -20
  16. data/bundler/lib/bundler/cli/lock.rb +1 -1
  17. data/bundler/lib/bundler/cli/open.rb +2 -1
  18. data/bundler/lib/bundler/cli/outdated.rb +91 -43
  19. data/bundler/lib/bundler/cli/update.rb +3 -10
  20. data/bundler/lib/bundler/compact_index_client.rb +7 -1
  21. data/bundler/lib/bundler/current_ruby.rb +1 -0
  22. data/bundler/lib/bundler/definition.rb +9 -5
  23. data/bundler/lib/bundler/dependency.rb +12 -0
  24. data/bundler/lib/bundler/env.rb +25 -20
  25. data/bundler/lib/bundler/errors.rb +21 -0
  26. data/bundler/lib/bundler/fetcher.rb +2 -2
  27. data/bundler/lib/bundler/fetcher/compact_index.rb +15 -3
  28. data/bundler/lib/bundler/friendly_errors.rb +23 -7
  29. data/bundler/lib/bundler/index.rb +9 -4
  30. data/bundler/lib/bundler/inline.rb +1 -1
  31. data/bundler/lib/bundler/installer.rb +1 -1
  32. data/bundler/lib/bundler/installer/gem_installer.rb +2 -2
  33. data/bundler/lib/bundler/installer/parallel_installer.rb +40 -9
  34. data/bundler/lib/bundler/lockfile_parser.rb +0 -1
  35. data/bundler/lib/bundler/match_platform.rb +12 -4
  36. data/bundler/lib/bundler/plugin/api.rb +2 -1
  37. data/bundler/lib/bundler/plugin/api/source.rb +1 -1
  38. data/bundler/lib/bundler/postit_trampoline.rb +3 -3
  39. data/bundler/lib/bundler/resolver.rb +6 -1
  40. data/bundler/lib/bundler/retry.rb +4 -1
  41. data/bundler/lib/bundler/rubygems_gem_installer.rb +18 -6
  42. data/bundler/lib/bundler/rubygems_integration.rb +16 -3
  43. data/bundler/lib/bundler/settings.rb +8 -3
  44. data/bundler/lib/bundler/shared_helpers.rb +15 -12
  45. data/bundler/lib/bundler/source.rb +4 -0
  46. data/bundler/lib/bundler/source/git/git_proxy.rb +2 -1
  47. data/bundler/lib/bundler/source/rubygems.rb +9 -0
  48. data/bundler/lib/bundler/spec_set.rb +4 -0
  49. data/bundler/lib/bundler/templates/newgem/gitignore.tt +5 -0
  50. data/bundler/lib/bundler/templates/newgem/spec/newgem_spec.rb.tt +1 -1
  51. data/bundler/lib/bundler/templates/newgem/spec/spec_helper.rb.tt +10 -1
  52. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +10 -1
  53. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/action.rb +1 -1
  54. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb +2 -2
  55. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex.rb +2 -2
  56. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/delete_edge.rb +62 -0
  57. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb +10 -3
  58. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/log.rb +12 -1
  59. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/set_payload.rb +2 -2
  60. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb +2 -2
  61. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb +2 -0
  62. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb +1 -1
  63. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb +27 -19
  64. data/bundler/lib/bundler/vendor/{net → net-http-persistent/lib/net}/http/faster.rb +1 -0
  65. data/bundler/lib/bundler/vendor/{net → net-http-persistent/lib/net}/http/persistent.rb +24 -23
  66. data/bundler/lib/bundler/vendor/{net → net-http-persistent/lib/net}/http/persistent/ssl_reuse.rb +2 -1
  67. data/bundler/lib/bundler/vendored_persistent.rb +9 -4
  68. data/bundler/lib/bundler/version.rb +1 -1
  69. data/bundler/lib/bundler/worker.rb +27 -5
  70. data/bundler/man/bundle-config.ronn +28 -1
  71. data/bundler/man/bundle-install.ronn +1 -1
  72. data/bundler/man/bundle-lock.ronn +47 -0
  73. data/bundler/man/bundle-outdated.ronn +107 -0
  74. data/bundler/man/bundle-update.ronn +152 -3
  75. data/bundler/man/bundle.ronn +22 -4
  76. data/bundler/man/gemfile.5.ronn +16 -0
  77. data/lib/rubygems.rb +1 -1
  78. data/lib/rubygems/ext/ext_conf_builder.rb +5 -3
  79. data/lib/rubygems/ext/rake_builder.rb +1 -1
  80. data/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph.rb +3 -1
  81. data/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb +9 -2
  82. data/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/vertex.rb +2 -0
  83. data/lib/rubygems/resolver/molinillo/lib/molinillo/gem_metadata.rb +1 -1
  84. data/lib/rubygems/resolver/molinillo/lib/molinillo/resolution.rb +17 -17
  85. data/lib/rubygems/server.rb +11 -4
  86. data/lib/rubygems/stub_specification.rb +6 -1
  87. data/lib/rubygems/version.rb +6 -2
  88. data/test/rubygems/test_gem.rb +2 -0
  89. data/test/rubygems/test_gem_ext_ext_conf_builder.rb +23 -0
  90. data/test/rubygems/test_gem_ext_rake_builder.rb +34 -17
  91. data/test/rubygems/test_gem_server.rb +16 -0
  92. data/test/rubygems/test_gem_specification.rb +1 -1
  93. data/test/rubygems/test_gem_stub_specification.rb +61 -0
  94. data/test/rubygems/test_gem_version.rb +6 -0
  95. data/util/ci +5 -5
  96. metadata +31 -29
@@ -43,7 +43,10 @@ module Bundler
43
43
 
44
44
  def fail_attempt(e)
45
45
  @failed = true
46
- raise e if last_attempt? || @exceptions.any? {|k| e.is_a?(k) }
46
+ if last_attempt? || @exceptions.any? {|k| e.is_a?(k) }
47
+ Bundler.ui.info "" unless Bundler.ui.debug?
48
+ raise e
49
+ end
47
50
  return true unless name
48
51
  Bundler.ui.info "" unless Bundler.ui.debug? # Add new line incase dots preceded this
49
52
  Bundler.ui.warn "Retrying #{name} due to error (#{current_run.next}/#{total_runs}): #{e.class} #{e.message}", Bundler.ui.debug?
@@ -31,12 +31,24 @@ module Bundler
31
31
  send(checksum_type(checksum), digest)
32
32
  end
33
33
  unless digest == checksum
34
- raise SecurityError,
35
- "The checksum for the downloaded `#{spec.full_name}.gem` did not match " \
36
- "the checksum given by the API. This means that the contents of the " \
37
- "gem appear to be different from what was uploaded, and could be an indicator of a security issue.\n" \
38
- "(The expected SHA256 checksum was #{checksum.inspect}, but the checksum for the downloaded gem was #{digest.inspect}.)\n" \
39
- "Bundler cannot continue installing #{spec.name} (#{spec.version})."
34
+ raise SecurityError, <<-MESSAGE
35
+ Bundler cannot continue installing #{spec.name} (#{spec.version}).
36
+ The checksum for the downloaded `#{spec.full_name}.gem` does not match \
37
+ the checksum given by the server. This means the contents of the downloaded \
38
+ gem is different from what was uploaded to the server, and could be a potential security issue.
39
+
40
+ To resolve this issue:
41
+ 1. delete the downloaded gem located at: `#{spec.gem_dir}/#{spec.full_name}.gem`
42
+ 2. run `bundle install`
43
+
44
+ If you wish to continue installing the downloaded gem, and are certain it does not pose a \
45
+ security issue despite the mismatching checksum, do the following:
46
+ 1. run `bundle config disable.checksum_validation true` to turn off checksum verification
47
+ 2. run `bundle install`
48
+
49
+ (More info: The expected SHA256 checksum was #{checksum.inspect}, but the \
50
+ checksum for the downloaded gem was #{digest.inspect}.)
51
+ MESSAGE
40
52
  end
41
53
  true
42
54
  end
@@ -71,8 +71,13 @@ module Bundler
71
71
  spec.installed_by_version = Gem::Version.create(installed_by_version)
72
72
  end
73
73
 
74
- def spec_missing_extensions?(spec)
75
- !spec.respond_to?(:missing_extensions?) || spec.missing_extensions?
74
+ def spec_missing_extensions?(spec, default = true)
75
+ return spec.missing_extensions? if spec.respond_to?(:missing_extensions?)
76
+
77
+ return false if spec.respond_to?(:default_gem?) && spec.default_gem?
78
+ return false if spec.extensions.empty?
79
+
80
+ default
76
81
  end
77
82
 
78
83
  def path(obj)
@@ -196,7 +201,7 @@ module Bundler
196
201
  end
197
202
 
198
203
  def load_plugins
199
- Gem.load_plugins
204
+ Gem.load_plugins if Gem.respond_to?(:load_plugins)
200
205
  end
201
206
 
202
207
  def ui=(obj)
@@ -248,6 +253,10 @@ module Bundler
248
253
  end
249
254
  end
250
255
 
256
+ def install_with_build_args(args)
257
+ with_build_args(args) { yield }
258
+ end
259
+
251
260
  def gem_from_path(path, policy = nil)
252
261
  require "rubygems/format"
253
262
  Gem::Format.from_file_by_path(path, policy)
@@ -715,6 +724,10 @@ module Bundler
715
724
  def repository_subdirectories
716
725
  Gem::REPOSITORY_SUBDIRECTORIES
717
726
  end
727
+
728
+ def install_with_build_args(args)
729
+ yield
730
+ end
718
731
  end
719
732
 
720
733
  # RubyGems 2.1.0
@@ -240,7 +240,12 @@ module Bundler
240
240
  end
241
241
 
242
242
  def to_bool(value)
243
- !(value.nil? || value == "" || value =~ /^(false|f|no|n|0)$/i || value == false)
243
+ case value
244
+ when nil, /\A(false|f|no|n|0|)\z/i, false
245
+ false
246
+ else
247
+ true
248
+ end
244
249
  end
245
250
 
246
251
  def is_num(value)
@@ -298,10 +303,10 @@ module Bundler
298
303
  }xo
299
304
 
300
305
  def load_config(config_file)
301
- return {} unless config_file
306
+ return {} if !config_file || ignore_config?
302
307
  SharedHelpers.filesystem_access(config_file, :read) do |file|
303
308
  valid_file = file.exist? && !file.size.zero?
304
- return {} if ignore_config? || !valid_file
309
+ return {} unless valid_file
305
310
  require "bundler/yaml_serializer"
306
311
  YAMLSerializer.load file.read
307
312
  end
@@ -8,6 +8,7 @@ require "bundler/current_ruby"
8
8
 
9
9
  module Gem
10
10
  class Dependency
11
+ # This is only needed for RubyGems < 1.4
11
12
  unless method_defined? :requirement
12
13
  def requirement
13
14
  version_requirements
@@ -18,8 +19,6 @@ end
18
19
 
19
20
  module Bundler
20
21
  module SharedHelpers
21
- attr_accessor :gem_loaded
22
-
23
22
  def default_gemfile
24
23
  gemfile = find_gemfile
25
24
  raise GemfileNotFound, "Could not locate Gemfile" unless gemfile
@@ -111,8 +110,14 @@ module Bundler
111
110
  raise TemporaryResourceError.new(path, action)
112
111
  rescue Errno::EPROTO
113
112
  raise VirtualProtocolError.new
113
+ rescue Errno::ENOSPC
114
+ raise NoSpaceOnDeviceError.new(path, action)
114
115
  rescue *[const_get_safely(:ENOTSUP, Errno)].compact
115
116
  raise OperationNotSupportedError.new(path, action)
117
+ rescue Errno::EEXIST, Errno::ENOENT
118
+ raise
119
+ rescue SystemCallError => e
120
+ raise GenericSystemCallError.new(e, "There was an error accessing `#{path}`.")
116
121
  end
117
122
 
118
123
  def const_get_safely(constant_name, namespace)
@@ -211,22 +216,20 @@ module Bundler
211
216
  def bundler_ruby_lib
212
217
  File.expand_path("../..", __FILE__)
213
218
  end
214
- private :bundler_ruby_lib
215
219
 
216
220
  def clean_load_path
217
221
  # handle 1.9 where system gems are always on the load path
218
- if defined?(::Gem)
219
- me = File.expand_path("../../", __FILE__)
220
- me = /^#{Regexp.escape(me)}/
222
+ return unless defined?(::Gem)
221
223
 
222
- loaded_gem_paths = Bundler.rubygems.loaded_gem_paths
224
+ bundler_lib = bundler_ruby_lib
223
225
 
224
- $LOAD_PATH.reject! do |p|
225
- next if File.expand_path(p) =~ me
226
- loaded_gem_paths.delete(p)
227
- end
228
- $LOAD_PATH.uniq!
226
+ loaded_gem_paths = Bundler.rubygems.loaded_gem_paths
227
+
228
+ $LOAD_PATH.reject! do |p|
229
+ next if File.expand_path(p).start_with?(bundler_lib)
230
+ loaded_gem_paths.delete(p)
229
231
  end
232
+ $LOAD_PATH.uniq!
230
233
  end
231
234
 
232
235
  def prints_major_deprecations?
@@ -34,5 +34,9 @@ module Bundler
34
34
  def include?(other)
35
35
  other == self
36
36
  end
37
+
38
+ def inspect
39
+ "#<#{self.class}:0x#{object_id} #{self}>"
40
+ end
37
41
  end
38
42
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+ require "shellwords"
2
3
  require "tempfile"
3
4
  module Bundler
4
5
  class Source
@@ -180,7 +181,7 @@ module Bundler
180
181
 
181
182
  def find_local_revision
182
183
  allowed_in_path do
183
- git("rev-parse --verify #{ref}", true).strip
184
+ git("rev-parse --verify #{Shellwords.shellescape(ref)}", true).strip
184
185
  end
185
186
  end
186
187
 
@@ -141,6 +141,7 @@ module Bundler
141
141
  :ignore_dependencies => true,
142
142
  :wrappers => true,
143
143
  :env_shebang => true,
144
+ :build_args => opts[:build_args],
144
145
  :bundler_expected_checksum => spec.respond_to?(:checksum) && spec.checksum
145
146
  ).install
146
147
  end
@@ -292,6 +293,10 @@ module Bundler
292
293
  next if spec.name == "bundler" && spec.version.to_s != VERSION
293
294
  have_bundler = true if spec.name == "bundler"
294
295
  spec.source = self
296
+ if Bundler.rubygems.spec_missing_extensions?(spec, false)
297
+ Bundler.ui.debug "Source #{self} is ignoring #{spec} because it is missing extensions"
298
+ next
299
+ end
295
300
  idx << spec
296
301
  end
297
302
 
@@ -322,6 +327,10 @@ module Bundler
322
327
  next if gemfile =~ /^bundler\-[\d\.]+?\.gem/
323
328
  s ||= Bundler.rubygems.spec_from_gem(gemfile)
324
329
  s.source = self
330
+ if Bundler.rubygems.spec_missing_extensions?(s, false)
331
+ Bundler.ui.debug "Source #{self} is ignoring #{s} because it is missing extensions"
332
+ next
333
+ end
325
334
  idx << s
326
335
  end
327
336
  end
@@ -114,6 +114,10 @@ module Bundler
114
114
  SpecSet.new(arr)
115
115
  end
116
116
 
117
+ def find_by_name_and_platform(name, platform)
118
+ @specs.detect {|spec| spec.name == name && spec.match_platform(platform) }
119
+ end
120
+
117
121
  private
118
122
 
119
123
  def sorted
@@ -14,3 +14,8 @@
14
14
  *.a
15
15
  mkmf.log
16
16
  <%- end -%>
17
+ <%- if config[:test] == "rspec" -%>
18
+
19
+ # rspec failure tracking
20
+ .rspec_status
21
+ <%- end -%>
@@ -1,6 +1,6 @@
1
1
  require "spec_helper"
2
2
 
3
- describe <%= config[:constant_name] %> do
3
+ RSpec.describe <%= config[:constant_name] %> do
4
4
  it "has a version number" do
5
5
  expect(<%= config[:constant_name] %>::VERSION).not_to be nil
6
6
  end
@@ -1,2 +1,11 @@
1
- $LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
1
+ require "bundler/setup"
2
2
  require "<%= config[:namespaced_path] %>"
3
+
4
+ RSpec.configure do |config|
5
+ # Enable flags like --only-failures and --next-failure
6
+ config.example_status_persistence_file_path = ".rspec_status"
7
+
8
+ config.expect_with :rspec do |c|
9
+ c.syntax = :expect
10
+ end
11
+ end
@@ -119,6 +119,7 @@ module Bundler::Molinillo
119
119
  # {Vertex#successors}
120
120
  def ==(other)
121
121
  return false unless other
122
+ return true if equal?(other)
122
123
  vertices.each do |name, vertex|
123
124
  other_vertex = other.vertex_named(name)
124
125
  return false unless other_vertex
@@ -134,6 +135,7 @@ module Bundler::Molinillo
134
135
  def add_child_vertex(name, payload, parent_names, requirement)
135
136
  root = !parent_names.delete(nil) { true }
136
137
  vertex = add_vertex(name, payload, root)
138
+ vertex.explicit_requirements << requirement if root
137
139
  parent_names.each do |parent_name|
138
140
  parent_node = vertex_named(parent_name)
139
141
  add_edge(parent_node, vertex, requirement)
@@ -152,7 +154,7 @@ module Bundler::Molinillo
152
154
  # Detaches the {#vertex_named} `name` {Vertex} from the graph, recursively
153
155
  # removing any non-root vertices that were orphaned in the process
154
156
  # @param [String] name
155
- # @return [void]
157
+ # @return [Array<Vertex>] the vertices which have been detached
156
158
  def detach_vertex_named(name)
157
159
  log.detach_vertex_named(self, name)
158
160
  end
@@ -182,6 +184,13 @@ module Bundler::Molinillo
182
184
  add_edge_no_circular(origin, destination, requirement)
183
185
  end
184
186
 
187
+ # Deletes an {Edge} from the dependency graph
188
+ # @param [Edge] edge
189
+ # @return [Void]
190
+ def delete_edge(edge)
191
+ log.delete_edge(self, edge.origin.name, edge.destination.name, edge.requirement)
192
+ end
193
+
185
194
  # Sets the payload of the vertex with the given name
186
195
  # @param [String] name the name of the vertex
187
196
  # @param [Object] payload the payload
@@ -7,7 +7,7 @@ module Bundler::Molinillo
7
7
  # rubocop:disable Lint/UnusedMethodArgument
8
8
 
9
9
  # @return [Symbol] The name of the action.
10
- def self.name
10
+ def self.action_name
11
11
  raise 'Abstract'
12
12
  end
13
13
 
@@ -7,8 +7,8 @@ module Bundler::Molinillo
7
7
  class AddEdgeNoCircular < Action
8
8
  # @!group Action
9
9
 
10
- # (see Action.name)
11
- def self.name
10
+ # (see Action.action_name)
11
+ def self.action_name
12
12
  :add_vertex
13
13
  end
14
14
 
@@ -7,8 +7,8 @@ module Bundler::Molinillo
7
7
  class AddVertex < Action # :nodoc:
8
8
  # @!group Action
9
9
 
10
- # (see Action.name)
11
- def self.name
10
+ # (see Action.action_name)
11
+ def self.action_name
12
12
  :add_vertex
13
13
  end
14
14
 
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+ require 'bundler/vendor/molinillo/lib/molinillo/dependency_graph/action'
3
+ module Bundler::Molinillo
4
+ class DependencyGraph
5
+ # @!visibility private
6
+ # (see DependencyGraph#delete_edge)
7
+ class DeleteEdge < Action
8
+ # @!group Action
9
+
10
+ # (see Action.action_name)
11
+ def self.action_name
12
+ :delete_edge
13
+ end
14
+
15
+ # (see Action#up)
16
+ def up(graph)
17
+ edge = make_edge(graph)
18
+ edge.origin.outgoing_edges.delete(edge)
19
+ edge.destination.incoming_edges.delete(edge)
20
+ end
21
+
22
+ # (see Action#down)
23
+ def down(graph)
24
+ edge = make_edge(graph)
25
+ edge.origin.outgoing_edges << edge
26
+ edge.destination.incoming_edges << edge
27
+ edge
28
+ end
29
+
30
+ # @!group DeleteEdge
31
+
32
+ # @return [String] the name of the origin of the edge
33
+ attr_reader :origin_name
34
+
35
+ # @return [String] the name of the destination of the edge
36
+ attr_reader :destination_name
37
+
38
+ # @return [Object] the requirement that the edge represents
39
+ attr_reader :requirement
40
+
41
+ # @param [DependencyGraph] graph the graph to find vertices from
42
+ # @return [Edge] The edge this action adds
43
+ def make_edge(graph)
44
+ Edge.new(
45
+ graph.vertex_named(origin_name),
46
+ graph.vertex_named(destination_name),
47
+ requirement
48
+ )
49
+ end
50
+
51
+ # Initialize an action to add an edge to a dependency graph
52
+ # @param [String] origin_name the name of the origin of the edge
53
+ # @param [String] destination_name the name of the destination of the edge
54
+ # @param [Object] requirement the requirement that the edge represents
55
+ def initialize(origin_name, destination_name, requirement)
56
+ @origin_name = origin_name
57
+ @destination_name = destination_name
58
+ @requirement = requirement
59
+ end
60
+ end
61
+ end
62
+ end
@@ -8,22 +8,29 @@ module Bundler::Molinillo
8
8
  # @!group Action
9
9
 
10
10
  # (see Action#name)
11
- def self.name
11
+ def self.action_name
12
12
  :add_vertex
13
13
  end
14
14
 
15
15
  # (see Action#up)
16
16
  def up(graph)
17
- return unless @vertex = graph.vertices.delete(name)
17
+ return [] unless @vertex = graph.vertices.delete(name)
18
+
19
+ removed_vertices = [@vertex]
18
20
  @vertex.outgoing_edges.each do |e|
19
21
  v = e.destination
20
22
  v.incoming_edges.delete(e)
21
- graph.detach_vertex_named(v.name) unless v.root? || v.predecessors.any?
23
+ if !v.root? && v.incoming_edges.empty?
24
+ removed_vertices.concat graph.detach_vertex_named(v.name)
25
+ end
22
26
  end
27
+
23
28
  @vertex.incoming_edges.each do |e|
24
29
  v = e.origin
25
30
  v.outgoing_edges.delete(e)
26
31
  end
32
+
33
+ removed_vertices
27
34
  end
28
35
 
29
36
  # (see Action#down)