# The CocoaPods check command. # The CocoaPods namespace module Pod class Command class Check < Command self.summary = <<-SUMMARY Displays which Pods would be changed by running `pod install` SUMMARY self.description = <<-DESC Compares the Pod lockfile with the manifest lockfile and shows any differences. In non-verbose mode, '~' indicates an existing Pod will be updated to the version specified in Podfile.lock, '+' indicates a missing Pod will be installed, and 'Δ' indicates a Pod is a development Pod. Development Pods are always considered to need installation. DESC self.arguments = [] def self.options [ ['--verbose', 'Show change details.'] ].concat(super) end def initialize(argv) @check_command_verbose = argv.flag?('verbose') super end def run unless config.lockfile raise Informative, 'Missing Podfile.lock!' end development_pods = find_development_pods(config.podfile) results = find_differences(config, development_pods) print_results(results) end def find_development_pods(podfile) development_pods = {} podfile.dependencies.each do |dependency| development_pods[dependency.name] = dependency.external_source if dependency.external? end development_pods end def find_differences(config, development_pods) all_pod_names = config.lockfile.pod_names all_pod_names.concat development_pods.keys all_pod_names.sort.uniq.map do |spec_name| locked_version = config.lockfile.version(spec_name) # If no manifest, assume Pod hasn't been installed if config.sandbox.manifest manifest_version = config.sandbox.manifest.version(spec_name) else manifest_version = nil end # If this Pod is installed if manifest_version if development_pods[spec_name] != nil if is_development_pod_modified?(config, development_pods[spec_name]) changed_result(spec_name, manifest_version, locked_version) end elsif locked_version != manifest_version changed_result(spec_name, manifest_version, locked_version) end # If this Pod is not installed else added_result(spec_name) end end.compact end def is_development_pod_modified?(config, development_pod) development_podspec_file = development_pod[:path] development_pod_dir = File.dirname(development_podspec_file) spec = Specification.from_file(development_podspec_file) # Gather all the dependencies used by the spec, across all platforms, and including subspecs. all_files = [spec, spec.subspecs].flatten.map { |a_spec| a_spec.available_platforms.map { |platform| accessor = Sandbox::FileAccessor.new(Sandbox::PathList.new(Pathname.new(development_pod_dir)), a_spec.consumer(platform)) [ accessor.vendored_frameworks, accessor.vendored_libraries, accessor.resource_bundle_files, accessor.license, accessor.prefix_header, accessor.preserve_paths, accessor.readme, accessor.resources, accessor.source_files ].compact } }.flatten # Also check the podspec date all_files.push(development_podspec_file) latest_modified_file = all_files.max_by {|f| File.mtime(f)} if latest_modified_file pod_mtime = File.mtime(latest_modified_file) manifest_mtime = File.mtime(config.lockfile.defined_in_file) pod_mtime >= manifest_mtime else false end end def changed_result(spec_name, manifest_version, locked_version) if @check_command_verbose "#{spec_name} #{manifest_version} -> #{locked_version}" else "~#{spec_name}" end end def added_result(spec_name) if @check_command_verbose "#{spec_name} newly added" else "+#{spec_name}" end end def print_results(results) return UI.puts "The Podfile's dependencies are satisfied" if results.empty? if @check_command_verbose UI.puts results.join("\n") else UI.puts results.join(', ') end raise Informative, "`pod install` will install #{results.length} Pod#{'s' if results.length > 1}." end end end end