Commit e08a67a6 authored by Nolan Waite's avatar Nolan Waite

Template maintains its project

parent 5129dcdc
...@@ -133,31 +133,26 @@ module Pod ...@@ -133,31 +133,26 @@ module Pod
end end
def template def template
@template ||= ProjectTemplate.new(@podfile.platform) return @template if @template
end @template = ProjectTemplate.new(@podfile.platform)
# First we need to resolve dependencies across *all* targets, so that the
def xcodeproj # same correct versions of pods are being used for all targets. This
unless @xcodeproj # happens when we call `build_specifications'.
@xcodeproj = Xcode::Project.new(template.xcodeproj_path) build_specifications.each do |spec|
# First we need to resolve dependencies across *all* targets, so that the # Add all source files to the project grouped by pod
# same correct versions of pods are being used for all targets. This group = @template.project.add_pod_group(spec.name)
# happens when we call `build_specifications'. spec.expanded_source_files.each do |path|
build_specifications.each do |spec| group.children.new('path' => path.to_s)
# 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 end
# Add a group to hold all the target support files
xcodeproj.main_group.groups.new('name' => 'Targets Support Files')
end end
@xcodeproj # Add a group to hold all the target support files
@template.project.main_group.groups.new('name' => 'Targets Support Files')
@template
end end
def targets def targets
@targets ||= @podfile.targets.values.map do |target_definition| @targets ||= @podfile.targets.values.map do |target_definition|
Target.new(@podfile, xcodeproj, target_definition) Target.new(@podfile, template.project, target_definition)
end end
end end
...@@ -176,7 +171,7 @@ module Pod ...@@ -176,7 +171,7 @@ module Pod
end end
pbxproj = File.join(root, 'Pods.xcodeproj') pbxproj = File.join(root, 'Pods.xcodeproj')
puts " * Writing Xcode project file to `#{pbxproj}'" if config.verbose? puts " * Writing Xcode project file to `#{pbxproj}'" if config.verbose?
xcodeproj.save_as(pbxproj) template.project.save_as(pbxproj)
# Post install hooks run last! # Post install hooks run last!
targets.each do |target| targets.each do |target|
......
...@@ -4,8 +4,11 @@ module Pod ...@@ -4,8 +4,11 @@ module Pod
class ProjectTemplate class ProjectTemplate
def initialize(platform) def initialize(platform)
@platform = platform @platform = platform
@project = Xcode::Project.new(File.join(path, 'Pods.xcodeproj'))
end end
attr_reader :project
# TODO this is a workaround for an issue with MacRuby with compiled files # TODO this is a workaround for an issue with MacRuby with compiled files
# that makes the use of __FILE__ impossible. # that makes the use of __FILE__ impossible.
# #
...@@ -34,12 +37,9 @@ module Pod ...@@ -34,12 +37,9 @@ module Pod
end end
end end
def xcodeproj_path
@xcodeproj_path = File.join(path, 'Pods.xcodeproj')
end
def copy_to(pods_root) def copy_to(pods_root)
FileUtils.cp_r("#{path}/.", pods_root) FileUtils.cp_r("#{path}/.", pods_root)
@project.save_as(File.join(pods_root, 'Pods.xcodeproj'))
end end
end end
end end
...@@ -77,7 +77,7 @@ else ...@@ -77,7 +77,7 @@ else
(root + 'Pods.xcconfig').read.should == installer.targets.first.xcconfig.to_s (root + 'Pods.xcconfig').read.should == installer.targets.first.xcconfig.to_s
project_file = (root + 'Pods.xcodeproj/project.pbxproj').to_s project_file = (root + 'Pods.xcodeproj/project.pbxproj').to_s
NSDictionary.dictionaryWithContentsOfFile(project_file).should == installer.xcodeproj.to_hash NSDictionary.dictionaryWithContentsOfFile(project_file).should == installer.template.project.to_hash
puts "\n[!] Compiling static library..." puts "\n[!] Compiling static library..."
Dir.chdir(config.project_pods_root) do Dir.chdir(config.project_pods_root) do
...@@ -144,7 +144,7 @@ else ...@@ -144,7 +144,7 @@ else
installer.install! installer.install!
project = Pod::Xcode::Project.new(config.project_pods_root + 'Pods.xcodeproj') project = Pod::Xcode::Project.new(config.project_pods_root + 'Pods.xcodeproj')
project.source_files.should == installer.xcodeproj.source_files project.source_files.should == installer.template.project.source_files
end end
it "creates a project with multiple targets" do it "creates a project with multiple targets" do
......
...@@ -5,11 +5,10 @@ describe "Pod::Xcode::Project" do ...@@ -5,11 +5,10 @@ describe "Pod::Xcode::Project" do
before do before do
@template = Pod::ProjectTemplate.new(:ios) @template = Pod::ProjectTemplate.new(:ios)
@project = Pod::Xcode::Project.new(@template.xcodeproj_path)
end end
def find_objects(conditions) def find_objects(conditions)
@project.objects_hash.select do |_, object| @template.project.objects_hash.select do |_, object|
object.objectsForKeys(conditions.keys, notFoundMarker:Object.new) == conditions.values object.objectsForKeys(conditions.keys, notFoundMarker:Object.new) == conditions.values
end end
end end
...@@ -19,21 +18,21 @@ describe "Pod::Xcode::Project" do ...@@ -19,21 +18,21 @@ describe "Pod::Xcode::Project" do
end end
it "returns an instance initialized from the iOS static library template" do it "returns an instance initialized from the iOS static library template" do
template_file = (@template.xcodeproj_path + '/project.pbxproj').to_s template_file = File.join(@template.path, 'Pods.xcodeproj', 'project.pbxproj')
@project.to_hash.should == NSDictionary.dictionaryWithContentsOfFile(template_file) @template.project.to_hash.should == NSDictionary.dictionaryWithContentsOfFile(template_file)
end end
before do before do
@target = @project.targets.new_static_library('Pods') @target = @template.project.targets.new_static_library('Pods')
end end
it "returns the objects hash" do it "returns the objects hash" do
@project.objects_hash.should == @project.to_hash['objects'] @template.project.objects_hash.should == @template.project.to_hash['objects']
end end
describe "PBXObject" do describe "PBXObject" do
before do before do
@object = Pod::Xcode::Project::PBXObject.new(@project, nil, 'name' => 'AnObject') @object = Pod::Xcode::Project::PBXObject.new(@template.project, nil, 'name' => 'AnObject')
end end
it "merges the class name into the attributes" do it "merges the class name into the attributes" do
...@@ -54,29 +53,29 @@ describe "Pod::Xcode::Project" do ...@@ -54,29 +53,29 @@ describe "Pod::Xcode::Project" do
end end
it "adds the object to the objects hash" do it "adds the object to the objects hash" do
@project.objects_hash[@object.uuid].should == @object.attributes @template.project.objects_hash[@object.uuid].should == @object.attributes
end end
end end
describe "a PBXFileReference" do describe "a PBXFileReference" do
before do before do
@file = @project.files.new('path' => 'some/file.m') @file = @template.project.files.new('path' => 'some/file.m')
end end
it "is automatically added to the main group" do it "is automatically added to the main group" do
@file.group.should == @project.main_group @file.group.should == @template.project.main_group
end end
it "is removed from the original group when added to another group" do it "is removed from the original group when added to another group" do
@project.pods.children << @file @template.project.pods.children << @file
@file.group.should == @project.pods @file.group.should == @template.project.pods
@project.main_group.children.should.not.include @file @template.project.main_group.children.should.not.include @file
end end
end end
describe "a new PBXBuildPhase" do describe "a new PBXBuildPhase" do
before do before do
@phase = @project.objects.add(Pod::Xcode::Project::PBXBuildPhase) @phase = @template.project.objects.add(Pod::Xcode::Project::PBXBuildPhase)
end end
it "has an empty list of files" do it "has an empty list of files" do
...@@ -94,7 +93,7 @@ describe "Pod::Xcode::Project" do ...@@ -94,7 +93,7 @@ describe "Pod::Xcode::Project" do
describe "a new PBXCopyFilesBuildPhase" do describe "a new PBXCopyFilesBuildPhase" do
before do before do
@phase = @project.objects.add(Pod::Xcode::Project::PBXCopyFilesBuildPhase, 'dstPath' => 'some/path') @phase = @template.project.objects.add(Pod::Xcode::Project::PBXCopyFilesBuildPhase, 'dstPath' => 'some/path')
end end
it "is a PBXBuildPhase" do it "is a PBXBuildPhase" do
...@@ -112,7 +111,7 @@ describe "Pod::Xcode::Project" do ...@@ -112,7 +111,7 @@ describe "Pod::Xcode::Project" do
describe "a new PBXSourcesBuildPhase" do describe "a new PBXSourcesBuildPhase" do
before do before do
@phase = @project.objects.add(Pod::Xcode::Project::PBXSourcesBuildPhase) @phase = @template.project.objects.add(Pod::Xcode::Project::PBXSourcesBuildPhase)
end end
it "is a PBXBuildPhase" do it "is a PBXBuildPhase" do
...@@ -122,7 +121,7 @@ describe "Pod::Xcode::Project" do ...@@ -122,7 +121,7 @@ describe "Pod::Xcode::Project" do
describe "a new PBXFrameworksBuildPhase" do describe "a new PBXFrameworksBuildPhase" do
before do before do
@phase = @project.objects.add(Pod::Xcode::Project::PBXFrameworksBuildPhase) @phase = @template.project.objects.add(Pod::Xcode::Project::PBXFrameworksBuildPhase)
end end
it "is a PBXBuildPhase" do it "is a PBXBuildPhase" do
...@@ -132,11 +131,11 @@ describe "Pod::Xcode::Project" do ...@@ -132,11 +131,11 @@ describe "Pod::Xcode::Project" do
describe "a new XCBuildConfiguration" do describe "a new XCBuildConfiguration" do
before do before do
@configuration = @project.objects.add(Pod::Xcode::Project::XCBuildConfiguration) @configuration = @template.project.objects.add(Pod::Xcode::Project::XCBuildConfiguration)
end end
it "returns the xcconfig that this configuration is based on (baseConfigurationReference)" do it "returns the xcconfig that this configuration is based on (baseConfigurationReference)" do
xcconfig = @project.objects.new xcconfig = @template.project.objects.new
@configuration.baseConfiguration = xcconfig @configuration.baseConfiguration = xcconfig
@configuration.baseConfigurationReference.should == xcconfig.uuid @configuration.baseConfigurationReference.should == xcconfig.uuid
end end
...@@ -144,11 +143,11 @@ describe "Pod::Xcode::Project" do ...@@ -144,11 +143,11 @@ describe "Pod::Xcode::Project" do
describe "a new XCConfigurationList" do describe "a new XCConfigurationList" do
before do before do
@list = @project.objects.add(Pod::Xcode::Project::XCConfigurationList) @list = @template.project.objects.add(Pod::Xcode::Project::XCConfigurationList)
end end
it "returns the configurations" do it "returns the configurations" do
configuration = @project.objects.add(Pod::Xcode::Project::XCBuildConfiguration) configuration = @template.project.objects.add(Pod::Xcode::Project::XCBuildConfiguration)
@list.buildConfigurations.to_a.should == [] @list.buildConfigurations.to_a.should == []
@list.buildConfigurations = [configuration] @list.buildConfigurations = [configuration]
@list.buildConfigurationReferences.should == [configuration.uuid] @list.buildConfigurationReferences.should == [configuration.uuid]
...@@ -221,45 +220,45 @@ describe "Pod::Xcode::Project" do ...@@ -221,45 +220,45 @@ describe "Pod::Xcode::Project" do
end end
it "returns the objects as PBXObject instances" do it "returns the objects as PBXObject instances" do
@project.objects.each do |object| @template.project.objects.each do |object|
@project.objects_hash[object.uuid].should == object.attributes @template.project.objects_hash[object.uuid].should == object.attributes
end end
end end
it "adds any type of new PBXObject to the objects hash" do it "adds any type of new PBXObject to the objects hash" do
object = @project.objects.add(Pod::Xcode::Project::PBXObject, 'name' => 'An Object') object = @template.project.objects.add(Pod::Xcode::Project::PBXObject, 'name' => 'An Object')
object.name.should == 'An Object' object.name.should == 'An Object'
@project.objects_hash[object.uuid].should == object.attributes @template.project.objects_hash[object.uuid].should == object.attributes
end end
it "adds a new PBXObject, of the configured type, to the objects hash" do it "adds a new PBXObject, of the configured type, to the objects hash" do
group = @project.groups.new('name' => 'A new group') group = @template.project.groups.new('name' => 'A new group')
group.isa.should == 'PBXGroup' group.isa.should == 'PBXGroup'
group.name.should == 'A new group' group.name.should == 'A new group'
@project.objects_hash[group.uuid].should == group.attributes @template.project.objects_hash[group.uuid].should == group.attributes
end end
it "adds a new PBXFileReference to the objects hash" do it "adds a new PBXFileReference to the objects hash" do
file = @project.files.new('path' => '/some/file.m') file = @template.project.files.new('path' => '/some/file.m')
file.isa.should == 'PBXFileReference' file.isa.should == 'PBXFileReference'
file.name.should == 'file.m' file.name.should == 'file.m'
file.path.should == '/some/file.m' file.path.should == '/some/file.m'
file.sourceTree.should == 'SOURCE_ROOT' file.sourceTree.should == 'SOURCE_ROOT'
@project.objects_hash[file.uuid].should == file.attributes @template.project.objects_hash[file.uuid].should == file.attributes
end end
it "adds a new PBXBuildFile to the objects hash when a new PBXFileReference is created" 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') file = @template.project.files.new('name' => '/some/source/file.h')
build_file = file.buildFiles.new build_file = file.buildFiles.new
build_file.file = file build_file.file = file
build_file.fileRef.should == file.uuid build_file.fileRef.should == file.uuid
build_file.isa.should == 'PBXBuildFile' build_file.isa.should == 'PBXBuildFile'
@project.objects_hash[build_file.uuid].should == build_file.attributes @template.project.objects_hash[build_file.uuid].should == build_file.attributes
end end
it "adds a group to the `Pods' group" do it "adds a group to the `Pods' group" do
group = @project.add_pod_group('JSONKit') group = @template.project.add_pod_group('JSONKit')
@project.pods.childReferences.should.include group.uuid @template.project.pods.childReferences.should.include group.uuid
find_object({ find_object({
'isa' => 'PBXGroup', 'isa' => 'PBXGroup',
'name' => 'JSONKit', 'name' => 'JSONKit',
...@@ -273,7 +272,7 @@ describe "Pod::Xcode::Project" do ...@@ -273,7 +272,7 @@ describe "Pod::Xcode::Project" do
path = Pathname.new("path/to/file.#{ext}") path = Pathname.new("path/to/file.#{ext}")
file = @target.add_source_file(path) file = @target.add_source_file(path)
# ensure that it was added to all objects # ensure that it was added to all objects
file = @project.objects[file.uuid] file = @template.project.objects[file.uuid]
phase = @target.buildPhases.find { |phase| phase.is_a?(Pod::Xcode::Project::PBXSourcesBuildPhase) } phase = @target.buildPhases.find { |phase| phase.is_a?(Pod::Xcode::Project::PBXSourcesBuildPhase) }
phase.files.map { |buildFile| buildFile.file }.should.include file phase.files.map { |buildFile| buildFile.file }.should.include file
...@@ -287,7 +286,7 @@ describe "Pod::Xcode::Project" do ...@@ -287,7 +286,7 @@ describe "Pod::Xcode::Project" do
build_file_uuids = [] build_file_uuids = []
%w{ m mm c cpp }.each do |ext| %w{ m mm c cpp }.each do |ext|
path = Pathname.new("path/to/file.#{ext}") path = Pathname.new("path/to/file.#{ext}")
file = @project.targets.first.add_source_file(path, nil, '-fno-obj-arc') file = @template.project.targets.first.add_source_file(path, nil, '-fno-obj-arc')
find_object({ find_object({
'isa' => 'PBXBuildFile', 'isa' => 'PBXBuildFile',
'fileRef' => file.uuid, 'fileRef' => file.uuid,
...@@ -297,13 +296,13 @@ describe "Pod::Xcode::Project" do ...@@ -297,13 +296,13 @@ describe "Pod::Xcode::Project" do
end end
it "creates a copy build header phase which will copy headers to a specified path" do it "creates a copy build header phase which will copy headers to a specified path" do
phase = @project.targets.first.copy_files_build_phases.new_pod_dir("SomePod", "Path/To/Source") phase = @template.project.targets.first.copy_files_build_phases.new_pod_dir("SomePod", "Path/To/Source")
find_object({ find_object({
'isa' => 'PBXCopyFilesBuildPhase', 'isa' => 'PBXCopyFilesBuildPhase',
'dstPath' => '$(PUBLIC_HEADERS_FOLDER_PATH)/Path/To/Source', 'dstPath' => '$(PUBLIC_HEADERS_FOLDER_PATH)/Path/To/Source',
'name' => 'Copy SomePod Public Headers' 'name' => 'Copy SomePod Public Headers'
}).should.not == nil }).should.not == nil
@project.targets.first.buildPhases.should.include phase @template.project.targets.first.buildPhases.should.include phase
end end
# TODO add test for the optional copy_header_phase # TODO add test for the optional copy_header_phase
...@@ -312,7 +311,7 @@ describe "Pod::Xcode::Project" do ...@@ -312,7 +311,7 @@ describe "Pod::Xcode::Project" do
path = Pathname.new("path/to/file.h") path = Pathname.new("path/to/file.h")
file = @target.add_source_file(path) file = @target.add_source_file(path)
# ensure that it was added to all objects # ensure that it was added to all objects
file = @project.objects[file.uuid] file = @template.project.objects[file.uuid]
phase = @target.buildPhases.find { |phase| phase.is_a?(Pod::Xcode::Project::PBXSourcesBuildPhase) } phase = @target.buildPhases.find { |phase| phase.is_a?(Pod::Xcode::Project::PBXSourcesBuildPhase) }
phase.files.map { |buildFile| buildFile.file }.should.not.include file phase.files.map { |buildFile| buildFile.file }.should.not.include file
...@@ -323,13 +322,13 @@ describe "Pod::Xcode::Project" do ...@@ -323,13 +322,13 @@ describe "Pod::Xcode::Project" do
it "saves the template with the adjusted project" do it "saves the template with the adjusted project" do
@template.copy_to(temporary_directory) @template.copy_to(temporary_directory)
@project.save_as(temporary_directory + 'Pods.xcodeproj') @template.project.save_as(temporary_directory + 'Pods.xcodeproj')
project_file = (temporary_directory + 'Pods.xcodeproj/project.pbxproj') project_file = (temporary_directory + 'Pods.xcodeproj/project.pbxproj')
NSDictionary.dictionaryWithContentsOfFile(project_file.to_s).should == @project.to_hash NSDictionary.dictionaryWithContentsOfFile(project_file.to_s).should == @template.project.to_hash
end end
it "returns all source files" do it "returns all source files" do
group = @project.groups.new('name' => 'SomeGroup') group = @template.project.groups.new('name' => 'SomeGroup')
files = [Pathname.new('/some/file.h'), Pathname.new('/some/file.m')] files = [Pathname.new('/some/file.h'), Pathname.new('/some/file.m')]
files.each { |file| group << @target.add_source_file(file) } files.each { |file| group << @target.add_source_file(file) }
group.source_files.map(&:pathname).sort.should == files.sort 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