Commit ed6862fd authored by Nolan Waite's avatar Nolan Waite

ProjectTemplate is really a module

parent 70858e8c
......@@ -20,8 +20,8 @@ module Pod
attr_reader :target
def initialize(podfile, xcodeproj, definition)
@podfile, @xcodeproj, @definition = podfile, xcodeproj, definition
def initialize(podfile, project, definition)
@podfile, @project, @definition = podfile, project, definition
end
def xcconfig
......@@ -77,7 +77,7 @@ module Pod
# TODO move xcconfig related code into the xcconfig method, like copy_resources_script and generate_bridge_support.
def install!
# First add the target to the project
@target = @xcodeproj.targets.new_static_library(@definition.lib_name)
@target = @project.targets.new_static_library(@definition.lib_name)
user_header_search_paths = []
build_specifications.each do |spec|
......@@ -101,7 +101,7 @@ module Pod
# 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|
support_files_group = @project.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)
......@@ -132,27 +132,27 @@ module Pod
@podfile = podfile
end
def template
return @template if @template
@template = ProjectTemplate.new(@podfile.platform)
def project
return @project if @project
@project = ProjectTemplate.for_platform(@podfile.platform)
# 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 = @template.project.add_pod_group(spec.name)
group = @project.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
@template.project.main_group.groups.new('name' => 'Targets Support Files')
@template
@project.main_group.groups.new('name' => 'Targets Support Files')
@project
end
def targets
@targets ||= @podfile.targets.values.map do |target_definition|
Target.new(@podfile, template.project, target_definition)
Target.new(@podfile, project, target_definition)
end
end
......@@ -166,9 +166,9 @@ module Pod
target.install!
target.create_files_in(root)
end
pbxproj = File.join(root, 'Pods.xcodeproj')
puts " * Writing Xcode project file to `#{pbxproj}'" if config.verbose?
template.project.save_as(pbxproj)
projpath = File.join(root, 'Pods.xcodeproj')
puts " * Writing Xcode project file to `#{projpath}'" if config.verbose?
project.save_as(projpath)
# Post install hooks run last!
targets.each do |target|
......
require 'fileutils'
module Pod
class ProjectTemplate
def initialize(platform)
@platform = platform
generate_template_project!
end
attr_reader :platform
attr_reader :project
def save_to(pods_root)
@project.save_as(File.join(pods_root, 'Pods.xcodeproj'))
end
def generate_template_project!
@project = Xcode::Project.new
root = @project.objects.add(Xcode::Project::PBXProject, {
module ProjectTemplate
def self.for_platform(platform)
project = Xcode::Project.new
root = project.objects.add(Xcode::Project::PBXProject, {
'attributes' => { 'LastUpgradeCheck' => '0420' },
'compatibilityVersion' => 'Xcode 3.2',
'developmentRegion' => 'English',
'hasScannedForEncodings' => '0',
'knownRegions' => ['en'],
'mainGroup' => @project.groups.new({ 'sourceTree' => '<group>' }).uuid,
'mainGroup' => project.groups.new({ 'sourceTree' => '<group>' }).uuid,
'projectDirPath' => '',
'projectRoot' => '',
'targets' => []
})
@project.root_object = root
@project.main_group << @project.groups.new({
project.root_object = root
project.main_group << project.groups.new({
'name' => 'Pods',
'sourceTree' => '<group>'
})
framework = @project.files.new({
framework = project.files.new({
'lastKnownFileType' => 'wrapper.framework',
'name' => platform == :ios ? 'Foundation.framework' : 'Cocoa.framework',
'path' => "System/Library/Frameworks/#{platform == :ios ? 'Framework' : 'Cocoa'}.framework",
'sourceTree' => 'SDKROOT'
})
framework.group = @project.groups.new({
framework.group = project.groups.new({
'name' => 'Frameworks',
'sourceTree' => '<group>'
})
@project.main_group << framework.group
products = @project.groups.new({
project.main_group << framework.group
products = project.groups.new({
'name' => 'Products',
'sourceTree' => '<group>'
})
@project.main_group << products
@project.root_object.products = products
project.main_group << products
project.root_object.products = products
@project.root_object.attributes['buildConfigurationList'] = @project.objects.add(Xcode::Project::XCConfigurationList, {
project.root_object.attributes['buildConfigurationList'] = project.objects.add(Xcode::Project::XCConfigurationList, {
'defaultConfigurationIsVisible' => '0',
'defaultConfigurationName' => 'Release',
'buildConfigurations' => [
@project.objects.add(Xcode::Project::XCBuildConfiguration, {
project.objects.add(Xcode::Project::XCBuildConfiguration, {
'name' => 'Debug',
'buildSettings' => build_settings(:debug)
'buildSettings' => build_settings(platform, :debug)
}),
@project.objects.add(Xcode::Project::XCBuildConfiguration, {
project.objects.add(Xcode::Project::XCBuildConfiguration, {
'name' => 'Release',
'buildSettings' => build_settings(:release)
'buildSettings' => build_settings(platform, :release)
})
].map(&:uuid)
}).uuid
project
end
private
COMMON_BUILD_SETTINGS = {
:all => {
'ALWAYS_SEARCH_USER_PATHS' => 'NO',
......@@ -97,7 +88,7 @@ module Pod
'SDKROOT' => 'macosx'
}
}
def build_settings(scheme)
def self.build_settings(platform, scheme)
settings = COMMON_BUILD_SETTINGS[:all].merge(COMMON_BUILD_SETTINGS[platform])
settings['COPY_PHASE_STRIP'] = scheme == :debug ? 'NO' : 'YES'
if scheme == :debug
......
......@@ -77,7 +77,7 @@ else
(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.template.project.to_hash
NSDictionary.dictionaryWithContentsOfFile(project_file).should == installer.project.to_hash
puts "\n[!] Compiling static library..."
Dir.chdir(config.project_pods_root) do
......@@ -144,7 +144,7 @@ else
installer.install!
project = Pod::Xcode::Project.new(config.project_pods_root + 'Pods.xcodeproj')
project.source_files.should == installer.template.project.source_files
project.source_files.should == installer.project.source_files
end
it "creates a project with multiple targets" do
......
......@@ -4,11 +4,11 @@ describe "Pod::Xcode::Project" do
extend SpecHelper::TemporaryDirectory
before do
@template = Pod::ProjectTemplate.new(:ios)
@project = Pod::ProjectTemplate.for_platform(:ios)
end
def find_objects(conditions)
@template.project.objects_hash.select do |_, object|
@project.objects_hash.select do |_, object|
object.objectsForKeys(conditions.keys, notFoundMarker:Object.new) == conditions.values
end
end
......@@ -18,16 +18,16 @@ describe "Pod::Xcode::Project" do
end
before do
@target = @template.project.targets.new_static_library('Pods')
@target = @project.targets.new_static_library('Pods')
end
it "returns the objects hash" do
@template.project.objects_hash.should == @template.project.to_hash['objects']
@project.objects_hash.should == @project.to_hash['objects']
end
describe "PBXObject" do
before do
@object = Pod::Xcode::Project::PBXObject.new(@template.project, nil, 'name' => 'AnObject')
@object = Pod::Xcode::Project::PBXObject.new(@project, nil, 'name' => 'AnObject')
end
it "merges the class name into the attributes" do
......@@ -48,29 +48,29 @@ describe "Pod::Xcode::Project" do
end
it "adds the object to the objects hash" do
@template.project.objects_hash[@object.uuid].should == @object.attributes
@project.objects_hash[@object.uuid].should == @object.attributes
end
end
describe "a PBXFileReference" do
before do
@file = @template.project.files.new('path' => 'some/file.m')
@file = @project.files.new('path' => 'some/file.m')
end
it "is automatically added to the main group" do
@file.group.should == @template.project.main_group
@file.group.should == @project.main_group
end
it "is removed from the original group when added to another group" do
@template.project.pods.children << @file
@file.group.should == @template.project.pods
@template.project.main_group.children.should.not.include @file
@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 = @template.project.objects.add(Pod::Xcode::Project::PBXBuildPhase)
@phase = @project.objects.add(Pod::Xcode::Project::PBXBuildPhase)
end
it "has an empty list of files" do
......@@ -88,7 +88,7 @@ describe "Pod::Xcode::Project" do
describe "a new PBXCopyFilesBuildPhase" do
before do
@phase = @template.project.objects.add(Pod::Xcode::Project::PBXCopyFilesBuildPhase, 'dstPath' => 'some/path')
@phase = @project.objects.add(Pod::Xcode::Project::PBXCopyFilesBuildPhase, 'dstPath' => 'some/path')
end
it "is a PBXBuildPhase" do
......@@ -106,7 +106,7 @@ describe "Pod::Xcode::Project" do
describe "a new PBXSourcesBuildPhase" do
before do
@phase = @template.project.objects.add(Pod::Xcode::Project::PBXSourcesBuildPhase)
@phase = @project.objects.add(Pod::Xcode::Project::PBXSourcesBuildPhase)
end
it "is a PBXBuildPhase" do
......@@ -116,7 +116,7 @@ describe "Pod::Xcode::Project" do
describe "a new PBXFrameworksBuildPhase" do
before do
@phase = @template.project.objects.add(Pod::Xcode::Project::PBXFrameworksBuildPhase)
@phase = @project.objects.add(Pod::Xcode::Project::PBXFrameworksBuildPhase)
end
it "is a PBXBuildPhase" do
......@@ -126,11 +126,11 @@ describe "Pod::Xcode::Project" do
describe "a new XCBuildConfiguration" do
before do
@configuration = @template.project.objects.add(Pod::Xcode::Project::XCBuildConfiguration)
@configuration = @project.objects.add(Pod::Xcode::Project::XCBuildConfiguration)
end
it "returns the xcconfig that this configuration is based on (baseConfigurationReference)" do
xcconfig = @template.project.objects.new
xcconfig = @project.objects.new
@configuration.baseConfiguration = xcconfig
@configuration.baseConfigurationReference.should == xcconfig.uuid
end
......@@ -138,11 +138,11 @@ describe "Pod::Xcode::Project" do
describe "a new XCConfigurationList" do
before do
@list = @template.project.objects.add(Pod::Xcode::Project::XCConfigurationList)
@list = @project.objects.add(Pod::Xcode::Project::XCConfigurationList)
end
it "returns the configurations" do
configuration = @template.project.objects.add(Pod::Xcode::Project::XCBuildConfiguration)
configuration = @project.objects.add(Pod::Xcode::Project::XCBuildConfiguration)
@list.buildConfigurations.to_a.should == []
@list.buildConfigurations = [configuration]
@list.buildConfigurationReferences.should == [configuration.uuid]
......@@ -215,45 +215,45 @@ describe "Pod::Xcode::Project" do
end
it "returns the objects as PBXObject instances" do
@template.project.objects.each do |object|
@template.project.objects_hash[object.uuid].should == object.attributes
@project.objects.each do |object|
@project.objects_hash[object.uuid].should == object.attributes
end
end
it "adds any type of new PBXObject to the objects hash" do
object = @template.project.objects.add(Pod::Xcode::Project::PBXObject, 'name' => 'An Object')
object = @project.objects.add(Pod::Xcode::Project::PBXObject, 'name' => 'An Object')
object.name.should == 'An Object'
@template.project.objects_hash[object.uuid].should == object.attributes
@project.objects_hash[object.uuid].should == object.attributes
end
it "adds a new PBXObject, of the configured type, to the objects hash" do
group = @template.project.groups.new('name' => 'A new group')
group = @project.groups.new('name' => 'A new group')
group.isa.should == 'PBXGroup'
group.name.should == 'A new group'
@template.project.objects_hash[group.uuid].should == group.attributes
@project.objects_hash[group.uuid].should == group.attributes
end
it "adds a new PBXFileReference to the objects hash" do
file = @template.project.files.new('path' => '/some/file.m')
file = @project.files.new('path' => '/some/file.m')
file.isa.should == 'PBXFileReference'
file.name.should == 'file.m'
file.path.should == '/some/file.m'
file.sourceTree.should == 'SOURCE_ROOT'
@template.project.objects_hash[file.uuid].should == file.attributes
@project.objects_hash[file.uuid].should == file.attributes
end
it "adds a new PBXBuildFile to the objects hash when a new PBXFileReference is created" do
file = @template.project.files.new('name' => '/some/source/file.h')
file = @project.files.new('name' => '/some/source/file.h')
build_file = file.buildFiles.new
build_file.file = file
build_file.fileRef.should == file.uuid
build_file.isa.should == 'PBXBuildFile'
@template.project.objects_hash[build_file.uuid].should == build_file.attributes
@project.objects_hash[build_file.uuid].should == build_file.attributes
end
it "adds a group to the `Pods' group" do
group = @template.project.add_pod_group('JSONKit')
@template.project.pods.childReferences.should.include group.uuid
group = @project.add_pod_group('JSONKit')
@project.pods.childReferences.should.include group.uuid
find_object({
'isa' => 'PBXGroup',
'name' => 'JSONKit',
......@@ -267,7 +267,7 @@ describe "Pod::Xcode::Project" do
path = Pathname.new("path/to/file.#{ext}")
file = @target.add_source_file(path)
# ensure that it was added to all objects
file = @template.project.objects[file.uuid]
file = @project.objects[file.uuid]
phase = @target.buildPhases.find { |phase| phase.is_a?(Pod::Xcode::Project::PBXSourcesBuildPhase) }
phase.files.map { |buildFile| buildFile.file }.should.include file
......@@ -281,7 +281,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 = @template.project.targets.first.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,
......@@ -291,13 +291,13 @@ describe "Pod::Xcode::Project" do
end
it "creates a copy build header phase which will copy headers to a specified path" do
phase = @template.project.targets.first.copy_files_build_phases.new_pod_dir("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
@template.project.targets.first.buildPhases.should.include phase
@project.targets.first.buildPhases.should.include phase
end
# TODO add test for the optional copy_header_phase
......@@ -306,7 +306,7 @@ describe "Pod::Xcode::Project" do
path = Pathname.new("path/to/file.h")
file = @target.add_source_file(path)
# ensure that it was added to all objects
file = @template.project.objects[file.uuid]
file = @project.objects[file.uuid]
phase = @target.buildPhases.find { |phase| phase.is_a?(Pod::Xcode::Project::PBXSourcesBuildPhase) }
phase.files.map { |buildFile| buildFile.file }.should.not.include file
......@@ -316,13 +316,13 @@ describe "Pod::Xcode::Project" do
end
it "saves the template with the adjusted project" do
@template.save_to(temporary_directory)
@project.save_as(File.join(temporary_directory, 'Pods.xcodeproj'))
project_file = (temporary_directory + 'Pods.xcodeproj/project.pbxproj')
NSDictionary.dictionaryWithContentsOfFile(project_file.to_s).should == @template.project.to_hash
NSDictionary.dictionaryWithContentsOfFile(project_file.to_s).should == @project.to_hash
end
it "returns all source files" do
group = @template.project.groups.new('name' => 'SomeGroup')
group = @project.groups.new('name' => 'SomeGroup')
files = [Pathname.new('/some/file.h'), Pathname.new('/some/file.m')]
files.each { |file| group << @target.add_source_file(file) }
group.source_files.map(&:pathname).sort.should == files.sort
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment