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 +3 -3
- data/lib/cocoapods.rb +1 -1
- data/lib/cocoapods/command/spec.rb +1 -1
- data/lib/cocoapods/installer.rb +30 -6
- data/lib/cocoapods/source.rb +2 -2
- data/lib/cocoapods/specification.rb +71 -3
- data/lib/cocoapods/specification/set.rb +4 -1
- data/lib/cocoapods/xcode/project.rb +60 -19
- data/xcode-project-templates/cocoa-touch-static-library/Pods.xcodeproj/project.pbxproj +14 -0
- metadata +3 -3
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
|
4
|
-
hard work of maintaining your dependencies
|
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
|
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:
|
data/lib/cocoapods.rb
CHANGED
@@ -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' }
|
data/lib/cocoapods/installer.rb
CHANGED
@@ -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
|
-
|
50
|
+
puts "==> Generating Xcode project and xcconfig" unless config.silent?
|
51
|
+
user_header_search_paths = []
|
50
52
|
build_specification_sets.each do |set|
|
51
|
-
|
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
|
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)
|
data/lib/cocoapods/source.rb
CHANGED
@@ -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
|
24
|
-
"#{extra}
|
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
|
-
|
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 =
|
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 +
|
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
|
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
|
-
|
46
|
-
find_objects(
|
47
|
-
if
|
48
|
-
|
49
|
-
|
50
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
100
|
-
|
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
|
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'] <<
|
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
|
-
-
|
9
|
-
version: 0.0.
|
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
|
17
|
+
date: 2011-09-17 00:00:00 +02:00
|
18
18
|
default_executable:
|
19
19
|
dependencies: []
|
20
20
|
|