cocoapods 1.10.0 → 1.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +571 -7
  3. data/README.md +10 -11
  4. data/bin/sandbox-pod +1 -1
  5. data/lib/cocoapods/command/lib/lint.rb +4 -1
  6. data/lib/cocoapods/command/outdated.rb +12 -1
  7. data/lib/cocoapods/command/repo/push.rb +20 -0
  8. data/lib/cocoapods/command/setup.rb +2 -2
  9. data/lib/cocoapods/command/spec/cat.rb +3 -1
  10. data/lib/cocoapods/command/spec/create.rb +1 -0
  11. data/lib/cocoapods/command/spec/lint.rb +4 -1
  12. data/lib/cocoapods/command/spec/which.rb +3 -1
  13. data/lib/cocoapods/command/spec.rb +18 -9
  14. data/lib/cocoapods/config.rb +8 -7
  15. data/lib/cocoapods/downloader/cache.rb +98 -6
  16. data/lib/cocoapods/downloader.rb +4 -2
  17. data/lib/cocoapods/executable.rb +1 -1
  18. data/lib/cocoapods/external_sources/abstract_external_source.rb +1 -1
  19. data/lib/cocoapods/external_sources/path_source.rb +1 -1
  20. data/lib/cocoapods/external_sources/podspec_source.rb +1 -1
  21. data/lib/cocoapods/gem_version.rb +1 -1
  22. data/lib/cocoapods/generator/acknowledgements.rb +13 -1
  23. data/lib/cocoapods/generator/app_target_helper.rb +8 -4
  24. data/lib/cocoapods/generator/copy_dsyms_script.rb +4 -4
  25. data/lib/cocoapods/generator/copy_resources_script.rb +2 -1
  26. data/lib/cocoapods/generator/copy_xcframework_script.rb +52 -70
  27. data/lib/cocoapods/generator/embed_frameworks_script.rb +4 -3
  28. data/lib/cocoapods/generator/info_plist_file.rb +1 -1
  29. data/lib/cocoapods/generator/script_phase_constants.rb +1 -0
  30. data/lib/cocoapods/installer/analyzer/analysis_result.rb +3 -3
  31. data/lib/cocoapods/installer/analyzer/pod_variant.rb +1 -1
  32. data/lib/cocoapods/installer/analyzer/sandbox_analyzer.rb +38 -10
  33. data/lib/cocoapods/installer/analyzer.rb +21 -13
  34. data/lib/cocoapods/installer/base_install_hooks_context.rb +19 -4
  35. data/lib/cocoapods/installer/installation_options.rb +11 -0
  36. data/lib/cocoapods/installer/pod_source_downloader.rb +159 -0
  37. data/lib/cocoapods/installer/pod_source_installer.rb +10 -36
  38. data/lib/cocoapods/installer/podfile_validator.rb +2 -2
  39. data/lib/cocoapods/installer/pre_integrate_hooks_context.rb +9 -0
  40. data/lib/cocoapods/installer/project_cache/project_cache_analyzer.rb +14 -7
  41. data/lib/cocoapods/installer/project_cache/project_installation_cache.rb +15 -2
  42. data/lib/cocoapods/installer/project_cache/target_cache_key.rb +48 -7
  43. data/lib/cocoapods/installer/user_project_integrator/target_integrator.rb +150 -9
  44. data/lib/cocoapods/installer/xcode/pods_project_generator/app_host_installer.rb +11 -3
  45. data/lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb +62 -9
  46. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_dependency_installer.rb +6 -19
  47. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_installer.rb +86 -59
  48. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_integrator.rb +48 -6
  49. data/lib/cocoapods/installer/xcode/pods_project_generator/project_generator.rb +3 -1
  50. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installation_result.rb +2 -2
  51. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installer.rb +8 -5
  52. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installer_helper.rb +9 -3
  53. data/lib/cocoapods/installer/xcode/pods_project_generator.rb +37 -2
  54. data/lib/cocoapods/installer/xcode/target_validator.rb +1 -1
  55. data/lib/cocoapods/installer.rb +150 -34
  56. data/lib/cocoapods/native_target_extension.rb +1 -1
  57. data/lib/cocoapods/open-uri.rb +1 -1
  58. data/lib/cocoapods/project.rb +8 -8
  59. data/lib/cocoapods/resolver/resolver_specification.rb +1 -1
  60. data/lib/cocoapods/resolver.rb +7 -7
  61. data/lib/cocoapods/sandbox/file_accessor.rb +67 -11
  62. data/lib/cocoapods/sandbox/headers_store.rb +3 -1
  63. data/lib/cocoapods/sandbox/path_list.rb +2 -2
  64. data/lib/cocoapods/sandbox/pod_dir_cleaner.rb +1 -1
  65. data/lib/cocoapods/sandbox.rb +48 -12
  66. data/lib/cocoapods/sources_manager.rb +18 -9
  67. data/lib/cocoapods/target/aggregate_target.rb +23 -1
  68. data/lib/cocoapods/target/build_settings.rb +67 -22
  69. data/lib/cocoapods/target/pod_target.rb +49 -24
  70. data/lib/cocoapods/target.rb +1 -1
  71. data/lib/cocoapods/user_interface.rb +6 -2
  72. data/lib/cocoapods/validator.rb +58 -22
  73. data/lib/cocoapods/version_metadata.rb +1 -1
  74. data/lib/cocoapods/xcode/xcframework/xcframework_slice.rb +22 -7
  75. data/lib/cocoapods/xcode/xcframework.rb +9 -4
  76. data/lib/cocoapods.rb +2 -0
  77. metadata +35 -27
data/bin/sandbox-pod CHANGED
@@ -61,7 +61,7 @@ PROFILE_ERB_TEMPLATE = <<-EOS
61
61
 
62
62
  (allow file-read-metadata)
63
63
  (allow file-read*
64
- ; This is currenly only added because using `xcodebuild` to build a resource
64
+ ; This is currently only added because using `xcodebuild` to build a resource
65
65
  ; bundle target starts a FSEvents stream on `/`. No idea why that would be
66
66
  ; needed, but for now it doesn’t seem like a real problem.
67
67
  (literal "/")
@@ -25,7 +25,7 @@ module Pod
25
25
  ['--use-static-frameworks', 'Lint uses static frameworks during installation'],
26
26
  ["--sources=#{Pod::TrunkSource::TRUNK_REPO_URL}", 'The sources from which to pull dependent pods ' \
27
27
  "(defaults to #{Pod::TrunkSource::TRUNK_REPO_URL}). Multiple sources must be comma-delimited"],
28
- ['--platforms=ios,macos', 'Lint against specific platforms (defaults to all platforms supported by the ' \
28
+ ['--platforms=ios,macos,visionos', 'Lint against specific platforms (defaults to all platforms supported by the ' \
29
29
  'podspec). Multiple platforms must be comma-delimited'],
30
30
  ['--private', 'Lint skips checks that apply only to public specs'],
31
31
  ['--swift-version=VERSION', 'The `SWIFT_VERSION` that should be used to lint the spec. ' \
@@ -38,6 +38,7 @@ module Pod
38
38
  ['--test-specs=test-spec1,test-spec2,etc', 'List of test specs to run'],
39
39
  ['--analyze', 'Validate with the Xcode Static Analysis tool'],
40
40
  ['--configuration=CONFIGURATION', 'Build using the given configuration (defaults to Release)'],
41
+ ['--validation-dir', 'The directory to use for validation. If none is specified a temporary directory will be used.'],
41
42
  ].concat(super)
42
43
  end
43
44
 
@@ -63,6 +64,7 @@ module Pod
63
64
  @analyze = argv.flag?('analyze', false)
64
65
  @podspecs_paths = argv.arguments!
65
66
  @configuration = argv.option('configuration', nil)
67
+ @validation_dir = argv.option('validation-dir', nil)
66
68
  super
67
69
  end
68
70
 
@@ -93,6 +95,7 @@ module Pod
93
95
  validator.include_podspecs = @include_podspecs
94
96
  validator.external_podspecs = @external_podspecs
95
97
  validator.configuration = @configuration
98
+ validator.validation_dir = @validation_dir
96
99
  validator.validate
97
100
 
98
101
  unless @clean
@@ -11,6 +11,17 @@ module Pod
11
11
  spec repos, not those from local/external sources.
12
12
  DESC
13
13
 
14
+ def self.options
15
+ [
16
+ ['--ignore-prerelease', "Don't consider prerelease versions to be updates"],
17
+ ].concat(super)
18
+ end
19
+
20
+ def initialize(argv)
21
+ @ignore_prerelease = argv.flag?('ignore-prerelease')
22
+ super
23
+ end
24
+
14
25
  # Run the command
15
26
  #
16
27
  def run
@@ -67,7 +78,7 @@ module Pod
67
78
  ensure_external_podspecs_present!
68
79
  spec_sets.map do |set|
69
80
  spec = set.specification
70
- source_version = set.versions.first
81
+ source_version = set.versions.find { |version| !@ignore_prerelease || !version.prerelease? }
71
82
  pod_name = spec.root.name
72
83
  lockfile_version = lockfile.version(pod_name)
73
84
  if source_version > lockfile_version
@@ -37,6 +37,8 @@ module Pod
37
37
  ['--swift-version=VERSION', 'The `SWIFT_VERSION` that should be used when linting the spec. ' \
38
38
  'This takes precedence over the Swift versions specified by the spec or a `.swift-version` file'],
39
39
  ['--no-overwrite', 'Disallow pushing that would overwrite an existing spec'],
40
+ ['--update-sources', 'Make sure sources are up-to-date before a push'],
41
+ ['--validation-dir', 'The directory to use for validation. If none is specified a temporary directory will be used.'],
40
42
  ].concat(super)
41
43
  end
42
44
 
@@ -46,6 +48,7 @@ module Pod
46
48
  @repo = argv.shift_argument
47
49
  @source = source_for_repo
48
50
  @source_urls = argv.option('sources', config.sources_manager.all.map(&:url).append(Pod::TrunkSource::TRUNK_REPO_URL).uniq.join(',')).split(',')
51
+ @update_sources = argv.flag?('update-sources')
49
52
  @podspec = argv.shift_argument
50
53
  @use_frameworks = !argv.flag?('use-libraries')
51
54
  @use_modular_headers = argv.flag?('use-modular-headers', false)
@@ -57,6 +60,7 @@ module Pod
57
60
  @skip_import_validation = argv.flag?('skip-import-validation', false)
58
61
  @skip_tests = argv.flag?('skip-tests', false)
59
62
  @allow_overwrite = argv.flag?('overwrite', true)
63
+ @validation_dir = argv.option('validation-dir', nil)
60
64
  super
61
65
  end
62
66
 
@@ -73,6 +77,7 @@ module Pod
73
77
  def run
74
78
  open_editor if @commit_message && @message.nil?
75
79
  check_if_push_allowed
80
+ update_sources if @update_sources
76
81
  validate_podspec_files
77
82
  check_repo_status
78
83
  update_repo
@@ -141,6 +146,7 @@ module Pod
141
146
  validator.swift_version = @swift_version
142
147
  validator.skip_import_validation = @skip_import_validation
143
148
  validator.skip_tests = @skip_tests
149
+ validator.validation_dir = @validation_dir
144
150
  begin
145
151
  validator.validate
146
152
  rescue => e
@@ -177,6 +183,20 @@ module Pod
177
183
  git!(%W(-C #{repo_dir} pull))
178
184
  end
179
185
 
186
+ # Update sources if present
187
+ #
188
+ # @return [void]
189
+ #
190
+ def update_sources
191
+ return if @source_urls.nil?
192
+ @source_urls.each do |source_url|
193
+ source = config.sources_manager.source_with_name_or_url(source_url)
194
+ dir = source.specs_dir
195
+ UI.puts "Updating a source at #{dir} for #{source}"
196
+ git!(%W(-C #{dir} pull))
197
+ end
198
+ end
199
+
180
200
  # Commits the podspecs to the source, which should be a git repo.
181
201
  #
182
202
  # @note The pre commit hook of the repo is skipped as the podspecs have
@@ -3,10 +3,10 @@ require 'fileutils'
3
3
  module Pod
4
4
  class Command
5
5
  class Setup < Command
6
- self.summary = 'Setup the CocoaPods environment'
6
+ self.summary = 'Set up the CocoaPods environment'
7
7
 
8
8
  self.description = <<-DESC
9
- Setup the CocoaPods environment
9
+ Set up the CocoaPods environment
10
10
  DESC
11
11
 
12
12
  def run
@@ -16,6 +16,7 @@ module Pod
16
16
  [
17
17
  ['--regex', 'Interpret the `QUERY` as a regular expression'],
18
18
  ['--show-all', 'Pick from all versions of the given podspec'],
19
+ ['--version', 'Print a specific version of the given podspec'],
19
20
  ].concat(super)
20
21
  end
21
22
 
@@ -24,6 +25,7 @@ module Pod
24
25
  @show_all = argv.flag?('show-all')
25
26
  @query = argv.shift_argument
26
27
  @query = @query.gsub('.podspec', '') unless @query.nil?
28
+ @version = argv.option('version')
27
29
  super
28
30
  end
29
31
 
@@ -40,7 +42,7 @@ module Pod
40
42
  index = UI.choose_from_array(specs, "Which spec would you like to print [1-#{specs.count}]? ")
41
43
  specs[index]
42
44
  else
43
- get_path_of_spec(query)
45
+ get_path_of_spec(query, @version)
44
46
  end
45
47
 
46
48
  UI.puts File.read(filepath)
@@ -181,6 +181,7 @@ Pod::Spec.new do |spec|
181
181
  # spec.osx.deployment_target = "10.7"
182
182
  # spec.watchos.deployment_target = "2.0"
183
183
  # spec.tvos.deployment_target = "9.0"
184
+ # spec.visionos.deployment_target = "1.0"
184
185
 
185
186
 
186
187
  # ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
@@ -37,6 +37,7 @@ module Pod
37
37
  ['--test-specs=test-spec1,test-spec2,etc', 'List of test specs to run'],
38
38
  ['--analyze', 'Validate with the Xcode Static Analysis tool'],
39
39
  ['--configuration=CONFIGURATION', 'Build using the given configuration (defaults to Release)'],
40
+ ['--validation-dir', 'The directory to use for validation. If none is specified a temporary directory will be used.'],
40
41
  ].concat(super)
41
42
  end
42
43
 
@@ -60,6 +61,7 @@ module Pod
60
61
  @analyze = argv.flag?('analyze', false)
61
62
  @podspecs_paths = argv.arguments!
62
63
  @configuration = argv.option('configuration', nil)
64
+ @validation_dir = argv.option('validation-dir', nil)
63
65
  super
64
66
  end
65
67
 
@@ -84,6 +86,7 @@ module Pod
84
86
  validator.test_specs = @test_specs
85
87
  validator.analyze = @analyze
86
88
  validator.configuration = @configuration
89
+ validator.validation_dir = @validation_dir
87
90
  validator.validate
88
91
  failure_reasons << validator.failure_reason
89
92
 
@@ -122,7 +125,7 @@ module Pod
122
125
  output_path = podspecs_tmp_dir + File.basename(path)
123
126
  output_path.dirname.mkpath
124
127
  begin
125
- open(path) do |io|
128
+ OpenURI.open_uri(path) do |io|
126
129
  output_path.open('w') { |f| f << io.read }
127
130
  end
128
131
  rescue => e
@@ -16,12 +16,14 @@ module Pod
16
16
  [
17
17
  ['--regex', 'Interpret the `QUERY` as a regular expression'],
18
18
  ['--show-all', 'Print all versions of the given podspec'],
19
+ ['--version', 'Print a specific version of the given podspec'],
19
20
  ].concat(super)
20
21
  end
21
22
 
22
23
  def initialize(argv)
23
24
  @use_regex = argv.flag?('regex')
24
25
  @show_all = argv.flag?('show-all')
26
+ @version = argv.option('version')
25
27
  @query = argv.shift_argument
26
28
  @query = @query.gsub('.podspec', '') unless @query.nil?
27
29
  super
@@ -35,7 +37,7 @@ module Pod
35
37
 
36
38
  def run
37
39
  query = @use_regex ? @query : Regexp.escape(@query)
38
- UI.puts get_path_of_spec(query, @show_all)
40
+ UI.puts get_path_of_spec(query, @show_all || @version)
39
41
  end
40
42
  end
41
43
  end
@@ -33,13 +33,14 @@ module Pod
33
33
  # @param [String] spec
34
34
  # The name of the specification.
35
35
  #
36
- # @param [Bool] show_all
37
- # Whether the paths for all the versions should be returned or
38
- # only the one for the last version.
36
+ # @param [Bool,String] version_filter
37
+ # - If set to false, will return only the spec path for the latest version (the default).
38
+ # - If set to true, will return a list of all paths of all the versions of that spec.
39
+ # - If set to a String, will return only the spec path for the version specified by that string.
39
40
  #
40
41
  # @return [Pathname] the absolute path or paths of the given podspec
41
42
  #
42
- def get_path_of_spec(spec, show_all = false)
43
+ def get_path_of_spec(spec, version_filter = false)
43
44
  sets = config.sources_manager.search_by_name(spec)
44
45
 
45
46
  if sets.count == 1
@@ -51,12 +52,14 @@ module Pod
51
52
  raise Informative, "More than one spec found for '#{spec}':\n#{names}"
52
53
  end
53
54
 
54
- unless show_all
55
+ if version_filter.is_a? String
56
+ all_paths_from_set(set, version_filter).split(/\n/).first
57
+ elsif version_filter == true
58
+ all_paths_from_set(set)
59
+ else
55
60
  best_spec, spec_source = spec_and_source_from_set(set)
56
- return pathname_from_spec(best_spec, spec_source)
61
+ pathname_from_spec(best_spec, spec_source)
57
62
  end
58
-
59
- all_paths_from_set(set)
60
63
  end
61
64
 
62
65
  # @return [Pathname] the absolute path of the given spec and source
@@ -67,7 +70,7 @@ module Pod
67
70
 
68
71
  # @return [String] of spec paths one on each line
69
72
  #
70
- def all_paths_from_set(set)
73
+ def all_paths_from_set(set, specific_version = nil)
71
74
  paths = ''
72
75
 
73
76
  sources = set.sources
@@ -75,12 +78,18 @@ module Pod
75
78
  sources.each do |source|
76
79
  versions = source.versions(set.name)
77
80
 
81
+ if specific_version
82
+ versions = versions.select { |v| v.version == specific_version }
83
+ end
84
+
78
85
  versions.each do |version|
79
86
  spec = source.specification(set.name, version)
80
87
  paths += "#{pathname_from_spec(spec, source)}\n"
81
88
  end
82
89
  end
83
90
 
91
+ raise Informative, "Can't find spec for #{set.name}." if paths.empty?
92
+
84
93
  paths
85
94
  end
86
95
 
@@ -49,23 +49,23 @@ module Pod
49
49
 
50
50
  # @!group UI
51
51
 
52
- # @return [Bool] Whether CocoaPods should provide detailed output about the
52
+ # @return [Boolean] Whether CocoaPods should provide detailed output about the
53
53
  # performed actions.
54
54
  #
55
55
  attr_accessor :verbose
56
56
  alias_method :verbose?, :verbose
57
57
 
58
- # @return [Bool] Whether CocoaPods should produce not output.
58
+ # @return [Boolean] Whether CocoaPods should produce not output.
59
59
  #
60
60
  attr_accessor :silent
61
61
  alias_method :silent?, :silent
62
62
 
63
- # @return [Bool] Whether CocoaPods is allowed to run as root.
63
+ # @return [Boolean] Whether CocoaPods is allowed to run as root.
64
64
  #
65
65
  attr_accessor :allow_root
66
66
  alias_method :allow_root?, :allow_root
67
67
 
68
- # @return [Bool] Whether a message should be printed when a new version of
68
+ # @return [Boolean] Whether a message should be printed when a new version of
69
69
  # CocoaPods is available.
70
70
  #
71
71
  attr_accessor :new_version_message
@@ -75,7 +75,7 @@ module Pod
75
75
 
76
76
  # @!group Installation
77
77
 
78
- # @return [Bool] Whether the installer should skip the download cache.
78
+ # @return [Boolean] Whether the installer should skip the download cache.
79
79
  #
80
80
  attr_accessor :skip_download_cache
81
81
  alias_method :skip_download_cache?, :skip_download_cache
@@ -111,7 +111,8 @@ module Pod
111
111
 
112
112
  if use_user_settings && user_settings_file.exist?
113
113
  require 'yaml'
114
- user_settings = YAML.load_file(user_settings_file)
114
+ user_settings_contents = File.read(user_settings_file)
115
+ user_settings = YAML.safe_load(user_settings_contents)
115
116
  configure_with(user_settings)
116
117
  end
117
118
 
@@ -163,7 +164,7 @@ module Pod
163
164
  #
164
165
  def installation_root
165
166
  @installation_root ||= begin
166
- current_dir = Pathname.new(ActiveSupport::Multibyte::Unicode.normalize(Dir.pwd))
167
+ current_dir = Pathname.new(Dir.pwd.unicode_normalize(:nfkc))
167
168
  current_path = current_dir
168
169
  until current_path.root?
169
170
  if podfile_path_in_dir(current_path)
@@ -69,6 +69,91 @@ module Pod
69
69
  end
70
70
  end
71
71
 
72
+ # Convenience method for acquiring a shared lock to safely read from the
73
+ # cache. See `Cache.lock` for more details.
74
+ #
75
+ # @param [Pathname] location
76
+ # the path to require a lock for.
77
+ #
78
+ # @param [block] &block
79
+ # the block to execute inside the lock.
80
+ #
81
+ # @return [void]
82
+ #
83
+ def self.read_lock(location, &block)
84
+ Cache.lock(location, File::LOCK_SH, &block)
85
+ end
86
+
87
+ # Convenience method for acquiring an exclusive lock to safely write to
88
+ # the cache. See `Cache.lock` for more details.
89
+ #
90
+ # @param [Pathname] location
91
+ # the path to require a lock for.
92
+ #
93
+ # @param [block] &block
94
+ # the block to execute inside the lock.
95
+ #
96
+ # @return [void]
97
+ #
98
+ def self.write_lock(location, &block)
99
+ Cache.lock(location, File::LOCK_EX, &block)
100
+ end
101
+
102
+ # Creates a .lock file at `location`, aquires a lock of type
103
+ # `lock_type`, checks that it is valid, and executes passed block while
104
+ # holding on to that lock. Afterwards, the .lock file is deleted, which is
105
+ # why validation of the lock is necessary, as you might have a lock on a
106
+ # file that doesn't exist on the filesystem anymore.
107
+ #
108
+ # @param [Pathname] location
109
+ # the path to require a lock for.
110
+ #
111
+ # @param [locking_constant] lock_type
112
+ # the type of lock, either exclusive (File::LOCK_EX) or shared
113
+ # (File::LOCK_SH).
114
+ #
115
+ # @return [void]
116
+ #
117
+ def self.lock(location, lock_type)
118
+ raise ArgumentError, 'no block given' unless block_given?
119
+ lockfile = "#{location}.lock"
120
+ f = nil
121
+ loop do
122
+ f.close if f
123
+ f = File.open(lockfile, File::CREAT, 0o644)
124
+ f.flock(lock_type)
125
+ break if Cache.valid_lock?(f, lockfile)
126
+ end
127
+ begin
128
+ yield location
129
+ ensure
130
+ if lock_type == File::LOCK_SH
131
+ f.flock(File::LOCK_EX)
132
+ File.delete(lockfile) if Cache.valid_lock?(f, lockfile)
133
+ else
134
+ File.delete(lockfile)
135
+ end
136
+ f.close
137
+ end
138
+ end
139
+
140
+ # Checks that the lock is on a file that still exists on the filesystem.
141
+ #
142
+ # @param [File] file
143
+ # the actual file that we have a lock for.
144
+ #
145
+ # @param [String] filename
146
+ # the filename of the file that we have a lock for.
147
+ #
148
+ # @return [Boolean]
149
+ # true if `filename` still exists and is the same file as `file`
150
+ #
151
+ def self.valid_lock?(file, filename)
152
+ file.stat.ino == File.stat(filename).ino
153
+ rescue Errno::ENOENT
154
+ false
155
+ end
156
+
72
157
  private
73
158
 
74
159
  # Ensures the cache on disk was created with the same CocoaPods version as
@@ -112,7 +197,7 @@ module Pod
112
197
  #
113
198
  def path_for_spec(request, slug_opts = {})
114
199
  path = root + 'Specs' + request.slug(**slug_opts)
115
- path.sub_ext('.podspec.json')
200
+ Pathname.new(path.to_path + '.podspec.json')
116
201
  end
117
202
 
118
203
  # @param [Request] request
@@ -197,10 +282,15 @@ module Pod
197
282
  def copy_and_clean(source, destination, spec)
198
283
  specs_by_platform = group_subspecs_by_platform(spec)
199
284
  destination.parent.mkpath
200
- FileUtils.rm_rf(destination)
201
- FileUtils.cp_r(source, destination)
202
- Pod::Installer::PodSourcePreparer.new(spec, destination).prepare!
203
- Sandbox::PodDirCleaner.new(destination, specs_by_platform).clean!
285
+ Cache.write_lock(destination) do
286
+ rsync_contents(source, destination)
287
+ Pod::Installer::PodSourcePreparer.new(spec, destination).prepare!
288
+ Sandbox::PodDirCleaner.new(destination, specs_by_platform).clean!
289
+ end
290
+ end
291
+
292
+ def rsync_contents(source, destination)
293
+ Pod::Executable.execute_command('rsync', ['-a', '--exclude=.git', '--delete', "#{source}/", destination])
204
294
  end
205
295
 
206
296
  def group_subspecs_by_platform(spec)
@@ -226,7 +316,9 @@ module Pod
226
316
  #
227
317
  def write_spec(spec, path)
228
318
  path.dirname.mkpath
229
- path.open('w') { |f| f.write spec.to_pretty_json }
319
+ Cache.write_lock(path) do
320
+ path.open('w') { |f| f.write spec.to_pretty_json }
321
+ end
230
322
  end
231
323
  end
232
324
  end
@@ -50,8 +50,10 @@ module Pod
50
50
 
51
51
  if target && result.location && target != result.location
52
52
  UI.message "Copying #{request.name} from `#{result.location}` to #{UI.path target}", '> ' do
53
- FileUtils.rm_rf target
54
- FileUtils.cp_r(result.location, target)
53
+ Cache.read_lock(result.location) do
54
+ FileUtils.rm_rf target
55
+ FileUtils.cp_r(result.location, target)
56
+ end
55
57
  end
56
58
  end
57
59
  result
@@ -36,7 +36,7 @@ module Pod
36
36
  # @param [Array<#to_s>] command
37
37
  # The command to send to the binary.
38
38
  #
39
- # @param [Bool] raise_on_failure
39
+ # @param [Boolean] raise_on_failure
40
40
  # Whether it should raise if the command fails.
41
41
  #
42
42
  # @raise If the executable could not be located.
@@ -36,7 +36,7 @@ module Pod
36
36
  @can_cache = can_cache
37
37
  end
38
38
 
39
- # @return [Bool] whether an external source source is equal to another
39
+ # @return [Boolean] whether an external source source is equal to another
40
40
  # according to the {#name} and to the {#params}.
41
41
  #
42
42
  def ==(other)
@@ -45,7 +45,7 @@ module Pod
45
45
  path.exist? ? path : Pathname("#{path}.json")
46
46
  end
47
47
 
48
- # @return [Bool]
48
+ # @return [Boolean]
49
49
  #
50
50
  def absolute?(path)
51
51
  Pathname(path).absolute? || path.to_s.start_with?('~')
@@ -16,7 +16,7 @@ module Pod
16
16
  else
17
17
  require 'cocoapods/open-uri'
18
18
  begin
19
- open(podspec_uri) { |io| store_podspec(sandbox, io.read, is_json) }
19
+ OpenURI.open_uri(podspec_uri) { |io| store_podspec(sandbox, io.read, is_json) }
20
20
  rescue OpenURI::HTTPError => e
21
21
  status = e.io.status.join(' ')
22
22
  raise Informative, "Failed to fetch podspec for `#{name}` at `#{podspec_uri}`.\n Error: #{status}"
@@ -1,5 +1,5 @@
1
1
  module Pod
2
2
  # The version of the CocoaPods command line tool.
3
3
  #
4
- VERSION = '1.10.0'.freeze unless defined? Pod::VERSION
4
+ VERSION = '1.16.0'.freeze unless defined? Pod::VERSION
5
5
  end
@@ -67,7 +67,7 @@ module Pod
67
67
  # the specification for which license is needed.
68
68
  #
69
69
  # @return [String] The text of the license.
70
- # @return [Nil] If not license text could be found.
70
+ # @return [Nil] If no license text could be found.
71
71
  #
72
72
  def license_text(spec)
73
73
  return nil unless spec.license
@@ -84,10 +84,22 @@ module Pod
84
84
  elsif license_file = file_accessor(spec).license
85
85
  text = IO.read(license_file)
86
86
  end
87
+ text = format_license(text)
87
88
  end
88
89
  text
89
90
  end
90
91
 
92
+ # Convenience method for users to format licenses
93
+ #
94
+ # @param [String] text
95
+ # Unformatted license text
96
+ #
97
+ # @return [String] Formatted license text
98
+ #
99
+ def format_license(text)
100
+ text
101
+ end
102
+
91
103
  protected
92
104
 
93
105
  # Returns the file accessor for the given spec.
@@ -9,7 +9,7 @@ module Pod
9
9
  # @param [Project] project
10
10
  # the Xcodeproj to generate the target into.
11
11
  #
12
- # @param [Symbol] platform
12
+ # @param [Symbol] platform_name
13
13
  # the platform of the target. Can be `:ios` or `:osx`, etc.
14
14
  #
15
15
  # @param [String] deployment_target
@@ -18,10 +18,14 @@ module Pod
18
18
  # @param [String] name
19
19
  # The name to use for the target, defaults to 'App'.
20
20
  #
21
+ # @param [String] product_basename
22
+ # The product basename to use for the target, defaults to `name`.
23
+ #
21
24
  # @return [PBXNativeTarget] the new target that was created.
22
25
  #
23
- def self.add_app_target(project, platform, deployment_target, name = 'App')
24
- project.new_target(:application, name, platform, deployment_target)
26
+ def self.add_app_target(project, platform_name, deployment_target, name = 'App', product_basename = nil)
27
+ project.new_target(:application, name, platform_name, deployment_target, nil,
28
+ nil, product_basename)
25
29
  end
26
30
 
27
31
  # Creates and links an import file for the given pod target and into the given native target.
@@ -199,7 +203,7 @@ module Pod
199
203
  f << "@import Foundation;\n"
200
204
  f << "@import UIKit;\n" if platform == :ios || platform == :tvos
201
205
  f << "@import Cocoa;\n" if platform == :osx
202
- f << "#{import_statement}int main() {}\n"
206
+ f << "#{import_statement}int main(void) {}\n"
203
207
  end
204
208
  end
205
209
  source_file
@@ -1,18 +1,18 @@
1
1
  module Pod
2
2
  module Generator
3
3
  class CopydSYMsScript
4
- # @return [Array<Pathname>] dsym_paths the dSYM paths to include in the script contents.
4
+ # @return [Array<Pathname, String>] dsym_paths the dSYM paths to include in the script contents.
5
5
  #
6
6
  attr_reader :dsym_paths
7
7
 
8
- # @return [Array<Pathname>] bcsymbolmap_paths the bcsymbolmap paths to include in the script contents.
8
+ # @return [Array<Pathname, String>] bcsymbolmap_paths the bcsymbolmap paths to include in the script contents.
9
9
  #
10
10
  attr_reader :bcsymbolmap_paths
11
11
 
12
12
  # Initialize a new instance
13
13
  #
14
- # @param [Array<Pathname>] dsym_paths @see dsym_paths
15
- # @param [Array<Pathname>] bcsymbolmap_paths @see bcsymbolmap_paths
14
+ # @param [Array<Pathname, String>] dsym_paths @see dsym_paths
15
+ # @param [Array<Pathname, String>] bcsymbolmap_paths @see bcsymbolmap_paths
16
16
  #
17
17
  def initialize(dsym_paths, bcsymbolmap_paths)
18
18
  @dsym_paths = Array(dsym_paths)
@@ -57,9 +57,10 @@ module Pod
57
57
  :osx => Version.new('10.8'),
58
58
  :watchos => Version.new('2.0'),
59
59
  :tvos => Version.new('9.0'),
60
+ :visionos => Version.new('1.0'),
60
61
  }
61
62
 
62
- # @return [Bool] Whether the external strings file is supported by the
63
+ # @return [Boolean] Whether the external strings file is supported by the
63
64
  # `ibtool` according to the deployment target of the platform.
64
65
  #
65
66
  def use_external_strings_file?