cocoapods 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,10 +1,10 @@
1
1
  # CocoaPods
2
2
 
3
- CocoaPods is an Objective-C library package manager. It tries to take away all
4
- hard work of maintaining your dependencies, but in a lean and flexible way.
3
+ CocoaPods is an Objective-C library dependency/package manager. It tries to take
4
+ away all hard work of maintaining your dependencies.
5
5
 
6
6
  Its goal is to create a more centralized overview of open-source libraries and
7
- unify the way in which we deal with them, like RubyGems[http://rubygems.org]
7
+ unify the way in which we deal with them, like [RubyGems](http://rubygems.org)
8
8
  does for the Ruby community.
9
9
 
10
10
  CocoaPods will:
@@ -1,5 +1,5 @@
1
1
  module Pod
2
- VERSION = '0.0.6'
2
+ VERSION = '0.0.7'
3
3
 
4
4
  class Informative < StandardError
5
5
  end
@@ -42,7 +42,7 @@ module Pod
42
42
  s.description = 'An optional longer description of #{@name}.'
43
43
 
44
44
  # A list of file patterns. If the pattern is a directory then the path will
45
- # automatically have '*.{h,m,mm,c,cpp' appended.
45
+ # automatically have '*.{h,m,mm,c,cpp}' appended.
46
46
  s.source_files = 'Classes', 'Classes/**/*.{h,m}'
47
47
 
48
48
  s.xcconfig = { 'OTHER_LDFLAGS' => '-framework SomeRequiredFramework' }
@@ -17,14 +17,15 @@ module Pod
17
17
  end
18
18
 
19
19
  def source_files
20
- source_files = []
20
+ source_files = {}
21
21
  build_specification_sets.each do |set|
22
22
  spec = set.specification
23
+ source_files[spec.name] = []
23
24
  spec.source_files.each do |pattern|
24
25
  pattern = spec.pod_destroot + pattern
25
26
  pattern = pattern + '*.{h,m,mm,c,cpp}' if pattern.directory?
26
27
  pattern.glob.each do |file|
27
- source_files << file.relative_path_from(config.project_pods_root)
28
+ source_files[spec.name] << file.relative_path_from(config.project_pods_root)
28
29
  end
29
30
  end
30
31
  end
@@ -35,7 +36,7 @@ module Pod
35
36
  @xcconfig ||= Xcode::Config.new({
36
37
  # In a workspace this is where the static library headers should be found
37
38
  # We could also make this recursive, but let's let the user decide on that.
38
- 'USER_HEADER_SEARCH_PATHS' => '$(BUILT_PRODUCTS_DIR)/Pods',
39
+ 'USER_HEADER_SEARCH_PATHS' => '"$(BUILT_PRODUCTS_DIR)/Pods"',
39
40
  # search the user headers
40
41
  'ALWAYS_SEARCH_USER_PATHS' => 'YES',
41
42
  })
@@ -46,17 +47,40 @@ module Pod
46
47
  end
47
48
 
48
49
  def generate_project
49
- source_files.each { |file| xcodeproj.add_source_file(file) }
50
+ puts "==> Generating Xcode project and xcconfig" unless config.silent?
51
+ user_header_search_paths = []
50
52
  build_specification_sets.each do |set|
51
- xcconfig << set.specification.xcconfig
53
+ spec = set.specification
54
+ xcconfig.merge!(spec.xcconfig)
55
+ xcodeproj.add_group(spec.name)
56
+
57
+ # Only add implementation files to the compile phase
58
+ spec.implementation_files.each do |file|
59
+ xcodeproj.add_source_file(file, spec.name)
60
+ end
61
+
62
+ # Add header files to a `copy header build phase` for each destination
63
+ # directory in the pod's header directory.
64
+ set.specification.copy_header_mappings.each do |header_dir, files|
65
+ copy_phase_uuid = xcodeproj.add_copy_header_build_phase(spec.name, header_dir)
66
+ files.each do |file|
67
+ xcodeproj.add_source_file(file, spec.name, copy_phase_uuid)
68
+ end
69
+ end
70
+
71
+ # Collect all header search paths
72
+ user_header_search_paths.concat(spec.user_header_search_paths)
52
73
  end
74
+ xcconfig.merge!('USER_HEADER_SEARCH_PATHS' => user_header_search_paths.sort.uniq.join(" "))
53
75
  end
54
76
 
55
77
  # TODO we need a spec that tests that all dependencies are first downloaded/installed
56
78
  # before #generate_project is called!
57
79
  def install!
58
80
  puts "Installing dependencies of: #{@specification.defined_in_file}" unless config.silent?
59
- build_specification_sets.each { |set| set.specification.install! }
81
+ build_specification_sets.each do |set|
82
+ set.specification.install!
83
+ end
60
84
  generate_project
61
85
  xcodeproj.create_in(config.project_pods_root)
62
86
  xcconfig.create_in(config.project_pods_root)
@@ -20,8 +20,8 @@ module Pod
20
20
  result = all.map { |s| s.search_by_name(query, full_text_search) }.flatten
21
21
  if result.empty?
22
22
  extra = ", summary, or description" if full_text_search
23
- raise(Informative, "Unable to find a pod who's name" \
24
- "#{extra} matches `#{query}'")
23
+ raise(Informative, "Unable to find a pod with name" \
24
+ "#{extra} matching `#{query}'")
25
25
  end
26
26
  result
27
27
  end
@@ -1,5 +1,9 @@
1
1
  module Pod
2
- class Specification
2
+ def self._eval_podspec(path)
3
+ eval(path.read, nil, path.to_s)
4
+ end
5
+
6
+ class Specification
3
7
  autoload :Set, 'cocoapods/specification/set'
4
8
 
5
9
  def self.from_podfile(path)
@@ -12,7 +16,7 @@ module Pod
12
16
  end
13
17
 
14
18
  def self.from_podspec(path)
15
- spec = eval(path.read, nil, path.to_s)
19
+ spec = Pod._eval_podspec(path)
16
20
  spec.defined_in_file = path
17
21
  spec
18
22
  end
@@ -95,6 +99,13 @@ module Pod
95
99
  end
96
100
  alias_method :library=, :libraries=
97
101
 
102
+ def header_dir=(dir)
103
+ @header_dir = Pathname.new(dir)
104
+ end
105
+ def header_dir
106
+ @header_dir || pod_destroot_name
107
+ end
108
+
98
109
  # Not attributes
99
110
 
100
111
  include Config::Mixin
@@ -125,7 +136,13 @@ module Pod
125
136
  if part_of_other_pod?
126
137
  part_of_specification.pod_destroot
127
138
  else
128
- config.project_pods_root + "#{@name}-#{@version}"
139
+ config.project_pods_root + @name
140
+ end
141
+ end
142
+
143
+ def pod_destroot_name
144
+ if root = pod_destroot
145
+ root.basename
129
146
  end
130
147
  end
131
148
 
@@ -137,6 +154,57 @@ module Pod
137
154
  @name.nil? && @version.nil?
138
155
  end
139
156
 
157
+ # Returns all source files of this pod including header files.
158
+ def expanded_source_files
159
+ files = []
160
+ source_files.each do |pattern|
161
+ pattern = pod_destroot + pattern
162
+ pattern = pattern + '*.{h,m,mm,c,cpp}' if pattern.directory?
163
+ pattern.glob.each do |file|
164
+ files << file.relative_path_from(config.project_pods_root)
165
+ end
166
+ end
167
+ files
168
+ end
169
+
170
+ def implementation_files
171
+ expanded_source_files.select { |f| f.extname != '.h' }
172
+ end
173
+
174
+ # Returns only the header files of this pod.
175
+ def header_files
176
+ expanded_source_files.select { |f| f.extname == '.h' }
177
+ end
178
+
179
+ # This method takes a header path and returns the location it should have
180
+ # in the pod's header dir.
181
+ #
182
+ # By default all headers are copied to the pod's header dir without any
183
+ # namespacing. You can, however, override this method in the podspec, or
184
+ # copy_header_mappings for full control.
185
+ def copy_header_mapping(from)
186
+ from.basename
187
+ end
188
+
189
+ # See copy_header_mapping.
190
+ def copy_header_mappings
191
+ header_files.inject({}) do |mappings, from|
192
+ from_without_prefix = from.relative_path_from(pod_destroot_name)
193
+ to = header_dir + copy_header_mapping(from_without_prefix)
194
+ (mappings[to.dirname] ||= []) << from
195
+ mappings
196
+ end
197
+ end
198
+
199
+ # Returns a list of search paths where the pod's headers can be found. This
200
+ # includes the pod's header dir root and any other directories that might
201
+ # have been added by overriding the copy_header_mapping/copy_header_mappings
202
+ # methods.
203
+ def user_header_search_paths
204
+ dirs = [header_dir] + copy_header_mappings.keys
205
+ dirs.map { |dir| %{"$(BUILT_PRODUCTS_DIR)/Pods/#{dir}"} }
206
+ end
207
+
140
208
  def to_s
141
209
  if from_podfile?
142
210
  "podfile at `#{@defined_in_file}'"
@@ -75,7 +75,10 @@ module Pod
75
75
  # Returns Pod::Version instances, for each version directory, sorted from
76
76
  # highest version to lowest.
77
77
  def versions
78
- @pod_dir.children.map { |v| Version.new(v.basename) }.sort.reverse
78
+ @pod_dir.children.map do |v|
79
+ basename = v.basename.to_s
80
+ Version.new(basename) if v.directory? && basename[0,1] != '.'
81
+ end.compact.sort.reverse
79
82
  end
80
83
  end
81
84
  end
@@ -41,21 +41,27 @@ module Pod
41
41
  find_objects(conditions).first
42
42
  end
43
43
 
44
+ IGNORE_GROUPS = ['Pods', 'Frameworks', 'Products', 'Supporting Files']
44
45
  def source_files
45
- conditions = { 'isa' => 'PBXFileReference', 'sourceTree' => 'SOURCE_ROOT' }
46
- find_objects(conditions).map do |_, object|
47
- if %w{ .h .m .mm .c .cpp }.include?(File.extname(object['path']))
48
- Pathname.new(object['path'])
49
- end
50
- end.compact
46
+ source_files = {}
47
+ find_objects('isa' => 'PBXGroup').each do |_, object|
48
+ next if object['name'].nil? || IGNORE_GROUPS.include?(object['name'])
49
+ source_files[object['name']] = object['children'].map do |uuid|
50
+ Pathname.new(objects[uuid]['path'])
51
+ end
52
+ end
53
+ source_files
51
54
  end
52
55
 
53
- def add_source_file(file, compiler_flags = nil)
56
+ def add_source_file(file, group, phase_uuid = nil, compiler_flags = nil)
54
57
  file_ref_uuid = add_file_reference(file, 'SOURCE_ROOT')
55
- add_file_to_group(file_ref_uuid, 'Pods')
58
+ add_object_to_group(file_ref_uuid, group)
56
59
  if file.extname == '.h'
57
60
  build_file_uuid = add_build_file(file_ref_uuid, "settings" => { "ATTRIBUTES" => ["Public"] })
58
- add_file_to_list('PBXHeadersBuildPhase', build_file_uuid)
61
+ # Working around a bug in Xcode 4.2 betas, remove this once the Xcode bug is fixed:
62
+ # https://github.com/alloy/cocoapods/issues/13
63
+ #add_file_to_list('PBXHeadersBuildPhase', build_file_uuid)
64
+ add_file_to_list('PBXCopyFilesBuildPhase', build_file_uuid, phase_uuid)
59
65
  else
60
66
  extra = compiler_flags ? {"settings" => { "COMPILER_FLAGS" => compiler_flags }} : {}
61
67
  build_file_uuid = add_build_file(file_ref_uuid, extra)
@@ -63,6 +69,17 @@ module Pod
63
69
  end
64
70
  file_ref_uuid
65
71
  end
72
+
73
+ def add_group(name)
74
+ group_uuid = add_object({
75
+ "name" => name,
76
+ "isa" => "PBXGroup",
77
+ "sourceTree" => "<group>",
78
+ "children" => []
79
+ })
80
+ add_object_to_group(group_uuid, 'Pods')
81
+ group_uuid
82
+ end
66
83
 
67
84
  def create_in(pods_root)
68
85
  puts " * Copying contents of template directory `#{@template_dir}' to `#{pods_root}'" if config.verbose?
@@ -72,6 +89,27 @@ module Pod
72
89
  @template.writeToFile(pbxproj.to_s, atomically:true)
73
90
  end
74
91
 
92
+ # TODO add comments, or even constants, describing what these magic numbers are.
93
+ def add_copy_header_build_phase(name, path)
94
+ phase_uuid = add_object({
95
+ "isa" => "PBXCopyFilesBuildPhase",
96
+ "buildActionMask" => "2147483647",
97
+ "dstPath" => "$(PUBLIC_HEADERS_FOLDER_PATH)/#{path}",
98
+ "dstSubfolderSpec" => "16",
99
+ "files" => [],
100
+ "name" => "Copy #{name} Public Headers",
101
+ "runOnlyForDeploymentPostprocessing" => "0",
102
+ })
103
+
104
+ object_uuid, object = objects_by_isa('PBXNativeTarget').first
105
+ object['buildPhases'] << phase_uuid
106
+ phase_uuid
107
+ end
108
+
109
+ def objects_by_isa(isa)
110
+ objects.select { |_, object| object['isa'] == isa }
111
+ end
112
+
75
113
  private
76
114
 
77
115
  def add_object(object)
@@ -88,34 +126,37 @@ module Pod
88
126
  "path" => path.to_s,
89
127
  })
90
128
  end
91
-
129
+
92
130
  def add_build_file(file_ref_uuid, extra = {})
93
131
  add_object(extra.merge({
94
132
  "isa" => "PBXBuildFile",
95
133
  "fileRef" => file_ref_uuid
96
134
  }))
97
135
  end
98
-
99
- def add_file_to_list(isa, build_file_uuid)
100
- object_uuid, object = objects_by_isa(isa).first
136
+
137
+ # TODO refactor to create PBX object classes and make this take aither a uuid or a class instead of both.
138
+ def add_file_to_list(isa, build_file_uuid, phase_uuid = nil)
139
+ objects = objects_by_isa(isa)
140
+ _ = object = nil
141
+ if phase_uuid.nil?
142
+ _, object = objects.first
143
+ else
144
+ object = objects[phase_uuid]
145
+ end
101
146
  object['files'] << build_file_uuid
102
147
  end
103
148
 
104
- def add_file_to_group(file_ref_uuid, name)
149
+ def add_object_to_group(object_ref_uuid, name)
105
150
  object_uuid, object = objects.find do |_, object|
106
151
  object['isa'] == 'PBXGroup' && object['name'] == name
107
152
  end
108
- object['children'] << file_ref_uuid
153
+ object['children'] << object_ref_uuid
109
154
  end
110
155
 
111
156
  def objects
112
157
  @template['objects']
113
158
  end
114
159
 
115
- def objects_by_isa(isa)
116
- objects.select { |_, object| object['isa'] == isa }
117
- end
118
-
119
160
  def generate_uuid
120
161
  _uuid = CFUUIDCreate(nil)
121
162
  uuid = CFUUIDCreateString(nil, _uuid)
@@ -10,6 +10,19 @@
10
10
  515B0FB9141D52E0001DC3E6 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 515B0FB8141D52E0001DC3E6 /* Foundation.framework */; };
11
11
  /* End PBXBuildFile section */
12
12
 
13
+ /* Begin PBXCopyFilesBuildPhase section */
14
+ 82A8B61C142F7EC7006897C9 /* Copy Public Headers */ = {
15
+ isa = PBXCopyFilesBuildPhase;
16
+ buildActionMask = 2147483647;
17
+ dstPath = "$(PUBLIC_HEADERS_FOLDER_PATH)";
18
+ dstSubfolderSpec = 16;
19
+ files = (
20
+ );
21
+ name = "Copy Public Headers";
22
+ runOnlyForDeploymentPostprocessing = 0;
23
+ };
24
+ /* End PBXCopyFilesBuildPhase section */
25
+
13
26
  /* Begin PBXFileReference section */
14
27
  515160D0141EC5D100EBB823 /* Pods.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Pods.xcconfig; sourceTree = "<group>"; };
15
28
  515B0FB5141D52E0001DC3E6 /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -92,6 +105,7 @@
92
105
  515B0FB1141D52E0001DC3E6 /* Sources */,
93
106
  515B0FB2141D52E0001DC3E6 /* Frameworks */,
94
107
  515B0FB3141D52E0001DC3E6 /* Headers */,
108
+ 82A8B61C142F7EC7006897C9 /* Copy Public Headers */,
95
109
  );
96
110
  buildRules = (
97
111
  );
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 6
9
- version: 0.0.6
8
+ - 7
9
+ version: 0.0.7
10
10
  platform: ruby
11
11
  authors:
12
12
  - Eloy Duran
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2011-09-17 00:00:00 -05:00
17
+ date: 2011-09-17 00:00:00 +02:00
18
18
  default_executable:
19
19
  dependencies: []
20
20