Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
C
cocoapods
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
gengmeiios
cocoapods
Commits
ec3d6542
Commit
ec3d6542
authored
Nov 05, 2011
by
Eloy Duran
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'dependency-targets'. Closes #11.
parents
99417d11
340bdb1e
Show whitespace changes
Inline
Side-by-side
Showing
24 changed files
with
886 additions
and
613 deletions
+886
-613
Podfile
examples/MacRubySample/Podfile
+8
-0
project.pbxproj
examples/SSCatalog/SSCatalog.xcodeproj/project.pbxproj
+1
-1
bridge_support_generator.rb
lib/cocoapods/bridge_support_generator.rb
+2
-4
installer.rb
lib/cocoapods/installer.rb
+138
-40
podfile.rb
lib/cocoapods/podfile.rb
+63
-5
resolver.rb
lib/cocoapods/resolver.rb
+5
-5
specification.rb
lib/cocoapods/specification.rb
+5
-4
config.rb
lib/cocoapods/xcode/config.rb
+2
-2
copy_resources_script.rb
lib/cocoapods/xcode/copy_resources_script.rb
+15
-3
project.rb
lib/cocoapods/xcode/project.rb
+324
-139
integration_spec.rb
spec/integration_spec.rb
+76
-26
bridge_support_generator_spec.rb
spec/unit/bridge_support_generator_spec.rb
+2
-2
installer_spec.rb
spec/unit/installer_spec.rb
+5
-70
podfile_spec.rb
spec/unit/podfile_spec.rb
+41
-0
config_spec.rb
spec/unit/xcode/config_spec.rb
+1
-1
project_spec.rb
spec/unit/xcode/project_spec.rb
+195
-53
Pods-Prefix.pch
xcode-project-templates/cocoa-static-library/Pods-Prefix.pch
+0
-7
Pods.xcconfig
xcode-project-templates/cocoa-static-library/Pods.xcconfig
+0
-1
project.pbxproj
...lates/cocoa-static-library/Pods.xcodeproj/project.pbxproj
+0
-104
PodsResources.sh
...e-project-templates/cocoa-static-library/PodsResources.sh
+0
-8
Pods-Prefix.pch
...ject-templates/cocoa-touch-static-library/Pods-Prefix.pch
+0
-7
Pods.xcconfig
...roject-templates/cocoa-touch-static-library/Pods.xcconfig
+0
-1
project.pbxproj
...cocoa-touch-static-library/Pods.xcodeproj/project.pbxproj
+3
-122
PodsResources.sh
...ect-templates/cocoa-touch-static-library/PodsResources.sh
+0
-8
No files found.
examples/MacRubySample/Podfile
View file @
ec3d6542
...
...
@@ -4,3 +4,11 @@ generate_bridge_support!
dependency
'ASIHTTPRequest'
dependency
'SBJson'
target
:debug
do
dependency
'CocoaLumberjack'
end
target
:test
,
:exclusive
=>
true
do
dependency
'Kiwi'
end
examples/SSCatalog/SSCatalog.xcodeproj/project.pbxproj
View file @
ec3d6542
...
...
@@ -330,7 +330,7 @@
);
runOnlyForDeploymentPostprocessing
=
0
;
shellPath
=
/bin/sh
;
shellScript
=
"${SRCROOT}/Pods/Pods
R
esources.sh"
;
shellScript
=
"${SRCROOT}/Pods/Pods
-r
esources.sh"
;
showEnvVarsInLog
=
0
;
};
/* End PBXShellScriptBuildPhase section */
...
...
lib/cocoapods/bridge_support_generator.rb
View file @
ec3d6542
...
...
@@ -15,11 +15,9 @@ module Pod
@headers
.
map
{
|
header
|
"-I '
#{
header
.
dirname
}
'"
}.
uniq
end
def
create_in
(
root
)
def
save_as
(
pathname
)
puts
"==> Generating BridgeSupport metadata file"
unless
config
.
silent?
file
=
root
+
"Pods.bridgesupport"
gen_bridge_metadata
%{-c "#{search_paths.join(' ')}" -o '#{file}' '#{headers.join("' '")}'}
file
gen_bridge_metadata
%{-c "#{search_paths.join(' ')}" -o '#{pathname}' '#{headers.join("' '")}'}
end
end
end
lib/cocoapods/installer.rb
View file @
ec3d6542
module
Pod
class
Installer
include
Config
::
Mixin
def
initialize
(
specification
)
@specification
=
specification
end
module
Shared
def
dependent_specification_sets
@dependent_specification_sets
||=
Resolver
.
new
(
@specification
).
resolve
@dependent_specification_sets
||=
Resolver
.
new
(
@podfile
,
@definition
?
@definition
.
dependencies
:
nil
).
resolve
end
def
build_specification_sets
...
...
@@ -17,6 +12,17 @@ module Pod
def
build_specifications
build_specification_sets
.
map
(
&
:specification
)
end
end
class
Target
include
Config
::
Mixin
include
Shared
attr_reader
:target
def
initialize
(
podfile
,
xcodeproj
,
definition
)
@podfile
,
@xcodeproj
,
@definition
=
podfile
,
xcodeproj
,
definition
end
def
xcconfig
@xcconfig
||=
Xcode
::
Config
.
new
({
...
...
@@ -29,75 +35,167 @@ module Pod
})
end
def
templat
e
@template
||=
ProjectTemplate
.
new
(
@specification
.
platform
)
def
xcconfig_filenam
e
"
#{
@definition
.
lib_name
}
.xcconfig"
end
def
xcodeproj
@xcodeproj
||=
Xcode
::
Project
.
new
(
template
.
xcodeproj_path
)
def
copy_resources_script
@copy_resources_script
||=
Xcode
::
CopyResourcesScript
.
new
(
build_specifications
.
map
do
|
spec
|
spec
.
expanded_resources
end
.
flatten
)
end
def
copy_resources_filename
"
#{
@definition
.
lib_name
}
-resources.sh"
end
def
bridge_support_generator
BridgeSupportGenerator
.
new
(
build_specifications
.
map
do
|
spec
|
spec
.
header_files
.
map
do
|
header
|
config
.
project_pods_root
+
header
end
end
.
flatten
)
end
def
bridge_support_filename
"
#{
@definition
.
lib_name
}
.bridgesupport"
end
# TODO move out
def
save_prefix_header_as
(
pathname
)
pathname
.
open
(
'w'
)
do
|
header
|
header
.
puts
"#ifdef __OBJC__"
header
.
puts
"#import
#{
@podfile
.
platform
==
:ios
?
'<UIKit/UIKit.h>'
:
'<Cocoa/Cocoa.h>'
}
"
header
.
puts
"#endif"
end
end
def
prefix_header_filename
"
#{
@definition
.
lib_name
}
-prefix.pch"
end
# TODO move xcconfig related code into the xcconfig method, like copy_resources_script and generate_bridge_support.
def
generate_project
puts
"==> Generating Xcode project and xcconfig"
unless
config
.
silent?
def
install!
# First add the target to the project
@target
=
@xcodeproj
.
targets
.
new_static_library
(
@definition
.
lib_name
)
user_header_search_paths
=
[]
build_specifications
.
each
do
|
spec
|
xcconfig
.
merge!
(
spec
.
xcconfig
)
group
=
xcodeproj
.
add_pod_group
(
spec
.
name
)
# Only add implementation files to the compile phase
spec
.
implementation_files
.
each
do
|
file
|
group
.
add_source_file
(
file
,
nil
,
spec
.
compiler_flags
)
@target
.
add_source_file
(
file
,
nil
,
spec
.
compiler_flags
)
end
# Add header files to a `copy header build phase` for each destination
# directory in the pod's header directory.
spec
.
copy_header_mappings
.
each
do
|
header_dir
,
files
|
copy_phase
=
xcodeproj
.
add_copy_header_build_phase
(
spec
.
name
,
header_dir
)
copy_phase
=
@target
.
copy_files_build_phases
.
new_pod_dir
(
spec
.
name
,
header_dir
)
files
.
each
do
|
file
|
group
.
add_source_file
(
file
,
copy_phase
)
@target
.
add_source_file
(
file
,
copy_phase
)
end
end
# Collect all header search paths
user_header_search_paths
.
concat
(
spec
.
user_header_search_paths
)
end
xcconfig
.
merge!
(
'USER_HEADER_SEARCH_PATHS'
=>
user_header_search_paths
.
sort
.
uniq
.
join
(
" "
))
# Add all the target related support files to the group, even the copy
# resources script although the project doesn't actually use them.
support_files_group
=
@xcodeproj
.
groups
.
find
do
|
group
|
group
.
name
==
"Targets Support Files"
end
.
groups
.
new
(
"name"
=>
@definition
.
lib_name
)
support_files_group
.
files
.
new
(
'path'
=>
copy_resources_filename
)
prefix_file
=
support_files_group
.
files
.
new
(
'path'
=>
prefix_header_filename
)
xcconfig_file
=
support_files_group
.
files
.
new
(
"path"
=>
xcconfig_filename
)
# Assign the xcconfig as the base config of each config.
@target
.
buildConfigurations
.
each
do
|
config
|
config
.
baseConfiguration
=
xcconfig_file
config
.
buildSettings
[
'GCC_PREFIX_HEADER'
]
=
prefix_header_filename
end
end
def
copy_resources_script
@copy_resources_script
||=
Xcode
::
CopyResourcesScript
.
new
(
build_specifications
.
map
{
|
spec
|
spec
.
expanded_resources
}.
flatten
)
def
create_files_in
(
root
)
xcconfig
.
save_as
(
root
+
xcconfig_filename
)
if
@podfile
.
generate_bridge_support?
bridge_support_generator
.
save_as
(
root
+
bridge_support_filename
)
copy_resources_script
.
resources
<<
bridge_support_filename
end
save_prefix_header_as
(
root
+
prefix_header_filename
)
copy_resources_script
.
save_as
(
root
+
copy_resources_filename
)
end
end
def
bridge_support_generator
BridgeSupportGenerator
.
new
(
build_specifications
.
map
do
|
spec
|
spec
.
header_files
.
map
do
|
header
|
config
.
project_pods_root
+
header
include
Config
::
Mixin
include
Shared
def
initialize
(
podfile
)
@podfile
=
podfile
end
def
template
@template
||=
ProjectTemplate
.
new
(
@podfile
.
platform
)
end
def
xcodeproj
unless
@xcodeproj
@xcodeproj
=
Xcode
::
Project
.
new
(
template
.
xcodeproj_path
)
# First we need to resolve dependencies across *all* targets, so that the
# same correct versions of pods are being used for all targets. This
# happens when we call `build_specifications'.
build_specifications
.
each
do
|
spec
|
# Add all source files to the project grouped by pod
group
=
xcodeproj
.
add_pod_group
(
spec
.
name
)
spec
.
expanded_source_files
.
each
do
|
path
|
group
.
children
.
new
(
'path'
=>
path
.
to_s
)
end
end
# Add a group to hold all the target support files
xcodeproj
.
main_group
.
groups
.
new
(
'name'
=>
'Targets Support Files'
)
end
@xcodeproj
end
def
targets
@targets
||=
@podfile
.
targets
.
values
.
map
do
|
target_definition
|
Target
.
new
(
@podfile
,
xcodeproj
,
target_definition
)
end
end
.
flatten
)
end
def
install!
puts
"Installing dependencies of:
#{
@
specification
.
defined_in_file
}
"
unless
config
.
silent?
puts
"Installing dependencies of:
#{
@
podfile
.
defined_in_file
}
"
unless
config
.
silent?
build_specifications
.
each
(
&
:install!
)
generate_project
root
=
config
.
project_pods_root
puts
" * Copying contents of template directory `
#{
template
.
path
}
' to `
#{
root
}
'"
if
config
.
verbose?
template
.
copy_to
(
root
)
puts
"==> Generating Xcode project and xcconfig"
unless
config
.
silent?
targets
.
each
do
|
target
|
target
.
install!
target
.
create_files_in
(
root
)
end
pbxproj
=
File
.
join
(
root
,
'Pods.xcodeproj'
)
puts
" * Writing Xcode project file to `
#{
pbxproj
}
'"
if
config
.
verbose?
xcodeproj
.
save_as
(
pbxproj
)
xcconfig
.
create_in
(
root
)
if
@specification
.
generate_bridge_support?
path
=
bridge_support_generator
.
create_in
(
root
)
copy_resources_script
.
resources
<<
path
.
relative_path_from
(
config
.
project_pods_root
)
end
copy_resources_script
.
create_in
(
root
)
build_specifications
.
each
(
&
:post_install
)
# Post install hooks run last!
targets
.
each
do
|
target
|
target
.
build_specifications
.
each
{
|
spec
|
spec
.
post_install
(
target
)
}
end
end
# For now this assumes just one pods target, i.e. only libPods.a.
# Not sure yet if we should try to be smart with apps that have multiple
# targets and try to map pod targets to those app targets.
#
# Possible options are:
# 1. Only cater to the most simple setup
# 2. Try to automagically figure it out by name. For example, a pod target
# called `:some_target' could map to an app target called `SomeTarget'.
# (A variation would be to not even camelize the target name, but simply
# let the user specify it with the proper case.)
# 3. Let the user specify the app target name as an extra argument, but this
# seems to be a less good version of the variation on #2.
def
configure_project
(
projpath
)
root
=
File
.
dirname
(
projpath
)
xcworkspace
=
File
.
join
(
root
,
File
.
basename
(
projpath
,
'.xcodeproj'
)
+
'.xcworkspace'
)
...
...
@@ -118,8 +216,8 @@ module Pod
'lastKnownFileType'
=>
'text.xcconfig'
})
app_project
.
targets
.
each
do
|
target
|
target
.
buildConfiguration
List
.
buildConfiguration
s
.
each
do
|
config
|
config
.
baseConfiguration
Reference
=
configfile
target
.
buildConfigurations
.
each
do
|
config
|
config
.
baseConfiguration
=
configfile
end
end
app_project
.
main_group
<<
configfile
...
...
@@ -131,7 +229,7 @@ module Pod
'sourceTree'
=>
'BUILT_PRODUCTS_DIR'
})
app_project
.
objects
.
select_by_class
(
Xcode
::
Project
::
PBXFrameworksBuildPhase
).
each
do
|
build_phase
|
build_phase
.
files
<<
libfile
.
build
_file
build_phase
.
files
<<
libfile
.
build
Files
.
new
end
app_project
.
main_group
<<
libfile
...
...
@@ -143,7 +241,7 @@ module Pod
'outputPaths'
=>
[],
'runOnlyForDeploymentPostprocessing'
=>
'0'
,
'shellPath'
=>
'/bin/sh'
,
'shellScript'
=>
"${SRCROOT}/Pods/Pods
R
esources.sh
\n
"
'shellScript'
=>
"${SRCROOT}/Pods/Pods
-r
esources.sh
\n
"
})
app_project
.
targets
.
each
{
|
target
|
target
.
buildPhases
<<
copy_resources
}
...
...
lib/cocoapods/podfile.rb
View file @
ec3d6542
module
Pod
class
Podfile
class
Target
attr_reader
:name
,
:parent
,
:target_dependencies
def
initialize
(
name
,
parent
=
nil
)
@name
,
@parent
,
@target_dependencies
=
name
,
parent
,
[]
end
def
lib_name
name
==
:default
?
"Pods"
:
"Pods-
#{
name
}
"
end
# Returns *all* dependencies of this target, not only the target specific
# ones in `target_dependencies`.
def
dependencies
@target_dependencies
+
(
@parent
?
@parent
.
dependencies
:
[])
end
end
def
self
.
from_file
(
path
)
podfile
=
Podfile
.
new
do
eval
(
path
.
read
,
nil
,
path
.
to_s
)
...
...
@@ -9,8 +27,10 @@ module Pod
podfile
end
include
Config
::
Mixin
def
initialize
(
&
block
)
@
dependencies
=
[]
@
targets
=
{
:default
=>
(
@target
=
Target
.
new
(
:default
))
}
instance_eval
(
&
block
)
end
...
...
@@ -58,10 +78,12 @@ module Pod
# * http://semver.org
# * http://docs.rubygems.org/read/chapter/7
def
dependency
(
name
,
*
version_requirements
)
@dependencies
<<
Dependency
.
new
(
name
,
*
version_requirements
)
@
target
.
target_
dependencies
<<
Dependency
.
new
(
name
,
*
version_requirements
)
end
attr_reader
:dependencies
def
dependencies
@targets
.
values
.
map
(
&
:target_dependencies
).
flatten
end
# Specifies that a BridgeSupport metadata should be generated from the
# headers of all installed Pods.
...
...
@@ -72,6 +94,42 @@ module Pod
@generate_bridge_support
=
true
end
attr_reader
:targets
# Defines a new static library target and scopes dependencies defined from
# the given block. The target will by default include the dependencies
# defined outside of the block, unless the `:exclusive => true` option is
# given.
#
# Consider the following Podfile:
#
# dependency 'ASIHTTPRequest'
#
# target :debug do
# dependency 'SSZipArchive'
# end
#
# target :test, :exclusive => true do
# dependency 'JSONKit'
# end
#
# This Podfile defines three targets. The first one is the `:default` target,
# which produces the `libPods.a` file. The second and third are the `:debug`
# and `:test` ones, which produce the `libPods-debug.a` and `libPods-test.a`
# files.
#
# The `:default` target has only one dependency (ASIHTTPRequest), whereas the
# `:debug` target has two (ASIHTTPRequest, SSZipArchive). The `:test` target,
# however, is an exclusive target which means it will only have one
# dependency (JSONKit).
def
target
(
name
,
options
=
{})
parent
=
@target
@targets
[
name
]
=
@target
=
Target
.
new
(
name
,
options
[
:exclusive
]
?
nil
:
parent
)
yield
ensure
@target
=
parent
end
# This is to be compatible with a Specification for use in the Installer and
# Resolver.
...
...
@@ -86,13 +144,13 @@ module Pod
end
def
dependency_by_name
(
name
)
@
dependencies
.
find
{
|
d
|
d
.
name
==
name
}
dependencies
.
find
{
|
d
|
d
.
name
==
name
}
end
def
validate!
lines
=
[]
lines
<<
"* the `platform` attribute should be either `:osx` or `:ios`"
unless
[
:osx
,
:ios
].
include?
(
@platform
)
lines
<<
"* no dependencies were specified, which is, well, kinda pointless"
if
@
dependencies
.
empty?
lines
<<
"* no dependencies were specified, which is, well, kinda pointless"
if
dependencies
.
empty?
raise
(
Informative
,
([
"The Podfile at `
#{
@defined_in_file
}
' is invalid:"
]
+
lines
).
join
(
"
\n
"
))
unless
lines
.
empty?
end
end
...
...
lib/cocoapods/resolver.rb
View file @
ec3d6542
module
Pod
class
Resolver
def
initialize
(
specification
)
@specification
=
specification
def
initialize
(
specification
,
dependencies
=
nil
)
@specification
,
@dependencies
=
specification
,
dependencies
||
specification
.
dependencies
end
def
resolve
@sets
=
[]
find_dependency_sets
(
@specification
)
find_dependency_sets
(
@specification
,
@dependencies
)
@sets
end
def
find_dependency_sets
(
specification
)
specification
.
dependencies
.
each
do
|
dependency
|
def
find_dependency_sets
(
specification
,
dependencies
=
nil
)
(
dependencies
||
specification
.
dependencies
)
.
each
do
|
dependency
|
set
=
find_dependency_set
(
dependency
)
set
.
required_by
(
specification
)
unless
@sets
.
include?
(
set
)
...
...
lib/cocoapods/specification.rb
View file @
ec3d6542
...
...
@@ -325,17 +325,18 @@ module Pod
# This is a convenience method which gets called after all pods have been
# downloaded, installed, and the Xcode project and related files have been
# generated. Override this to, for instance, add to the prefix header:
# generated. (It receives the Pod::Installer::Target instance for the current
# target.) Override this to, for instance, add to the prefix header:
#
# Pod::Spec.new do |s|
# def s.post_install
# prefix_header = config.project_pods_root +
'Pods-Prefix.pch'
# def s.post_install
(target)
# prefix_header = config.project_pods_root +
target.prefix_header_filename
# prefix_header.open('a') do |file|
# file.puts(%{#ifdef __OBJC__\n#import "SSToolkitDefines.h"\n#endif})
# end
# end
# end
def
post_install
def
post_install
(
target
)
end
end
...
...
lib/cocoapods/xcode/config.rb
View file @
ec3d6542
...
...
@@ -25,8 +25,8 @@ module Pod
@attributes
.
map
{
|
key
,
value
|
"
#{
key
}
=
#{
value
}
"
}.
join
(
"
\n
"
)
end
def
create_in
(
pods_root
)
(
pods_root
+
'Pods.xcconfig'
)
.
open
(
'w'
)
{
|
file
|
file
<<
to_s
}
def
save_as
(
pathname
)
pathname
.
open
(
'w'
)
{
|
file
|
file
<<
to_s
}
end
end
end
...
...
lib/cocoapods/xcode/copy_resources_script.rb
View file @
ec3d6542
module
Pod
module
Xcode
class
CopyResourcesScript
CONTENT
=
<<
EOS
#!/bin/sh
install_resource()
{
echo "cp -R ${SRCROOT}/Pods/$1 ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
cp -R ${SRCROOT}/Pods/$1 ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}
}
EOS
attr_reader
:resources
# A list of files relative to the project pods root.
...
...
@@ -8,13 +18,15 @@ module Pod
@resources
=
resources
end
def
create_in
(
root
)
return
if
@resources
.
empty?
(
root
+
'PodsResources.sh'
).
open
(
'a'
)
do
|
script
|
def
save_as
(
pathname
)
pathname
.
open
(
'w'
)
do
|
script
|
script
.
puts
CONTENT
@resources
.
each
do
|
resource
|
script
.
puts
"install_resource '
#{
resource
}
'"
end
end
# TODO use File api
system
(
"chmod +x '
#{
pathname
}
'"
)
end
end
end
...
...
lib/cocoapods/xcode/project.rb
View file @
ec3d6542
...
...
@@ -5,11 +5,88 @@ module Pod
module
Xcode
class
Project
class
PBXObject
def
self
.
attributes_accessor
(
*
names
)
names
.
each
do
|
name
|
name
=
name
.
to_s
define_method
(
name
)
{
@attributes
[
name
]
}
define_method
(
"
#{
name
}
="
)
{
|
value
|
@attributes
[
name
]
=
value
}
def
self
.
attribute
(
attribute_name
,
accessor_name
=
nil
)
attribute_name
=
attribute_name
.
to_s
name
=
(
accessor_name
||
attribute_name
).
to_s
define_method
(
name
)
{
@attributes
[
attribute_name
]
}
define_method
(
"
#{
name
}
="
)
{
|
value
|
@attributes
[
attribute_name
]
=
value
}
end
def
self
.
attributes
(
*
names
)
names
.
each
{
|
name
|
attribute
(
name
)
}
end
def
self
.
has_many
(
plural_attr_name
,
options
=
{},
&
block
)
klass
=
options
[
:class
]
||
PBXFileReference
singular_attr_name
=
options
[
:singular
]
||
plural_attr_name
.
to_s
[
0
..-
2
]
# strip off 's'
if
options
[
:fkey_on_target
]
define_method
(
plural_attr_name
)
do
scoped
=
@project
.
objects
.
select_by_class
(
klass
).
select
do
|
object
|
object
.
send
(
options
[
:uuid
])
==
self
.
uuid
end
PBXObjectList
.
new
(
klass
,
@project
,
scoped
)
do
|
object
|
object
.
send
(
"
#{
options
[
:uuid
]
}
="
,
self
.
uuid
)
end
end
else
uuid_list_name
=
options
[
:uuid
]
||
"
#{
singular_attr_name
}
References"
attribute
(
plural_attr_name
,
uuid_list_name
)
define_method
(
plural_attr_name
)
do
uuids
=
send
(
uuid_list_name
)
if
block
list_by_class
(
uuids
,
klass
)
do
|
object
|
instance_exec
(
object
,
&
block
)
end
else
list_by_class
(
uuids
,
klass
)
end
end
define_method
(
"
#{
plural_attr_name
}
="
)
do
|
objects
|
send
(
"
#{
uuid_list_name
}
="
,
objects
.
map
(
&
:uuid
))
end
end
end
def
self
.
belongs_to
(
singular_attr_name
,
options
=
{})
if
uuid_name
=
options
[
:uuids
]
# part of another objects uuid list
klass
=
options
[
:class
]
define_method
(
singular_attr_name
)
do
# Loop over all objects of the class and find the one that includes
# this object in the specified uuid list.
@project
.
objects
.
select_by_class
(
klass
).
find
do
|
object
|
object
.
send
(
uuid_name
).
include?
(
self
.
uuid
)
end
end
define_method
(
"
#{
singular_attr_name
}
="
)
do
|
object
|
# Remove this object from the uuid list of the target
# that this object was associated to.
if
previous
=
send
(
singular_attr_name
)
previous
.
send
(
uuid_name
).
delete
(
self
.
uuid
)
end
# Now assign this object to the new object
object
.
send
(
uuid_name
)
<<
self
.
uuid
end
else
uuid_name
=
options
[
:uuid
]
||
"
#{
singular_attr_name
}
Reference"
attribute
(
options
[
:uuid
]
||
singular_attr_name
,
uuid_name
)
define_method
(
singular_attr_name
)
do
uuid
=
send
(
uuid_name
)
@project
.
objects
[
uuid
]
end
define_method
(
"
#{
singular_attr_name
}
="
)
do
|
object
|
send
(
"
#{
uuid_name
}
="
,
object
.
uuid
)
end
end
end
def
self
.
has_one
(
singular_attr_name
,
options
=
{})
klass
=
options
[
:class
]
uuid_name
=
options
[
:uuid
]
||
"
#{
singular_attr_name
}
Reference"
define_method
(
singular_attr_name
)
do
@project
.
objects
.
select_by_class
(
klass
).
find
do
|
object
|
object
.
respond_to?
(
uuid_name
)
&&
object
.
send
(
uuid_name
)
==
self
.
uuid
end
end
end
...
...
@@ -18,13 +95,23 @@ module Pod
end
attr_reader
:uuid
,
:attributes
attributes
_accessor
:isa
,
:name
attributes
:isa
,
:name
def
initialize
(
project
,
uuid
,
attributes
)
@project
,
@uuid
,
@attributes
=
project
,
uuid
||
generate_uuid
,
attributes
@project
,
@attributes
=
project
,
attributes
unless
uuid
# Add new objects to the main hash with a unique UUID
begin
;
uuid
=
generate_uuid
;
end
while
@project
.
objects_hash
.
has_key?
(
uuid
)
@project
.
objects_hash
[
uuid
]
=
@attributes
end
@uuid
=
uuid
self
.
isa
||=
self
.
class
.
isa
end
def
==
(
other
)
other
.
is_a?
(
PBXObject
)
&&
self
.
uuid
==
other
.
uuid
end
def
inspect
"#<
#{
isa
}
UUID: `
#{
uuid
}
', name: `
#{
name
}
'>"
end
...
...
@@ -40,179 +127,263 @@ module Pod
uuid
.
gsub
(
'-'
,
''
)[
0
..
23
]
end
def
list_by_class
(
uuids
,
klass
,
scoped
=
nil
)
def
list_by_class
(
uuids
,
klass
,
scoped
=
nil
,
&
block
)
unless
scoped
scoped
=
uuids
.
map
{
|
uuid
|
@project
.
objects
[
uuid
]
}.
select
{
|
o
|
o
.
is_a?
(
klass
)
}
end
if
block
PBXObjectList
.
new
(
klass
,
@project
,
scoped
,
&
block
)
else
PBXObjectList
.
new
(
klass
,
@project
,
scoped
)
do
|
object
|
# Add the uuid of a newly created object to the uuids list
uuids
<<
object
.
uuid
end
end
end
end
class
PBXGroup
<
PBXObject
attributes_accessor
:sourceTree
,
:children
# Missing constants that begin with either `PBX' or `XC' are assumed to be
# valid classes in a Xcode project. A new PBXObject subclass is created
# for the constant and returned.
def
self
.
const_missing
(
name
)
if
name
=~
/^(PBX|XC)/
klass
=
Class
.
new
(
PBXObject
)
const_set
(
name
,
klass
)
klass
else
super
end
end
class
PBXFileReference
<
PBXObject
attributes
:path
,
:sourceTree
,
:explicitFileType
,
:includeInIndex
has_many
:buildFiles
,
:uuid
=>
:fileRef
,
:fkey_on_target
=>
true
,
:class
=>
Project
::
PBXBuildFile
belongs_to
:group
,
:class
=>
Project
::
PBXGroup
,
:uuids
=>
:childReferences
def
initialize
(
project
,
uuid
,
attributes
)
is_new
=
uuid
.
nil?
super
self
.
sourceTree
||=
'<group>'
self
.
children
||=
[]
self
.
path
=
path
if
path
# sets default name
self
.
sourceTree
||=
'SOURCE_ROOT'
if
is_new
@project
.
main_group
.
children
<<
self
end
def
files
list_by_class
(
children
,
PBXFileReference
)
end
def
source_files
list_by_class
(
children
,
PBXFileReference
,
files
.
select
{
|
file
|
!
file
.
build_file
.
nil?
})
alias_method
:_path
=
,
:path
=
def
path
=
(
path
)
self
.
_path
=
path
self
.
name
||=
pathname
.
basename
.
to_s
path
end
def
groups
list_by_class
(
children
,
PBXGroup
)
def
pathname
Pathname
.
new
(
path
)
end
end
def
add_source_file
(
path
,
copy_header_phase
=
nil
,
compiler_flags
=
nil
)
file
=
files
.
new
(
'path'
=>
path
.
to_s
)
build_file
=
file
.
build_file
if
path
.
extname
==
'.h'
build_file
.
settings
=
{
'ATTRIBUTES'
=>
[
"Public"
]
}
# Working around a bug in Xcode 4.2 betas, remove this once the Xcode bug is fixed:
# https://github.com/alloy/cocoapods/issues/13
#phase = copy_header_phase || @project.headers_build_phases.first
phase
=
copy_header_phase
||
@project
.
copy_files_build_phases
.
first
# TODO is this really needed?
phase
.
files
<<
build_file
class
PBXGroup
<
PBXObject
attributes
:sourceTree
has_many
:children
,
:singular
=>
:child
do
|
object
|
if
object
.
is_a?
(
Pod
::
Xcode
::
Project
::
PBXFileReference
)
# Associating the file to this group through the inverse
# association will also remove it from the group it was in.
object
.
group
=
self
else
build_file
.
settings
=
{
'COMPILER_FLAGS'
=>
compiler_flags
}
if
compiler_flags
@project
.
source_build_phase
.
files
<<
build_file
# TODO What objects can actually be in a group and don't they
# all need the above treatment.
childReferences
<<
object
.
uuid
end
file
end
def
<<
(
child
)
children
<<
child
.
uuid
end
def
initialize
(
*
)
super
self
.
sourceTree
||=
'<group>'
self
.
childReferences
||=
[]
end
class
PBXFileReference
<
PBXObject
attributes_accessor
:path
,
:sourceTree
def
files
list_by_class
(
childReferences
,
Pod
::
Xcode
::
Project
::
PBXFileReference
)
do
|
file
|
file
.
group
=
self
end
end
def
initialize
(
project
,
uuid
,
attributes
)
is_new
=
uuid
.
nil?
super
self
.
name
||=
pathname
.
basename
.
to_s
self
.
sourceTree
||=
'SOURCE_ROOT'
if
is_new
@project
.
build_files
.
new
.
file
=
self
def
source_files
files
=
self
.
files
.
reject
{
|
file
|
file
.
buildFiles
.
empty?
}
list_by_class
(
childReferences
,
Pod
::
Xcode
::
Project
::
PBXFileReference
,
files
)
do
|
file
|
file
.
group
=
self
end
end
def
pathname
Pathname
.
new
(
path
)
def
groups
list_by_class
(
childReferences
,
Pod
::
Xcode
::
Project
::
PBXGroup
)
end
def
build_file
@project
.
build_files
.
find
{
|
o
|
o
.
fileRef
==
uuid
}
def
<<
(
child
)
children
<<
child
end
end
class
PBXBuildFile
<
PBXObject
attributes_accessor
:fileRef
,
:settings
# Takes a PBXFileReference instance and assigns its uuid to the fileRef attribute.
def
file
=
(
file
)
self
.
fileRef
=
file
.
uuid
attributes
:settings
belongs_to
:file
,
:uuid
=>
:fileRef
end
# Returns a PBXFileReference instance corresponding to the uuid in the fileRef attribute.
def
file
@project
.
objects
[
fileRef
]
class
PBXBuildPhase
<
PBXObject
# TODO rename this to buildFiles and add a files :through => :buildFiles shortcut
has_many
:files
,
:class
=>
PBXBuildFile
attributes
:buildActionMask
,
:runOnlyForDeploymentPostprocessing
def
initialize
(
*
)
super
self
.
fileReferences
||=
[]
# These are always the same, no idea what they are.
self
.
buildActionMask
||=
"2147483647"
self
.
runOnlyForDeploymentPostprocessing
||=
"0"
end
end
class
PBXBuildPhase
<
PBXObject
attributes_accessor
:files
alias_method
:file_uuids
,
:files
alias_method
:file_uuids
=
,
:files
=
class
PBXCopyFilesBuildPhase
<
PBXBuildPhase
attributes
:dstPath
,
:dstSubfolderSpec
def
initialize
(
project
,
uuid
,
attributes
)
super
self
.
file_uuids
||=
[]
def
self
.
new_pod_dir
(
project
,
pod_name
,
path
)
new
(
project
,
nil
,
{
"dstPath"
=>
"$(PUBLIC_HEADERS_FOLDER_PATH)/
#{
path
}
"
,
"name"
=>
"Copy
#{
pod_name
}
Public Headers"
,
})
end
def
files
list_by_class
(
file_uuids
,
PBXBuildFile
)
def
initialize
(
*
)
super
self
.
dstSubfolderSpec
||=
"16"
end
end
class
PBXSourcesBuildPhase
<
PBXBuildPhase
;
end
class
PBXCopyFilesBuildPhase
<
PBXBuildPhase
;
end
class
PBXFrameworksBuildPhase
<
PBXBuildPhase
;
end
class
PBXShellScriptBuildPhase
<
PBXBuildPhase
attribute
s_accessor
:shellScript
attribute
:shellScript
end
class
PBXNativeTarget
<
PBXObject
attributes_accessor
:buildPhases
,
:buildConfigurationList
alias_method
:build_phase_uuids
,
:buildPhases
alias_method
:build_phase_uuids
=
,
:buildPhases
=
alias_method
:build_configuration_list_uuid
,
:buildConfigurationList
alias_method
:build_configuration_list_uuid
=
,
:buildConfigurationList
=
STATIC_LIBRARY
=
'com.apple.product-type.library.static'
def
buildPhases
list_by_class
(
build_phase_uuids
,
PBXBuildPhase
)
end
attributes
:productName
,
:productType
def
buildConfigurationList
@project
.
objects
[
build_configuration_list_uuid
]
end
has_many
:buildPhases
,
:class
=>
PBXBuildPhase
has_many
:dependencies
,
:singular
=>
:dependency
# TODO :class => ?
has_many
:buildRules
# TODO :class => ?
belongs_to
:buildConfigurationList
belongs_to
:product
,
:uuid
=>
:productReference
def
self
.
new_static_library
(
project
,
productName
)
# TODO should probably switch the uuid and attributes argument
target
=
new
(
project
,
nil
,
'productType'
=>
STATIC_LIBRARY
,
'productName'
=>
productName
)
target
.
product
.
path
=
"lib
#{
productName
}
.a"
target
.
product
.
includeInIndex
=
"0"
# no idea what this is
target
.
product
.
explicitFileType
=
"archive.ar"
target
.
buildPhases
.
add
(
PBXSourcesBuildPhase
)
def
buildConfigurationList
=
(
config_list
)
self
.
build_configuration_list_uuid
=
config_list
.
uuid
buildPhase
=
target
.
buildPhases
.
add
(
PBXFrameworksBuildPhase
)
project
.
groups
.
find
{
|
g
|
g
.
name
==
'Frameworks'
}.
files
.
each
do
|
framework
|
buildPhase
.
files
<<
framework
.
buildFiles
.
new
end
target
.
buildPhases
.
add
(
PBXCopyFilesBuildPhase
,
'dstPath'
=>
'$(PUBLIC_HEADERS_FOLDER_PATH)'
)
target
end
class
XCBuildConfiguration
<
PBXObject
attributes_accessor
:baseConfigurationReference
alias_method
:base_configuration_reference_uuid
,
:baseConfigurationReference
alias_method
:base_configuration_reference_uuid
=
,
:baseConfigurationReference
=
def
initialize
(
project
,
*
)
super
self
.
name
||=
productName
self
.
buildRuleReferences
||=
[]
self
.
dependencyReferences
||=
[]
self
.
buildPhaseReferences
||=
[]
def
baseConfigurationReference
@project
.
objects
[
base_configuration_reference_uuid
]
unless
buildConfigurationList
self
.
buildConfigurationList
=
project
.
objects
.
add
(
XCConfigurationList
)
# TODO or should this happen in buildConfigurationList?
buildConfigurationList
.
buildConfigurations
.
new
(
'name'
=>
'Debug'
)
buildConfigurationList
.
buildConfigurations
.
new
(
'name'
=>
'Release'
)
end
def
baseConfigurationReference
=
(
config
)
self
.
base_configuration_reference_uuid
=
config
.
uuid
unless
product
self
.
product
=
project
.
files
.
new
(
'sourceTree'
=>
'BUILT_PRODUCTS_DIR'
)
product
.
group
=
project
.
products
end
end
class
XCConfigurationList
<
PBXObject
attributes_accessor
:buildConfigurations
alias_method
:build_configuration_uuids
,
:buildConfigurations
alias_method
:build_configuration_uuids
=
,
:buildConfigurations
=
def
buildConfigurations
list_by_class
(
build_configuration_uuids
,
XCBuildConfiguration
)
buildConfigurationList
.
buildConfigurations
end
def
buildConfigurations
=
(
configs
)
self
.
build_configuration_uuids
=
configs
.
map
(
&
:uuid
)
def
source_build_phases
buildPhases
.
select_by_class
(
PBXSourcesBuildPhase
)
end
def
copy_files_build_phases
buildPhases
.
select_by_class
(
PBXCopyFilesBuildPhase
)
end
# Missing constants that begin with either `PBX' or `XC' are assumed to be
# valid classes in a Xcode project. A new PBXObject subclass is created
# for the constant and returned.
def
self
.
const_missing
(
name
)
if
name
=~
/^(PBX|XC)/
klass
=
Class
.
new
(
PBXObject
)
const_set
(
name
,
klass
)
klass
def
frameworks_build_phases
buildPhases
.
select_by_class
(
PBXFrameworksBuildPhase
)
end
# Finds an existing file reference or creates a new one.
def
add_source_file
(
path
,
copy_header_phase
=
nil
,
compiler_flags
=
nil
)
file
=
@project
.
files
.
find
{
|
file
|
file
.
path
==
path
.
to_s
}
||
@project
.
files
.
new
(
'path'
=>
path
.
to_s
)
buildFile
=
file
.
buildFiles
.
new
if
path
.
extname
==
'.h'
buildFile
.
settings
=
{
'ATTRIBUTES'
=>
[
"Public"
]
}
# Working around a bug in Xcode 4.2 betas, remove this once the Xcode bug is fixed:
# https://github.com/alloy/cocoapods/issues/13
#phase = copy_header_phase || headers_build_phases.first
phase
=
copy_header_phase
||
copy_files_build_phases
.
first
phase
.
files
<<
buildFile
else
buildFile
.
settings
=
{
'COMPILER_FLAGS'
=>
compiler_flags
}
if
compiler_flags
source_build_phases
.
first
.
files
<<
buildFile
end
file
end
end
class
XCBuildConfiguration
<
PBXObject
attribute
:buildSettings
belongs_to
:baseConfiguration
,
:uuid
=>
:baseConfigurationReference
def
initialize
(
*
)
super
# TODO These are from an iOS static library, need to check if it works for any product type
self
.
buildSettings
=
{
'DSTROOT'
=>
'/tmp/Pods.dst'
,
'GCC_PRECOMPILE_PREFIX_HEADER'
=>
'YES'
,
'GCC_VERSION'
=>
'com.apple.compilers.llvm.clang.1_0'
,
# The OTHER_LDFLAGS option *has* to be overriden so that it does not
# use those from the xcconfig (for CocoaPods specifically).
'OTHER_LDFLAGS'
=>
''
,
'PRODUCT_NAME'
=>
'$(TARGET_NAME)'
,
'SKIP_INSTALL'
=>
'YES'
,
}.
merge
(
buildSettings
||
{})
end
end
class
XCConfigurationList
<
PBXObject
has_many
:buildConfigurations
,
:class
=>
XCBuildConfiguration
def
initialize
(
*
)
super
self
.
buildConfigurationReferences
||=
[]
end
end
class
PBXProject
<
PBXObject
has_many
:targets
,
:class
=>
PBXNativeTarget
belongs_to
:products
,
:uuid
=>
:productRefGroup
,
:class
=>
PBXGroup
end
class
PBXObjectList
include
Enumerable
...
...
@@ -223,6 +394,10 @@ module Pod
@callback
=
new_object_callback
end
def
empty?
@scoped_hash
.
empty?
end
def
[]
(
uuid
)
if
hash
=
@scoped_hash
[
uuid
]
Project
.
const_get
(
hash
[
'isa'
]).
new
(
@project
,
uuid
,
hash
)
...
...
@@ -231,14 +406,12 @@ module Pod
def
add
(
klass
,
hash
=
{})
object
=
klass
.
new
(
@project
,
nil
,
hash
)
@
project
.
objects_hash
[
object
.
uuid
]
=
object
.
attributes
@
callback
.
call
(
object
)
if
@callback
object
end
def
new
(
hash
=
{})
object
=
add
(
@represented_class
,
hash
)
@callback
.
call
(
object
)
if
@callback
object
add
(
@represented_class
,
hash
)
end
def
<<
(
object
)
...
...
@@ -251,14 +424,42 @@ module Pod
end
end
def
==
(
other
)
self
.
to_a
==
other
.
to_a
end
def
first
to_a
.
first
end
def
last
to_a
.
last
end
def
inspect
"<PBXObjectList:
#{
map
(
&
:inspect
)
}
>"
end
# Only makes sense on
the list that has the full objects_hash as its scoped hash
.
# Only makes sense on
lists that contain mixed classes
.
def
select_by_class
(
klass
)
scoped
=
@project
.
objects_hash
.
select
{
|
_
,
attr
|
attr
[
'isa'
]
==
klass
.
isa
}
PBXObjectList
.
new
(
klass
,
@project
,
scoped
)
scoped
=
@scoped_hash
.
select
{
|
_
,
attr
|
attr
[
'isa'
]
==
klass
.
isa
}
PBXObjectList
.
new
(
klass
,
@project
,
scoped
)
do
|
object
|
# Objects added to the subselection should still use the same
# callback as this list.
self
<<
object
end
end
def
method_missing
(
name
,
*
args
,
&
block
)
if
@represented_class
.
respond_to?
(
name
)
object
=
@represented_class
.
send
(
name
,
@project
,
*
args
)
# The callbacks are only for PBXObject instances instantiated
# from the class method that we forwarded the message to.
@callback
.
call
(
object
)
if
object
.
is_a?
(
PBXObject
)
object
else
super
end
end
end
...
...
@@ -279,13 +480,17 @@ module Pod
@objects
||=
PBXObjectList
.
new
(
PBXObject
,
self
,
objects_hash
)
end
# TODO This should probably be the actual Project class (PBXProject).
def
project_object
objects
[
@plist
[
'rootObject'
]]
end
def
groups
objects
.
select_by_class
(
PBXGroup
)
end
def
main_group
project
=
objects
[
@plist
[
'rootObject'
]]
objects
[
project
.
attributes
[
'mainGroup'
]]
objects
[
project_object
.
attributes
[
'mainGroup'
]]
end
# Shortcut access to the `Pods' PBXGroup.
...
...
@@ -306,16 +511,14 @@ module Pod
objects
.
select_by_class
(
PBXBuildFile
)
end
def
source_build_phase
objects
.
find
{
|
o
|
o
.
is_a?
(
PBXSourcesBuildPhase
)
}
end
def
copy_files_build_phases
objects
.
select_by_class
(
PBXCopyFilesBuildPhase
)
def
targets
# Better to check the project object for targets to ensure they are
# actually there so the project will work
project_object
.
targets
end
def
targe
ts
objects
.
select_by_class
(
PBXNativeTarget
)
def
produc
ts
project_object
.
products
end
IGNORE_GROUPS
=
[
'Pods'
,
'Frameworks'
,
'Products'
,
'Supporting Files'
]
...
...
@@ -333,24 +536,6 @@ module Pod
FileUtils
.
mkdir_p
(
projpath
)
@plist
.
writeToFile
(
File
.
join
(
projpath
,
'project.pbxproj'
),
atomically
:true
)
end
# TODO add comments, or even constants, describing what these magic numbers are.
def
add_copy_header_build_phase
(
name
,
path
)
phase
=
copy_files_build_phases
.
new
({
"buildActionMask"
=>
"2147483647"
,
"dstPath"
=>
"$(PUBLIC_HEADERS_FOLDER_PATH)/
#{
path
}
"
,
"dstSubfolderSpec"
=>
"16"
,
"name"
=>
"Copy
#{
name
}
Public Headers"
,
"runOnlyForDeploymentPostprocessing"
=>
"0"
,
})
targets
.
first
.
buildPhases
<<
phase
phase
end
# A silly hack to pretty print the objects hash from MacRuby.
def
pretty_print
puts
`ruby -r pp -e 'pp(
#{
@template
.
inspect
}
)'`
end
end
end
end
spec/integration_spec.rb
View file @
ec3d6542
...
...
@@ -38,8 +38,6 @@ else
config
.
silent
=
true
config
.
repos_dir
=
fixture
(
'spec-repos'
)
config
.
project_pods_root
=
temporary_directory
+
'Pods'
def
config
.
ios?
;
true
;
end
def
config
.
osx?
;
false
;
end
FileUtils
.
cp_r
(
fixture
(
'integration/.'
),
config
.
project_pods_root
)
end
...
...
@@ -51,6 +49,9 @@ else
# TODO add a simple source file which uses the compiled lib to check that it really really works
it
"should activate required pods and create a working static library xcode project"
do
spec
=
Pod
::
Podfile
.
new
do
# first ensure that the correct info is available to the specs when they load
config
.
rootspec
=
self
self
.
platform
platform
dependency
'ASIWebPageRequest'
,
'>= 1.8.1'
dependency
'JSONKit'
,
'>= 1.0'
...
...
@@ -61,26 +62,29 @@ else
installer
.
install!
root
=
config
.
project_pods_root
(
root
+
'Reachability.podspec'
).
should
.
exist
(
root
+
'Reachability.podspec'
).
should
.
exist
if
platform
==
:ios
(
root
+
'ASIHTTPRequest.podspec'
).
should
.
exist
(
root
+
'ASIWebPageRequest.podspec'
).
should
.
exist
(
root
+
'JSONKit.podspec'
).
should
.
exist
(
root
+
'SSZipArchive.podspec'
).
should
.
exist
(
root
+
'Pods.xcconfig'
).
read
.
should
==
installer
.
xcconfig
.
to_s
(
root
+
'Pods.xcconfig'
).
read
.
should
==
installer
.
targets
.
first
.
xcconfig
.
to_s
project_file
=
(
root
+
'Pods.xcodeproj/project.pbxproj'
).
to_s
NSDictionary
.
dictionaryWithContentsOfFile
(
project_file
).
should
==
installer
.
xcodeproj
.
to_hash
#
puts "\n[!] Compiling static library..."
#
Dir.chdir(config.project_pods_root) do
#
system("xcodebuild > /dev/null 2>&1").should == true
puts
"
\n
[!] Compiling static library..."
Dir
.
chdir
(
config
.
project_pods_root
)
do
system
(
"xcodebuild > /dev/null 2>&1"
).
should
==
true
#system("xcodebuild").should == true
#
end
end
end
it
"does not activate pods that are only part of other pods"
do
spec
=
Pod
::
Podfile
.
new
do
# first ensure that the correct info is available to the specs when they load
config
.
rootspec
=
self
self
.
platform
platform
dependency
'Reachability'
end
...
...
@@ -94,16 +98,18 @@ else
it
"adds resources to the xcode copy script"
do
spec
=
Pod
::
Podfile
.
new
do
# first ensure that the correct info is available to the specs when they load
config
.
rootspec
=
self
self
.
platform
platform
dependency
'SSZipArchive'
end
installer
=
SpecHelper
::
Installer
.
new
(
spec
)
dependency_spec
=
installer
.
build_specifications
.
first
dependency_spec
.
resources
=
'LICEN*'
,
'Readme.*'
installer
.
targets
.
first
.
build_specifications
.
first
.
resources
=
'LICEN*'
,
'Readme.*'
installer
.
install!
contents
=
(
config
.
project_pods_root
+
'Pods
R
esources.sh'
).
read
contents
=
(
config
.
project_pods_root
+
'Pods
-r
esources.sh'
).
read
contents
.
should
.
include
"install_resource 'SSZipArchive/LICENSE'
\n
"
\
"install_resource 'SSZipArchive/Readme.markdown'"
end
...
...
@@ -111,6 +117,9 @@ else
# TODO we need to do more cleaning and/or add a --prune task
it
"overwrites an existing project.pbxproj file"
do
spec
=
Pod
::
Podfile
.
new
do
# first ensure that the correct info is available to the specs when they load
config
.
rootspec
=
self
self
.
platform
platform
dependency
'JSONKit'
end
...
...
@@ -120,18 +129,60 @@ else
Pod
::
Source
.
reset!
Pod
::
Spec
::
Set
.
reset!
spec
=
Pod
::
Podfile
.
new
do
# first ensure that the correct info is available to the specs when they load
config
.
rootspec
=
self
self
.
platform
platform
dependency
'SSZipArchive'
end
installer
=
SpecHelper
::
Installer
.
new
(
spec
)
installer
.
install!
installer
=
Pod
::
Installer
.
new
(
spec
)
installer
.
generate_project
project
=
Pod
::
Xcode
::
Project
.
new
(
config
.
project_pods_root
+
'Pods.xcodeproj'
)
project
.
source_files
.
should
==
installer
.
xcodeproj
.
source_files
end
it
"creates a project with multiple targets"
do
Pod
::
Source
.
reset!
Pod
::
Spec
::
Set
.
reset!
podfile
=
Pod
::
Podfile
.
new
do
# first ensure that the correct info is available to the specs when they load
config
.
rootspec
=
self
self
.
platform
platform
target
(
:debug
)
{
dependency
'SSZipArchive'
}
target
(
:test
,
:exclusive
=>
true
)
{
dependency
'JSONKit'
}
dependency
'ASIHTTPRequest'
end
installer
=
Pod
::
Installer
.
new
(
podfile
)
installer
.
install!
#project = Pod::Xcode::Project.new(config.project_pods_root + 'Pods.xcodeproj')
#p project
#project.targets.each do |target|
#target.source_build_phases.
#end
root
=
config
.
project_pods_root
(
root
+
'Pods.xcconfig'
).
should
.
exist
(
root
+
'Pods-debug.xcconfig'
).
should
.
exist
(
root
+
'Pods-test.xcconfig'
).
should
.
exist
(
root
+
'Pods-resources.sh'
).
should
.
exist
(
root
+
'Pods-debug-resources.sh'
).
should
.
exist
(
root
+
'Pods-test-resources.sh'
).
should
.
exist
Dir
.
chdir
(
config
.
project_pods_root
)
do
puts
"
\n
[!] Compiling static library `Pods'..."
#system("xcodebuild -target Pods").should == true
system
(
"xcodebuild -target Pods > /dev/null 2>&1"
).
should
==
true
puts
"
\n
[!] Compiling static library `Pods-debug'..."
system
(
"xcodebuild -target Pods-debug > /dev/null 2>&1"
).
should
==
true
puts
"
\n
[!] Compiling static library `Pods-test'..."
system
(
"xcodebuild -target Pods-test > /dev/null 2>&1"
).
should
==
true
end
end
it
"sets up an existing project with pods"
do
basename
=
platform
==
:ios
?
'iPhone'
:
'Mac'
projpath
=
temporary_directory
+
'ASIHTTPRequest.xcodeproj'
...
...
@@ -143,27 +194,26 @@ else
installer
=
SpecHelper
::
Installer
.
new
(
spec
)
installer
.
install!
installer
.
configure_project
(
projpath
)
xcworkspace
=
temporary_directory
+
'ASIHTTPRequest.xcworkspace'
workspace
=
Pod
::
Xcode
::
Workspace
.
new_from_xcworkspace
(
xcworkspace
)
workspace
.
projpaths
.
sort
.
should
==
[
'ASIHTTPRequest.xcodeproj'
,
'Pods/Pods.xcodeproj'
]
project
=
Pod
::
Xcode
::
Project
.
new
(
projpath
)
config
=
project
.
files
.
find
{
|
f
|
f
.
path
=~
/Pods.xcconfig$/
}
config
.
should
.
not
.
equal
nil
copy_resources
=
project
.
objects
.
select_by_class
(
Pod
::
Xcode
::
Project
::
PBXShellScriptBuildPhase
).
find
do
|
ss
|
ss
.
shellScript
[
'PodsResources.sh'
]
end
copy_resources
.
should
.
not
.
equal
nil
libPods
=
project
.
files
.
find
{
|
f
|
f
.
name
==
'libPods.a'
}
project
.
targets
.
each
do
|
target
|
bases
=
target
.
buildConfigurationList
.
buildConfigurations
.
map
(
&
:baseConfigurationReference
)
bases
.
uniq
[
0
].
uuid
.
should
==
config
.
uuid
target
.
buildPhases
.
map
(
&
:uuid
).
should
.
include
copy_resources
.
uuid
target
.
buildConfigurations
.
each
do
|
config
|
config
.
baseConfiguration
.
path
.
should
==
'Pods/Pods.xcconfig'
end
lib
=
project
.
files
.
find
{
|
f
|
f
.
path
=~
/libPods.a$/
}
lib
.
should
.
not
.
equal
nil
project
.
objects
.
select_by_class
(
Pod
::
Xcode
::
Project
::
PBXFrameworksBuildPhase
).
each
do
|
build_phase
|
build_phase
.
files
.
map
(
&
:uuid
).
should
.
include
lib
.
build_file
.
uuid
phase
=
target
.
frameworks_build_phases
.
first
phase
.
files
.
map
{
|
buildFile
|
buildFile
.
file
}.
should
.
include
libPods
# should be the last phase
target
.
buildPhases
.
last
.
shellScript
.
should
==
"${SRCROOT}/Pods/Pods-resources.sh
\n
"
end
end
end
end
end
spec/unit/bridge_support_generator_spec.rb
View file @
ec3d6542
...
...
@@ -7,8 +7,8 @@ describe "Pod::BridgeSupportGenerator" do
def
generator
.
gen_bridge_metadata
(
command
)
@command
=
command
end
generator
.
create_in
(
Pathname
.
new
(
"/path/to/Pods
"
))
generator
.
save_as
(
Pathname
.
new
(
"/path/to/Pods.bridgesupport
"
))
generator
.
instance_variable_get
(
:@command
).
should
==
%{-c "-I '/some/dir' -I '/some/other/dir'" -o '/path/to/Pods
/Pods
.bridgesupport' '#{headers.join("' '")}'}
%{-c "-I '/some/dir' -I '/some/other/dir'" -o '/path/to/Pods.bridgesupport' '#{headers.join("' '")}'}
end
end
spec/unit/installer_spec.rb
View file @
ec3d6542
...
...
@@ -3,7 +3,7 @@ require File.expand_path('../../spec_helper', __FILE__)
describe
"Pod::Installer"
do
describe
", by default,"
do
before
do
@xcconfig
=
Pod
::
Installer
.
new
(
Pod
::
Spec
.
new
)
.
xcconfig
.
to_hash
@xcconfig
=
Pod
::
Installer
.
new
(
Pod
::
Podfile
.
new
{
platform
:ios
}).
targets
.
first
.
xcconfig
.
to_hash
end
it
"sets the header search paths where installed Pod headers can be found"
do
...
...
@@ -33,9 +33,9 @@ describe "Pod::Installer" do
end
it
"generates a BridgeSupport metadata file from all the pod headers"
do
spec
=
Pod
::
Spec
.
new
do
|
s
|
s
.
platform
=
:osx
s
.
dependency
'ASIHTTPRequest'
spec
=
Pod
::
Podfile
.
new
do
platform
:osx
dependency
'ASIHTTPRequest'
end
expected
=
[]
installer
=
Pod
::
Installer
.
new
(
spec
)
...
...
@@ -44,71 +44,6 @@ describe "Pod::Installer" do
expected
<<
config
.
project_pods_root
+
header
end
end
installer
.
bridge_support_generator
.
headers
.
should
==
expected
end
it
"adds all source files that should be included in the library to the xcode project"
do
[
[
'ASIHTTPRequest'
,
[
'Classes'
],
{
'ASIHTTPRequest'
=>
"Classes/*.{h,m}"
,
'Reachability'
=>
"External/Reachability/*.{h,m}"
},
{
"USER_HEADER_SEARCH_PATHS"
=>
'"$(BUILT_PRODUCTS_DIR)/Pods" '
\
'"$(BUILT_PRODUCTS_DIR)/Pods/ASIHTTPRequest" '
\
'"$(BUILT_PRODUCTS_DIR)/Pods/Reachability"'
,
"ALWAYS_SEARCH_USER_PATHS"
=>
"YES"
,
"OTHER_LDFLAGS"
=>
"-ObjC -all_load "
\
"-framework SystemConfiguration -framework MobileCoreServices "
\
"-framework CFNetwork -lz.1"
}
],
[
'Reachability'
,
[
"External/Reachability/*.h"
,
"External/Reachability/*.m"
],
{
'Reachability'
=>
"External/Reachability/*.{h,m}"
,
},
{
"USER_HEADER_SEARCH_PATHS"
=>
'"$(BUILT_PRODUCTS_DIR)/Pods" '
\
'"$(BUILT_PRODUCTS_DIR)/Pods/Reachability"'
,
"ALWAYS_SEARCH_USER_PATHS"
=>
"YES"
,
"OTHER_LDFLAGS"
=>
"-ObjC -all_load"
}
],
[
'ASIWebPageRequest'
,
[
'**/ASIWebPageRequest.*'
],
{
'ASIHTTPRequest'
=>
"Classes/*.{h,m}"
,
'ASIWebPageRequest'
=>
"Classes/ASIWebPageRequest/*.{h,m}"
,
'Reachability'
=>
"External/Reachability/*.{h,m}"
},
{
"USER_HEADER_SEARCH_PATHS"
=>
'"$(BUILT_PRODUCTS_DIR)/Pods" '
\
'"$(BUILT_PRODUCTS_DIR)/Pods/ASIHTTPRequest" '
\
'"$(BUILT_PRODUCTS_DIR)/Pods/Reachability"'
,
"ALWAYS_SEARCH_USER_PATHS"
=>
"YES"
,
"HEADER_SEARCH_PATHS"
=>
"$(SDKROOT)/usr/include/libxml2"
,
"OTHER_LDFLAGS"
=>
"-ObjC -all_load "
\
"-lxml2.2.7.3 -framework SystemConfiguration "
\
"-framework MobileCoreServices -framework CFNetwork -lz.1"
}
],
].
each
do
|
name
,
patterns
,
expected_patterns
,
xcconfig
|
Pod
::
Source
.
reset!
Pod
::
Spec
::
Set
.
reset!
installer
=
Pod
::
Installer
.
new
(
Pod
::
Spec
.
new
do
|
s
|
s
.
platform
=
:ios
s
.
dependency
(
name
)
s
.
source_files
=
*
patterns
end
)
installer
.
generate_project
expected_patterns
.
each
do
|
name
,
pattern
|
pattern
=
config
.
project_pods_root
+
'ASIHTTPRequest'
+
pattern
expected
=
pattern
.
glob
.
map
do
|
file
|
file
.
relative_path_from
(
config
.
project_pods_root
)
end
installer
.
xcodeproj
.
source_files
[
name
].
size
.
should
==
expected
.
size
installer
.
xcodeproj
.
source_files
[
name
].
sort
.
should
==
expected
.
sort
end
installer
.
xcconfig
.
to_hash
.
should
==
xcconfig
end
installer
.
targets
.
first
.
bridge_support_generator
.
headers
.
should
==
expected
end
end
spec/unit/podfile_spec.rb
View file @
ec3d6542
...
...
@@ -23,6 +23,47 @@ describe "Pod::Podfile" do
podfile
.
generate_bridge_support?
.
should
==
true
end
describe
"concerning targets (dependency groups)"
do
before
do
@podfile
=
Pod
::
Podfile
.
new
do
target
:debug
do
dependency
'SSZipArchive'
end
target
:test
,
:exclusive
=>
true
do
dependency
'JSONKit'
end
dependency
'ASIHTTPRequest'
end
end
it
"returns all dependencies of all targets combined, which is used during resolving to enusre compatible dependencies"
do
@podfile
.
dependencies
.
map
(
&
:name
).
sort
.
should
==
%w{ ASIHTTPRequest JSONKit SSZipArchive }
end
it
"adds dependencies outside of any explicit target block to the default target"
do
target
=
@podfile
.
targets
[
:default
]
target
.
lib_name
.
should
==
'Pods'
target
.
dependencies
.
should
==
[
Pod
::
Dependency
.
new
(
'ASIHTTPRequest'
)]
end
it
"adds dependencies of the outer target to non-exclusive targets"
do
target
=
@podfile
.
targets
[
:debug
]
target
.
lib_name
.
should
==
'Pods-debug'
target
.
dependencies
.
sort_by
(
&
:name
).
should
==
[
Pod
::
Dependency
.
new
(
'ASIHTTPRequest'
),
Pod
::
Dependency
.
new
(
'SSZipArchive'
)
]
end
it
"does not add dependencies of the outer target to exclusive targets"
do
target
=
@podfile
.
targets
[
:test
]
target
.
lib_name
.
should
==
'Pods-test'
target
.
dependencies
.
should
==
[
Pod
::
Dependency
.
new
(
'JSONKit'
)]
end
end
describe
"concerning validations"
do
it
"raises if no platform is specified"
do
exception
=
lambda
{
...
...
spec/unit/xcode/config_spec.rb
View file @
ec3d6542
...
...
@@ -25,7 +25,7 @@ describe "Pod::Xcode::Config" do
it
"creates the config file"
do
@config
.
merge!
(
'HEADER_SEARCH_PATHS'
=>
'/some/path'
)
@config
.
merge!
(
'OTHER_LD_FLAGS'
=>
'-l xml2.2.7.3'
)
@config
.
create_in
(
temporary_directory
)
@config
.
save_as
(
temporary_directory
+
'Pods.xcconfig'
)
(
temporary_directory
+
'Pods.xcconfig'
).
read
.
split
(
"
\n
"
).
sort
.
should
==
[
"OTHER_LD_FLAGS = -framework Foundation -l xml2.2.7.3"
,
"HEADER_SEARCH_PATHS = /some/path"
...
...
spec/unit/xcode/project_spec.rb
View file @
ec3d6542
...
...
@@ -23,13 +23,17 @@ describe "Pod::Xcode::Project" do
@project
.
to_hash
.
should
==
NSDictionary
.
dictionaryWithContentsOfFile
(
template_file
)
end
before
do
@target
=
@project
.
targets
.
new_static_library
(
'Pods'
)
end
it
"returns the objects hash"
do
@project
.
objects_hash
.
should
==
@project
.
to_hash
[
'objects'
]
end
describe
"PBXObject"
do
before
do
@object
=
Pod
::
Xcode
::
Project
::
PBXObject
.
new
(
@project
.
objects
,
nil
,
'name'
=>
'AnObject'
)
@object
=
Pod
::
Xcode
::
Project
::
PBXObject
.
new
(
@project
,
nil
,
'name'
=>
'AnObject'
)
end
it
"merges the class name into the attributes"
do
...
...
@@ -48,6 +52,172 @@ describe "Pod::Xcode::Project" do
@object
.
uuid
.
size
.
should
==
24
@object
.
uuid
.
should
==
@object
.
uuid
end
it
"adds the object to the objects hash"
do
@project
.
objects_hash
[
@object
.
uuid
].
should
==
@object
.
attributes
end
end
describe
"a PBXFileReference"
do
before
do
@file
=
@project
.
files
.
new
(
'path'
=>
'some/file.m'
)
end
it
"is automatically added to the main group"
do
@file
.
group
.
should
==
@project
.
main_group
end
it
"is removed from the original group when added to another group"
do
@project
.
pods
.
children
<<
@file
@file
.
group
.
should
==
@project
.
pods
@project
.
main_group
.
children
.
should
.
not
.
include
@file
end
end
describe
"a new PBXBuildPhase"
do
before
do
@phase
=
@project
.
objects
.
add
(
Pod
::
Xcode
::
Project
::
PBXBuildPhase
)
end
it
"has an empty list of files"
do
@phase
.
files
.
to_a
.
should
==
[]
end
it
"always returns the same buildActionMask (no idea what it is)"
do
@phase
.
buildActionMask
.
should
==
"2147483647"
end
it
"always returns zero for runOnlyForDeploymentPostprocessing (no idea what it is)"
do
@phase
.
runOnlyForDeploymentPostprocessing
.
should
==
"0"
end
end
describe
"a new PBXCopyFilesBuildPhase"
do
before
do
@phase
=
@project
.
objects
.
add
(
Pod
::
Xcode
::
Project
::
PBXCopyFilesBuildPhase
,
'dstPath'
=>
'some/path'
)
end
it
"is a PBXBuildPhase"
do
@phase
.
should
.
be
.
kind_of
Pod
::
Xcode
::
Project
::
PBXBuildPhase
end
it
"returns the dstPath"
do
@phase
.
dstPath
.
should
==
'some/path'
end
it
"returns the dstSubfolderSpec (no idea what it is yet, but it's not always the same)"
do
@phase
.
dstSubfolderSpec
.
should
==
"16"
end
end
describe
"a new PBXSourcesBuildPhase"
do
before
do
@phase
=
@project
.
objects
.
add
(
Pod
::
Xcode
::
Project
::
PBXSourcesBuildPhase
)
end
it
"is a PBXBuildPhase"
do
@phase
.
should
.
be
.
kind_of
Pod
::
Xcode
::
Project
::
PBXBuildPhase
end
end
describe
"a new PBXFrameworksBuildPhase"
do
before
do
@phase
=
@project
.
objects
.
add
(
Pod
::
Xcode
::
Project
::
PBXFrameworksBuildPhase
)
end
it
"is a PBXBuildPhase"
do
@phase
.
should
.
be
.
kind_of
Pod
::
Xcode
::
Project
::
PBXBuildPhase
end
end
describe
"a new XCBuildConfiguration"
do
before
do
@configuration
=
@project
.
objects
.
add
(
Pod
::
Xcode
::
Project
::
XCBuildConfiguration
)
end
it
"returns the xcconfig that this configuration is based on (baseConfigurationReference)"
do
xcconfig
=
@project
.
objects
.
new
@configuration
.
baseConfiguration
=
xcconfig
@configuration
.
baseConfigurationReference
.
should
==
xcconfig
.
uuid
end
end
describe
"a new XCConfigurationList"
do
before
do
@list
=
@project
.
objects
.
add
(
Pod
::
Xcode
::
Project
::
XCConfigurationList
)
end
it
"returns the configurations"
do
configuration
=
@project
.
objects
.
add
(
Pod
::
Xcode
::
Project
::
XCBuildConfiguration
)
@list
.
buildConfigurations
.
to_a
.
should
==
[]
@list
.
buildConfigurations
=
[
configuration
]
@list
.
buildConfigurationReferences
.
should
==
[
configuration
.
uuid
]
end
end
describe
"a new PBXNativeTarget"
do
it
"returns the product name, which is the name of the binary (minus prefix/suffix)"
do
@target
.
name
.
should
==
"Pods"
@target
.
productName
.
should
==
"Pods"
end
it
"returns the product"
do
product
=
@target
.
product
product
.
uuid
.
should
==
@target
.
productReference
product
.
should
.
be
.
instance_of
Pod
::
Xcode
::
Project
::
PBXFileReference
product
.
path
.
should
==
"libPods.a"
product
.
name
.
should
==
"libPods.a"
product
.
group
.
name
.
should
==
"Products"
product
.
sourceTree
.
should
==
"BUILT_PRODUCTS_DIR"
product
.
explicitFileType
.
should
==
"archive.ar"
product
.
includeInIndex
.
should
==
"0"
end
it
"returns that product type is a static library"
do
@target
.
productType
.
should
==
"com.apple.product-type.library.static"
end
it
"returns the buildConfigurationList"
do
list
=
@target
.
buildConfigurationList
list
.
should
.
be
.
instance_of
Pod
::
Xcode
::
Project
::
XCConfigurationList
list
.
buildConfigurations
.
each
do
|
configuration
|
configuration
.
buildSettings
.
should
==
{
'DSTROOT'
=>
'/tmp/Pods.dst'
,
'GCC_PRECOMPILE_PREFIX_HEADER'
=>
'YES'
,
# TODO do we need a default?
#'GCC_PREFIX_HEADER' => 'Pods-Prefix.pch',
'OTHER_LDFLAGS'
=>
''
,
'GCC_VERSION'
=>
'com.apple.compilers.llvm.clang.1_0'
,
'PRODUCT_NAME'
=>
'$(TARGET_NAME)'
,
'SKIP_INSTALL'
=>
'YES'
,
}
end
end
it
"returns an empty list of dependencies and buildRules (not sure yet which classes those are yet)"
do
@target
.
dependencies
.
to_a
.
should
==
[]
@target
.
buildRules
.
to_a
.
should
==
[]
end
describe
"concerning its build phases"
do
extend
SpecHelper
::
TemporaryDirectory
it
"returns an empty sources build phase"
do
phase
=
@target
.
buildPhases
.
select_by_class
(
Pod
::
Xcode
::
Project
::
PBXSourcesBuildPhase
).
first
phase
.
files
.
to_a
.
should
==
[]
end
it
"returns a libraries/frameworks build phase, which by default only contains `Foundation.framework'"
do
phase
=
@target
.
buildPhases
.
select_by_class
(
Pod
::
Xcode
::
Project
::
PBXFrameworksBuildPhase
).
first
phase
.
files
.
map
{
|
buildFile
|
buildFile
.
file
.
name
}.
should
==
[
'Foundation.framework'
]
end
it
"returns an empty 'copy headers' phase"
do
phase
=
@target
.
buildPhases
.
select_by_class
(
Pod
::
Xcode
::
Project
::
PBXCopyFilesBuildPhase
).
first
phase
.
dstPath
.
should
==
"$(PUBLIC_HEADERS_FOLDER_PATH)"
phase
.
files
.
to_a
.
should
==
[]
end
end
end
it
"returns the objects as PBXObject instances"
do
...
...
@@ -80,7 +250,7 @@ describe "Pod::Xcode::Project" do
it
"adds a new PBXBuildFile to the objects hash when a new PBXFileReference is created"
do
file
=
@project
.
files
.
new
(
'name'
=>
'/some/source/file.h'
)
build_file
=
file
.
build
_file
build_file
=
file
.
build
Files
.
new
build_file
.
file
=
file
build_file
.
fileRef
.
should
==
file
.
uuid
build_file
.
isa
.
should
==
'PBXBuildFile'
...
...
@@ -89,7 +259,7 @@ describe "Pod::Xcode::Project" do
it
"adds a group to the `Pods' group"
do
group
=
@project
.
add_pod_group
(
'JSONKit'
)
@project
.
pods
.
child
ren
.
should
.
include
group
.
uuid
@project
.
pods
.
child
References
.
should
.
include
group
.
uuid
find_object
({
'isa'
=>
'PBXGroup'
,
'name'
=>
'JSONKit'
,
...
...
@@ -98,35 +268,18 @@ describe "Pod::Xcode::Project" do
}).
should
.
not
==
nil
end
it
"adds an `m' or `c' file as a build file, adds it to the specified group, and adds it to the `sources build' phase list"
do
file_ref_uuids
,
build_file_uuids
=
[],
[]
group
=
@project
.
add_pod_group
(
'SomeGroup'
)
it
"adds an `m' or `c' file to the `sources build' phase list"
do
%w{ m mm c cpp }
.
each
do
|
ext
|
path
=
Pathname
.
new
(
"path/to/file.
#{
ext
}
"
)
file
=
group
.
add_source_file
(
path
)
file
=
@target
.
add_source_file
(
path
)
# ensure that it was added to all objects
file
=
@project
.
objects
[
file
.
uuid
]
@project
.
objects_hash
[
file
.
uuid
].
should
==
{
'name'
=>
path
.
basename
.
to_s
,
'isa'
=>
'PBXFileReference'
,
'sourceTree'
=>
'SOURCE_ROOT'
,
'path'
=>
path
.
to_s
}
file_ref_uuids
<<
file
.
uuid
build_file_uuid
,
_
=
find_object
({
'isa'
=>
'PBXBuildFile'
,
'fileRef'
=>
file
.
uuid
})
build_file_uuids
<<
build_file_uuid
phase
=
@target
.
buildPhases
.
find
{
|
phase
|
phase
.
is_a?
(
Pod
::
Xcode
::
Project
::
PBXSourcesBuildPhase
)
}
phase
.
files
.
map
{
|
buildFile
|
buildFile
.
file
}.
should
.
include
file
group
.
children
.
should
==
file_ref_uuids
_
,
object
=
find_object
(
'isa'
=>
'PBXSourcesBuildPhase'
)
object
[
'files'
].
should
==
build_file_uuids
_
,
object
=
find_object
(
'isa'
=>
'PBXHeadersBuildPhase'
)
object
[
'files'
].
should
.
not
.
include
build_file_uuid
phase
=
@target
.
buildPhases
.
find
{
|
phase
|
phase
.
is_a?
(
Pod
::
Xcode
::
Project
::
PBXCopyFilesBuildPhase
)
}
phase
.
files
.
map
{
|
buildFile
|
buildFile
.
file
}.
should
.
not
.
include
file
end
end
...
...
@@ -134,7 +287,7 @@ describe "Pod::Xcode::Project" do
build_file_uuids
=
[]
%w{ m mm c cpp }
.
each
do
|
ext
|
path
=
Pathname
.
new
(
"path/to/file.
#{
ext
}
"
)
file
=
@project
.
pods
.
add_source_file
(
path
,
nil
,
'-fno-obj-arc'
)
file
=
@project
.
targets
.
first
.
add_source_file
(
path
,
nil
,
'-fno-obj-arc'
)
find_object
({
'isa'
=>
'PBXBuildFile'
,
'fileRef'
=>
file
.
uuid
,
...
...
@@ -144,44 +297,33 @@ describe "Pod::Xcode::Project" do
end
it
"creates a copy build header phase which will copy headers to a specified path"
do
phase
=
@project
.
add_copy_header_build_phase
(
"SomePod"
,
"Path/To/Source"
)
phase
=
@project
.
targets
.
first
.
copy_files_build_phases
.
new_pod_dir
(
"SomePod"
,
"Path/To/Source"
)
find_object
({
'isa'
=>
'PBXCopyFilesBuildPhase'
,
'dstPath'
=>
'$(PUBLIC_HEADERS_FOLDER_PATH)/Path/To/Source'
,
'name'
=>
'Copy SomePod Public Headers'
}).
should
.
not
==
nil
target
=
@project
.
targets
.
first
target
.
attributes
[
'buildPhases'
].
should
.
include
phase
.
uuid
@project
.
targets
.
first
.
buildPhases
.
should
.
include
phase
end
it
"adds a `h' file as a build file and adds it to the `headers build' phase list"
do
group
=
@project
.
groups
.
new
(
'name'
=>
'SomeGroup'
)
# TODO add test for the optional copy_header_phase
#it "adds a `h' file as a build file and adds it to the `headers build' phase list" do
it
"adds a `h' file as a build file and adds it to the `copy header files' build phase list"
do
path
=
Pathname
.
new
(
"path/to/file.h"
)
file
=
group
.
add_source_file
(
path
)
@project
.
objects_hash
[
file
.
uuid
].
should
==
{
'name'
=>
path
.
basename
.
to_s
,
'isa'
=>
'PBXFileReference'
,
'sourceTree'
=>
'SOURCE_ROOT'
,
'path'
=>
path
.
to_s
}
build_file_uuid
,
_
=
find_object
({
'isa'
=>
'PBXBuildFile'
,
'fileRef'
=>
file
.
uuid
})
file
=
@target
.
add_source_file
(
path
)
# ensure that it was added to all objects
file
=
@project
.
objects
[
file
.
uuid
]
#_, object = find_object('isa' => 'PBXHeadersBuildPhase')
_
,
object
=
find_object
(
'isa'
=>
'PBXCopyFilesBuildPhase'
)
object
[
'files'
].
should
==
[
build_file_uuid
]
phase
=
@target
.
buildPhases
.
find
{
|
phase
|
phase
.
is_a?
(
Pod
::
Xcode
::
Project
::
PBXSourcesBuildPhase
)
}
phase
.
files
.
map
{
|
buildFile
|
buildFile
.
file
}.
should
.
not
.
include
file
_
,
object
=
find_object
(
'isa'
=>
'PBXSourcesBuildPhase'
)
object
[
'files'
].
should
.
not
.
include
build_file_uuid
phase
=
@target
.
buildPhases
.
find
{
|
phase
|
phase
.
is_a?
(
Pod
::
Xcode
::
Project
::
PBXCopyFilesBuildPhase
)
}
phase
.
files
.
map
{
|
buildFile
|
buildFile
.
file
}.
should
.
include
file
end
it
"saves the template with the adjusted project"
do
@template
.
copy_to
(
temporary_directory
)
@project
.
save_as
(
temporary_directory
+
'Pods.xcodeproj'
)
(
temporary_directory
+
'Pods-Prefix.pch'
).
should
.
exist
(
temporary_directory
+
'Pods.xcconfig'
).
should
.
exist
project_file
=
(
temporary_directory
+
'Pods.xcodeproj/project.pbxproj'
)
NSDictionary
.
dictionaryWithContentsOfFile
(
project_file
.
to_s
).
should
==
@project
.
to_hash
end
...
...
@@ -189,7 +331,7 @@ describe "Pod::Xcode::Project" do
it
"returns all source files"
do
group
=
@project
.
groups
.
new
(
'name'
=>
'SomeGroup'
)
files
=
[
Pathname
.
new
(
'/some/file.h'
),
Pathname
.
new
(
'/some/file.m'
)]
files
.
each
{
|
file
|
group
.
add_source_file
(
file
)
}
files
.
each
{
|
file
|
group
<<
@target
.
add_source_file
(
file
)
}
group
.
source_files
.
map
(
&
:pathname
).
sort
.
should
==
files
.
sort
end
end
xcode-project-templates/cocoa-static-library/Pods-Prefix.pch
deleted
100644 → 0
View file @
99417d11
//
// Prefix header for all source files of the 'Pods' target in the 'Pods' project
//
#ifdef __OBJC__
#import <Cocoa/Cocoa.h>
#endif
xcode-project-templates/cocoa-static-library/Pods.xcconfig
deleted
100644 → 0
View file @
99417d11
xcode-project-templates/cocoa-static-library/Pods.xcodeproj/project.pbxproj
View file @
ec3d6542
...
...
@@ -6,33 +6,14 @@
objectVersion
=
46
;
objects
=
{
/* Begin PBXBuildFile section */
518ACD3F1446050200F6BE80
/* Cocoa.framework in Frameworks */
=
{
isa
=
PBXBuildFile
;
fileRef
=
518ACD3E1446050200F6BE80
/* Cocoa.framework */
;
};
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
518ACD3B1446050200F6BE80
/* libPods.a */
=
{
isa
=
PBXFileReference
;
explicitFileType
=
archive.ar
;
includeInIndex
=
0
;
path
=
libPods.a
;
sourceTree
=
BUILT_PRODUCTS_DIR
;
};
518ACD3E1446050200F6BE80
/* Cocoa.framework */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
wrapper.framework
;
name
=
Cocoa.framework
;
path
=
System/Library/Frameworks/Cocoa.framework
;
sourceTree
=
SDKROOT
;
};
518ACD461446050200F6BE80
/* Pods-Prefix.pch */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.c.h
;
path
=
"Pods-Prefix.pch"
;
sourceTree
=
"<group>"
;
};
518ACD53144605B400F6BE80
/* Pods.xcconfig */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
text.xcconfig
;
path
=
Pods.xcconfig
;
sourceTree
=
"<group>"
;
};
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
518ACD381446050200F6BE80
/* Frameworks */
=
{
isa
=
PBXFrameworksBuildPhase
;
buildActionMask
=
2147483647
;
files
=
(
518ACD3F1446050200F6BE80
/* Cocoa.framework in Frameworks */
,
);
runOnlyForDeploymentPostprocessing
=
0
;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
518ACD301446050100F6BE80
=
{
isa
=
PBXGroup
;
children
=
(
518ACD53144605B400F6BE80
/* Pods.xcconfig */
,
518ACD5B1446449B00F6BE80
/* Pods */
,
518ACD3D1446050200F6BE80
/* Frameworks */
,
518ACD3C1446050200F6BE80
/* Products */
,
...
...
@@ -42,7 +23,6 @@
518ACD3C1446050200F6BE80
/* Products */
=
{
isa
=
PBXGroup
;
children
=
(
518ACD3B1446050200F6BE80
/* libPods.a */
,
);
name
=
Products
;
sourceTree
=
"<group>"
;
...
...
@@ -55,55 +35,15 @@
name
=
Frameworks
;
sourceTree
=
"<group>"
;
};
518ACD451446050200F6BE80
/* Supporting Files */
=
{
isa
=
PBXGroup
;
children
=
(
518ACD461446050200F6BE80
/* Pods-Prefix.pch */
,
);
name
=
"Supporting Files"
;
path
=
Pods
;
sourceTree
=
"<group>"
;
};
518ACD5B1446449B00F6BE80
/* Pods */
=
{
isa
=
PBXGroup
;
children
=
(
518ACD451446050200F6BE80
/* Supporting Files */
,
);
name
=
Pods
;
sourceTree
=
"<group>"
;
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
518ACD391446050200F6BE80
/* Headers */
=
{
isa
=
PBXHeadersBuildPhase
;
buildActionMask
=
2147483647
;
files
=
(
);
runOnlyForDeploymentPostprocessing
=
0
;
};
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
518ACD3A1446050200F6BE80
/* Pods */
=
{
isa
=
PBXNativeTarget
;
buildConfigurationList
=
518ACD4C1446050200F6BE80
/* Build configuration list for PBXNativeTarget "Pods" */
;
buildPhases
=
(
518ACD371446050200F6BE80
/* Sources */
,
518ACD381446050200F6BE80
/* Frameworks */
,
518ACD391446050200F6BE80
/* Headers */
,
);
buildRules
=
(
);
dependencies
=
(
);
name
=
Pods
;
productName
=
Pods
;
productReference
=
518ACD3B1446050200F6BE80
/* libPods.a */
;
productType
=
"com.apple.product-type.library.static"
;
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
518ACD321446050100F6BE80
/* Project object */
=
{
isa
=
PBXProject
;
...
...
@@ -122,21 +62,10 @@
projectDirPath
=
""
;
projectRoot
=
""
;
targets
=
(
518ACD3A1446050200F6BE80
/* Pods */
,
);
};
/* End PBXProject section */
/* Begin PBXSourcesBuildPhase section */
518ACD371446050200F6BE80
/* Sources */
=
{
isa
=
PBXSourcesBuildPhase
;
buildActionMask
=
2147483647
;
files
=
(
);
runOnlyForDeploymentPostprocessing
=
0
;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
518ACD4A1446050200F6BE80
/* Debug */
=
{
isa
=
XCBuildConfiguration
;
...
...
@@ -185,30 +114,6 @@
};
name
=
Release
;
};
518ACD4D1446050200F6BE80
/* Debug */
=
{
isa
=
XCBuildConfiguration
;
baseConfigurationReference
=
518ACD53144605B400F6BE80
/* Pods.xcconfig */
;
buildSettings
=
{
GCC_PRECOMPILE_PREFIX_HEADER
=
YES
;
GCC_PREFIX_HEADER
=
"Pods-Prefix.pch"
;
OTHER_LDFLAGS
=
(
);
PRODUCT_NAME
=
"$(TARGET_NAME)"
;
};
name
=
Debug
;
};
518ACD4E1446050200F6BE80
/* Release */
=
{
isa
=
XCBuildConfiguration
;
baseConfigurationReference
=
518ACD53144605B400F6BE80
/* Pods.xcconfig */
;
buildSettings
=
{
GCC_PRECOMPILE_PREFIX_HEADER
=
YES
;
GCC_PREFIX_HEADER
=
"Pods-Prefix.pch"
;
OTHER_LDFLAGS
=
(
);
PRODUCT_NAME
=
"$(TARGET_NAME)"
;
};
name
=
Release
;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
...
...
@@ -221,15 +126,6 @@
defaultConfigurationIsVisible
=
0
;
defaultConfigurationName
=
Release
;
};
518ACD4C1446050200F6BE80
/* Build configuration list for PBXNativeTarget "Pods" */
=
{
isa
=
XCConfigurationList
;
buildConfigurations
=
(
518ACD4D1446050200F6BE80
/* Debug */
,
518ACD4E1446050200F6BE80
/* Release */
,
);
defaultConfigurationIsVisible
=
0
;
defaultConfigurationName
=
Release
;
};
/* End XCConfigurationList section */
};
rootObject
=
518ACD321446050100F6BE80
/* Project object */
;
...
...
xcode-project-templates/cocoa-static-library/PodsResources.sh
deleted
100755 → 0
View file @
99417d11
#!/bin/sh
install_resource
()
{
echo
"cp -R
${
SRCROOT
}
/Pods/
$1
${
CONFIGURATION_BUILD_DIR
}
/
${
UNLOCALIZED_RESOURCES_FOLDER_PATH
}
"
cp
-R
${
SRCROOT
}
/Pods/
$1
${
CONFIGURATION_BUILD_DIR
}
/
${
UNLOCALIZED_RESOURCES_FOLDER_PATH
}
}
xcode-project-templates/cocoa-touch-static-library/Pods-Prefix.pch
deleted
100644 → 0
View file @
99417d11
//
// Prefix header for all source files of the 'Pods' target in the 'Pods' project
//
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#endif
xcode-project-templates/cocoa-touch-static-library/Pods.xcconfig
deleted
100644 → 0
View file @
99417d11
xcode-project-templates/cocoa-touch-static-library/Pods.xcodeproj/project.pbxproj
View file @
ec3d6542
...
...
@@ -6,46 +6,14 @@
objectVersion
=
46
;
objects
=
{
/* Begin PBXBuildFile section */
515B0FB9141D52E0001DC3E6
/* Foundation.framework in Frameworks */
=
{
isa
=
PBXBuildFile
;
fileRef
=
515B0FB8141D52E0001DC3E6
/* Foundation.framework */
;
};
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
82A8B61C142F7EC7006897C9
/* Copy Public Headers */
=
{
isa
=
PBXCopyFilesBuildPhase
;
buildActionMask
=
2147483647
;
dstPath
=
"$(PUBLIC_HEADERS_FOLDER_PATH)"
;
dstSubfolderSpec
=
16
;
files
=
(
);
name
=
"Copy Public Headers"
;
runOnlyForDeploymentPostprocessing
=
0
;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
515160D0141EC5D100EBB823
/* Pods.xcconfig */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
text.xcconfig
;
path
=
Pods.xcconfig
;
sourceTree
=
"<group>"
;
};
515B0FB5141D52E0001DC3E6
/* libPods.a */
=
{
isa
=
PBXFileReference
;
explicitFileType
=
archive.ar
;
includeInIndex
=
0
;
path
=
libPods.a
;
sourceTree
=
BUILT_PRODUCTS_DIR
;
};
515B0FB8141D52E0001DC3E6
/* Foundation.framework */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
wrapper.framework
;
name
=
Foundation.framework
;
path
=
System/Library/Frameworks/Foundation.framework
;
sourceTree
=
SDKROOT
;
};
515B0FBC141D52E0001DC3E6
/* Pods-Prefix.pch */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.c.h
;
path
=
"Pods-Prefix.pch"
;
sourceTree
=
SOURCE_ROOT
;
};
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
515B0FB2141D52E0001DC3E6
/* Frameworks */
=
{
isa
=
PBXFrameworksBuildPhase
;
buildActionMask
=
2147483647
;
files
=
(
515B0FB9141D52E0001DC3E6
/* Foundation.framework in Frameworks */
,
);
runOnlyForDeploymentPostprocessing
=
0
;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
515B0FAA141D52E0001DC3E6
=
{
isa
=
PBXGroup
;
children
=
(
515160D0141EC5D100EBB823
/* Pods.xcconfig */
,
515B0FC9141D5FBE001DC3E6
/* Pods */
,
515B0FB7141D52E0001DC3E6
/* Frameworks */
,
515B0FB6141D52E0001DC3E6
/* Products */
,
...
...
@@ -55,7 +23,6 @@
515B0FB6141D52E0001DC3E6
/* Products */
=
{
isa
=
PBXGroup
;
children
=
(
515B0FB5141D52E0001DC3E6
/* libPods.a */
,
);
name
=
Products
;
sourceTree
=
"<group>"
;
...
...
@@ -68,59 +35,21 @@
name
=
Frameworks
;
sourceTree
=
"<group>"
;
};
515B0FBB141D52E0001DC3E6
/* Supporting Files */
=
{
isa
=
PBXGroup
;
children
=
(
515B0FBC141D52E0001DC3E6
/* Pods-Prefix.pch */
,
);
name
=
"Supporting Files"
;
path
=
Pods
;
sourceTree
=
"<group>"
;
};
515B0FC9141D5FBE001DC3E6
/* Pods */
=
{
isa
=
PBXGroup
;
children
=
(
515B0FBB141D52E0001DC3E6
/* Supporting Files */
,
);
name
=
Pods
;
sourceTree
=
"<group>"
;
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
515B0FB3141D52E0001DC3E6
/* Headers */
=
{
isa
=
PBXHeadersBuildPhase
;
buildActionMask
=
2147483647
;
files
=
(
);
runOnlyForDeploymentPostprocessing
=
0
;
};
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
515B0FB4141D52E0001DC3E6
/* Pods */
=
{
isa
=
PBXNativeTarget
;
buildConfigurationList
=
515B0FC2141D52E0001DC3E6
/* Build configuration list for PBXNativeTarget "Pods" */
;
buildPhases
=
(
515B0FB1141D52E0001DC3E6
/* Sources */
,
515B0FB2141D52E0001DC3E6
/* Frameworks */
,
515B0FB3141D52E0001DC3E6
/* Headers */
,
82A8B61C142F7EC7006897C9
/* Copy Public Headers */
,
);
buildRules
=
(
);
dependencies
=
(
);
name
=
Pods
;
productName
=
Pods
;
productReference
=
515B0FB5141D52E0001DC3E6
/* libPods.a */
;
productType
=
"com.apple.product-type.library.static"
;
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
515B0FAC141D52E0001DC3E6
/* Project object */
=
{
isa
=
PBXProject
;
attributes
=
{
LastUpgradeCheck
=
0420
;
};
buildConfigurationList
=
515B0FAF141D52E0001DC3E6
/* Build configuration list for PBXProject "Pods" */
;
compatibilityVersion
=
"Xcode 3.2"
;
developmentRegion
=
English
;
...
...
@@ -133,21 +62,10 @@
projectDirPath
=
""
;
projectRoot
=
""
;
targets
=
(
515B0FB4141D52E0001DC3E6
/* Pods */
,
);
};
/* End PBXProject section */
/* Begin PBXSourcesBuildPhase section */
515B0FB1141D52E0001DC3E6
/* Sources */
=
{
isa
=
PBXSourcesBuildPhase
;
buildActionMask
=
2147483647
;
files
=
(
);
runOnlyForDeploymentPostprocessing
=
0
;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
515B0FC0141D52E0001DC3E6
/* Debug */
=
{
isa
=
XCBuildConfiguration
;
...
...
@@ -193,34 +111,6 @@
};
name
=
Release
;
};
515B0FC3141D52E0001DC3E6
/* Debug */
=
{
isa
=
XCBuildConfiguration
;
baseConfigurationReference
=
515160D0141EC5D100EBB823
/* Pods.xcconfig */
;
buildSettings
=
{
DSTROOT
=
/tmp/Pods.dst
;
GCC_PRECOMPILE_PREFIX_HEADER
=
YES
;
GCC_PREFIX_HEADER
=
"Pods-Prefix.pch"
;
GCC_VERSION
=
com.apple.compilers.llvm.clang.1_0
;
OTHER_LDFLAGS
=
"-ObjC"
;
PRODUCT_NAME
=
"$(TARGET_NAME)"
;
SKIP_INSTALL
=
YES
;
};
name
=
Debug
;
};
515B0FC4141D52E0001DC3E6
/* Release */
=
{
isa
=
XCBuildConfiguration
;
baseConfigurationReference
=
515160D0141EC5D100EBB823
/* Pods.xcconfig */
;
buildSettings
=
{
DSTROOT
=
/tmp/Pods.dst
;
GCC_PRECOMPILE_PREFIX_HEADER
=
YES
;
GCC_PREFIX_HEADER
=
"Pods-Prefix.pch"
;
GCC_VERSION
=
com.apple.compilers.llvm.clang.1_0
;
OTHER_LDFLAGS
=
"-ObjC"
;
PRODUCT_NAME
=
"$(TARGET_NAME)"
;
SKIP_INSTALL
=
YES
;
};
name
=
Release
;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
...
...
@@ -233,15 +123,6 @@
defaultConfigurationIsVisible
=
0
;
defaultConfigurationName
=
Release
;
};
515B0FC2141D52E0001DC3E6
/* Build configuration list for PBXNativeTarget "Pods" */
=
{
isa
=
XCConfigurationList
;
buildConfigurations
=
(
515B0FC3141D52E0001DC3E6
/* Debug */
,
515B0FC4141D52E0001DC3E6
/* Release */
,
);
defaultConfigurationIsVisible
=
0
;
defaultConfigurationName
=
Release
;
};
/* End XCConfigurationList section */
};
rootObject
=
515B0FAC141D52E0001DC3E6
/* Project object */
;
...
...
xcode-project-templates/cocoa-touch-static-library/PodsResources.sh
deleted
100755 → 0
View file @
99417d11
#!/bin/sh
install_resource
()
{
echo
"cp -R
${
SRCROOT
}
/Pods/
$1
${
CONFIGURATION_BUILD_DIR
}
/
${
UNLOCALIZED_RESOURCES_FOLDER_PATH
}
"
cp
-R
${
SRCROOT
}
/Pods/
$1
${
CONFIGURATION_BUILD_DIR
}
/
${
UNLOCALIZED_RESOURCES_FOLDER_PATH
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment