cocoapods 0.16.4 → 0.17.0.rc1

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 (71) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +108 -0
  3. data/README.md +3 -3
  4. data/bin/pod +1 -1
  5. data/lib/cocoapods.rb +31 -31
  6. data/lib/cocoapods/command.rb +62 -107
  7. data/lib/cocoapods/command/inter_process_communication.rb +103 -0
  8. data/lib/cocoapods/command/list.rb +45 -44
  9. data/lib/cocoapods/command/outdated.rb +28 -25
  10. data/lib/cocoapods/command/project.rb +90 -0
  11. data/lib/cocoapods/command/push.rb +50 -32
  12. data/lib/cocoapods/command/repo.rb +125 -155
  13. data/lib/cocoapods/command/search.rb +23 -12
  14. data/lib/cocoapods/command/setup.rb +103 -64
  15. data/lib/cocoapods/command/spec.rb +329 -90
  16. data/lib/cocoapods/config.rb +197 -44
  17. data/lib/cocoapods/downloader.rb +47 -34
  18. data/lib/cocoapods/executable.rb +98 -41
  19. data/lib/cocoapods/external_sources.rb +325 -0
  20. data/lib/cocoapods/file_list.rb +8 -1
  21. data/lib/cocoapods/gem_version.rb +7 -0
  22. data/lib/cocoapods/generator/acknowledgements.rb +71 -7
  23. data/lib/cocoapods/generator/acknowledgements/markdown.rb +10 -9
  24. data/lib/cocoapods/generator/acknowledgements/plist.rb +9 -8
  25. data/lib/cocoapods/generator/copy_resources_script.rb +2 -2
  26. data/lib/cocoapods/generator/documentation.rb +153 -37
  27. data/lib/cocoapods/generator/prefix_header.rb +82 -0
  28. data/lib/cocoapods/generator/target_header.rb +58 -0
  29. data/lib/cocoapods/generator/xcconfig.rb +130 -0
  30. data/lib/cocoapods/hooks/installer_representation.rb +123 -0
  31. data/lib/cocoapods/hooks/library_representation.rb +79 -0
  32. data/lib/cocoapods/hooks/pod_representation.rb +74 -0
  33. data/lib/cocoapods/installer.rb +398 -147
  34. data/lib/cocoapods/installer/analyzer.rb +556 -0
  35. data/lib/cocoapods/installer/analyzer/sandbox_analyzer.rb +253 -0
  36. data/lib/cocoapods/installer/file_references_installer.rb +179 -0
  37. data/lib/cocoapods/installer/pod_source_installer.rb +289 -0
  38. data/lib/cocoapods/installer/target_installer.rb +307 -112
  39. data/lib/cocoapods/installer/user_project_integrator.rb +140 -176
  40. data/lib/cocoapods/installer/user_project_integrator/target_integrator.rb +193 -0
  41. data/lib/cocoapods/library.rb +195 -0
  42. data/lib/cocoapods/open_uri.rb +16 -14
  43. data/lib/cocoapods/project.rb +175 -52
  44. data/lib/cocoapods/resolver.rb +151 -164
  45. data/lib/cocoapods/sandbox.rb +276 -54
  46. data/lib/cocoapods/sandbox/file_accessor.rb +210 -0
  47. data/lib/cocoapods/sandbox/headers_store.rb +96 -0
  48. data/lib/cocoapods/sandbox/path_list.rb +178 -0
  49. data/lib/cocoapods/sources_manager.rb +218 -0
  50. data/lib/cocoapods/user_interface.rb +82 -18
  51. data/lib/cocoapods/{command → user_interface}/error_report.rb +5 -5
  52. data/lib/cocoapods/validator.rb +379 -0
  53. metadata +74 -55
  54. data/lib/cocoapods/command/install.rb +0 -55
  55. data/lib/cocoapods/command/linter.rb +0 -317
  56. data/lib/cocoapods/command/update.rb +0 -25
  57. data/lib/cocoapods/dependency.rb +0 -285
  58. data/lib/cocoapods/downloader/git.rb +0 -276
  59. data/lib/cocoapods/downloader/http.rb +0 -99
  60. data/lib/cocoapods/downloader/mercurial.rb +0 -26
  61. data/lib/cocoapods/downloader/subversion.rb +0 -42
  62. data/lib/cocoapods/local_pod.rb +0 -620
  63. data/lib/cocoapods/lockfile.rb +0 -274
  64. data/lib/cocoapods/platform.rb +0 -127
  65. data/lib/cocoapods/podfile.rb +0 -551
  66. data/lib/cocoapods/source.rb +0 -223
  67. data/lib/cocoapods/specification.rb +0 -579
  68. data/lib/cocoapods/specification/set.rb +0 -175
  69. data/lib/cocoapods/specification/statistics.rb +0 -112
  70. data/lib/cocoapods/user_interface/ui_pod.rb +0 -130
  71. data/lib/cocoapods/version.rb +0 -26
@@ -0,0 +1,210 @@
1
+ module Pod
2
+ class Sandbox
3
+
4
+ # Resolves the file patterns of a specification against its root directory,
5
+ # taking into account any exclude pattern and the default extensions to use
6
+ # for directories.
7
+ #
8
+ class FileAccessor
9
+
10
+ HEADER_EXTENSIONS = Xcodeproj::Constants::HEADER_FILES_EXTENSIONS
11
+
12
+ # @return [Sandbox::PathList] the directory where the source of the Pod
13
+ # is located.
14
+ #
15
+ attr_reader :path_list
16
+
17
+ # @return [Specification::Consumer] the consumer of the specification for
18
+ # which the file patterns should be resolved.
19
+ #
20
+ attr_reader :spec_consumer
21
+
22
+ # @param [Sandbox::PathList] path_list @see path_list
23
+ # @param [Specification::Consumer] spec_consumer @see spec_consumer
24
+ #
25
+ def initialize(path_list, spec_consumer)
26
+ @path_list = path_list
27
+ @spec_consumer = spec_consumer
28
+
29
+ unless @spec_consumer
30
+ raise Informative, "Attempt to initialize File Accessor without a specification consumer."
31
+ end
32
+ end
33
+
34
+ # @return [Specification] the specification.
35
+ #
36
+ def spec
37
+ spec_consumer.spec
38
+ end
39
+
40
+ # @return [Specification] the platform used to consume the specification.
41
+ #
42
+ def platform
43
+ spec_consumer.platform
44
+ end
45
+
46
+ # @return [String] A string suitable for debugging.
47
+ #
48
+ def inspect
49
+ "<#{self.class} spec=#{spec.name} platform=#{spec_consumer.platform} root=#{path_list.root}>"
50
+ end
51
+
52
+ #-----------------------------------------------------------------------#
53
+
54
+ public
55
+
56
+ # @!group Paths
57
+
58
+ # @return [Array<Pathname>] the source files of the specification.
59
+ #
60
+ def source_files
61
+ paths_for_attribute(:source_files)
62
+ end
63
+
64
+ # @return [Array<Pathname>] the headers of the specification.
65
+ #
66
+ def headers
67
+ extensions = HEADER_EXTENSIONS
68
+ source_files.select { |f| extensions.include?(f.extname) }
69
+ end
70
+
71
+ # @return [Array<Pathname>] the public headers of the specification.
72
+ #
73
+ def public_headers
74
+ public_headers = paths_for_attribute(:public_header_files)
75
+ if public_headers.nil? || public_headers.empty?
76
+ headers
77
+ else
78
+ public_headers
79
+ end
80
+ end
81
+
82
+ # @return [Hash{ Symbol => Array<Pathname> }] the resources of the
83
+ # specification grouped by destination.
84
+ #
85
+ def resources
86
+ options = {
87
+ :exclude_patterns => spec_consumer.exclude_files,
88
+ :include_dirs => true,
89
+ }
90
+ expanded_paths(spec_consumer.resources, options)
91
+ end
92
+
93
+ # @return [Array<Pathname>] the files of the specification to preserve.
94
+ #
95
+ def preserve_paths
96
+ paths_for_attribute(:preserve_paths)
97
+ end
98
+
99
+ # @return [Pathname] The of the prefix header file of the specification.
100
+ #
101
+ def prefix_header
102
+ if spec_consumer.prefix_header_file
103
+ path_list.root + spec_consumer.prefix_header_file
104
+ end
105
+ end
106
+
107
+ # @return [Pathname] The path of the auto-detected README file.
108
+ #
109
+ def readme
110
+ path_list.glob(%w[ readme{*,.*} ]).first
111
+ end
112
+
113
+ # @return [Pathname] The path of the license file as indicated in the
114
+ # specification or auto-detected.
115
+ #
116
+ def license
117
+ if spec_consumer.spec.root.license[:file]
118
+ path_list.root + spec_consumer.spec.root.license[:file]
119
+ else
120
+ path_list.glob(%w[ licen{c,s}e{*,.*} ]).first
121
+ end
122
+ end
123
+
124
+ #-----------------------------------------------------------------------#
125
+
126
+ private
127
+
128
+ # @!group Private helpers
129
+
130
+ # Returns the list of the paths founds in the file system for the
131
+ # attribute with given name. It takes into account any dir pattern and
132
+ # any file excluded in the specification.
133
+ #
134
+ # @param [Symbol] attribute
135
+ # the name of the attribute.
136
+ #
137
+ # @return [Array<Pathname>] the paths.
138
+ #
139
+ def paths_for_attribute(attribute)
140
+ file_patterns = spec_consumer.send(attribute)
141
+ options = {
142
+ :exclude_patterns => spec_consumer.exclude_files,
143
+ :dir_pattern => glob_for_attribute(attribute)
144
+ }
145
+ expanded_paths(file_patterns, options)
146
+ end
147
+
148
+ # Returns the pattern to use to glob a directory for an attribute.
149
+ #
150
+ # @param [Symbol] attribute
151
+ # the name of the attribute
152
+ #
153
+ # @return [String] the glob pattern.
154
+ #
155
+ # @todo Move to the cocoapods-core so it appears in the docs?
156
+ #
157
+ def glob_for_attribute(attrbute)
158
+ globs = {
159
+ :source_files => '*.{h,hpp,hh,m,mm,c,cpp}'.freeze,
160
+ :public_header_files => "*.{#{ HEADER_EXTENSIONS * ',' }}".freeze,
161
+ }
162
+ globs[attrbute]
163
+ end
164
+
165
+ # Matches the given patterns to the file present in the root of the path
166
+ # list.
167
+ #
168
+ # @param [Array<String, FileList>] patterns
169
+ # The patterns to expand.
170
+ #
171
+ # @param [String] dir_pattern
172
+ # The pattern to add to directories.
173
+ #
174
+ # @param [Array<String>] exclude_patterns
175
+ # The exclude patterns to pass to the PathList.
176
+ #
177
+ # @raise [Informative] If the pod does not exists.
178
+ #
179
+ # @return [Array<Pathname>] A list of the paths.
180
+ #
181
+ # @todo Implement case insensitive search
182
+ #
183
+ def expanded_paths(patterns, options = {})
184
+ return [] if patterns.empty?
185
+
186
+ file_lists = patterns.select { |p| p.is_a?(FileList) }
187
+ glob_patterns = patterns - file_lists
188
+
189
+ result = []
190
+ result << path_list.glob(glob_patterns, options)
191
+ result << file_lists.map do |file_list|
192
+ file_list.prepend_patterns(path_list.root)
193
+ file_list.glob
194
+ end
195
+
196
+ unless file_lists.empty?
197
+ # TODO Restore warning in 0.17 proper
198
+ # UI.warn "[#{spec_consumer.spec.name}] The usage of Rake FileList is deprecated. Use `exclude_files`."
199
+ end
200
+
201
+ result.flatten.compact.uniq
202
+ end
203
+
204
+ #-----------------------------------------------------------------------#
205
+
206
+ end
207
+ end
208
+ end
209
+
210
+
@@ -0,0 +1,96 @@
1
+ module Pod
2
+ class Sandbox
3
+
4
+ # Provides support for managing a header directory. It also keeps track of
5
+ # the header search paths.
6
+ #
7
+ class HeadersStore
8
+
9
+ # @return [Pathname] the absolute path of this header directory.
10
+ #
11
+ def root
12
+ @sandbox.root + @relative_path
13
+ end
14
+
15
+ # @return [Sandbox] the sandbox where this header directory is stored.
16
+ #
17
+ attr_reader :sandbox
18
+
19
+ # @param [Sandbox] @see sandbox
20
+ #
21
+ # @param [String] relative_path
22
+ # the relative path to the sandbox root and hence to the Pods
23
+ # project.
24
+ #
25
+ def initialize(sandbox, relative_path)
26
+ @sandbox = sandbox
27
+ @relative_path = relative_path
28
+ @search_paths = [relative_path]
29
+ end
30
+
31
+ # @return [Array<String>] All the search paths of the header directory in
32
+ # xcconfig format. The paths are specified relative to the pods
33
+ # root with the `${PODS_ROOT}` variable.
34
+ #
35
+ def search_paths
36
+ @search_paths.uniq.map { |path| "${PODS_ROOT}/#{path}" }
37
+ end
38
+
39
+ # Removes the directory as it is regenerated from scratch during each
40
+ # installation.
41
+ #
42
+ # @return [void]
43
+ #
44
+ def implode!
45
+ root.rmtree if root.exist?
46
+ end
47
+
48
+ #-----------------------------------------------------------------------#
49
+
50
+ public
51
+
52
+ # @!group Adding headers
53
+
54
+ # Adds a header to the directory.
55
+ #
56
+ # @param [Pathname] namespace_path
57
+ # the path where the header file should be stored relative to the
58
+ # headers directory.
59
+ #
60
+ # @param [Pathname] relative_header_path
61
+ # the path of the header file relative to the sandbox.
62
+ #
63
+ # @note This method adds the files to the search paths.
64
+ #
65
+ # @return [Pathname]
66
+ #
67
+ def add_files(namespace, relative_header_paths)
68
+ add_search_path(namespace)
69
+ namespaced_path = root + namespace
70
+ namespaced_path.mkpath unless File.exist?(namespaced_path)
71
+
72
+ relative_header_paths.map do |relative_header_path|
73
+ source = (@sandbox.root + relative_header_path).relative_path_from(namespaced_path)
74
+ Dir.chdir(namespaced_path) do
75
+ FileUtils.ln_sf(source, relative_header_path.basename)
76
+ end
77
+ namespaced_path + relative_header_path.basename
78
+ end
79
+ end
80
+
81
+ # Adds an header search path to the sandbox.
82
+ #
83
+ # @param [Pathname] path
84
+ # the path tho add.
85
+ #
86
+ # @return [void]
87
+ #
88
+ def add_search_path(path)
89
+ @search_paths << Pathname.new(@relative_path) + path
90
+ end
91
+
92
+ #-----------------------------------------------------------------------#
93
+
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,178 @@
1
+ module Pod
2
+ class Sandbox
3
+
4
+ # The PathList class is designed to perform multiple glob matches against
5
+ # a given directory. Basically, it generates a list of all the children
6
+ # paths and matches the globs patterns against them, resulting in just one
7
+ # access to the file system.
8
+ #
9
+ # @note A PathList once it has generated the list of the paths this is
10
+ # updated only if explicitly requested by calling
11
+ # {#read_file_system}
12
+ #
13
+ class PathList
14
+
15
+ # @return [Pathname] The root of the list whose files and directories
16
+ # are used to perform the matching operations.
17
+ #
18
+ attr_accessor :root
19
+
20
+ # @param [Pathname] root The root of the PathList.
21
+ #
22
+ def initialize(root)
23
+ @root = root
24
+ end
25
+
26
+ # @return [Array<String>] The list of absolute the path of all the files
27
+ # contained in {root}.
28
+ #
29
+ def files
30
+ read_file_system unless @files
31
+ @files
32
+ end
33
+
34
+ # @return [Array<String>] The list of absolute the path of all the
35
+ # directories contained in {root}.
36
+ #
37
+ def dirs
38
+ read_file_system unless @dirs
39
+ @dirs
40
+ end
41
+
42
+ # @return [void] Reads the file system and populates the files and paths
43
+ # lists.
44
+ #
45
+ def read_file_system
46
+ unless root.exist?
47
+ raise Informative, "Attempt to read non existent folder `#{root}`."
48
+ end
49
+ root_length = root.to_s.length+1
50
+ paths = Dir.glob(root + "**/*", File::FNM_DOTMATCH)
51
+ absolute_dirs = paths.select { |path| File.directory?(path) }
52
+ relative_dirs = absolute_dirs.map { |p| p[root_length..-1] }
53
+ absolute_paths = paths.reject { |p| p == "#{root}/." || p == "#{root}/.." }
54
+ relative_paths = absolute_paths.map { |p| p[root_length..-1] }
55
+ @files = relative_paths - relative_dirs
56
+ @dirs = relative_dirs.map { |d| d.gsub(/\/\.\.?$/,'') }.reject { |d| d == '.' || d == '..' } .uniq
57
+ end
58
+
59
+ #-----------------------------------------------------------------------#
60
+
61
+ public
62
+
63
+ # @!group Globbing
64
+
65
+ # @return [Array<Pathname>] Similar to {glob} but returns the absolute
66
+ # paths.
67
+ #
68
+ def glob(patterns, options = {})
69
+ relative_glob(patterns, options).map {|p| root + p }
70
+ end
71
+
72
+ # @return [Array<Pathname>] The list of relative paths that are case
73
+ # insensitively matched by a given pattern. This method emulates
74
+ # {Dir#glob} with the {File::FNM_CASEFOLD} option.
75
+ #
76
+ # @param [String,Array<String>] patterns
77
+ # A single {Dir#glob} like pattern, or a list of patterns.
78
+ #
79
+ # @param [String] dir_pattern
80
+ # An optional pattern to append to a pattern, if it is the path
81
+ # to a directory.
82
+ #
83
+ def relative_glob(patterns, options = {})
84
+ return [] if patterns.empty?
85
+
86
+ dir_pattern = options[:dir_pattern]
87
+ exclude_patterns = options[:exclude_patterns]
88
+ include_dirs = options[:include_dirs]
89
+
90
+ if include_dirs
91
+ full_list = files + dirs
92
+ else
93
+ full_list = files
94
+ end
95
+
96
+ list = Array(patterns).map do |pattern|
97
+ if pattern.is_a?(String)
98
+ pattern += '/' + dir_pattern if directory?(pattern) && dir_pattern
99
+ expanded_patterns = dir_glob_equivalent_patterns(pattern)
100
+ full_list.select do |path|
101
+ expanded_patterns.any? do |p|
102
+ File.fnmatch(p, path, File::FNM_CASEFOLD | File::FNM_PATHNAME)
103
+ end
104
+ end
105
+ else
106
+ full_list.select { |path| path.match(pattern) }
107
+ end
108
+ end.flatten
109
+
110
+ list = list.map { |path| Pathname.new(path) }
111
+ list -= relative_glob(exclude_patterns) if exclude_patterns
112
+ list
113
+ end
114
+
115
+ #-----------------------------------------------------------------------#
116
+
117
+ private
118
+
119
+ # @!group Private helpers
120
+
121
+ # @return [Bool] Wether a path is a directory. The result of this method
122
+ # computed without accessing the file system and is case
123
+ # insensitive.
124
+ #
125
+ # @param [String, Pathname] sub_path The path that could be a directory.
126
+ #
127
+ def directory?(sub_path)
128
+ sub_path = sub_path.to_s.downcase.sub(/\/$/, '')
129
+ dirs.any? { |dir| dir.downcase == sub_path }
130
+ end
131
+
132
+ # @return [Array<String>] An array of patterns converted from a
133
+ # {Dir.glob} pattern to patterns that {File.fnmatch} can handle.
134
+ # This is used by the {#relative_glob} method to emulate
135
+ # {Dir.glob}.
136
+ #
137
+ # The expansion provides support for:
138
+ #
139
+ # - Literals
140
+ #
141
+ # dir_glob_equivalent_patterns('{file1,file2}.{h,m}')
142
+ # => ["file1.h", "file1.m", "file2.h", "file2.m"]
143
+ #
144
+ # - Matching the direct children of a directory with `**`
145
+ #
146
+ # dir_glob_equivalent_patterns('Classes/**/file.m')
147
+ # => ["Classes/**/file.m", "Classes/file.m"]
148
+ #
149
+ # @param [String] pattern A {Dir#glob} like pattern.
150
+ #
151
+ def dir_glob_equivalent_patterns(pattern)
152
+ pattern = pattern.gsub('/**/', '{/**/,/}')
153
+ values_by_set = {}
154
+ pattern.scan(/\{[^}]*\}/) do |set|
155
+ values = set.gsub(/[{}]/, '').split(',')
156
+ values_by_set[set] = values
157
+ end
158
+
159
+ if values_by_set.empty?
160
+ [ pattern ]
161
+ else
162
+ patterns = [ pattern ]
163
+ values_by_set.each do |set, values|
164
+ patterns = patterns.map do |old_pattern|
165
+ values.map do |value|
166
+ old_pattern.gsub(set, value)
167
+ end
168
+ end.flatten
169
+ end
170
+ patterns
171
+ end
172
+ end
173
+
174
+ #-----------------------------------------------------------------------#
175
+
176
+ end
177
+ end
178
+ end