cocoapods 0.0.6 → 0.0.7

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.
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