cocoapods 0.15.1 → 0.15.2

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.
@@ -1,6 +1,29 @@
1
1
  ## Master
2
2
 
3
- [CocoaPods](https://github.com/CocoaPods/CocoaPods/compare/0.15.1...master)
3
+ [CocoaPods](https://github.com/CocoaPods/CocoaPods/compare/0.15.1...master) • [Xcodeproj](https://github.com/CocoaPods/Xcodeproj/compare/0.3.4...master)
4
+
5
+ ## 0.15.2
6
+
7
+ [CocoaPods](https://github.com/CocoaPods/CocoaPods/compare/0.15.1...0.15.2)
8
+
9
+ ###### Enhancements
10
+
11
+ - Added support for `.hh` headers.
12
+ [#576](https://github.com/CocoaPods/CocoaPods/pull/576)
13
+
14
+ ###### Bug fixes
15
+
16
+ - Restored support for running CocoaPods without a terminal.
17
+ [#575](https://github.com/CocoaPods/CocoaPods/issues/575)
18
+ [#577](https://github.com/CocoaPods/CocoaPods/issues/577)
19
+ - The git cache now always uses a barebones repo preventing a number of related issues.
20
+ [#581](https://github.com/CocoaPods/CocoaPods/issues/581)
21
+ [#569](https://github.com/CocoaPods/CocoaPods/issues/569)
22
+ - Improved fix for the issue that lead to empty directories for Pods.
23
+ [#572](https://github.com/CocoaPods/CocoaPods/issues/572)
24
+ [#602](https://github.com/CocoaPods/CocoaPods/issues/602)
25
+ - Xcodeproj robustness against invalid values, such as malformed UTF8.
26
+ [#592](https://github.com/CocoaPods/CocoaPods/issues/592)
4
27
 
5
28
  ## 0.15.1
6
29
 
@@ -12,7 +12,7 @@ unless Gem::Version::Requirement.new('>= 1.4.0').satisfied_by?(Gem::Version.new(
12
12
  end
13
13
 
14
14
  module Pod
15
- VERSION = '0.15.1'
15
+ VERSION = '0.15.2'
16
16
 
17
17
  class PlainInformative < StandardError
18
18
  end
@@ -57,13 +57,6 @@ module Pod
57
57
  end
58
58
  end
59
59
 
60
- class Pathname
61
- def glob(pattern = '')
62
- Dir.glob((self + pattern).to_s).map { |f| Pathname.new(f) }
63
- end
64
- end
65
-
66
60
  if ENV['COCOA_PODS_ENV'] == 'development'
67
- require 'letters'
68
61
  require 'awesome_print'
69
62
  end
@@ -1,4 +1,5 @@
1
1
  require 'fileutils'
2
+ require 'active_support/core_ext/string/inflections'
2
3
 
3
4
  module Pod
4
5
  class Command
@@ -66,12 +67,18 @@ module Pod
66
67
 
67
68
  def podspec_files
68
69
  files = Pathname.glob(@podspec || "*.podspec")
69
- raise Informative, "[!] Couldn't find .podspec file in current directory".red if files.empty?
70
+ raise Informative, "[!] Couldn't find any .podspec file in current directory".red if files.empty?
70
71
  files
71
72
  end
72
73
 
74
+ # @return [Integer] The number of the podspec files to push.
75
+ #
76
+ def count
77
+ podspec_files.count
78
+ end
79
+
73
80
  def validate_podspec_files
74
- UI.puts "\nValidating specs".yellow unless config.silent
81
+ UI.puts "\nValidating #{'spec'.pluralize(count)}".yellow unless config.silent
75
82
  lint_argv = ["lint"]
76
83
  lint_argv << "--only-errors" if @allow_warnings
77
84
  lint_argv << "--silent" if config.silent
@@ -82,7 +89,7 @@ module Pod
82
89
  end
83
90
 
84
91
  def add_specs_to_repo
85
- UI.puts "\nAdding the specs to the #{@repo} repo\n".yellow unless config.silent
92
+ UI.puts "\nAdding the #{'spec'.pluralize(count)} to the `#{@repo}' repo\n".yellow unless config.silent
86
93
  podspec_files.each do |spec_file|
87
94
  spec = Pod::Specification.from_file(spec_file)
88
95
  output_path = File.join(repo_dir, spec.name, spec.version.to_s)
@@ -90,7 +90,7 @@ module Pod
90
90
  dirs.each do |dir|
91
91
  check_versions(dir)
92
92
  UI.puts "\nLinting spec repo `#{dir.realpath.basename}'\n".yellow
93
- podspecs = dir.glob('**/*.podspec')
93
+ podspecs = Pathname.glob( dir + '**/*.podspec')
94
94
  invalid_count = 0
95
95
 
96
96
  podspecs.each do |podspec|
@@ -1,5 +1,7 @@
1
1
  # encoding: utf-8
2
2
 
3
+ require 'active_support/core_ext/string/inflections'
4
+
3
5
  module Pod
4
6
  class Command
5
7
  class Spec < Command
@@ -104,8 +106,8 @@ module Pod
104
106
  UI.puts unless config.silent?
105
107
  end
106
108
 
107
- UI.puts "Analyzed #{podspecs_to_lint.count} podspecs files.\n\n" unless config.silent?
108
109
  count = podspecs_to_lint.count
110
+ UI.puts "Analyzed #{count} #{'podspec'.pluralize(count)}.\n\n" unless config.silent?
109
111
  if invalid_count == 0
110
112
  lint_passed_message = count == 1 ? "#{podspecs_to_lint.first.basename} passed validation." : "All the specs passed validation."
111
113
  UI.puts lint_passed_message.green << "\n\n" unless config.silent?
@@ -136,7 +138,7 @@ module Pod
136
138
  end
137
139
  files << output_path
138
140
  else if (pathname = Pathname.new(path)).directory?
139
- files += pathname.glob('**/*.podspec')
141
+ files += Pathname.glob(pathname + '**/*.podspec')
140
142
  raise Informative, "No specs found in the current directory." if files.empty?
141
143
  else
142
144
  files << (pathname = Pathname.new(path))
@@ -1,17 +1,19 @@
1
1
  require 'open-uri'
2
- require 'tempfile'
2
+ # require 'tempfile'
3
3
  require 'zlib'
4
4
  require 'digest/sha1'
5
5
 
6
6
  module Pod
7
7
  class Downloader
8
+
9
+ # Concreted Downloader class that provides support for specifications with
10
+ # git sources.
11
+ #
8
12
  class Git < Downloader
9
13
  include Config::Mixin
10
14
 
11
15
  executable :git
12
16
 
13
- MAX_CACHE_SIZE = 500
14
-
15
17
  def download
16
18
  create_cache unless cache_exist?
17
19
  UI.section(' > Cloning git repo', '', 1) do
@@ -29,89 +31,26 @@ module Pod
29
31
  prune_cache
30
32
  end
31
33
 
32
- def create_cache
33
- UI.section(" > Creating cache git repo (#{cache_path})",'',1) do
34
- cache_path.rmtree if cache_path.exist?
35
- cache_path.mkpath
36
- git! %Q|clone --mirror "#{url}" "#{cache_path}"|
37
- end
38
- end
39
-
40
- def prune_cache
41
- return unless caches_dir.exist?
42
- Dir.chdir(caches_dir) do
43
- repos = Pathname.new(caches_dir).children.select { |c| c.directory? }.sort_by(&:ctime)
44
- while caches_size >= MAX_CACHE_SIZE && !repos.empty?
45
- dir = repos.shift
46
- UI.message "#{'->'.yellow} Removing git cache for `#{origin_url(dir)}'"
47
- dir.rmtree
48
- end
49
- end
50
- end
51
-
52
- def cache_path
53
- @cache_path ||= caches_dir + "#{Digest::SHA1.hexdigest(url.to_s)}"
54
- end
55
-
56
- def cache_exist?
57
- cache_path.exist? && origin_url(cache_path).to_s == url.to_s
58
- end
59
-
60
- def origin_url(dir)
61
- Dir.chdir(dir) { `git config remote.origin.url`.chomp }
62
- end
63
34
 
64
- def caches_dir
65
- Pathname.new(File.expand_path("~/Library/Caches/CocoaPods/Git"))
66
- end
35
+ # @!group Download implementations
67
36
 
37
+ # @return [Pathname] The clone URL, which resolves to the cache path.
38
+ #
68
39
  def clone_url
69
40
  cache_path
70
41
  end
71
42
 
72
- def caches_size
73
- # expressed in Mb
74
- `du -cm`.split("\n").last.to_i
75
- end
76
-
77
- def update_cache
78
- UI.section(" > Updating cache git repo (#{cache_path})",'',1) do
79
- Dir.chdir(cache_path) do
80
- if git("config core.bare").chomp == "true"
81
- git! "remote update"
82
- else
83
- git! "reset --hard HEAD"
84
- git! "clean -d -x -f"
85
- git! "pull origin master"
86
- git! "fetch --tags"
87
- end
88
- end
43
+ # @return [void] Convenience method to perform clones operations.
44
+ #
45
+ def clone(from, to)
46
+ UI.section(" > Cloning to Pods folder",'',1) do
47
+ git! %Q|clone "#{from}" "#{to}"|
89
48
  end
90
49
  end
91
50
 
92
- def ref_exists?(ref)
93
- Dir.chdir(cache_path) { git "rev-list --max-count=1 #{ref}" }
94
- $? == 0
95
- end
96
-
97
- def ensure_ref_exists(ref)
98
- return if ref_exists?(ref)
99
- # Skip pull if not needed
100
- update_cache
101
- raise Informative, "[!] Cache unable to find git reference `#{ref}' for `#{url}'.".red unless ref_exists?(ref)
102
- end
103
-
104
- def branch_exists?(branch)
105
- Dir.chdir(cache_path) { git "branch --all | grep #{branch}$" } # check for remote branch and do suffix matching ($ anchor)
106
- $? == 0
107
- end
108
-
109
- def ensure_remote_branch_exists(branch)
110
- return if branch_exists?(branch)
111
- update_cache
112
- raise Informative, "[!] Cache unable to find git reference `#{branch}' for `#{url}' (#{$?}).".red unless branch_exists?(branch)
113
- end
114
-
51
+ # @return [void] Checkouts the HEAD of the git source in the destination
52
+ # path.
53
+ #
115
54
  def download_head
116
55
  if cache_exist?
117
56
  update_cache
@@ -123,6 +62,9 @@ module Pod
123
62
  Dir.chdir(target_path) { git! "submodule update --init" } if options[:submodules]
124
63
  end
125
64
 
65
+ # @return [void] Checkouts a specific tag of the git source in the
66
+ # destination path.
67
+ #
126
68
  def download_tag
127
69
  ensure_ref_exists(options[:tag])
128
70
  Dir.chdir(target_path) do
@@ -134,6 +76,9 @@ module Pod
134
76
  end
135
77
  end
136
78
 
79
+ # @return [void] Checkouts a specific commit of the git source in the
80
+ # destination path.
81
+ #
137
82
  def download_commit
138
83
  ensure_ref_exists(options[:commit])
139
84
  clone(clone_url, target_path)
@@ -142,6 +87,9 @@ module Pod
142
87
  end
143
88
  end
144
89
 
90
+ # @return [void] Checkouts the HEAD of a specific branch of the git
91
+ # source in the destination path.
92
+ #
145
93
  def download_branch
146
94
  ensure_remote_branch_exists(options[:branch])
147
95
  clone(clone_url, target_path)
@@ -153,13 +101,135 @@ module Pod
153
101
  end
154
102
  end
155
103
 
156
- def clone(from, to)
157
- UI.section(" > Cloning to Pods folder",'',1) do
158
- git! %Q|clone "#{from}" "#{to}"|
104
+
105
+
106
+ # @!group Checking references
107
+
108
+ # @return [Bool] Wether a reference (commit SHA or tag)
109
+ #
110
+ def ref_exists?(ref)
111
+ Dir.chdir(cache_path) { git "rev-list --max-count=1 #{ref}" }
112
+ $? == 0
113
+ end
114
+
115
+ # @return [void] Checks if a reference exists in the cache and updates
116
+ # only if necessary.
117
+ #
118
+ # @raises if after the update the reference can't be found.
119
+ #
120
+ def ensure_ref_exists(ref)
121
+ return if ref_exists?(ref)
122
+ update_cache
123
+ raise Informative, "[!] Cache unable to find git reference `#{ref}' for `#{url}'.".red unless ref_exists?(ref)
124
+ end
125
+
126
+ # @return [Bool] Wether a branch exists in the cache.
127
+ #
128
+ def branch_exists?(branch)
129
+ Dir.chdir(cache_path) { git "branch --all | grep #{branch}$" } # check for remote branch and do suffix matching ($ anchor)
130
+ $? == 0
131
+ end
132
+
133
+ # @return [void] Checks if a branch exists in the cache and updates
134
+ # only if necessary.
135
+ #
136
+ # @raises if after the update the branch can't be found.
137
+ #
138
+ def ensure_remote_branch_exists(branch)
139
+ return if branch_exists?(branch)
140
+ update_cache
141
+ raise Informative, "[!] Cache unable to find git reference `#{branch}' for `#{url}' (#{$?}).".red unless branch_exists?(branch)
142
+ end
143
+
144
+
145
+ # @!group Cache
146
+
147
+ # The maximum allowed size for the cache expressed in Mb.
148
+ #
149
+ MAX_CACHE_SIZE = 500
150
+
151
+ # @return [Pathname] The directory where the cache for the current git
152
+ # repo is stored.
153
+ #
154
+ # @note The name of the directory is the SHA1 hash value of the URL of
155
+ # the git repo.
156
+ #
157
+ def cache_path
158
+ @cache_path ||= caches_root + "#{Digest::SHA1.hexdigest(url.to_s)}"
159
+ end
160
+
161
+ # @return [Pathname] The directory where the git caches are stored.
162
+ #
163
+ def caches_root
164
+ Pathname.new(File.expand_path("~/Library/Caches/CocoaPods/Git"))
165
+ end
166
+
167
+ # @return [Integer] The global size of the git cache expressed in Mb.
168
+ #
169
+ def caches_size
170
+ `du -cm`.split("\n").last.to_i
171
+ end
172
+
173
+ # @return [Bool] Wether the cache exits.
174
+ #
175
+ # @note The previous implementation of the cache didn't use a barebone
176
+ # git repo. This method takes into account this fact and checks
177
+ # that the cache is actually a barebone repo. If the cache was not
178
+ # barebone it will be deleted and recreated.
179
+ #
180
+ def cache_exist?
181
+ cache_path.exist? &&
182
+ cache_origin_url(cache_path).to_s == url.to_s &&
183
+ Dir.chdir(cache_path) { git("config core.bare").chomp == "true" }
184
+ end
185
+
186
+ # @return [String] The origin URL of the cache with the given directory.
187
+ #
188
+ # @param [String] dir The directory of the cache.
189
+ #
190
+ def cache_origin_url(dir)
191
+ Dir.chdir(dir) { `git config remote.origin.url`.chomp }
192
+ end
193
+
194
+ # @return [void] Creates the barebone repo that will serve as the cache
195
+ # for the current repo.
196
+ #
197
+ def create_cache
198
+ UI.section(" > Creating cache git repo (#{cache_path})",'',1) do
199
+ cache_path.rmtree if cache_path.exist?
200
+ cache_path.mkpath
201
+ git! %Q|clone --mirror "#{url}" "#{cache_path}"|
202
+ end
203
+ end
204
+
205
+ # @return [void] Updates the barebone repo used as a cache against its
206
+ # remote.
207
+ #
208
+ def update_cache
209
+ UI.section(" > Updating cache git repo (#{cache_path})",'',1) do
210
+ Dir.chdir(cache_path) { git! "remote update" }
211
+ end
212
+ end
213
+
214
+ # @return [void] Deletes the oldest caches until they the global size is
215
+ # below the maximum allowed.
216
+ #
217
+ def prune_cache
218
+ return unless caches_root.exist?
219
+ Dir.chdir(caches_root) do
220
+ repos = Pathname.new(caches_root).children.select { |c| c.directory? }.sort_by(&:ctime)
221
+ while caches_size >= MAX_CACHE_SIZE && !repos.empty?
222
+ dir = repos.shift
223
+ UI.message "#{'->'.yellow} Removing git cache for `#{cache_origin_url(dir)}'"
224
+ dir.rmtree
225
+ end
159
226
  end
160
227
  end
161
228
  end
162
229
 
230
+ # This class allows to download tarballs from GitHub and is not currently
231
+ # being used by CocoaPods as the git cache is preferable.
232
+ #
163
233
  class GitHub < Git
164
234
  def download_head
165
235
  download_only? ? download_and_extract_tarball('master') : super
@@ -163,14 +163,15 @@ module Pod
163
163
  #
164
164
  # @return [Array<Strings>] The paths that can be deleted.
165
165
  #
166
- # @note The Paths are downcased to prevent issues. See #568.
166
+ # @note Implementation detail: Don't use Dir#glob as there is an
167
+ # unexplained issue (#568, #572 and #602).
167
168
  #
168
169
  def clean_paths
169
- used = used_files.map(&:downcase)
170
- files = Dir.glob(root + "**/*", File::FNM_DOTMATCH).map(&:downcase)
170
+ cached_used = used_files
171
+ files = Pathname.glob(root + "**/*", File::FNM_DOTMATCH | File::FNM_CASEFOLD).map(&:to_s)
171
172
 
172
173
  files.reject! do |candidate|
173
- candidate.end_with?('.', '..') || used.any? do |path|
174
+ candidate.end_with?('.', '..') || cached_used.any? do |path|
174
175
  path.include?(candidate) || candidate.include?(path)
175
176
  end
176
177
  end
@@ -240,7 +241,7 @@ module Pod
240
241
  # {Specification}.
241
242
  #
242
243
  def source_files_by_spec
243
- options = {:glob => '*.{h,hpp,m,mm,c,cpp}'}
244
+ options = {:glob => '*.{h,hpp,hh,m,mm,c,cpp}'}
244
245
  paths_by_spec(:source_files, options)
245
246
  end
246
247
 
@@ -262,7 +263,7 @@ module Pod
262
263
  def header_files_by_spec
263
264
  result = {}
264
265
  source_files_by_spec.each do |spec, paths|
265
- headers = paths.select { |f| f.extname == '.h' || f.extname == '.hpp' }
266
+ headers = paths.select { |f| f.extname == '.h' || f.extname == '.hpp' || f.extname == '.hh' }
266
267
  result[spec] = headers unless headers.empty?
267
268
  end
268
269
  result
@@ -276,7 +277,7 @@ module Pod
276
277
  # header files (i.e. the build ones) are intended to be public.
277
278
  #
278
279
  def public_header_files_by_spec
279
- public_headers = paths_by_spec(:public_header_files, :glob => '*.{h,hpp}')
280
+ public_headers = paths_by_spec(:public_header_files, :glob => '*.{h,hpp,hh}')
280
281
  build_headers = header_files_by_spec
281
282
 
282
283
  result = {}
@@ -379,7 +380,7 @@ module Pod
379
380
  if (public_h = public_headers[spec]) && !public_h.empty?
380
381
  result += public_h
381
382
  elsif (source_f = source_files[spec]) && !source_f.empty?
382
- build_h = source_f.select { |f| f.extname == '.h' || f.extname == '.hpp' }
383
+ build_h = source_f.select { |f| f.extname == '.h' || f.extname == '.hpp' || f.extname == '.hh' }
383
384
  result += build_h unless build_h.empty?
384
385
  end
385
386
  end
@@ -433,7 +434,7 @@ module Pod
433
434
  # (the files the need to compiled) of the pod.
434
435
  #
435
436
  def implementation_files
436
- relative_source_files.reject { |f| f.extname == '.h' || f.extname == '.hpp' }
437
+ relative_source_files.reject { |f| f.extname == '.h' || f.extname == '.hpp' || f.extname == '.hh' }
437
438
  end
438
439
 
439
440
  # @return [Pathname] The path of the pod relative from the sandbox.
@@ -476,7 +477,7 @@ module Pod
476
477
  # included in the linker search paths.
477
478
  #
478
479
  def headers_excluded_from_search_paths
479
- options = { :glob => '*.{h,hpp}' }
480
+ options = { :glob => '*.{h,hpp,hh}' }
480
481
  paths = paths_by_spec(:exclude_header_search_paths, options)
481
482
  paths.values.compact.uniq
482
483
  end
@@ -35,7 +35,7 @@ module Pod
35
35
  if @path
36
36
  @path
37
37
  else
38
- xcodeprojs = config.project_root.glob('*.xcodeproj')
38
+ xcodeprojs = Pathname.glob(config.project_root + '*.xcodeproj')
39
39
  if xcodeprojs.size == 1
40
40
  @path = xcodeprojs.first
41
41
  end
@@ -196,8 +196,9 @@ module Pod
196
196
 
197
197
  # @!group Helpers
198
198
 
199
- # Wraps a string taking into account the width of the terminal and an
200
- # option indent. Adapted from http://blog.macromates.com/2006/wrapping-text-with-regular-expressions/
199
+ # @return [String] Wraps a string taking into account the width of the
200
+ # terminal and an option indent. Adapted from
201
+ # http://blog.macromates.com/2006/wrapping-text-with-regular-expressions/
201
202
  #
202
203
  # @param [String] txt The string to wrap
203
204
  #
@@ -205,8 +206,12 @@ module Pod
205
206
  #
206
207
  # @return [String] The formatted string.
207
208
  #
209
+ # @note If CocoaPods is not being run in a terminal or the width of the
210
+ # terminal is too small a width of 80 is assumed.
211
+ #
208
212
  def wrap_string(txt, indent = '')
209
213
  width = `stty size`.split(' ')[1].to_i - indent.length
214
+ width = 80 unless width >= 10
210
215
  txt.strip.gsub(/(.{1,#{width}})( +|$)\n?|(.{#{width}})/, indent + "\\1\\3\n")
211
216
  end
212
217
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cocoapods
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.15.1
4
+ version: 0.15.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,24 +10,24 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-10-04 00:00:00.000000000 Z
13
+ date: 2012-10-19 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: xcodeproj
17
17
  requirement: !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
- - - ! '>='
20
+ - - ~>
21
21
  - !ruby/object:Gem::Version
22
- version: 0.3.4
22
+ version: 0.3.5
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  none: false
27
27
  requirements:
28
- - - ! '>='
28
+ - - ~>
29
29
  - !ruby/object:Gem::Version
30
- version: 0.3.4
30
+ version: 0.3.5
31
31
  - !ruby/object:Gem::Dependency
32
32
  name: faraday
33
33
  requirement: !ruby/object:Gem::Requirement
@@ -256,7 +256,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
256
256
  version: '0'
257
257
  segments:
258
258
  - 0
259
- hash: -3399336200991652352
259
+ hash: -1344889839066477359
260
260
  required_rubygems_version: !ruby/object:Gem::Requirement
261
261
  none: false
262
262
  requirements: