From 5c9dd7792648ae24ea32f6fcb761a082ff5976b6 Mon Sep 17 00:00:00 2001 From: Dimitris Koutsogiorgas Date: Fri, 8 Jan 2021 14:40:01 -0800 Subject: [PATCH] Properly handle incremental installation when sharing schemes --- Gemfile.lock | 2 +- VERSION | 2 +- lib/cocoapods/generate/installer.rb | 1 + spec/cocoapods/generate/installer_spec.rb | 81 +++++++++++++++++++++++ 4 files changed, 84 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index e2e7a91..b3197c5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -39,7 +39,7 @@ GIT PATH remote: . specs: - cocoapods-generate (2.2.0) + cocoapods-generate (2.2.1) cocoapods-disable-podfile-validations (~> 0.1.1) GEM diff --git a/VERSION b/VERSION index ccbccc3..c043eea 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.2.0 +2.2.1 diff --git a/lib/cocoapods/generate/installer.rb b/lib/cocoapods/generate/installer.rb index 5910361..f9fa4ca 100644 --- a/lib/cocoapods/generate/installer.rb +++ b/lib/cocoapods/generate/installer.rb @@ -248,6 +248,7 @@ def perform_post_install_steps(app_project, installer) pod_targets.each do |pod_target| result = installer.target_installation_results.pod_target_installation_results[pod_target.name] + next unless result share_scheme(result.native_target.project, pod_target.label) pod_target.test_specs.each do |test_spec| share_scheme(result.native_target.project, pod_target.test_target_label(test_spec)) diff --git a/spec/cocoapods/generate/installer_spec.rb b/spec/cocoapods/generate/installer_spec.rb index bc0c2f8..5056db1 100644 --- a/spec/cocoapods/generate/installer_spec.rb +++ b/spec/cocoapods/generate/installer_spec.rb @@ -1,6 +1,28 @@ # frozen_string_literal: true RSpec.describe Pod::Generate::Installer do + def pod_target_double(name, platform = Pod::Platform.ios, test_specs = [], app_specs = [], swift_version = nil) + pod_target = double("pod_target_double (#{name})") + allow(pod_target).to receive(:platform).and_return(platform) + allow(pod_target).to receive(:name).and_return(name) + allow(pod_target).to receive(:pod_name).and_return(name) + allow(pod_target).to receive(:label).and_return(name) + allow(pod_target).to receive(:spec_consumers).and_return([]) + allow(pod_target).to receive(:product_module_name).and_return(name) + allow(pod_target).to receive(:should_build?).and_return(true) + allow(pod_target).to receive(:defines_module?).and_return(true) + allow(pod_target).to receive(:swift_version).and_return(swift_version) + allow(pod_target).to receive(:test_specs).and_return(test_specs) + allow(pod_target).to receive(:app_specs).and_return(app_specs) + pod_target + end + + def native_target_double(name, project) + native_target = double("native_target_double (#{name})") + allow(native_target).to receive(:project).and_return(project) + native_target + end + let(:podspecs) { [Pod::Spec.new(nil, 'A'), Pod::Spec.new(nil, 'B')] } let(:lockfile_specs) { [] } let(:gen_directory) { Pathname('./spec/cocoapods/generate/gen') } @@ -24,6 +46,65 @@ FileUtils.rm_rf gen_directory end + describe_method 'perform_post_install_steps' do + let(:app_project) do + app_project = Xcodeproj::Project.new(Pathname.new(gen_directory + 'AppProject.xcodeproj')) + app_project.new_target(:application, 'App-iOS', :ios) + app_project + end + let(:pods_project) do + Xcodeproj::Project.new(Pathname.new(gen_directory + 'Pods/Pods.xcodeproj')) + end + let(:pod_target_a) { pod_target_double('A') } + let(:pod_target_b) { pod_target_double('B') } + let(:native_target_a) { native_target_double('A', pods_project) } + let(:native_target_b) { native_target_double('B', pods_project) } + let(:pod_target_installation_results) do + pod_target_installation_result_a = Pod::Installer::Xcode::PodsProjectGenerator::TargetInstallationResult.new(pod_target_a, native_target_a) + pod_target_installation_result_b = Pod::Installer::Xcode::PodsProjectGenerator::TargetInstallationResult.new(pod_target_b, native_target_b) + { 'A' => pod_target_installation_result_a, 'B' => pod_target_installation_result_b } + end + let(:cocoapods_installer) do + installer = double('cocoapods_installer') + allow(installer).to receive(:pod_targets).and_return([pod_target_a, pod_target_b]) + allow(installer).to receive(:target_installation_results).and_return( + Pod::Installer::Xcode::PodsProjectGenerator::InstallationResults.new(pod_target_installation_results) + ) + installer + end + let(:method_args) { [app_project, cocoapods_installer] } + + context 'scheme sharing' do + it 'shares all schemes if they are present' do + allow(File).to receive(:exist?).with(Xcodeproj::XCScheme.user_data_dir(pods_project.path) + 'A.xcscheme').and_return(true) + allow(File).to receive(:exist?).with(Xcodeproj::XCScheme.user_data_dir(pods_project.path) + 'B.xcscheme').and_return(true) + expect(Xcodeproj::XCScheme).to receive(:share_scheme).with(pods_project.path, 'A') + expect(Xcodeproj::XCScheme).to receive(:share_scheme).with(pods_project.path, 'B') + subject + end + + it 'shares only schemes that exist' do + allow(File).to receive(:exist?).with(Xcodeproj::XCScheme.user_data_dir(pods_project.path) + 'A.xcscheme').and_return(true) + allow(File).to receive(:exist?).with(Xcodeproj::XCScheme.user_data_dir(pods_project.path) + 'B.xcscheme').and_return(false) + expect(Xcodeproj::XCScheme).to receive(:share_scheme).with(pods_project.path, 'A') + expect(Xcodeproj::XCScheme).to receive(:share_scheme).with(pods_project.path, 'B').never + subject + end + + context 'with incremental installation' do + let(:pod_target_installation_results) do + pod_target_installation_result_a = Pod::Installer::Xcode::PodsProjectGenerator::TargetInstallationResult.new(pod_target_a, native_target_a) + { 'A' => pod_target_installation_result_a } + end + it 'shares schemes of pod targets that were installed' do + allow(File).to receive(:exist?).with(Xcodeproj::XCScheme.user_data_dir(pods_project.path) + 'A.xcscheme').and_return(true) + expect(Xcodeproj::XCScheme).to receive(:share_scheme).with(pods_project.path, 'A') + subject + end + end + end + end + describe_method 'create_app_project' do it 'should create all targets across all specs for app project' do expect(subject.targets.map(&:name)).to eq(%w[App-macOS App-iOS App-tvOS App-watchOS])