diff --git a/CHANGELOG.md b/CHANGELOG.md index 578a47e29c..9ac6cc3cc6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,14 @@ To install release candidates run `[sudo] gem install cocoapods --pre` [lucasmpaim](https://github.com/lucasmpaim) [#7432](https://github.com/CocoaPods/CocoaPods/issues/7432) +* Option to lint a specified set of test_specs + [Paul Beusterien](https://github.com/paulb777) + [#9392](https://github.com/CocoaPods/CocoaPods/pull/9392) + +* Add --static-frameworks lint option + [Paul Beusterien](https://github.com/paulb777) + [#9632](https://github.com/CocoaPods/CocoaPods/pull/9632) + ##### Bug Fixes * When preserving pod paths, preserve ALL the paths @@ -43,10 +51,6 @@ To install release candidates run `[sudo] gem install cocoapods --pre` ##### Enhancements -* Option to lint a specified set of test_specs - [Paul Beusterien](https://github.com/paulb777) - [#9392](https://github.com/CocoaPods/CocoaPods/pull/9392) - ##### Bug Fixes * Apply correct `SYSTEM_FRAMEWORK_SEARCH_PATHS` for `XCTUnwrap` fix. diff --git a/lib/cocoapods/command/lib/lint.rb b/lib/cocoapods/command/lib/lint.rb index 82698d650a..f497ab1cb0 100644 --- a/lib/cocoapods/command/lib/lint.rb +++ b/lib/cocoapods/command/lib/lint.rb @@ -22,6 +22,7 @@ def self.options ['--fail-fast', 'Lint stops on the first failing platform or subspec'], ['--use-libraries', 'Lint uses static libraries to install the spec'], ['--use-modular-headers', 'Lint uses modular headers during installation'], + ['--use-static-frameworks', 'Lint uses static frameworks during installation'], ["--sources=#{Pod::TrunkSource::TRUNK_REPO_URL}", 'The sources from which to pull dependent pods ' \ "(defaults to #{Pod::TrunkSource::TRUNK_REPO_URL}). Multiple sources must be comma-delimited"], ['--platforms=ios,macos', 'Lint against specific platforms (defaults to all platforms supported by the ' \ @@ -48,6 +49,7 @@ def initialize(argv) @only_subspec = argv.option('subspec') @use_frameworks = !argv.flag?('use-libraries') @use_modular_headers = argv.flag?('use-modular-headers') + @use_static_frameworks = argv.flag?('use-static-frameworks') @source_urls = argv.option('sources', Pod::TrunkSource::TRUNK_REPO_URL).split(',') @platforms = argv.option('platforms', '').split(',') @private = argv.flag?('private', false) @@ -79,6 +81,7 @@ def run validator.only_subspec = @only_subspec validator.use_frameworks = @use_frameworks validator.use_modular_headers = @use_modular_headers + validator.use_static_frameworks = @use_static_frameworks validator.ignore_public_only_results = @private validator.swift_version = @swift_version validator.skip_import_validation = @skip_import_validation diff --git a/lib/cocoapods/command/repo/push.rb b/lib/cocoapods/command/repo/push.rb index 3101ab4fb2..92bdde48bb 100644 --- a/lib/cocoapods/command/repo/push.rb +++ b/lib/cocoapods/command/repo/push.rb @@ -25,6 +25,7 @@ def self.options ['--allow-warnings', 'Allows pushing even if there are warnings'], ['--use-libraries', 'Linter uses static libraries to install the spec'], ['--use-modular-headers', 'Lint uses modular headers during installation'], + ['--use-static-frameworks', 'Lint uses static frameworks during installation'], ["--sources=#{Pod::TrunkSource::TRUNK_REPO_URL}", 'The sources from which to pull dependent pods ' \ '(defaults to all available repos). Multiple sources must be comma-delimited'], ['--local-only', 'Does not perform the step of pushing REPO to its remote'], @@ -49,6 +50,7 @@ def initialize(argv) @podspec = argv.shift_argument @use_frameworks = !argv.flag?('use-libraries') @use_modular_headers = argv.flag?('use-modular-headers', false) + @use_static_frameworks = argv.flag?('use-static-frameworks', false) @private = argv.flag?('private', true) @message = argv.option('commit-message') @commit_message = argv.flag?('commit-message', false) @@ -137,6 +139,7 @@ def validate_podspec_files validator.allow_warnings = @allow_warnings validator.use_frameworks = @use_frameworks validator.use_modular_headers = @use_modular_headers + validator.use_static_frameworks = @use_static_frameworks validator.ignore_public_only_results = @private validator.swift_version = @swift_version validator.skip_import_validation = @skip_import_validation diff --git a/lib/cocoapods/command/spec/lint.rb b/lib/cocoapods/command/spec/lint.rb index e6222443f1..217d18e222 100644 --- a/lib/cocoapods/command/spec/lint.rb +++ b/lib/cocoapods/command/spec/lint.rb @@ -24,6 +24,7 @@ def self.options ['--fail-fast', 'Lint stops on the first failing platform or subspec'], ['--use-libraries', 'Lint uses static libraries to install the spec'], ['--use-modular-headers', 'Lint uses modular headers during installation'], + ['--use-static-frameworks', 'Lint uses static frameworks during installation'], ["--sources=#{Pod::TrunkSource::TRUNK_REPO_URL}", 'The sources from which to pull dependent pods ' \ "(defaults to #{Pod::TrunkSource::TRUNK_REPO_URL}). Multiple sources must be comma-delimited"], ['--platforms=ios,macos', 'Lint against specific platforms (defaults to all platforms supported by the ' \ @@ -47,6 +48,7 @@ def initialize(argv) @only_subspec = argv.option('subspec') @use_frameworks = !argv.flag?('use-libraries') @use_modular_headers = argv.flag?('use-modular-headers') + @use_static_frameworks = argv.flag?('use-static-frameworks') @source_urls = argv.option('sources', Pod::TrunkSource::TRUNK_REPO_URL).split(',') @platforms = argv.option('platforms', '').split(',') @private = argv.flag?('private', false) @@ -72,6 +74,7 @@ def run validator.only_subspec = @only_subspec validator.use_frameworks = @use_frameworks validator.use_modular_headers = @use_modular_headers + validator.use_static_frameworks = @use_static_frameworks validator.ignore_public_only_results = @private validator.swift_version = @swift_version validator.skip_import_validation = @skip_import_validation diff --git a/lib/cocoapods/validator.rb b/lib/cocoapods/validator.rb index 2d3414757b..30071d68b3 100644 --- a/lib/cocoapods/validator.rb +++ b/lib/cocoapods/validator.rb @@ -257,6 +257,10 @@ def failure_reason # attr_accessor :use_modular_headers + # @return [Boolean] Whether static frameworks should be used for the installation. + # + attr_accessor :use_static_frameworks + # @return [Boolean] Whether attributes that affect only public sources # Bool be skipped. # @@ -561,7 +565,7 @@ def deployment_target def download_pod test_spec_names = consumer.spec.test_specs.select { |ts| ts.supported_on_platform?(consumer.platform_name) }.map(&:name) - podfile = podfile_from_spec(consumer.platform_name, deployment_target, use_frameworks, test_spec_names, use_modular_headers) + podfile = podfile_from_spec(consumer.platform_name, deployment_target, use_frameworks, test_spec_names, use_modular_headers, use_static_frameworks) sandbox = Sandbox.new(config.sandbox_root) @installer = Installer.new(sandbox, podfile) @installer.use_default_plugins = false @@ -967,7 +971,7 @@ def initialize(type, attribute_name, message, public_only = false) # @note The generated podfile takes into account whether the linter is # in local mode. # - def podfile_from_spec(platform_name, deployment_target, use_frameworks = true, test_spec_names = [], use_modular_headers = false) + def podfile_from_spec(platform_name, deployment_target, use_frameworks = true, test_spec_names = [], use_modular_headers = false, use_static_frameworks = false) name = subspec_name || spec.name podspec = file.realpath local = local? @@ -982,7 +986,11 @@ def podfile_from_spec(platform_name, deployment_target, use_frameworks = true, t inhibit_all_warnings! urls.each { |u| source(u) } target 'App' do - use_frameworks!(use_frameworks) + if use_static_frameworks + use_frameworks!(:linkage => :static) + else + use_frameworks!(use_frameworks) + end use_modular_headers! if use_modular_headers platform(platform_name, deployment_target) if local diff --git a/spec/functional/command/repo/push_spec.rb b/spec/functional/command/repo/push_spec.rb index 8f892e429a..a6f71d50e0 100644 --- a/spec/functional/command/repo/push_spec.rb +++ b/spec/functional/command/repo/push_spec.rb @@ -204,10 +204,10 @@ module Pod end it 'validates specs as frameworks by default' do - Validator.any_instance.expects(:podfile_from_spec).with(:ios, '8.0', true, [], false).times(3).returns(stub('Podfile')) - Validator.any_instance.expects(:podfile_from_spec).with(:osx, nil, true, [], false).twice.returns(stub('Podfile')) - Validator.any_instance.expects(:podfile_from_spec).with(:watchos, nil, true, [], false).twice.returns(stub('Podfile')) - Validator.any_instance.expects(:podfile_from_spec).with(:tvos, nil, true, [], false).twice.returns(stub('Podfile')) + Validator.any_instance.expects(:podfile_from_spec).with(:ios, '8.0', true, [], false, false).times(3).returns(stub('Podfile')) + Validator.any_instance.expects(:podfile_from_spec).with(:osx, nil, true, [], false, false).twice.returns(stub('Podfile')) + Validator.any_instance.expects(:podfile_from_spec).with(:watchos, nil, true, [], false, false).twice.returns(stub('Podfile')) + Validator.any_instance.expects(:podfile_from_spec).with(:tvos, nil, true, [], false, false).twice.returns(stub('Podfile')) cmd = command('repo', 'push', 'master') # Git push will throw an exception here since this is a local custom git repo. All we care is the validator @@ -218,10 +218,10 @@ module Pod end it 'validates specs as libraries if requested' do - Validator.any_instance.expects(:podfile_from_spec).with(:ios, nil, false, [], false).times(3).returns(stub('Podfile')) - Validator.any_instance.expects(:podfile_from_spec).with(:osx, nil, false, [], false).twice.returns(stub('Podfile')) - Validator.any_instance.expects(:podfile_from_spec).with(:watchos, nil, false, [], false).twice.returns(stub('Podfile')) - Validator.any_instance.expects(:podfile_from_spec).with(:tvos, nil, false, [], false).twice.returns(stub('Podfile')) + Validator.any_instance.expects(:podfile_from_spec).with(:ios, nil, false, [], false, false).times(3).returns(stub('Podfile')) + Validator.any_instance.expects(:podfile_from_spec).with(:osx, nil, false, [], false, false).twice.returns(stub('Podfile')) + Validator.any_instance.expects(:podfile_from_spec).with(:watchos, nil, false, [], false, false).twice.returns(stub('Podfile')) + Validator.any_instance.expects(:podfile_from_spec).with(:tvos, nil, false, [], false, false).twice.returns(stub('Podfile')) cmd = command('repo', 'push', 'master', '--use-libraries') # Git push will throw an exception here since this is a local custom git repo. All we care is the validator @@ -232,10 +232,10 @@ module Pod end it 'validates specs with modular headers if requested' do - Validator.any_instance.expects(:podfile_from_spec).with(:ios, nil, false, [], true).times(3).returns(stub('Podfile')) - Validator.any_instance.expects(:podfile_from_spec).with(:osx, nil, false, [], true).twice.returns(stub('Podfile')) - Validator.any_instance.expects(:podfile_from_spec).with(:watchos, nil, false, [], true).twice.returns(stub('Podfile')) - Validator.any_instance.expects(:podfile_from_spec).with(:tvos, nil, false, [], true).twice.returns(stub('Podfile')) + Validator.any_instance.expects(:podfile_from_spec).with(:ios, nil, false, [], true, false).times(3).returns(stub('Podfile')) + Validator.any_instance.expects(:podfile_from_spec).with(:osx, nil, false, [], true, false).twice.returns(stub('Podfile')) + Validator.any_instance.expects(:podfile_from_spec).with(:watchos, nil, false, [], true, false).twice.returns(stub('Podfile')) + Validator.any_instance.expects(:podfile_from_spec).with(:tvos, nil, false, [], true, false).twice.returns(stub('Podfile')) cmd = command('repo', 'push', 'master', '--use-libraries', '--use-modular-headers') # Git push will throw an exception here since this is a local custom git repo. All we care is the validator @@ -245,6 +245,20 @@ module Pod end.should.raise Informative end + it 'validates specs with static frameworks if requested' do + Validator.any_instance.expects(:podfile_from_spec).with(:ios, '8.0', true, [], false, true).times(3).returns(stub('Podfile')) + Validator.any_instance.expects(:podfile_from_spec).with(:osx, nil, true, [], false, true).twice.returns(stub('Podfile')) + Validator.any_instance.expects(:podfile_from_spec).with(:watchos, nil, true, [], false, true).twice.returns(stub('Podfile')) + Validator.any_instance.expects(:podfile_from_spec).with(:tvos, nil, true, [], false, true).twice.returns(stub('Podfile')) + + cmd = command('repo', 'push', 'master', '--use-static-frameworks') + # Git push will throw an exception here since this is a local custom git repo. All we care is the validator + # tests so the exception is swallowed. + lambda do + Dir.chdir(temporary_directory) { cmd.run } + end.should.raise Informative + end + it 'raises error and exit code when push fails' do cmd = command('repo', 'push', 'master') Pod::TrunkSource.any_instance.stubs(:refresh_metadata) diff --git a/spec/unit/validator_spec.rb b/spec/unit/validator_spec.rb index 1e2b5b02e4..925cfac707 100644 --- a/spec/unit/validator_spec.rb +++ b/spec/unit/validator_spec.rb @@ -400,8 +400,8 @@ def podspec_path(name = 'JSONKit', version = '1.4') end Installer.any_instance.stubs(:aggregate_targets).returns([]) Installer.any_instance.stubs(:pod_targets).returns([]) - validator.expects(:podfile_from_spec).with(:osx, nil, false, [], nil).once.returns(stub('Podfile')) - validator.expects(:podfile_from_spec).with(:ios, nil, false, ['JSONKit/Tests'], nil).once.returns(stub('Podfile')) + validator.expects(:podfile_from_spec).with(:osx, nil, false, [], nil, nil).once.returns(stub('Podfile')) + validator.expects(:podfile_from_spec).with(:ios, nil, false, ['JSONKit/Tests'], nil, nil).once.returns(stub('Podfile')) validator.validate end @@ -590,11 +590,11 @@ def podspec_path(name = 'JSONKit', version = '1.4') s.ios.deployment_target = '7.0' end validator.spec.stubs(:subspecs).returns([subspec]) - validator.expects(:podfile_from_spec).with(:osx, nil, false, [], nil).once.returns(stub('Podfile')) - validator.expects(:podfile_from_spec).with(:ios, nil, false, [], nil).once.returns(stub('Podfile')) - validator.expects(:podfile_from_spec).with(:ios, '7.0', false, [], nil).once.returns(stub('Podfile')) - validator.expects(:podfile_from_spec).with(:tvos, nil, false, [], nil).once.returns(stub('Podfile')) - validator.expects(:podfile_from_spec).with(:watchos, nil, false, [], nil).once.returns(stub('Podfile')) + validator.expects(:podfile_from_spec).with(:osx, nil, false, [], nil, nil).once.returns(stub('Podfile')) + validator.expects(:podfile_from_spec).with(:ios, nil, false, [], nil, nil).once.returns(stub('Podfile')) + validator.expects(:podfile_from_spec).with(:ios, '7.0', false, [], nil, nil).once.returns(stub('Podfile')) + validator.expects(:podfile_from_spec).with(:tvos, nil, false, [], nil, nil).once.returns(stub('Podfile')) + validator.expects(:podfile_from_spec).with(:watchos, nil, false, [], nil, nil).once.returns(stub('Podfile')) validator.send(:perform_extensive_analysis, validator.spec) validator.results_message.strip.should.be.empty @@ -632,6 +632,14 @@ def podspec_path(name = 'JSONKit', version = '1.4') podfile = @validator.send(:podfile_from_spec, :ios, '5.0', false, [], true) target_definition = podfile.target_definitions['App'] target_definition.use_modular_headers_hash['all'].should.be.true + target_definition.uses_frameworks?.should == false + end + + it 'validates with --use-static-frameworks' do + podfile = @validator.send(:podfile_from_spec, :ios, '5.0', false, [], false, true) + target_definition = podfile.target_definitions['App'] + target_definition.uses_frameworks?.should == true + target_definition.use_frameworks!.should == { :linkage => :dynamic, :packaging => :framework } end it 'inhibits warnings for all pods except the one being validated' do @@ -1087,10 +1095,10 @@ def setup_validator setup_validator - @validator.expects(:podfile_from_spec).with(:osx, nil, true, [], nil).once.returns(stub('Podfile')) - @validator.expects(:podfile_from_spec).with(:ios, '8.0', true, [], nil).once.returns(stub('Podfile')) - @validator.expects(:podfile_from_spec).with(:tvos, nil, true, [], nil).once.returns(stub('Podfile')) - @validator.expects(:podfile_from_spec).with(:watchos, nil, true, [], nil).once.returns(stub('Podfile')) + @validator.expects(:podfile_from_spec).with(:osx, nil, true, [], nil, nil).once.returns(stub('Podfile')) + @validator.expects(:podfile_from_spec).with(:ios, '8.0', true, [], nil, nil).once.returns(stub('Podfile')) + @validator.expects(:podfile_from_spec).with(:tvos, nil, true, [], nil, nil).once.returns(stub('Podfile')) + @validator.expects(:podfile_from_spec).with(:watchos, nil, true, [], nil, nil).once.returns(stub('Podfile')) @validator.send(:perform_extensive_analysis, @validator.spec) @validator.results_message.strip.should.be.empty @@ -1101,10 +1109,10 @@ def setup_validator setup_validator - @validator.expects(:podfile_from_spec).with(:osx, nil, false, [], nil).once.returns(stub('Podfile')) - @validator.expects(:podfile_from_spec).with(:ios, nil, false, [], nil).once.returns(stub('Podfile')) - @validator.expects(:podfile_from_spec).with(:tvos, nil, false, [], nil).once.returns(stub('Podfile')) - @validator.expects(:podfile_from_spec).with(:watchos, nil, false, [], nil).once.returns(stub('Podfile')) + @validator.expects(:podfile_from_spec).with(:osx, nil, false, [], nil, nil).once.returns(stub('Podfile')) + @validator.expects(:podfile_from_spec).with(:ios, nil, false, [], nil, nil).once.returns(stub('Podfile')) + @validator.expects(:podfile_from_spec).with(:tvos, nil, false, [], nil, nil).once.returns(stub('Podfile')) + @validator.expects(:podfile_from_spec).with(:watchos, nil, false, [], nil, nil).once.returns(stub('Podfile')) @validator.send(:perform_extensive_analysis, @validator.spec) @validator.results_message.strip.should.be.empty