Use tree-style conflict messages

parent ba9d15ed
......@@ -33,7 +33,7 @@ group :development do
cp_gem 'cocoapods-stats', 'cocoapods-stats'
cp_gem 'cocoapods-trunk', 'cocoapods-trunk'
cp_gem 'cocoapods-try', 'cocoapods-try'
cp_gem 'molinillo', 'Molinillo', path: true
cp_gem 'molinillo', 'Molinillo'
cp_gem 'nanaimo', 'Nanaimo'
cp_gem 'xcodeproj', 'Xcodeproj'
......
......@@ -15,6 +15,13 @@ GIT
fuzzy_match (~> 2.0.4)
nap (~> 1.0)
GIT
remote: https://github.com/CocoaPods/Molinillo.git
revision: 04dd4c8789823654bde00569d28b189a79926c9f
branch: master
specs:
molinillo (0.5.7)
GIT
remote: https://github.com/CocoaPods/Nanaimo.git
revision: c9b1cf5734523cf523497fd6de11f7240fd18944
......@@ -92,11 +99,6 @@ GIT
specs:
json (1.7.7)
PATH
remote: ../Molinillo
specs:
molinillo (0.5.7)
PATH
remote: .
specs:
......@@ -291,4 +293,4 @@ DEPENDENCIES
xcodeproj!
BUNDLED WITH
1.15.2
1.15.3
......@@ -411,64 +411,69 @@ module Pod
# @param [Molinillo::ResolverError] error
#
def handle_resolver_error(error)
message = error.message.dup
message = error.message
type = Informative
case error
when Molinillo::VersionConflict
error.conflicts.each do |name, conflict|
local_pod_parent = conflict.requirement_trees.flatten.reverse.find(&:local?)
lockfile_reqs = conflict.requirements[name_for_locking_dependency_source]
if lockfile_reqs && lockfile_reqs.last && lockfile_reqs.last.prerelease? && !conflict.existing
message = 'Due to the previous naïve CocoaPods resolver, ' \
"you were using a pre-release version of `#{name}`, " \
'without explicitly asking for a pre-release version, which now leads to a conflict. ' \
'Please decide to either use that pre-release version by adding the ' \
'version requirement to your Podfile ' \
"(e.g. `pod '#{name}', '#{lockfile_reqs.map(&:requirement).join("', '")}'`) " \
"or revert to a stable version by running `pod update #{name}`."
elsif local_pod_parent && !specifications_for_dependency(conflict.requirement).empty? && !conflict.possibility && conflict.locked_requirement
# Conflict was caused by a requirement from a local dependency.
# Tell user to use `pod update`.
message << "\n\nIt seems like you've changed the constraints of dependency `#{name}` " \
"inside your development pod `#{local_pod_parent.name}`.\nYou should run `pod update #{name}` to apply " \
"changes you've made."
elsif (conflict.possibility && conflict.possibility.version.prerelease?) &&
(conflict.requirement && !(
conflict.requirement.prerelease? ||
conflict.requirement.external_source)
)
# Conflict was caused by not specifying an explicit version for the requirement #[name],
# and there is no available stable version satisfying constraints for the requirement.
message = "There are only pre-release versions available satisfying the following requirements:\n"
conflict.requirements.values.flatten.each do |r|
unless search_for(r).empty?
message << "\n\t'#{name}', '#{r.requirement}'\n"
message = error.message_with_trees(
:solver_name => 'CocoaPods',
:possibility_type => 'pod',
:version_for_spec => lambda(&:version),
:additional_message_for_conflict => lambda do |o, name, conflict|
local_pod_parent = conflict.requirement_trees.flatten.reverse.find(&:local?)
lockfile_reqs = conflict.requirements[name_for_locking_dependency_source]
if lockfile_reqs && lockfile_reqs.last && lockfile_reqs.last.prerelease? && !conflict.existing
o << "\nDue to the previous naïve CocoaPods resolver, " \
"you were using a pre-release version of `#{name}`, " \
'without explicitly asking for a pre-release version, which now leads to a conflict. ' \
'Please decide to either use that pre-release version by adding the ' \
'version requirement to your Podfile ' \
"(e.g. `pod '#{name}', '#{lockfile_reqs.map(&:requirement).join("', '")}'`) " \
"or revert to a stable version by running `pod update #{name}`."
elsif local_pod_parent && !specifications_for_dependency(conflict.requirement).empty? && !conflict.possibility && conflict.locked_requirement
# Conflict was caused by a requirement from a local dependency.
# Tell user to use `pod update`.
o << "\nIt seems like you've changed the constraints of dependency `#{name}` " \
"inside your development pod `#{local_pod_parent.name}`.\nYou should run `pod update #{name}` to apply " \
"changes you've made."
elsif (conflict.possibility && conflict.possibility.version.prerelease?) &&
(conflict.requirement && !(
conflict.requirement.prerelease? ||
conflict.requirement.external_source)
)
# Conflict was caused by not specifying an explicit version for the requirement #[name],
# and there is no available stable version satisfying constraints for the requirement.
o << "\nThere are only pre-release versions available satisfying the following requirements:\n"
conflict.requirements.values.flatten.each do |r|
unless search_for(r).empty?
o << "\n\t'#{name}', '#{r.requirement}'\n"
end
end
end
message << "\nYou should explicitly specify the version in order to install a pre-release version"
elsif !conflict.existing
conflicts = conflict.requirements.values.flatten.uniq
found_conflicted_specs = conflicts.reject { |c| search_for(c).empty? }
if found_conflicted_specs.empty?
# There are no existing specification inside any of the spec repos with given requirements.
type = NoSpecFoundError
dependencies = conflicts.count == 1 ? 'dependency' : 'dependencies'
message << "\n\nNone of your spec sources contain a spec satisfying "\
"the #{dependencies}: `#{conflicts.join(', ')}`." \
"\n\nYou have either:"
unless specs_updated?
message << "\n * out-of-date source repos which you can update with `pod repo update` or with `pod install --repo-update`."
o << "\nYou should explicitly specify the version in order to install a pre-release version"
elsif !conflict.existing
conflicts = conflict.requirements.values.flatten.uniq
found_conflicted_specs = conflicts.reject { |c| search_for(c).empty? }
if found_conflicted_specs.empty?
# There are no existing specification inside any of the spec repos with given requirements.
type = NoSpecFoundError
dependencies = conflicts.count == 1 ? 'dependency' : 'dependencies'
o << "\nNone of your spec sources contain a spec satisfying "\
"the #{dependencies}: `#{conflicts.join(', ')}`." \
"\n\nYou have either:"
unless specs_updated?
o << "\n * out-of-date source repos which you can update with `pod repo update` or with `pod install --repo-update`."
end
o << "\n * mistyped the name or version." \
"\n * not added the source repo that hosts the Podspec to your Podfile." \
"\n\nNote: as of CocoaPods 1.0, `pod repo update` does not happen on `pod install` by default."
else
o << "\nSpecs satisfying the `#{conflicts.join(', ')}` dependency were found, " \
'but they required a higher minimum deployment target.'
end
message << "\n * mistyped the name or version." \
"\n * not added the source repo that hosts the Podspec to your Podfile." \
"\n\nNote: as of CocoaPods 1.0, `pod repo update` does not happen on `pod install` by default."
else
message << "\n\nSpecs satisfying the `#{conflicts.join(', ')}` dependency were found, " \
'but they required a higher minimum deployment target.'
end
end
end
end,
)
end
raise type, message
end
......
......@@ -349,9 +349,13 @@ module Pod
end
resolver = Resolver.new(config.sandbox, podfile, empty_graph, config.sources_manager.all)
e = lambda { resolver.resolve }.should.raise Informative
e.message.should.match(/Unable to satisfy the following requirements/)
e.message.should.match(/`JSONKit \(= 1.4\)` required by `Podfile`/)
e.message.should.match(/`JSONKit \(= 1.5pre\)` required by `Podfile`/)
e.message.should == <<-EOS.strip
\e[31m[!] CocoaPods could not find compatible versions for pod "JSONKit":
In Podfile:
JSONKit (= 1.4)
JSONKit (= 1.5pre)\e[0m
EOS
end
it 'raises if it finds two conflicting dependencies' do
......@@ -362,9 +366,16 @@ module Pod
end
resolver = Resolver.new(config.sandbox, podfile, empty_graph, config.sources_manager.all)
e = lambda { resolver.resolve }.should.raise Informative
e.message.should.match(/Unable to satisfy the following requirements/)
e.message.should.match(/`AFNetworking \(~> 1.3.0\)` required by `RestKit\/Network \(.*\)`/)
e.message.should.match(/`AFNetworking \(> 2\)` required by `Podfile`/)
e.message.should == <<-EOS.strip
\e[31m[!] CocoaPods could not find compatible versions for pod "AFNetworking":
In Podfile:
AFNetworking (> 2)
RestKit (= 0.23.3) was resolved to 0.23.3, which depends on
RestKit/Core (= 0.23.3) was resolved to 0.23.3, which depends on
RestKit/Network (= 0.23.3) was resolved to 0.23.3, which depends on
AFNetworking (~> 1.3.0)\e[0m
EOS
end
it 'raises if no such version of a dependency exists' do
......@@ -374,14 +385,20 @@ module Pod
end
resolver = Resolver.new(config.sandbox, podfile, empty_graph, config.sources_manager.all)
e = lambda { resolver.resolve }.should.raise NoSpecFoundError
e.message.should.match(/Unable to satisfy the following requirements/)
e.message.should.match(/`AFNetworking \(= 999\.999\.999\)` required by `Podfile`/)
e.message.should.match(/None of your spec sources contain a spec satisfying the dependency: `AFNetworking \(= 999\.999\.999\)`./)
e.message.should.match(/You have either:/)
e.message.should.match(/ * out-of-date source repos which you can update with `pod repo update` or with `pod install --repo-update`./)
e.message.should.match(/ * mistyped the name or version./)
e.message.should.match(/ * not added the source repo that hosts the Podspec to your Podfile./)
e.message.should.match(/Note: as of CocoaPods 1.0, `pod repo update` does not happen on `pod install` by default./)
e.message.should == <<-EOS.strip
\e[31m[!] CocoaPods could not find compatible versions for pod "AFNetworking":
In Podfile:
AFNetworking (= 999.999.999)
None of your spec sources contain a spec satisfying the dependency: `AFNetworking \(= 999\.999\.999\)`.
You have either:
* out-of-date source repos which you can update with `pod repo update` or with `pod install --repo-update`.
* mistyped the name or version.
* not added the source repo that hosts the Podspec to your Podfile.
Note: as of CocoaPods 1.0, `pod repo update` does not happen on `pod install` by default.\e[0m
EOS
e.exit_status.should.equal(31)
end
......@@ -393,14 +410,19 @@ module Pod
resolver = Resolver.new(config.sandbox, podfile, empty_graph, config.sources_manager.all)
resolver.specs_updated = true
e = lambda { resolver.resolve }.should.raise NoSpecFoundError
e.message.should.match(/Unable to satisfy the following requirements/)
e.message.should.match(/`AFNetworking \(= 999\.999\.999\)` required by `Podfile`/)
e.message.should.match(/None of your spec sources contain a spec satisfying the dependency: `AFNetworking \(= 999\.999\.999\)`./)
e.message.should.match(/You have either:/)
e.message.should.not.match(/ * out-of-date source repos which you can update with `pod repo update` or with `pod install --repo-update`./)
e.message.should.match(/ * mistyped the name or version./)
e.message.should.match(/ * not added the source repo that hosts the Podspec to your Podfile./)
e.message.should.match(/Note: as of CocoaPods 1.0, `pod repo update` does not happen on `pod install` by default./)
e.message.should == <<-EOS.strip
\e[31m[!] CocoaPods could not find compatible versions for pod "AFNetworking":
In Podfile:
AFNetworking (= 999.999.999)
None of your spec sources contain a spec satisfying the dependency: `AFNetworking (= 999.999.999)`.
You have either:
* mistyped the name or version.
* not added the source repo that hosts the Podspec to your Podfile.
Note: as of CocoaPods 1.0, `pod repo update` does not happen on `pod install` by default.\e[0m
EOS
e.exit_status.should.equal(31)
end
......@@ -413,16 +435,23 @@ module Pod
resolver = Resolver.new(config.sandbox, podfile, locked_deps, config.sources_manager.all)
e = lambda { resolver.resolve }.should.raise NoSpecFoundError
e.message.should.match(/Unable to satisfy the following requirements/)
e.message.should.match(/`AFNetworking \(= 3.0.1\)` required by `Podfile`/)
e.message.should.match(/`AFNetworking \(= 1.4\)` required by `Podfile.lock`/)
e.message.should.match(/None of your spec sources contain a spec satisfying the dependencies:/)
e.message.should.match(/`AFNetworking \(= 3.0.1\), AFNetworking \(= 1.4\)`/)
e.message.should.match(/You have either:/)
e.message.should.match(/ * out-of-date source repos which you can update with `pod repo update` or with `pod install --repo-update`./)
e.message.should.match(/ * mistyped the name or version./)
e.message.should.match(/ * not added the source repo that hosts the Podspec to your Podfile./)
e.message.should.match(/Note: as of CocoaPods 1.0, `pod repo update` does not happen on `pod install` by default./)
e.message.should == <<-EOS.strip
\e[31m[!] CocoaPods could not find compatible versions for pod "AFNetworking":
In snapshot (Podfile.lock):
AFNetworking (= 1.4)
In Podfile:
AFNetworking (= 3.0.1)
None of your spec sources contain a spec satisfying the dependencies: `AFNetworking (= 3.0.1), AFNetworking (= 1.4)`.
You have either:
* out-of-date source repos which you can update with `pod repo update` or with `pod install --repo-update`.
* mistyped the name or version.
* not added the source repo that hosts the Podspec to your Podfile.
Note: as of CocoaPods 1.0, `pod repo update` does not happen on `pod install` by default.\e[0m
EOS
e.exit_status.should.equal(31)
end
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment