Commit 37c7e044 authored by Eric Amorde's avatar Eric Amorde

Truncate shared parent folders in Development Pods to the nearest ancestor

parent ce087202
......@@ -33,6 +33,10 @@ To install release candidates run `[sudo] gem install cocoapods --pre`
##### Bug Fixes
* Truncate extra groups in Development Pods when they are parents of all files
[Eric Amorde](https://github.com/amorde)
[#6814](https://github.com/CocoaPods/CocoaPods/pull/6814)
* Remove 0.34 migration for a small boost in `pod install` time
[Dimitris Koutsogiorgas](https://github.com/dnkoutso)
[#6783](hhttps://github.com/CocoaPods/CocoaPods/pull/6783)
......
......@@ -182,9 +182,10 @@ module Pod
local = sandbox.local?(pod_name)
paths = file_accessor.send(file_accessor_key)
paths = allowable_project_paths(paths)
base_path = local ? common_path(paths) : nil
paths.each do |path|
group = pods_project.group_for_spec(file_accessor.spec.name, group_key)
pods_project.add_file_reference(path, group, local && reflect_file_system_structure_for_development)
pods_project.add_file_reference(path, group, local && reflect_file_system_structure_for_development, base_path)
end
end
end
......@@ -240,6 +241,29 @@ module Pod
allowable_paths + lproj_paths.subtract(lproj_paths_with_files).to_a
end
# Returns a Pathname of the nearest parent from which all the given paths descend.
# Converts each Pathname to a string and finds the longest common prefix
#
# @param [Array<Pathname>] paths
# The paths to files or directories on disk. Must be absolute paths
#
# @return [Pathname] Pathname of the nearest parent shared by paths, or nil if none exists
#
def common_path(paths)
return nil if paths.empty?
strs = paths.map do |path|
unless path.absolute?
raise ArgumentError, "Paths must be absolute #{path}"
end
path.dirname.to_s
end
min, max = strs.minmax
idx = min.size.times { |i| break i if min[i] != max[i] }
result = Pathname.new(min[0...idx])
# Don't consider "/" a common path
return result unless result.to_s == '/'
end
# Computes the destination sub-directory in the sandbox
#
# @param [Pathname] headers_sandbox
......
......@@ -177,12 +177,15 @@ module Pod
# If yes, where needed, intermediate groups are created, similar to
# how mkdir -p operates.
#
# @param [Pathname] base_path
# The base path for newly created groups when reflect_file_system_structure is true.
# If nil, the provided group's real_path is used.
#
# @return [PBXFileReference] The new file reference.
#
def add_file_reference(absolute_path, group, reflect_file_system_structure = false)
def add_file_reference(absolute_path, group, reflect_file_system_structure = false, base_path = nil)
file_path_name = absolute_path.is_a?(Pathname) ? absolute_path : Pathname.new(absolute_path)
group = group_for_path_in_group(file_path_name, group, reflect_file_system_structure)
group = group_for_path_in_group(file_path_name, group, reflect_file_system_structure, base_path)
if ref = reference_for_path(file_path_name.realpath)
@refs_by_absolute_path[absolute_path.to_s] = ref
ref
......@@ -305,24 +308,35 @@ module Pod
# If yes, where needed, intermediate groups are created, similar to
# how mkdir -p operates.
#
# @param [Pathname] base_path
# The base path for the newly created group. If nil, the provided group's real_path is used.
#
# @return [PBXGroup] The appropriate group for the filepath.
# Can be PBXVariantGroup, if the file is localized.
#
def group_for_path_in_group(absolute_pathname, group, reflect_file_system_structure)
def group_for_path_in_group(absolute_pathname, group, reflect_file_system_structure, base_path = nil)
unless absolute_pathname.absolute?
raise ArgumentError, "Paths must be absolute #{absolute_pathname}"
end
unless base_path.nil? || base_path.absolute?
raise ArgumentError, "Paths must be absolute #{base_path}"
end
relative_pathname = absolute_pathname.relative_path_from(group.real_path)
relative_base = base_path.nil? ? group.real_path : base_path.realdirpath
relative_pathname = absolute_pathname.relative_path_from(relative_base)
relative_dir = relative_pathname.dirname
lproj_regex = /\.lproj/i
# Add subgroups for directories, but treat .lproj as a file
if reflect_file_system_structure
relative_dir.each_filename do|name|
path = relative_base
relative_dir.each_filename do |name|
break if name.to_s =~ lproj_regex
next if name == '.'
group = group[name] || group.new_group(name, name)
# Make sure groups have the correct absolute path set, as intermittent
# directories may not be included in the group structure
path += name
group = group[name] || group.new_group(name, path)
end
end
......
Subproject commit 72424f479a2e86682d511955ada020e87d631231
Subproject commit ab693a837228d3199f0e2d9e19a3ead5760c5905
......@@ -239,6 +239,47 @@ module Pod
end
end
describe '#common_path' do
it 'calculates the correct common path' do
paths = [
'/Base/Sub/A/1.txt',
'/Base/Sub/A/2.txt',
'/Base/Sub/A/B/1.txt',
'/Base/Sub/A/B/2.txt',
'/Base/Sub/A/D/E/1.txt',
].map { |p| Pathname.new(p) }
result = @installer.send(:common_path, paths)
result.should == Pathname.new('/Base/Sub/A')
end
it 'should not consider root \'/\' a common path' do
paths = [
'/A/B/C',
'/D/E/F',
'/G/H/I',
].map { |p| Pathname.new(p) }
result = @installer.send(:common_path, paths)
result.should.be.nil
end
it 'raises when given a relative path' do
paths = [
'/A/B/C',
'/D/E/F',
'bad/path',
].map { |p| Pathname.new(p) }
should.raise ArgumentError do
@installer.send(:common_path, paths)
end
end
it 'returns nil when given an empty path list' do
paths = []
result = @installer.send(:common_path, paths)
result.should.be.nil
end
end
describe '#vendored_frameworks_header_mappings' do
it 'returns the vendored frameworks header mappings' do
headers_sandbox = Pathname.new('BananaLib')
......
......@@ -168,6 +168,7 @@ module Pod
before do
@project.add_pod_group('BananaLib', config.sandbox.pod_dir('BananaLib'), false)
@file = config.sandbox.pod_dir('BananaLib') + 'file.m'
@pod_dir = config.sandbox.pod_dir('BananaLib')
@nested_file = config.sandbox.pod_dir('BananaLib') + 'Dir/SubDir/nested_file.m'
@localized_file = config.sandbox.pod_dir('BananaLib') + 'Dir/SubDir/de.lproj/Foo.strings'
@group = @project.group_for_spec('BananaLib')
......@@ -197,6 +198,15 @@ module Pod
ref.hierarchy_path.should == '/Pods/BananaLib/nested_file.m'
end
it 'adds subgroups relative to shared base if requested' do
base_path = @pod_dir + 'Dir'
Pathname.any_instance.stubs(:realdirpath).returns(@pod_dir + 'Dir')
Pathname.any_instance.stubs(:realpath).returns(@nested_file)
ref = @project.add_file_reference(@nested_file, @group, true, base_path)
ref.hierarchy_path.should == '/Pods/BananaLib/SubDir/nested_file.m'
ref.parent.path.should == 'Dir/SubDir'
end
it "it doesn't duplicate file references for a single path" do
Pathname.any_instance.stubs(:realpath).returns(@file)
ref_1 = @project.add_file_reference(@file, @group)
......
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