bundler 2.0.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of bundler might be problematic. Click here for more details.
- checksums.yaml +7 -0
- data/CHANGELOG.md +3111 -0
- data/LICENSE.md +23 -0
- data/README.md +63 -0
- data/bundler.gemspec +65 -0
- data/exe/bundle +31 -0
- data/exe/bundle_ruby +60 -0
- data/exe/bundler +4 -0
- data/lib/bundler.rb +567 -0
- data/lib/bundler/build_metadata.rb +53 -0
- data/lib/bundler/capistrano.rb +22 -0
- data/lib/bundler/cli.rb +792 -0
- data/lib/bundler/cli/add.rb +35 -0
- data/lib/bundler/cli/binstubs.rb +49 -0
- data/lib/bundler/cli/cache.rb +36 -0
- data/lib/bundler/cli/check.rb +38 -0
- data/lib/bundler/cli/clean.rb +25 -0
- data/lib/bundler/cli/common.rb +102 -0
- data/lib/bundler/cli/config.rb +119 -0
- data/lib/bundler/cli/console.rb +43 -0
- data/lib/bundler/cli/doctor.rb +140 -0
- data/lib/bundler/cli/exec.rb +105 -0
- data/lib/bundler/cli/gem.rb +252 -0
- data/lib/bundler/cli/info.rb +50 -0
- data/lib/bundler/cli/init.rb +47 -0
- data/lib/bundler/cli/inject.rb +60 -0
- data/lib/bundler/cli/install.rb +218 -0
- data/lib/bundler/cli/issue.rb +40 -0
- data/lib/bundler/cli/list.rb +58 -0
- data/lib/bundler/cli/lock.rb +63 -0
- data/lib/bundler/cli/open.rb +26 -0
- data/lib/bundler/cli/outdated.rb +266 -0
- data/lib/bundler/cli/package.rb +49 -0
- data/lib/bundler/cli/platform.rb +46 -0
- data/lib/bundler/cli/plugin.rb +24 -0
- data/lib/bundler/cli/pristine.rb +47 -0
- data/lib/bundler/cli/remove.rb +18 -0
- data/lib/bundler/cli/show.rb +75 -0
- data/lib/bundler/cli/update.rb +91 -0
- data/lib/bundler/cli/viz.rb +31 -0
- data/lib/bundler/compact_index_client.rb +109 -0
- data/lib/bundler/compact_index_client/cache.rb +118 -0
- data/lib/bundler/compact_index_client/updater.rb +116 -0
- data/lib/bundler/compatibility_guard.rb +13 -0
- data/lib/bundler/constants.rb +7 -0
- data/lib/bundler/current_ruby.rb +94 -0
- data/lib/bundler/definition.rb +995 -0
- data/lib/bundler/dep_proxy.rb +48 -0
- data/lib/bundler/dependency.rb +139 -0
- data/lib/bundler/deployment.rb +69 -0
- data/lib/bundler/deprecate.rb +44 -0
- data/lib/bundler/dsl.rb +615 -0
- data/lib/bundler/endpoint_specification.rb +141 -0
- data/lib/bundler/env.rb +149 -0
- data/lib/bundler/environment_preserver.rb +59 -0
- data/lib/bundler/errors.rb +158 -0
- data/lib/bundler/feature_flag.rb +75 -0
- data/lib/bundler/fetcher.rb +312 -0
- data/lib/bundler/fetcher/base.rb +52 -0
- data/lib/bundler/fetcher/compact_index.rb +126 -0
- data/lib/bundler/fetcher/dependency.rb +82 -0
- data/lib/bundler/fetcher/downloader.rb +84 -0
- data/lib/bundler/fetcher/index.rb +52 -0
- data/lib/bundler/friendly_errors.rb +131 -0
- data/lib/bundler/gem_helper.rb +217 -0
- data/lib/bundler/gem_helpers.rb +101 -0
- data/lib/bundler/gem_remote_fetcher.rb +43 -0
- data/lib/bundler/gem_tasks.rb +7 -0
- data/lib/bundler/gem_version_promoter.rb +190 -0
- data/lib/bundler/gemdeps.rb +29 -0
- data/lib/bundler/graph.rb +152 -0
- data/lib/bundler/index.rb +213 -0
- data/lib/bundler/injector.rb +253 -0
- data/lib/bundler/inline.rb +74 -0
- data/lib/bundler/installer.rb +318 -0
- data/lib/bundler/installer/gem_installer.rb +85 -0
- data/lib/bundler/installer/parallel_installer.rb +229 -0
- data/lib/bundler/installer/standalone.rb +53 -0
- data/lib/bundler/lazy_specification.rb +123 -0
- data/lib/bundler/lockfile_generator.rb +95 -0
- data/lib/bundler/lockfile_parser.rb +256 -0
- data/lib/bundler/match_platform.rb +24 -0
- data/lib/bundler/mirror.rb +223 -0
- data/lib/bundler/plugin.rb +294 -0
- data/lib/bundler/plugin/api.rb +81 -0
- data/lib/bundler/plugin/api/source.rb +306 -0
- data/lib/bundler/plugin/dsl.rb +53 -0
- data/lib/bundler/plugin/events.rb +61 -0
- data/lib/bundler/plugin/index.rb +165 -0
- data/lib/bundler/plugin/installer.rb +96 -0
- data/lib/bundler/plugin/installer/git.rb +38 -0
- data/lib/bundler/plugin/installer/rubygems.rb +27 -0
- data/lib/bundler/plugin/source_list.rb +27 -0
- data/lib/bundler/process_lock.rb +24 -0
- data/lib/bundler/psyched_yaml.rb +37 -0
- data/lib/bundler/remote_specification.rb +114 -0
- data/lib/bundler/resolver.rb +373 -0
- data/lib/bundler/resolver/spec_group.rb +106 -0
- data/lib/bundler/retry.rb +66 -0
- data/lib/bundler/ruby_dsl.rb +18 -0
- data/lib/bundler/ruby_version.rb +152 -0
- data/lib/bundler/rubygems_ext.rb +209 -0
- data/lib/bundler/rubygems_gem_installer.rb +99 -0
- data/lib/bundler/rubygems_integration.rb +915 -0
- data/lib/bundler/runtime.rb +322 -0
- data/lib/bundler/settings.rb +464 -0
- data/lib/bundler/settings/validator.rb +102 -0
- data/lib/bundler/setup.rb +28 -0
- data/lib/bundler/shared_helpers.rb +386 -0
- data/lib/bundler/similarity_detector.rb +63 -0
- data/lib/bundler/source.rb +94 -0
- data/lib/bundler/source/gemspec.rb +18 -0
- data/lib/bundler/source/git.rb +329 -0
- data/lib/bundler/source/git/git_proxy.rb +262 -0
- data/lib/bundler/source/metadata.rb +62 -0
- data/lib/bundler/source/path.rb +249 -0
- data/lib/bundler/source/path/installer.rb +74 -0
- data/lib/bundler/source/rubygems.rb +539 -0
- data/lib/bundler/source/rubygems/remote.rb +69 -0
- data/lib/bundler/source_list.rb +186 -0
- data/lib/bundler/spec_set.rb +208 -0
- data/lib/bundler/ssl_certs/.document +1 -0
- data/lib/bundler/ssl_certs/certificate_manager.rb +66 -0
- data/lib/bundler/ssl_certs/index.rubygems.org/GlobalSignRootCA.pem +21 -0
- data/lib/bundler/ssl_certs/rubygems.global.ssl.fastly.net/DigiCertHighAssuranceEVRootCA.pem +23 -0
- data/lib/bundler/ssl_certs/rubygems.org/AddTrustExternalCARoot.pem +25 -0
- data/lib/bundler/stub_specification.rb +108 -0
- data/lib/bundler/templates/.document +1 -0
- data/lib/bundler/templates/Executable +29 -0
- data/lib/bundler/templates/Executable.bundler +105 -0
- data/lib/bundler/templates/Executable.standalone +14 -0
- data/lib/bundler/templates/Gemfile +7 -0
- data/lib/bundler/templates/gems.rb +8 -0
- data/lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt +74 -0
- data/lib/bundler/templates/newgem/Gemfile.tt +4 -0
- data/lib/bundler/templates/newgem/LICENSE.txt.tt +21 -0
- data/lib/bundler/templates/newgem/README.md.tt +47 -0
- data/lib/bundler/templates/newgem/Rakefile.tt +29 -0
- data/lib/bundler/templates/newgem/bin/console.tt +14 -0
- data/lib/bundler/templates/newgem/bin/setup.tt +8 -0
- data/lib/bundler/templates/newgem/exe/newgem.tt +3 -0
- data/lib/bundler/templates/newgem/ext/newgem/extconf.rb.tt +3 -0
- data/lib/bundler/templates/newgem/ext/newgem/newgem.c.tt +9 -0
- data/lib/bundler/templates/newgem/ext/newgem/newgem.h.tt +6 -0
- data/lib/bundler/templates/newgem/gitignore.tt +20 -0
- data/lib/bundler/templates/newgem/lib/newgem.rb.tt +13 -0
- data/lib/bundler/templates/newgem/lib/newgem/version.rb.tt +7 -0
- data/lib/bundler/templates/newgem/newgem.gemspec.tt +50 -0
- data/lib/bundler/templates/newgem/rspec.tt +3 -0
- data/lib/bundler/templates/newgem/spec/newgem_spec.rb.tt +9 -0
- data/lib/bundler/templates/newgem/spec/spec_helper.rb.tt +14 -0
- data/lib/bundler/templates/newgem/test/newgem_test.rb.tt +11 -0
- data/lib/bundler/templates/newgem/test/test_helper.rb.tt +8 -0
- data/lib/bundler/templates/newgem/travis.yml.tt +7 -0
- data/lib/bundler/ui.rb +9 -0
- data/lib/bundler/ui/rg_proxy.rb +19 -0
- data/lib/bundler/ui/shell.rb +146 -0
- data/lib/bundler/ui/silent.rb +69 -0
- data/lib/bundler/uri_credentials_filter.rb +37 -0
- data/lib/bundler/vendor/fileutils/lib/fileutils.rb +1741 -0
- data/lib/bundler/vendor/fileutils/lib/fileutils/version.rb +5 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo.rb +12 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/compatibility.rb +26 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/delegates/resolution_state.rb +57 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/delegates/specification_provider.rb +81 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +223 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/action.rb +36 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb +66 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex.rb +62 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/delete_edge.rb +63 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb +61 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/log.rb +126 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/set_payload.rb +46 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb +36 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb +136 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/errors.rb +143 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb +6 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/modules/specification_provider.rb +101 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/modules/ui.rb +67 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb +837 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/resolver.rb +46 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/state.rb +58 -0
- data/lib/bundler/vendor/net-http-persistent/lib/net/http/faster.rb +27 -0
- data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +1233 -0
- data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/ssl_reuse.rb +129 -0
- data/lib/bundler/vendor/thor/lib/thor.rb +509 -0
- data/lib/bundler/vendor/thor/lib/thor/actions.rb +331 -0
- data/lib/bundler/vendor/thor/lib/thor/actions/create_file.rb +104 -0
- data/lib/bundler/vendor/thor/lib/thor/actions/create_link.rb +60 -0
- data/lib/bundler/vendor/thor/lib/thor/actions/directory.rb +118 -0
- data/lib/bundler/vendor/thor/lib/thor/actions/empty_directory.rb +143 -0
- data/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +373 -0
- data/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb +109 -0
- data/lib/bundler/vendor/thor/lib/thor/base.rb +678 -0
- data/lib/bundler/vendor/thor/lib/thor/command.rb +135 -0
- data/lib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +97 -0
- data/lib/bundler/vendor/thor/lib/thor/core_ext/io_binary_read.rb +12 -0
- data/lib/bundler/vendor/thor/lib/thor/core_ext/ordered_hash.rb +129 -0
- data/lib/bundler/vendor/thor/lib/thor/error.rb +114 -0
- data/lib/bundler/vendor/thor/lib/thor/group.rb +281 -0
- data/lib/bundler/vendor/thor/lib/thor/invocation.rb +177 -0
- data/lib/bundler/vendor/thor/lib/thor/line_editor.rb +17 -0
- data/lib/bundler/vendor/thor/lib/thor/line_editor/basic.rb +37 -0
- data/lib/bundler/vendor/thor/lib/thor/line_editor/readline.rb +88 -0
- data/lib/bundler/vendor/thor/lib/thor/parser.rb +4 -0
- data/lib/bundler/vendor/thor/lib/thor/parser/argument.rb +70 -0
- data/lib/bundler/vendor/thor/lib/thor/parser/arguments.rb +175 -0
- data/lib/bundler/vendor/thor/lib/thor/parser/option.rb +146 -0
- data/lib/bundler/vendor/thor/lib/thor/parser/options.rb +226 -0
- data/lib/bundler/vendor/thor/lib/thor/rake_compat.rb +71 -0
- data/lib/bundler/vendor/thor/lib/thor/runner.rb +324 -0
- data/lib/bundler/vendor/thor/lib/thor/shell.rb +81 -0
- data/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +482 -0
- data/lib/bundler/vendor/thor/lib/thor/shell/color.rb +149 -0
- data/lib/bundler/vendor/thor/lib/thor/shell/html.rb +126 -0
- data/lib/bundler/vendor/thor/lib/thor/util.rb +268 -0
- data/lib/bundler/vendor/thor/lib/thor/version.rb +3 -0
- data/lib/bundler/vendored_fileutils.rb +9 -0
- data/lib/bundler/vendored_molinillo.rb +4 -0
- data/lib/bundler/vendored_persistent.rb +52 -0
- data/lib/bundler/vendored_thor.rb +8 -0
- data/lib/bundler/version.rb +28 -0
- data/lib/bundler/version_ranges.rb +76 -0
- data/lib/bundler/vlad.rb +17 -0
- data/lib/bundler/worker.rb +106 -0
- data/lib/bundler/yaml_serializer.rb +90 -0
- data/man/bundle-add.1 +58 -0
- data/man/bundle-add.1.txt +52 -0
- data/man/bundle-add.ronn +40 -0
- data/man/bundle-binstubs.1 +40 -0
- data/man/bundle-binstubs.1.txt +48 -0
- data/man/bundle-binstubs.ronn +43 -0
- data/man/bundle-check.1 +31 -0
- data/man/bundle-check.1.txt +33 -0
- data/man/bundle-check.ronn +26 -0
- data/man/bundle-clean.1 +24 -0
- data/man/bundle-clean.1.txt +26 -0
- data/man/bundle-clean.ronn +18 -0
- data/man/bundle-config.1 +497 -0
- data/man/bundle-config.1.txt +529 -0
- data/man/bundle-config.ronn +397 -0
- data/man/bundle-doctor.1 +44 -0
- data/man/bundle-doctor.1.txt +44 -0
- data/man/bundle-doctor.ronn +33 -0
- data/man/bundle-exec.1 +165 -0
- data/man/bundle-exec.1.txt +178 -0
- data/man/bundle-exec.ronn +152 -0
- data/man/bundle-gem.1 +80 -0
- data/man/bundle-gem.1.txt +91 -0
- data/man/bundle-gem.ronn +78 -0
- data/man/bundle-info.1 +20 -0
- data/man/bundle-info.1.txt +21 -0
- data/man/bundle-info.ronn +17 -0
- data/man/bundle-init.1 +25 -0
- data/man/bundle-init.1.txt +34 -0
- data/man/bundle-init.ronn +29 -0
- data/man/bundle-inject.1 +33 -0
- data/man/bundle-inject.1.txt +32 -0
- data/man/bundle-inject.ronn +22 -0
- data/man/bundle-install.1 +308 -0
- data/man/bundle-install.1.txt +396 -0
- data/man/bundle-install.ronn +378 -0
- data/man/bundle-list.1 +50 -0
- data/man/bundle-list.1.txt +43 -0
- data/man/bundle-list.ronn +33 -0
- data/man/bundle-lock.1 +84 -0
- data/man/bundle-lock.1.txt +93 -0
- data/man/bundle-lock.ronn +94 -0
- data/man/bundle-open.1 +32 -0
- data/man/bundle-open.1.txt +29 -0
- data/man/bundle-open.ronn +19 -0
- data/man/bundle-outdated.1 +155 -0
- data/man/bundle-outdated.1.txt +131 -0
- data/man/bundle-outdated.ronn +111 -0
- data/man/bundle-package.1 +55 -0
- data/man/bundle-package.1.txt +79 -0
- data/man/bundle-package.ronn +72 -0
- data/man/bundle-platform.1 +61 -0
- data/man/bundle-platform.1.txt +57 -0
- data/man/bundle-platform.ronn +42 -0
- data/man/bundle-pristine.1 +34 -0
- data/man/bundle-pristine.1.txt +44 -0
- data/man/bundle-pristine.ronn +34 -0
- data/man/bundle-remove.1 +31 -0
- data/man/bundle-remove.1.txt +34 -0
- data/man/bundle-remove.ronn +23 -0
- data/man/bundle-show.1 +23 -0
- data/man/bundle-show.1.txt +27 -0
- data/man/bundle-show.ronn +21 -0
- data/man/bundle-update.1 +394 -0
- data/man/bundle-update.1.txt +391 -0
- data/man/bundle-update.ronn +350 -0
- data/man/bundle-viz.1 +39 -0
- data/man/bundle-viz.1.txt +39 -0
- data/man/bundle-viz.ronn +30 -0
- data/man/bundle.1 +136 -0
- data/man/bundle.1.txt +116 -0
- data/man/bundle.ronn +111 -0
- data/man/gemfile.5 +689 -0
- data/man/gemfile.5.ronn +521 -0
- data/man/gemfile.5.txt +653 -0
- data/man/index.txt +25 -0
- metadata +463 -0
@@ -0,0 +1,136 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Bundler::Molinillo
|
4
|
+
class DependencyGraph
|
5
|
+
# A vertex in a {DependencyGraph} that encapsulates a {#name} and a
|
6
|
+
# {#payload}
|
7
|
+
class Vertex
|
8
|
+
# @return [String] the name of the vertex
|
9
|
+
attr_accessor :name
|
10
|
+
|
11
|
+
# @return [Object] the payload the vertex holds
|
12
|
+
attr_accessor :payload
|
13
|
+
|
14
|
+
# @return [Array<Object>] the explicit requirements that required
|
15
|
+
# this vertex
|
16
|
+
attr_reader :explicit_requirements
|
17
|
+
|
18
|
+
# @return [Boolean] whether the vertex is considered a root vertex
|
19
|
+
attr_accessor :root
|
20
|
+
alias root? root
|
21
|
+
|
22
|
+
# Initializes a vertex with the given name and payload.
|
23
|
+
# @param [String] name see {#name}
|
24
|
+
# @param [Object] payload see {#payload}
|
25
|
+
def initialize(name, payload)
|
26
|
+
@name = name.frozen? ? name : name.dup.freeze
|
27
|
+
@payload = payload
|
28
|
+
@explicit_requirements = []
|
29
|
+
@outgoing_edges = []
|
30
|
+
@incoming_edges = []
|
31
|
+
end
|
32
|
+
|
33
|
+
# @return [Array<Object>] all of the requirements that required
|
34
|
+
# this vertex
|
35
|
+
def requirements
|
36
|
+
(incoming_edges.map(&:requirement) + explicit_requirements).uniq
|
37
|
+
end
|
38
|
+
|
39
|
+
# @return [Array<Edge>] the edges of {#graph} that have `self` as their
|
40
|
+
# {Edge#origin}
|
41
|
+
attr_accessor :outgoing_edges
|
42
|
+
|
43
|
+
# @return [Array<Edge>] the edges of {#graph} that have `self` as their
|
44
|
+
# {Edge#destination}
|
45
|
+
attr_accessor :incoming_edges
|
46
|
+
|
47
|
+
# @return [Array<Vertex>] the vertices of {#graph} that have an edge with
|
48
|
+
# `self` as their {Edge#destination}
|
49
|
+
def predecessors
|
50
|
+
incoming_edges.map(&:origin)
|
51
|
+
end
|
52
|
+
|
53
|
+
# @return [Array<Vertex>] the vertices of {#graph} where `self` is a
|
54
|
+
# {#descendent?}
|
55
|
+
def recursive_predecessors
|
56
|
+
vertices = predecessors
|
57
|
+
vertices += Compatibility.flat_map(vertices, &:recursive_predecessors)
|
58
|
+
vertices.uniq!
|
59
|
+
vertices
|
60
|
+
end
|
61
|
+
|
62
|
+
# @return [Array<Vertex>] the vertices of {#graph} that have an edge with
|
63
|
+
# `self` as their {Edge#origin}
|
64
|
+
def successors
|
65
|
+
outgoing_edges.map(&:destination)
|
66
|
+
end
|
67
|
+
|
68
|
+
# @return [Array<Vertex>] the vertices of {#graph} where `self` is an
|
69
|
+
# {#ancestor?}
|
70
|
+
def recursive_successors
|
71
|
+
vertices = successors
|
72
|
+
vertices += Compatibility.flat_map(vertices, &:recursive_successors)
|
73
|
+
vertices.uniq!
|
74
|
+
vertices
|
75
|
+
end
|
76
|
+
|
77
|
+
# @return [String] a string suitable for debugging
|
78
|
+
def inspect
|
79
|
+
"#{self.class}:#{name}(#{payload.inspect})"
|
80
|
+
end
|
81
|
+
|
82
|
+
# @return [Boolean] whether the two vertices are equal, determined
|
83
|
+
# by a recursive traversal of each {Vertex#successors}
|
84
|
+
def ==(other)
|
85
|
+
return true if equal?(other)
|
86
|
+
shallow_eql?(other) &&
|
87
|
+
successors.to_set == other.successors.to_set
|
88
|
+
end
|
89
|
+
|
90
|
+
# @param [Vertex] other the other vertex to compare to
|
91
|
+
# @return [Boolean] whether the two vertices are equal, determined
|
92
|
+
# solely by {#name} and {#payload} equality
|
93
|
+
def shallow_eql?(other)
|
94
|
+
return true if equal?(other)
|
95
|
+
other &&
|
96
|
+
name == other.name &&
|
97
|
+
payload == other.payload
|
98
|
+
end
|
99
|
+
|
100
|
+
alias eql? ==
|
101
|
+
|
102
|
+
# @return [Fixnum] a hash for the vertex based upon its {#name}
|
103
|
+
def hash
|
104
|
+
name.hash
|
105
|
+
end
|
106
|
+
|
107
|
+
# Is there a path from `self` to `other` following edges in the
|
108
|
+
# dependency graph?
|
109
|
+
# @return true iff there is a path following edges within this {#graph}
|
110
|
+
def path_to?(other)
|
111
|
+
_path_to?(other)
|
112
|
+
end
|
113
|
+
|
114
|
+
alias descendent? path_to?
|
115
|
+
|
116
|
+
# @param [Vertex] other the vertex to check if there's a path to
|
117
|
+
# @param [Set<Vertex>] visited the vertices of {#graph} that have been visited
|
118
|
+
# @return [Boolean] whether there is a path to `other` from `self`
|
119
|
+
def _path_to?(other, visited = Set.new)
|
120
|
+
return false unless visited.add?(self)
|
121
|
+
return true if equal?(other)
|
122
|
+
successors.any? { |v| v._path_to?(other, visited) }
|
123
|
+
end
|
124
|
+
protected :_path_to?
|
125
|
+
|
126
|
+
# Is there a path from `other` to `self` following edges in the
|
127
|
+
# dependency graph?
|
128
|
+
# @return true iff there is a path following edges within this {#graph}
|
129
|
+
def ancestor?(other)
|
130
|
+
other.path_to?(self)
|
131
|
+
end
|
132
|
+
|
133
|
+
alias is_reachable_from? ancestor?
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
@@ -0,0 +1,143 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Bundler::Molinillo
|
4
|
+
# An error that occurred during the resolution process
|
5
|
+
class ResolverError < StandardError; end
|
6
|
+
|
7
|
+
# An error caused by searching for a dependency that is completely unknown,
|
8
|
+
# i.e. has no versions available whatsoever.
|
9
|
+
class NoSuchDependencyError < ResolverError
|
10
|
+
# @return [Object] the dependency that could not be found
|
11
|
+
attr_accessor :dependency
|
12
|
+
|
13
|
+
# @return [Array<Object>] the specifications that depended upon {#dependency}
|
14
|
+
attr_accessor :required_by
|
15
|
+
|
16
|
+
# Initializes a new error with the given missing dependency.
|
17
|
+
# @param [Object] dependency @see {#dependency}
|
18
|
+
# @param [Array<Object>] required_by @see {#required_by}
|
19
|
+
def initialize(dependency, required_by = [])
|
20
|
+
@dependency = dependency
|
21
|
+
@required_by = required_by.uniq
|
22
|
+
super()
|
23
|
+
end
|
24
|
+
|
25
|
+
# The error message for the missing dependency, including the specifications
|
26
|
+
# that had this dependency.
|
27
|
+
def message
|
28
|
+
sources = required_by.map { |r| "`#{r}`" }.join(' and ')
|
29
|
+
message = "Unable to find a specification for `#{dependency}`"
|
30
|
+
message += " depended upon by #{sources}" unless sources.empty?
|
31
|
+
message
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# An error caused by attempting to fulfil a dependency that was circular
|
36
|
+
#
|
37
|
+
# @note This exception will be thrown iff a {Vertex} is added to a
|
38
|
+
# {DependencyGraph} that has a {DependencyGraph::Vertex#path_to?} an
|
39
|
+
# existing {DependencyGraph::Vertex}
|
40
|
+
class CircularDependencyError < ResolverError
|
41
|
+
# [Set<Object>] the dependencies responsible for causing the error
|
42
|
+
attr_reader :dependencies
|
43
|
+
|
44
|
+
# Initializes a new error with the given circular vertices.
|
45
|
+
# @param [Array<DependencyGraph::Vertex>] vertices the vertices in the dependency
|
46
|
+
# that caused the error
|
47
|
+
def initialize(vertices)
|
48
|
+
super "There is a circular dependency between #{vertices.map(&:name).join(' and ')}"
|
49
|
+
@dependencies = vertices.map { |vertex| vertex.payload.possibilities.last }.to_set
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# An error caused by conflicts in version
|
54
|
+
class VersionConflict < ResolverError
|
55
|
+
# @return [{String => Resolution::Conflict}] the conflicts that caused
|
56
|
+
# resolution to fail
|
57
|
+
attr_reader :conflicts
|
58
|
+
|
59
|
+
# @return [SpecificationProvider] the specification provider used during
|
60
|
+
# resolution
|
61
|
+
attr_reader :specification_provider
|
62
|
+
|
63
|
+
# Initializes a new error with the given version conflicts.
|
64
|
+
# @param [{String => Resolution::Conflict}] conflicts see {#conflicts}
|
65
|
+
# @param [SpecificationProvider] specification_provider see {#specification_provider}
|
66
|
+
def initialize(conflicts, specification_provider)
|
67
|
+
pairs = []
|
68
|
+
Compatibility.flat_map(conflicts.values.flatten, &:requirements).each do |conflicting|
|
69
|
+
conflicting.each do |source, conflict_requirements|
|
70
|
+
conflict_requirements.each do |c|
|
71
|
+
pairs << [c, source]
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
super "Unable to satisfy the following requirements:\n\n" \
|
77
|
+
"#{pairs.map { |r, d| "- `#{r}` required by `#{d}`" }.join("\n")}"
|
78
|
+
|
79
|
+
@conflicts = conflicts
|
80
|
+
@specification_provider = specification_provider
|
81
|
+
end
|
82
|
+
|
83
|
+
require 'bundler/vendor/molinillo/lib/molinillo/delegates/specification_provider'
|
84
|
+
include Delegates::SpecificationProvider
|
85
|
+
|
86
|
+
# @return [String] An error message that includes requirement trees,
|
87
|
+
# which is much more detailed & customizable than the default message
|
88
|
+
# @param [Hash] opts the options to create a message with.
|
89
|
+
# @option opts [String] :solver_name The user-facing name of the solver
|
90
|
+
# @option opts [String] :possibility_type The generic name of a possibility
|
91
|
+
# @option opts [Proc] :reduce_trees A proc that reduced the list of requirement trees
|
92
|
+
# @option opts [Proc] :printable_requirement A proc that pretty-prints requirements
|
93
|
+
# @option opts [Proc] :additional_message_for_conflict A proc that appends additional
|
94
|
+
# messages for each conflict
|
95
|
+
# @option opts [Proc] :version_for_spec A proc that returns the version number for a
|
96
|
+
# possibility
|
97
|
+
def message_with_trees(opts = {})
|
98
|
+
solver_name = opts.delete(:solver_name) { self.class.name.split('::').first }
|
99
|
+
possibility_type = opts.delete(:possibility_type) { 'possibility named' }
|
100
|
+
reduce_trees = opts.delete(:reduce_trees) { proc { |trees| trees.uniq.sort_by(&:to_s) } }
|
101
|
+
printable_requirement = opts.delete(:printable_requirement) { proc { |req| req.to_s } }
|
102
|
+
additional_message_for_conflict = opts.delete(:additional_message_for_conflict) { proc {} }
|
103
|
+
version_for_spec = opts.delete(:version_for_spec) { proc(&:to_s) }
|
104
|
+
incompatible_version_message_for_conflict = opts.delete(:incompatible_version_message_for_conflict) do
|
105
|
+
proc do |name, _conflict|
|
106
|
+
%(#{solver_name} could not find compatible versions for #{possibility_type} "#{name}":)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
conflicts.sort.reduce(''.dup) do |o, (name, conflict)|
|
111
|
+
o << "\n" << incompatible_version_message_for_conflict.call(name, conflict) << "\n"
|
112
|
+
if conflict.locked_requirement
|
113
|
+
o << %( In snapshot (#{name_for_locking_dependency_source}):\n)
|
114
|
+
o << %( #{printable_requirement.call(conflict.locked_requirement)}\n)
|
115
|
+
o << %(\n)
|
116
|
+
end
|
117
|
+
o << %( In #{name_for_explicit_dependency_source}:\n)
|
118
|
+
trees = reduce_trees.call(conflict.requirement_trees)
|
119
|
+
|
120
|
+
o << trees.map do |tree|
|
121
|
+
t = ''.dup
|
122
|
+
depth = 2
|
123
|
+
tree.each do |req|
|
124
|
+
t << ' ' * depth << req.to_s
|
125
|
+
unless tree.last == req
|
126
|
+
if spec = conflict.activated_by_name[name_for(req)]
|
127
|
+
t << %( was resolved to #{version_for_spec.call(spec)}, which)
|
128
|
+
end
|
129
|
+
t << %( depends on)
|
130
|
+
end
|
131
|
+
t << %(\n)
|
132
|
+
depth += 1
|
133
|
+
end
|
134
|
+
t
|
135
|
+
end.join("\n")
|
136
|
+
|
137
|
+
additional_message_for_conflict.call(o, name, conflict)
|
138
|
+
|
139
|
+
o
|
140
|
+
end.strip
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Bundler::Molinillo
|
4
|
+
# Provides information about specifcations and dependencies to the resolver,
|
5
|
+
# allowing the {Resolver} class to remain generic while still providing power
|
6
|
+
# and flexibility.
|
7
|
+
#
|
8
|
+
# This module contains the methods that users of Bundler::Molinillo must to implement,
|
9
|
+
# using knowledge of their own model classes.
|
10
|
+
module SpecificationProvider
|
11
|
+
# Search for the specifications that match the given dependency.
|
12
|
+
# The specifications in the returned array will be considered in reverse
|
13
|
+
# order, so the latest version ought to be last.
|
14
|
+
# @note This method should be 'pure', i.e. the return value should depend
|
15
|
+
# only on the `dependency` parameter.
|
16
|
+
#
|
17
|
+
# @param [Object] dependency
|
18
|
+
# @return [Array<Object>] the specifications that satisfy the given
|
19
|
+
# `dependency`.
|
20
|
+
def search_for(dependency)
|
21
|
+
[]
|
22
|
+
end
|
23
|
+
|
24
|
+
# Returns the dependencies of `specification`.
|
25
|
+
# @note This method should be 'pure', i.e. the return value should depend
|
26
|
+
# only on the `specification` parameter.
|
27
|
+
#
|
28
|
+
# @param [Object] specification
|
29
|
+
# @return [Array<Object>] the dependencies that are required by the given
|
30
|
+
# `specification`.
|
31
|
+
def dependencies_for(specification)
|
32
|
+
[]
|
33
|
+
end
|
34
|
+
|
35
|
+
# Determines whether the given `requirement` is satisfied by the given
|
36
|
+
# `spec`, in the context of the current `activated` dependency graph.
|
37
|
+
#
|
38
|
+
# @param [Object] requirement
|
39
|
+
# @param [DependencyGraph] activated the current dependency graph in the
|
40
|
+
# resolution process.
|
41
|
+
# @param [Object] spec
|
42
|
+
# @return [Boolean] whether `requirement` is satisfied by `spec` in the
|
43
|
+
# context of the current `activated` dependency graph.
|
44
|
+
def requirement_satisfied_by?(requirement, activated, spec)
|
45
|
+
true
|
46
|
+
end
|
47
|
+
|
48
|
+
# Returns the name for the given `dependency`.
|
49
|
+
# @note This method should be 'pure', i.e. the return value should depend
|
50
|
+
# only on the `dependency` parameter.
|
51
|
+
#
|
52
|
+
# @param [Object] dependency
|
53
|
+
# @return [String] the name for the given `dependency`.
|
54
|
+
def name_for(dependency)
|
55
|
+
dependency.to_s
|
56
|
+
end
|
57
|
+
|
58
|
+
# @return [String] the name of the source of explicit dependencies, i.e.
|
59
|
+
# those passed to {Resolver#resolve} directly.
|
60
|
+
def name_for_explicit_dependency_source
|
61
|
+
'user-specified dependency'
|
62
|
+
end
|
63
|
+
|
64
|
+
# @return [String] the name of the source of 'locked' dependencies, i.e.
|
65
|
+
# those passed to {Resolver#resolve} directly as the `base`
|
66
|
+
def name_for_locking_dependency_source
|
67
|
+
'Lockfile'
|
68
|
+
end
|
69
|
+
|
70
|
+
# Sort dependencies so that the ones that are easiest to resolve are first.
|
71
|
+
# Easiest to resolve is (usually) defined by:
|
72
|
+
# 1) Is this dependency already activated?
|
73
|
+
# 2) How relaxed are the requirements?
|
74
|
+
# 3) Are there any conflicts for this dependency?
|
75
|
+
# 4) How many possibilities are there to satisfy this dependency?
|
76
|
+
#
|
77
|
+
# @param [Array<Object>] dependencies
|
78
|
+
# @param [DependencyGraph] activated the current dependency graph in the
|
79
|
+
# resolution process.
|
80
|
+
# @param [{String => Array<Conflict>}] conflicts
|
81
|
+
# @return [Array<Object>] a sorted copy of `dependencies`.
|
82
|
+
def sort_dependencies(dependencies, activated, conflicts)
|
83
|
+
dependencies.sort_by do |dependency|
|
84
|
+
name = name_for(dependency)
|
85
|
+
[
|
86
|
+
activated.vertex_named(name).payload ? 0 : 1,
|
87
|
+
conflicts[name] ? 0 : 1,
|
88
|
+
]
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
# Returns whether this dependency, which has no possible matching
|
93
|
+
# specifications, can safely be ignored.
|
94
|
+
#
|
95
|
+
# @param [Object] dependency
|
96
|
+
# @return [Boolean] whether this dependency can safely be skipped.
|
97
|
+
def allow_missing?(dependency)
|
98
|
+
false
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Bundler::Molinillo
|
4
|
+
# Conveys information about the resolution process to a user.
|
5
|
+
module UI
|
6
|
+
# The {IO} object that should be used to print output. `STDOUT`, by default.
|
7
|
+
#
|
8
|
+
# @return [IO]
|
9
|
+
def output
|
10
|
+
STDOUT
|
11
|
+
end
|
12
|
+
|
13
|
+
# Called roughly every {#progress_rate}, this method should convey progress
|
14
|
+
# to the user.
|
15
|
+
#
|
16
|
+
# @return [void]
|
17
|
+
def indicate_progress
|
18
|
+
output.print '.' unless debug?
|
19
|
+
end
|
20
|
+
|
21
|
+
# How often progress should be conveyed to the user via
|
22
|
+
# {#indicate_progress}, in seconds. A third of a second, by default.
|
23
|
+
#
|
24
|
+
# @return [Float]
|
25
|
+
def progress_rate
|
26
|
+
0.33
|
27
|
+
end
|
28
|
+
|
29
|
+
# Called before resolution begins.
|
30
|
+
#
|
31
|
+
# @return [void]
|
32
|
+
def before_resolution
|
33
|
+
output.print 'Resolving dependencies...'
|
34
|
+
end
|
35
|
+
|
36
|
+
# Called after resolution ends (either successfully or with an error).
|
37
|
+
# By default, prints a newline.
|
38
|
+
#
|
39
|
+
# @return [void]
|
40
|
+
def after_resolution
|
41
|
+
output.puts
|
42
|
+
end
|
43
|
+
|
44
|
+
# Conveys debug information to the user.
|
45
|
+
#
|
46
|
+
# @param [Integer] depth the current depth of the resolution process.
|
47
|
+
# @return [void]
|
48
|
+
def debug(depth = 0)
|
49
|
+
if debug?
|
50
|
+
debug_info = yield
|
51
|
+
debug_info = debug_info.inspect unless debug_info.is_a?(String)
|
52
|
+
debug_info = debug_info.split("\n").map { |s| ":#{depth.to_s.rjust 4}: #{s}" }
|
53
|
+
output.puts debug_info
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# Whether or not debug messages should be printed.
|
58
|
+
# By default, whether or not the `MOLINILLO_DEBUG` environment variable is
|
59
|
+
# set.
|
60
|
+
#
|
61
|
+
# @return [Boolean]
|
62
|
+
def debug?
|
63
|
+
return @debug_mode if defined?(@debug_mode)
|
64
|
+
@debug_mode = ENV['MOLINILLO_DEBUG']
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|