@@ -95,6 +95,7 @@ def initialize(lockfile, dependencies, sources, unlock, ruby_version = nil, opti
9595 @locked_ruby_version = nil
9696 @new_platforms = [ ]
9797 @removed_platforms = [ ]
98+ @originally_invalid_platforms = [ ]
9899
99100 if lockfile_exists?
100101 @lockfile_contents = Bundler . read_file ( lockfile )
@@ -147,9 +148,8 @@ def initialize(lockfile, dependencies, sources, unlock, ruby_version = nil, opti
147148
148149 @current_platform_missing = add_current_platform unless Bundler . frozen_bundle?
149150
150- converge_path_sources_to_gemspec_sources
151- @path_changes = converge_paths
152151 @source_changes = converge_sources
152+ @path_changes = converge_paths
153153
154154 if conservative
155155 @gems_to_unlock = @explicit_unlocks . any? ? @explicit_unlocks : @dependencies . map ( &:name )
@@ -539,12 +539,13 @@ def lockfile_changes_summary(update_refused_reason)
539539
540540 reason = resolve_needed? ? change_reason : "some dependencies were deleted from your gemfile"
541541
542- msg = String . new
543- msg << "#{ reason . capitalize . strip } , but the lockfile can't be updated because #{ update_refused_reason } "
542+ msg = String . new ( "#{ reason . capitalize . strip } , but " )
543+ msg << "the lockfile " unless msg . start_with? ( "Your lockfile" )
544+ msg << "can't be updated because #{ update_refused_reason } "
544545 msg << "\n \n You have added to the Gemfile:\n " << added . join ( "\n " ) if added . any?
545546 msg << "\n \n You have deleted from the Gemfile:\n " << deleted . join ( "\n " ) if deleted . any?
546547 msg << "\n \n You have changed in the Gemfile:\n " << changed . join ( "\n " ) if changed . any?
547- msg << "\n \n Run `bundle install` elsewhere and add the updated #{ SharedHelpers . relative_gemfile_path } to version control.\n " unless unlocking?
548+ msg << "\n \n Run `bundle install` elsewhere and add the updated #{ SharedHelpers . relative_lockfile_path } to version control.\n " unless unlocking?
548549 msg
549550 end
550551
@@ -563,6 +564,7 @@ def something_changed?
563564 @local_changes ||
564565 @missing_lockfile_dep ||
565566 @unlocking_bundler ||
567+ @locked_spec_with_missing_checksums ||
566568 @locked_spec_with_missing_deps ||
567569 @locked_spec_with_invalid_deps
568570 end
@@ -759,7 +761,11 @@ def start_resolution
759761 end
760762 end
761763
762- @platforms = result . add_extra_platforms! ( platforms ) if should_add_extra_platforms?
764+ if should_add_extra_platforms?
765+ result . add_extra_platforms! ( platforms )
766+ elsif @originally_invalid_platforms . any?
767+ result . add_originally_invalid_platforms! ( platforms , @originally_invalid_platforms )
768+ end
763769
764770 SpecSet . new ( result . for ( dependencies , @platforms | [ Gem ::Platform ::RUBY ] ) )
765771 end
@@ -809,13 +815,14 @@ def change_reason
809815 [
810816 [ @source_changes , "the list of sources changed" ] ,
811817 [ @dependency_changes , "the dependencies in your gemfile changed" ] ,
812- [ @current_platform_missing , "your lockfile does not include the current platform" ] ,
818+ [ @current_platform_missing , "your lockfile is missing the current platform" ] ,
813819 [ @new_platforms . any? , "you are adding a new platform to your lockfile" ] ,
814820 [ @path_changes , "the gemspecs for path gems changed" ] ,
815821 [ @local_changes , "the gemspecs for git local gems changed" ] ,
816- [ @missing_lockfile_dep , "your lock file is missing \" #{ @missing_lockfile_dep } \" " ] ,
822+ [ @missing_lockfile_dep , "your lockfile is missing \" #{ @missing_lockfile_dep } \" " ] ,
817823 [ @unlocking_bundler , "an update to the version of Bundler itself was requested" ] ,
818- [ @locked_spec_with_missing_deps , "your lock file includes \" #{ @locked_spec_with_missing_deps } \" but not some of its dependencies" ] ,
824+ [ @locked_spec_with_missing_checksums , "your lockfile is missing a CHECKSUMS entry for \" #{ @locked_spec_with_missing_checksums } \" " ] ,
825+ [ @locked_spec_with_missing_deps , "your lockfile includes \" #{ @locked_spec_with_missing_deps } \" but not some of its dependencies" ] ,
819826 [ @locked_spec_with_invalid_deps , "your lockfile does not satisfy dependencies of \" #{ @locked_spec_with_invalid_deps } \" " ] ,
820827 ] . select ( &:first ) . map ( &:last ) . join ( ", " )
821828 end
@@ -832,16 +839,16 @@ def specs_changed?(source)
832839 !locked || dependencies_for_source_changed? ( source , locked ) || specs_for_source_changed? ( source )
833840 end
834841
835- def dependencies_for_source_changed? ( source , locked_source = source )
836- deps_for_source = @dependencies . select { |s | s . source == source }
842+ def dependencies_for_source_changed? ( source , locked_source )
843+ deps_for_source = @dependencies . select { |dep | dep . source == source }
837844 locked_deps_for_source = locked_dependencies . select { |dep | dep . source == locked_source }
838845
839846 deps_for_source . uniq . sort != locked_deps_for_source . sort
840847 end
841848
842849 def specs_for_source_changed? ( source )
843850 locked_index = Index . new
844- locked_index . use ( @locked_specs . select { |s | source . can_lock? ( s ) } )
851+ locked_index . use ( @locked_specs . select { |s | s . replace_source_with! ( source ) } )
845852
846853 !locked_index . subset? ( source . specs )
847854 rescue PathError , GitError => e
@@ -873,21 +880,27 @@ def converge_locals
873880 def check_lockfile
874881 @locked_spec_with_invalid_deps = nil
875882 @locked_spec_with_missing_deps = nil
883+ @locked_spec_with_missing_checksums = nil
876884
877- missing = [ ]
885+ missing_deps = [ ]
886+ missing_checksums = [ ]
878887 invalid = [ ]
879888
880889 @locked_specs . each do |s |
890+ missing_checksums << s if @locked_checksums && s . source . checksum_store . missing? ( s )
891+
881892 validation = @locked_specs . validate_deps ( s )
882893
883- missing << s if validation == :missing
894+ missing_deps << s if validation == :missing
884895 invalid << s if validation == :invalid
885896 end
886897
887- if missing . any?
888- @locked_specs . delete ( missing )
898+ @locked_spec_with_missing_checksums = missing_checksums . first . name if missing_checksums . any?
889899
890- @locked_spec_with_missing_deps = missing . first . name
900+ if missing_deps . any?
901+ @locked_specs . delete ( missing_deps )
902+
903+ @locked_spec_with_missing_deps = missing_deps . first . name
891904 end
892905
893906 if invalid . any?
@@ -903,24 +916,6 @@ def converge_paths
903916 end
904917 end
905918
906- def converge_path_source_to_gemspec_source ( source )
907- return source unless source . instance_of? ( Source ::Path )
908- gemspec_source = sources . path_sources . find { |s | s . is_a? ( Source ::Gemspec ) && s . as_path_source == source }
909- gemspec_source || source
910- end
911-
912- def converge_path_sources_to_gemspec_sources
913- @locked_sources . map! do |source |
914- converge_path_source_to_gemspec_source ( source )
915- end
916- @locked_specs . each do |spec |
917- spec . source &&= converge_path_source_to_gemspec_source ( spec . source )
918- end
919- @locked_deps . each do |_ , dep |
920- dep . source &&= converge_path_source_to_gemspec_source ( dep . source )
921- end
922- end
923-
924919 def converge_sources
925920 # Replace the sources from the Gemfile with the sources from the Gemfile.lock,
926921 # if they exist in the Gemfile.lock and are `==`. If you can't find an equivalent
@@ -963,11 +958,17 @@ def converge_dependencies
963958 unless name == "bundler"
964959 locked_specs = @originally_locked_specs [ name ]
965960
966- if locked_specs . any? && !dep . matches_spec? ( locked_specs . first )
967- @gems_to_unlock << name
968- dep_changed = true
969- elsif locked_specs . empty? && dep_changed == false
970- @missing_lockfile_dep = name
961+ if locked_specs . empty?
962+ @missing_lockfile_dep = name if dep_changed == false
963+ else
964+ if locked_specs . map ( &:source ) . uniq . size > 1
965+ @locked_specs . delete ( locked_specs . select { |s | s . source != dep . source } )
966+ end
967+
968+ unless dep . matches_spec? ( locked_specs . first )
969+ @gems_to_unlock << name
970+ dep_changed = true
971+ end
971972 end
972973 end
973974
@@ -1141,16 +1142,21 @@ def dup_for_full_unlock
11411142 def remove_invalid_platforms!
11421143 return if Bundler . frozen_bundle?
11431144
1144- platforms . reverse_each do |platform |
1145+ @originally_invalid_platforms = platforms . select do |platform |
11451146 next if local_platform == platform ||
1146- @new_platforms . include? ( platform ) ||
1147- @path_changes ||
1148- @dependency_changes ||
1149- @locked_spec_with_invalid_deps ||
1150- !spec_set_incomplete_for_platform? ( @originally_locked_specs , platform )
1147+ @new_platforms . include? ( platform )
11511148
1152- remove_platform ( platform )
1149+ # We should probably avoid removing non-ruby platforms, since that means
1150+ # lockfile will no longer install on those platforms, so a error to give
1151+ # heads up to the user may be better. However, we have tests expecting
1152+ # non ruby platform autoremoval to work, so leaving that in place for
1153+ # now.
1154+ next if @dependency_changes && platform != Gem ::Platform ::RUBY
1155+
1156+ spec_set_incomplete_for_platform? ( @originally_locked_specs , platform )
11531157 end
1158+
1159+ @platforms -= @originally_invalid_platforms
11541160 end
11551161
11561162 def spec_set_incomplete_for_platform? ( spec_set , platform )
0 commit comments