Commit 9515ffe1 authored by Fabio Pelosin's avatar Fabio Pelosin

Added Sandbox::FileAccessor to read specs.

parent 837e7147
......@@ -37,8 +37,8 @@ module Pod
#
class Sandbox
autoload :PathList, 'cocoapods/sandbox/path_list'
autoload :PathList, 'cocoapods/sandbox/path_list'
autoload :FileAccessor, 'cocoapods/sandbox/file_accessor'
# @return [Pathname] the root of the sandbox.
#
......
module Pod
class Sandbox
# Resolves the file patterns of a specification against its root directory,
# taking into account any exclude pattern and the default extensions to use
# for directories.
#
class FileAccessor
HEADER_EXTENSIONS = Xcodeproj::Constants::HEADER_FILES_EXTENSIONS
# @return [Sandbox::PathList] the directory where the source of the Pod
# is located.
#
attr_reader :path_list
# @return [Specification::Consumer] the consumer of the specification for
# which the file patterns should be resolved.
#
attr_reader :spec_consumer
# @param [Sandbox::PathList] path_list @see path_list
# @param [Specification::Consumer] spec_consumer @see spec_consumer
#
def initialize(path_list, spec_consumer)
@path_list = path_list
@spec_consumer = spec_consumer
unless @spec_consumer
raise Informative, "Attempt to initialize File Accessor without a specification consumer."
end
end
# @return [Specification] the specification.
#
def spec
spec_consumer.spec
end
# @return [Specification] the platform used to consume the specification.
#
def platform
spec_consumer.platform
end
# @return [String] A string suitable for debugging.
#
def inspect
"<#{self.class} spec=#{spec.name} platform=#{spec_consumer.platform} root=#{path_list.root}>"
end
#-----------------------------------------------------------------------#
public
# @!group Paths
# @return [Array<Pathname>] the source files of the specification.
#
def source_files
paths_for_attribute(:source_files)
end
# @return [Array<Pathname>] the headers of the specification.
#
def headers
extensions = HEADER_EXTENSIONS
source_files.select { |f| extensions.include?(f.extname) }
end
# @return [Array<Pathname>] the public headers of the specification.
#
def public_headers
public_headers = paths_for_attribute(:public_header_files)
if public_headers.nil? || public_headers.empty?
headers
else
public_headers
end
end
# @return [Hash{ Symbol => Array<Pathname> }] the resources of the
# specification grouped by destination.
#
def resources
result = {}
spec_consumer.resources.each do |destination, patterns|
result[destination] = expanded_paths(patterns)
end
result
end
# @return [Array<Pathname>] the files of the specification to preserve.
#
def preserve_paths
paths_for_attribute(:preserve_paths)
end
# @return [Pathname] The of the prefix header file of the specification.
#
def prefix_header
path_list.root + spec_consumer.prefix_header_file
end
# @return [Pathname] The path of the auto-detected README file.
#
def readme
path_list.glob(%w[ readme{*,.*} ]).first
end
# @return [Pathname] The path of the license file as indicated in the
# specification or auto-detected.
#
def license
specified = path_list.root + spec_consumer.spec.root.license[:file]
specified || path_list.glob(%w[ licen{c,s}e{*,.*} ]).first
end
#-----------------------------------------------------------------------#
private
# @!group Private helpers
# Returns the list of the paths founds in the file system for the
# attribute with given name. It takes into account any dir pattern and
# any file excluded in the specification.
#
# @param [Symbol] attribute
# the name of the attribute.
#
# @return [Array<Pathname>] the paths.
#
def paths_for_attribute(attribute)
file_patterns = spec_consumer.send(attribute)
dir_pattern = glob_for_attribute(attribute)
exclude_files = spec_consumer.exclude_files
expanded_paths(file_patterns, dir_pattern, exclude_files)
end
# Returns the pattern to use to glob a directory for an attribute.
#
# @param [Symbol] attribute
# the name of the attribute
#
# @return [String] the glob pattern.
#
# @todo move to the cocoapods-core so it appears in the docs?
#
def glob_for_attribute(attrbute)
globs = {
:source_files => '*.{h,hpp,hh,m,mm,c,cpp}'.freeze,
:public_header_files => "*.{#{ HEADER_EXTENSIONS * ',' }}".freeze,
}
globs[attrbute]
end
# Matches the given patterns to the file present in the root of the path list.
#
# @param [Array<String, FileList>] patterns
# The patterns to expand.
#
# @param [String] dir_pattern
# The pattern to add to directories.
#
# @param [Array<String>] exclude_patterns
# The exclude patterns to pass to the PathList.
#
# @raise [Informative] If the pod does not exists.
#
# @return [Array<Pathname>] A list of the paths.
#
# @todo Implement case insensitive search
#
def expanded_paths(patterns, dir_pattern = nil, exclude_patterns = nil)
return [] if patterns.empty?
file_lists = patterns.select { |p| p.is_a?(FileList) }
glob_patterns = patterns - file_lists
result = []
result << path_list.glob(glob_patterns, dir_pattern, exclude_patterns)
result << file_lists.map do |file_list|
file_list.prepend_patterns(path_list.root)
file_list.glob
end
unless file_lists.empty?
UI.warn "[#{spec_consumer.spec.name}] The usage of Rake FileList is deprecated. Use `exclude_files`."
end
result.flatten.compact.uniq
end
#-----------------------------------------------------------------------#
end
end
end
require File.expand_path('../../../spec_helper', __FILE__)
module Pod
describe FileAccessor = Sandbox::FileAccessor do
before do
@root = fixture('banana-lib')
@path_list = Sandbox::PathList.new(@root)
@spec = fixture_spec('banana-lib/BananaLib.podspec')
@spec_consumer = @spec.consumer(:ios)
@accessor = FileAccessor.new(@path_list, @spec_consumer)
end
describe "In general" do
it "returns the root" do
@accessor.path_list.should == @path_list
end
it "returns the specification" do
@accessor.spec_consumer.should == @spec_consumer
end
it "raises if the consumer is nil" do
e = lambda { FileAccessor.new(@path_list, nil) }.should.raise Informative
e.message.should.match /without a specification consumer/
end
it "raises if the root does not exits" do
root = temporary_directory + 'missing_folder'
path_list = Sandbox::PathList.new(root)
file_accessor = FileAccessor.new(path_list, @spec_consumer)
e = lambda { file_accessor.source_files }.should.raise Informative
e.message.should.match /non existent folder/
end
end
#-------------------------------------------------------------------------#
describe "Returning files" do
it "returns the source files" do
@accessor.source_files.should == [
@root + "Classes/Banana.m",
@root + "Classes/Banana.h",
@root + "Classes/BananaPrivate.h"
].sort
end
it "returns the header files" do
@accessor.headers.should == [
@root + "Classes/Banana.h",
@root + "Classes/BananaPrivate.h"
]
end
it "returns the public headers" do
@accessor.public_headers.should == [
@root + "Classes/Banana.h"
]
end
it "returns all the headers if no public headers are defined" do
@spec_consumer.stubs(:public_header_files).returns([])
@accessor.public_headers.should == [
@root + "Classes/Banana.h",
@root + "Classes/BananaPrivate.h"
]
end
it "returns the resources" do
@accessor.resources.should == {
:resources => [ @root + "Resources/logo-sidebar.png" ]
}
end
it "returns the preserve path" do
@accessor.preserve_paths.should == [
@root + "preserve_me.txt"
]
end
it "returns the prefix header of the specification" do
@accessor.prefix_header.should == @root + 'Classes/BananaLib.pch'
end
it "returns the README file of the specification" do
@accessor.readme.should == @root + 'README'
end
it "returns the license file of the specification" do
@accessor.license.should == @root + 'LICENSE'
end
#--------------------------------------#
it "respects the exclude files" do
@spec_consumer.stubs(:exclude_files).returns(["Classes/BananaPrivate.h"])
@accessor.source_files.should == [
@root + "Classes/Banana.m",
@root + "Classes/Banana.h",
].sort
end
end
#-------------------------------------------------------------------------#
describe "Private helpers" do
describe "#paths_for_attribute" do
it "takes into account dir patterns and excluded files" do
file_patterns = ["Classes/*.{h,m}", "Vendor"]
dir_pattern = "*.{h,hpp,hh,m,mm,c,cpp}"
exclude_files = ["Classes/**/osx/**/*", "Resources/**/osx/**/*"]
@accessor.expects(:expanded_paths).with(file_patterns, dir_pattern, exclude_files)
@accessor.send(:paths_for_attribute, :source_files)
end
end
describe "#expanded_paths" do
it "can handle Rake FileLists" do
@spec_consumer.stubs(:source_files).returns([FileList['Classes/Banana.*']])
@accessor.source_files.should == [
@root + "Classes/Banana.m",
@root + "Classes/Banana.h",
].sort
end
end
end
#-------------------------------------------------------------------------#
end
end
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