Commit 8ea1f5da authored by Fabio Pelosin's avatar Fabio Pelosin

[Project] Overhaul

parent fb38487b
......@@ -17,7 +17,7 @@ GIT
GIT
remote: https://github.com/CocoaPods/Xcodeproj.git
revision: 5f0fc07355716817b7591a859774a93f6773d559
revision: c7f6420dd3d0f1a5e3ab3f4983500d5076f85f28
branch: paths-refactor
specs:
xcodeproj (0.9.0)
......
......@@ -285,13 +285,23 @@ module Pod
#
def prepare_pods_project
UI.message "- Creating Pods project" do
@pods_project = Pod::Project.new(sandbox)
@pods_project = Pod::Project.new(sandbox.project_path)
analysis_result.all_user_build_configurations.each do |name, type|
@pods_project.add_build_configuration(name, type)
end
pod_names = pod_targets.map(&:pod_name).uniq
pod_names.each do |pod_name|
path = sandbox.pod_dir(pod_name)
local = sandbox.local?(pod_name)
@pods_project.add_pod_group(pod_name, path, local)
end
if config.podfile_path
@pods_project.add_podfile(config.podfile_path)
end
sandbox.project = @pods_project
platforms = aggregate_targets.map(&:platform)
osx_deployment_target = platforms.select { |p| p.name == :osx }.map(&:deployment_target).min
......@@ -378,6 +388,8 @@ module Pod
#
def write_pod_project
UI.message "- Writing Xcode project file to #{UI.path sandbox.project_path}" do
pods_project.pods.remove_from_project if pods_project.pods.empty?
pods_project.local_pods.remove_from_project if pods_project.local_pods.empty?
pods_project.main_group.sort_by_type!
pods_project['Frameworks'].sort_by_type!
pods_project.save
......
......@@ -65,10 +65,6 @@ module Pod
# @note The source files are grouped by Pod and in turn by subspec
# (recursively).
#
# @note Pods are generally added to the `Pods` group, however, if they
# have a local source they are added to the
# `Local Pods` group.
#
# @return [void]
#
def add_source_files_references
......
......@@ -90,7 +90,7 @@ module Pod
path = library.copy_resources_script_path
UI.message "- Generating copy resources script at #{UI.path(path)}" do
file_accessors = library.pod_targets.map(&:file_accessors).flatten
resource_paths = file_accessors.map { |accessor| accessor.resources.flatten.map { |res| res.relative_path_from(project.path) }}.flatten
resource_paths = file_accessors.map { |accessor| accessor.resources.flatten.map { |res| res.relative_path_from(project.path.dirname) }}.flatten
resource_bundles = file_accessors.map { |accessor| accessor.resource_bundles.keys.map {|name| "${TARGET_BUILD_DIR}/#{name}.bundle" } }.flatten
resources = []
resources.concat(resource_paths)
......
......@@ -40,7 +40,7 @@ module Pod
consumer = file_accessor.spec_consumer
flags = compiler_flags_for_consumer(consumer)
source_files = file_accessor.source_files
file_refs = source_files.map { |sf| project.file_reference(sf) }
file_refs = source_files.map { |sf| project.reference_for_path(sf) }
target.add_file_references(file_refs, flags)
file_accessor.spec_consumer.frameworks.each do |framework|
......@@ -61,7 +61,7 @@ module Pod
UI.message "- Adding resource bundles to Pods project" do
library.file_accessors.each do |file_accessor|
file_accessor.resource_bundles.each do |bundle_name, paths|
file_references = paths.map { |sf| project.file_reference(sf) }
file_references = paths.map { |sf| project.reference_for_path(sf) }
group = project.group_for_spec(file_accessor.spec.name, :resources)
product_group = project.group_for_spec(file_accessor.spec.name, :resources)
bundle_target = project.new_resources_bundle(bundle_name, file_accessor.spec_consumer.platform_name, product_group)
......
......@@ -9,75 +9,105 @@ module Pod
#
class Project < Xcodeproj::Project
# @return [Sandbox] the sandbox which returns the information about which
# Pods are local.
# @param [Pathname, String] path @see path
# @param [Bool] skip_initialization
# Wether the project should be initialized from scratch.
#
attr_reader :sandbox
# @param [Sandbox] sandbox @see #sandbox
#
def initialize(sandbox)
super(sandbox.project_path)
@sandbox = sandbox
def initialize(path, skip_initialization = false)
super
@support_files_group = new_group('Targets Support Files')
@refs_by_absolute_path = {}
@pods = new_group('Pods')
@local_pods = new_group('Local Pods')
end
# @return [Pathname] the directory where the project is stored.
# @return [PBXGroup] The group for the support files of the aggregate
# targets.
#
def root
@root ||= path.dirname
end
attr_reader :support_files_group
# @return [String] a string representation suited for debugging.
# @return [PBXGroup] The group for the Pods.
#
def inspect
"#<#{self.class}> path:#{path}"
end
attr_reader :pods
# @return [PBXGroup] The group for Local Pods.
#
attr_reader :local_pods
public
# @!group Groups
# @!group Pod Groups
#-------------------------------------------------------------------------#
# @return [PBXGroup] the group where the support files for the Pod
# libraries should be added.
# Creates a new group for the Pod with the given name and configures its
# path.
#
attr_reader :support_files_group
# Returns the `Pods` group, creating it if needed.
# @param [String] pod_name
# The name of the Pod.
#
# @param [#to_s] path
# The path to the root of the Pod.
#
# @return [PBXGroup] the group.
# @param [Bool] local
# Wether the group should be added to the Local Pods group.
#
def pods
@pods ||= new_group('Pods')
# @param [Bool] absolute
# Wether the path of the group should be set as absolute.
#
# @return [PBXGroup] The new group.
#
def add_pod_group(pod_name, path, local = false, absolute = false)
raise "[BUG]" if pod_group(pod_name)
parent_group = local ? local_pods : pods
source_tree = absolute ? :absolute : :group
parent_group.new_group(pod_name, path, source_tree)
end
# @return [Array<PBXGroup>] Returns all the group of the Pods.
#
def pod_groups
pods.children.objects + local_pods.children.objects
end
# Returns the `Local Pods` group, creating it if needed. This group is used
# to contain locally sourced pods.
# Returns the group for the Pod with the given name.
#
# @param [String] pod_name
# The name of the Pod.
#
# @return [PBXGroup] the group.
# @return [PBXGroup] The group.
#
def local_pods
@local_pods ||= new_group('Local Pods')
def pod_group(pod_name)
pod_groups.find { |group| group.name == pod_name }
end
# @return [PBXGroup] the group for the spec with the given name.
# @return [Hash] The names of the specification subgroups by key.
#
def group_for_spec(spec_name, type = nil)
local = sandbox.local?(spec_name)
parent_group = local ? local_pods : pods
spec_group = add_spec_group(spec_name, parent_group)
if type
case type
when :source_files then sub_group = 'Source Files'
when :resources then sub_group = 'Resources'
when :frameworks_and_libraries then sub_group = 'Frameworks & Libraries'
when :support_files then sub_group = 'Support Files'
else raise "[BUG]"
end
spec_group.find_subpath(sub_group, true)
SPEC_SUBGROUPS = {
:source_files => 'Source Files',
:resources => 'Resources',
:frameworks_and_libraries => 'Frameworks & Libraries',
:support_files => 'Support Files',
}
# Returns the group for the specification with the give name creating it if
# needed.
#
# @param [String] spec_name
# The full name of the specification.
#
# @param [Symbol] subgroup_key
# The optional key of the subgroup (@see #{SPEC_SUBGROUPS})
#
# @return [PBXGroup] The group.
#
def group_for_spec(spec_name, subgroup_key = nil)
spec_group = spec_group(spec_name)
if subgroup_key
subgroup = SPEC_SUBGROUPS[subgroup_key]
raise ArgumentError, "Unrecognized subgroup `#{subgroup_key}`" unless subgroup
spec_group.find_subpath(subgroup, true)
else
spec_group
end
......@@ -89,57 +119,54 @@ module Pod
# @!group File references
#-------------------------------------------------------------------------#
# Adds a file reference for each one of the given files in the specified
# group, namespaced by specification unless a file reference for the given
# path already exits.
#
# @note With this set-up different subspecs might not reference the same
# file (i.e. the first will win). Not sure thought if this is a
# limitation or a feature.
#
# @param [Array<Pathname,String>] paths
# The files for which the file reference is needed.
# Adds a file reference to given path as a child of the given group.
#
# @param [String] spec_name
# The full name of the specification.
# @param [Array<Pathname,String>] absolute_path
# The path of the file.
#
# @param [PBXGroup] parent_group
# The group where the file references should be added.
# @param [PBXGroup] group
# The group for the new file reference.
#
# @return [void]
# @return [PBXFileReference] The new file reference.
#
def add_file_reference(absolute_path, group)
# existing = file_reference(absolute_paths)
# unless existing
absolute_path = Pathname.new(absolute_path)
ref = group.new_file(absolute_path)
@refs_by_absolute_path[absolute_path] = ref
# end
unless Pathname.new(absolute_path).absolute?
raise ArgumentError, "Paths must be absolute #{absolute_path}"
end
if ref = reference_for_path(absolute_path)
ref
else
ref = group.new_file(absolute_path)
@refs_by_absolute_path[absolute_path.to_s] = ref
end
end
# Returns the file reference for the given absolute file path.
# Returns the file reference for the given absolute path.
#
# @param [Pathname,String] absolute_path
# @param [#to_s] absolute_path
# The absolute path of the file whose reference is needed.
#
# @return [PBXFileReference] The file reference.
# @return [Nil] If no file reference could be found.
#
def file_reference(absolute_path)
absolute_path = Pathname.new(absolute_path)
refs_by_absolute_path[absolute_path]
def reference_for_path(absolute_path)
unless Pathname.new(absolute_path).absolute?
raise ArgumentError, "Paths must be absolute #{absolute_path}"
end
refs_by_absolute_path[absolute_path.to_s]
end
# Adds a file reference to the podfile.
# Adds a file reference to the Podfile.
#
# @param [Pathname,String] podfile_path
# @param [#to_s] podfile_path
# The path of the Podfile.
#
# @return [PBXFileReference] The file reference.
# @return [PBXFileReference] The new file reference.
#
def add_podfile(podfile_path)
podfile_path = Pathname.new(podfile_path)
podfile_ref = new_file(podfile_path)
podfile_ref = new_file(podfile_path, :project)
podfile_ref.xc_language_specification_identifier = 'xcode.lang.ruby'
podfile_ref.last_known_file_type = 'text'
podfile_ref
......@@ -151,29 +178,27 @@ module Pod
# @!group Private helpers
#-------------------------------------------------------------------------#
# @return [Hash{Pathname => PBXFileReference}] The file references grouped
# @return [Hash{String => PBXFileReference}] The file references grouped
# by absolute path.
#
attr_reader :refs_by_absolute_path
# Returns a subgroup of the give group for the given spec creating it if
# needed.
# Returns the group for the given specification creating it if needed.
#
# @param [String] spec_name
# The full name of the specification.
#
# @param [PBXGroup] root_group
# The group where to add the specification. Either `Pods` or `Local
# Pods`.
#
# @return [PBXGroup] The group for the spec with the given name.
#
def add_spec_group(spec_name, root_group)
current_group = root_group
group = nil
spec_name.split('/').each do |name|
group = current_group[name] || current_group.new_group(name)
current_group = group
def spec_group(spec_name)
pod_name = Specification.root_name(spec_name)
group = pod_group(pod_name)
raise "[Bug] Unable to locate group for Pod named `#{pod_name}`" unless group
if spec_name != pod_name
subspecs_names = spec_name.gsub(pod_name + '/', '').split('/')
subspecs_names.each do |name|
group = group[name] || group.new_group(name)
end
end
group
end
......
Subproject commit fa5c727b65b4499b39d981685f93fc6369f46489
Subproject commit bcc200c3fee14a7506e9c865fe3b6912a955aa94
......@@ -193,21 +193,26 @@ def yaml_should_match(expected, produced)
produced_yaml.delete('COCOAPODS')
desc = []
desc << "YAML comparison error `#{expected}`"
diff_options = {:key_1 => "$produced", :key_2 => "$expected"}
diff = Xcodeproj::Differ.diff(produced_yaml, expected_yaml, diff_options).to_yaml
diff.gsub!("$produced", "produced".green)
diff.gsub!("$expected", "expected".red)
desc << ("--- DIFF " << "-" * 70)
desc << ("--- YAML DIFF " << "-" * 65)
diffy_diff = ''
Diffy::Diff.new(expected.to_s, produced.to_s, :source => 'files', :context => 3).each do |line|
case line
when /^\+/ then desc << line.gsub("\n",'').green
when /^-/ then desc << line.gsub("\n",'').red
else desc << line.gsub("\n",'')
when /^\+/ then diffy_diff << line.green
when /^-/ then diffy_diff << line.red
else diffy_diff << line
end
end
desc << ("--- DIFF " << "-" * 70)
desc << diffy_diff
desc << ("--- XCODEPROJ DIFF " << "-" * 60)
diff_options = {:key_1 => "$produced", :key_2 => "$expected"}
diff = Xcodeproj::Differ.diff(produced_yaml, expected_yaml, diff_options).to_yaml
diff.gsub!("$produced", "produced".green)
diff.gsub!("$expected", "expected".red)
desc << diff
desc << ("--- END " << "-" * 70)
expected_yaml.should.satisfy(desc * "\n\n") do
if RUBY_VERSION < "1.9"
true # CP is not sorting array derived from hashes whose order is
......
......@@ -7,7 +7,8 @@ module Pod
@file_accessor = fixture_file_accessor('banana-lib/BananaLib.podspec')
@pod_target = PodTarget.new([], nil, config.sandbox)
@pod_target.file_accessors = [@file_accessor]
@project = Project.new(config.sandbox)
@project = Project.new(config.sandbox.project_path)
@project.add_pod_group('BananaLib', fixture('banana-lib'))
@installer = Installer::FileReferencesInstaller.new(config.sandbox, [@pod_target], @project)
end
......@@ -25,14 +26,7 @@ module Pod
@installer.install!
file_ref = @installer.pods_project['Pods/BananaLib/Source Files/Banana.m']
file_ref.should.be.not.nil
file_ref.path.should == "../../spec/fixtures/banana-lib/Classes/Banana.m"
end
it "adds the files references of the local Pods in a dedicated group" do
config.sandbox.store_local_path('BananaLib', 'Some Path')
@installer.install!
file_ref = @installer.pods_project['Local Pods/BananaLib/Source Files/Banana.m']
file_ref.should.be.not.nil
file_ref.path.should == "Classes/Banana.m"
end
xit "adds the file references of the frameworks of the projet" do
......@@ -47,7 +41,7 @@ module Pod
@installer.install!
file_ref = @installer.pods_project['Pods/BananaLib/Resources/logo-sidebar.png']
file_ref.should.be.not.nil
file_ref.path.should == "../../spec/fixtures/banana-lib/Resources/logo-sidebar.png"
file_ref.path.should == "Resources/logo-sidebar.png"
end
it "links the build headers" do
......
......@@ -9,12 +9,13 @@ module Pod
xcodeproj 'dummy'
end
@target_definition = @podfile.target_definitions['Pods']
@project = Project.new(config.sandbox)
@project = Project.new(config.sandbox.project_path)
config.sandbox.project = @project
path_list = Sandbox::PathList.new(fixture('banana-lib'))
@spec = fixture_spec('banana-lib/BananaLib.podspec')
file_accessor = Sandbox::FileAccessor.new(path_list, @spec.consumer(:ios))
@project.add_pod_group('BananaLib', fixture('banana-lib'))
group = @project.group_for_spec('BananaLib', :source_files)
file_accessor.source_files.each do |file|
@project.add_file_reference(file, group)
......
......@@ -9,12 +9,13 @@ module Pod
xcodeproj 'dummy'
end
@target_definition = @podfile.target_definitions['Pods']
@project = Project.new(config.sandbox)
@project = Project.new(config.sandbox.project_path)
config.sandbox.project = @project
path_list = Sandbox::PathList.new(fixture('banana-lib'))
@spec = fixture_spec('banana-lib/BananaLib.podspec')
file_accessor = Sandbox::FileAccessor.new(path_list, @spec.consumer(:ios))
@project.add_pod_group('BananaLib', fixture('banana-lib'))
group = @project.group_for_spec('BananaLib', :source_files)
file_accessor.source_files.each do |file|
@project.add_file_reference(file, group)
......
......@@ -9,12 +9,13 @@ module Pod
xcodeproj 'dummy'
end
@target_definition = @podfile.target_definitions['Pods']
@project = Project.new(config.sandbox)
@project = Project.new(config.sandbox.project_path)
config.sandbox.project = @project
path_list = Sandbox::PathList.new(fixture('banana-lib'))
@spec = fixture_spec('banana-lib/BananaLib.podspec')
file_accessor = Sandbox::FileAccessor.new(path_list, @spec.consumer(:ios))
@project.add_pod_group('BananaLib', fixture('banana-lib'))
group = @project.group_for_spec('BananaLib', :source_files)
file_accessor.source_files.each do |file|
@project.add_file_reference(file, group)
......
......@@ -16,7 +16,7 @@ module Pod
end
end
config.sandbox.project = Project.new(config.sandbox)
config.sandbox.project = Project.new(config.sandbox.project_path)
Xcodeproj::Project.new(config.sandbox.project_path).save
@library = AggregateTarget.new(@podfile.target_definitions['Pods'], config.sandbox)
@library.client_root = sample_project_path.dirname
......
......@@ -259,6 +259,7 @@ module Pod
pod_target_ios.stubs(:platform).returns(Platform.new(:ios, '6.0'))
pod_target_osx.stubs(:platform).returns(Platform.new(:osx, '10.8'))
@installer.stubs(:aggregate_targets).returns([pod_target_ios, pod_target_osx])
@installer.stubs(:pod_targets).returns([])
@installer.send(:prepare_pods_project)
build_settings = @installer.pods_project.build_configurations.map(&:build_settings)
build_settings.each do |build_setting|
......
This diff is collapsed.
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