diff --git a/.kick b/.kick index ba565b2..fb88a84 100644 --- a/.kick +++ b/.kick @@ -6,7 +6,7 @@ process do |files| specs = files.take_and_map do |file| if file =~ %r{lib/cocoapods/(.+?)\.rb$} s = Dir.glob("spec/**/#{File.basename(file, '.rb')}_spec.rb") - if file =~ %r{lib/cocoapods/installer.+\.rb$} + if file =~ %r{lib/cocoapods/installer.*\.rb$} s.concat(['spec/unit/installer_spec.rb', 'spec/unit/installer/target_installer_spec.rb']) end s.uniq unless s.empty? diff --git a/TODO b/TODO index 6248119..46ade36 100644 --- a/TODO +++ b/TODO @@ -6,3 +6,4 @@ * Validate that the dependencies in the targets don't conflict. E.g. two different versions of the same pod. * Move Podfile.lock generator from Installer into its own file. * Remove better_installer.rb file +* One or more of the specs are changing the remote URL of the master repo in ~/.cocoapods diff --git a/lib/cocoapods/command/install.rb b/lib/cocoapods/command/install.rb index 9005003..e2ad7d7 100644 --- a/lib/cocoapods/command/install.rb +++ b/lib/cocoapods/command/install.rb @@ -24,18 +24,20 @@ module Pod end def self.options - " --no-clean Leave SCM dirs like `.git' and `.svn' intact after downloading\n" + - " --no-doc Skip documentation generation with appledoc\n" + - " --force-doc Force the generation of documentation\n" + - " --no-update Skip running `pod repo update` before install\n" + + " --no-clean Leave SCM dirs like `.git' and `.svn' in tact after downloading\n" + + " --no-doc Skip documentation generation with appledoc\n" + + " --force-doc Force the generation of documentation\n" + + " --no-integrate Skip integration of the Pods libraries in the Xcode project(s)\n" + + " --no-update Skip running `pod repo update` before install\n" + super end def initialize(argv) - config.clean = !argv.option('--no-clean') - config.doc = !argv.option('--no-doc') - config.force_doc = argv.option('--force-doc') - @update_repo = !argv.option('--no-update') + config.clean = !argv.option('--no-clean') + config.doc = !argv.option('--no-doc') + config.force_doc = argv.option('--force-doc') + config.integrate_targets = !argv.option('--no-integrate') + @update_repo = !argv.option('--no-update') super unless argv.empty? end @@ -44,15 +46,17 @@ module Pod raise Informative, "No `Podfile' found in the current working directory." end - # TODO this should be done for all targets (?) - if xcodeproj = podfile.target_definitions[:default].xcodeproj - raise Informative, "Please specify a valid xcodeproj path in your Podfile.\n\n" + - "Usage:\n\t" + - "xcodeproj 'path/to/project.xcodeproj'" - end + if config.integrate_targets? + # TODO this should be done for all targets (?) + unless xcodeproj = podfile.target_definitions[:default].xcodeproj + raise Informative, "Please specify a valid xcodeproj path in your Podfile.\n\n" + + "Usage:\n\t" + + "xcodeproj 'path/to/project.xcodeproj'" + end - if xcodeproj && !xcodeproj.exist? - raise Informative, "The specified project `#{xcodeproj}' does not exist." + if xcodeproj && !xcodeproj.exist? + raise Informative, "The specified project `#{xcodeproj}' does not exist." + end end if @update_repo diff --git a/lib/cocoapods/config.rb b/lib/cocoapods/config.rb index eb00a31..66bf169 100644 --- a/lib/cocoapods/config.rb +++ b/lib/cocoapods/config.rb @@ -10,18 +10,19 @@ module Pod @instance = instance end - attr_accessor :repos_dir, :project_root, :project_pods_root, :clean, :verbose, :silent, :doc, :doc_install, :force_doc - alias_method :clean?, :clean - alias_method :verbose?, :verbose - alias_method :silent?, :silent - alias_method :doc?, :doc - alias_method :doc_install?, :doc_install - alias_method :force_doc?, :force_doc + attr_accessor :repos_dir, :project_root, :project_pods_root, :clean, :verbose, :silent, :doc, :doc_install, :force_doc, :integrate_targets + alias_method :clean?, :clean + alias_method :verbose?, :verbose + alias_method :silent?, :silent + alias_method :doc?, :doc # TODO rename to generate_docs? + alias_method :doc_install?, :doc_install + alias_method :force_doc?, :force_doc + alias_method :integrate_targets?, :integrate_targets def initialize @repos_dir = Pathname.new(File.expand_path("~/.cocoapods")) @verbose = @silent = @force_doc = false - @clean = @doc = @doc_install = true + @clean = @doc = @doc_install = @integrate_targets = true end def project_root diff --git a/lib/cocoapods/installer.rb b/lib/cocoapods/installer.rb index 7fada5f..d8e66b5 100644 --- a/lib/cocoapods/installer.rb +++ b/lib/cocoapods/installer.rb @@ -91,8 +91,7 @@ module Pod puts "* Writing Xcode project file to `#{@sandbox.project_path}'\n\n" if config.verbose? project.save_as(@sandbox.project_path) - # The conditional is actually only so we omit the integration when running the specs. - UserProjectIntegrator.new(@podfile).integrate! if @podfile.xcodeproj(false) + UserProjectIntegrator.new(@podfile).integrate! if config.integrate_targets? end def run_post_install_hooks diff --git a/lib/cocoapods/installer/user_project_integrator.rb b/lib/cocoapods/installer/user_project_integrator.rb index 2dffbfd..024931d 100644 --- a/lib/cocoapods/installer/user_project_integrator.rb +++ b/lib/cocoapods/installer/user_project_integrator.rb @@ -85,18 +85,20 @@ module Pod # the Pods lib should be linked with. def targets @targets ||= begin - if link_with = @target_definition.link_with - user_project.targets.select do |target| - link_with.include? target.name - end - else - [user_project.targets.first] - end.reject do |target| - # reject any target that already has this Pods library in one of its frameworks build phases - target.frameworks_build_phases.any? do |phase| - phase.files.any? { |file| file.name == @target_definition.lib_name } - end + if link_with = @target_definition.link_with + # Find explicitly named targets. + user_project.targets.select do |target| + link_with.include? target.name end + else + # Default to the first, which in a simple project is probably an app target. + [user_project.targets.first] + end.reject do |target| + # Reject any target that already has this Pods library in one of its frameworks build phases + target.frameworks_build_phases.any? do |phase| + phase.files.any? { |file| file.name == @target_definition.lib_name } + end + end end end diff --git a/spec/functional/user_project_integrator_spec.rb b/spec/functional/user_project_integrator_spec.rb index 17d4b36..01cda51 100644 --- a/spec/functional/user_project_integrator_spec.rb +++ b/spec/functional/user_project_integrator_spec.rb @@ -39,7 +39,7 @@ describe Pod::Installer::UserProjectIntegrator do it 'adds the project being integrated to the workspace' do workspace = Xcodeproj::Workspace.new_from_xcworkspace(@sample_project_path.dirname + "SampleProject.xcworkspace") - workspace.should.include?("SampleProject.xcodeproj") + workspace.projpaths.sort.should == %w{ Pods/Pods.xcodeproj SampleProject.xcodeproj } end it 'adds the Pods project to the workspace' do @@ -82,22 +82,27 @@ describe Pod::Installer::UserProjectIntegrator do end end + before do + # Reset the cached TargetIntegrator#targets lists. + @integrator.instance_variable_set(:@target_integrators, nil) + end + it "only tries to integrate Pods libraries into user targets that haven't been integrated yet" do - app, test_runner = @integrator.target_integrators.first.user_project.targets.to_a - p app.frameworks_build_phases.first.files - test_runner.frameworks_build_phases.first.build_files.last.destroy - #p app, test_runner + app_integrator = @integrator.target_integrators.find { |t| t.target_definition.name == :default } + test_runner_integrator = @integrator.target_integrators.find { |t| t.target_definition.name == :test_runner } - target_integrators = @integrator.target_integrators.sort_by { |target| target.target_definition.label } - @integrator.stubs(:target_integrators).returns(target_integrators) - #p target_integrators + # Remove libPods.a from the app target. But don't do it through TargetIntegrator#targets, + # as it will return only those that still need integration. + app_target = app_integrator.user_project.targets.where(:name => 'SampleProject') + app_target.frameworks_build_phases.first.build_files.last.destroy + + app_integrator.expects(:add_pods_library) + test_runner_integrator.expects(:add_pods_library).never - target_integrators.first.expects(:add_pods_library).never - target_integrators.last.expects(:add_pods_library) @integrator.integrate! end - xit "does not even try to save the project if none of the target integrators had any work to do" do + it "does not even try to save the project if none of the target integrators had any work to do" do @integrator.target_integrators.first.user_project.expects(:save_as).never @integrator.integrate! end diff --git a/spec/integration_spec.rb b/spec/integration_spec.rb index 75128a7..fc237ac 100644 --- a/spec/integration_spec.rb +++ b/spec/integration_spec.rb @@ -37,6 +37,7 @@ else config.repos_dir = fixture('spec-repos') config.project_root = temporary_directory config.doc_install = false + config.integrate_targets = false end before do @@ -364,6 +365,8 @@ else end it "sets up an existing project with pods" do + config.integrate_targets = true + basename = platform == :ios ? 'iPhone' : 'Mac' projpath = temporary_directory + 'ASIHTTPRequest.xcodeproj' FileUtils.cp_r(fixture("integration/ASIHTTPRequest/#{basename}.xcodeproj"), projpath) diff --git a/spec/unit/command/install_command_spec.rb b/spec/unit/command/install_command_spec.rb index 451d017..eff51f9 100644 --- a/spec/unit/command/install_command_spec.rb +++ b/spec/unit/command/install_command_spec.rb @@ -36,12 +36,16 @@ describe "Pod::Command::Install" do describe "When the Podfile specifies xcodeproj to an invalid path" do before do - config.stubs(:podfile).returns(Pod::Podfile.new { platform :ios; xcodeproj 'nonexistent/project.xcodeproj'; dependency 'AFNetworking'}) + config.stubs(:podfile).returns(Pod::Podfile.new do + platform :ios + xcodeproj 'nonexistent/project.xcodeproj' + dependency 'AFNetworking' + end) @installer = Pod::Command::Install.new(Pod::Command::ARGV.new) end it "raises an informative error" do - should.raise(Pod::Informative) {@installer.run} + should.raise(Pod::Informative) { @installer.run } end it "should include an informative message" do