Permalink
Browse files

[Docs] Local Pod clean up.

  • Loading branch information...
1 parent 2d791bf commit c4cb7a492fbcf8b0b24304d2d1a2e49a0bf9fde7 @fabiopelosin fabiopelosin committed Jun 8, 2012
Showing with 171 additions and 29 deletions.
  1. +171 −29 lib/cocoapods/local_pod.rb
View
@@ -1,125 +1,236 @@
module Pod
+
+ # A {LocalPod} interfaces one or more specifications belonging to one pod (a
+ # library) and their concrete instance in the file system.
+ #
+ # The {LocalPod} is responsible for orchestrating the activated
+ # specifications of a single pod. Specifically, it keeps track of the
+ # activated specifications and handles issues related to duplicates
+ # files.
+ # Inheritance logic belongs to the {Specification} class.
+ #
+ # The activated specifications are used to compute the paths that can be
+ # safely cleaned by the pod.
+ #
+ # @example
+ #
+ # pod = LocalPod.new 'RestKit/Networking'
+ # pod.add_specification 'RestKit/UI'
+ #
class LocalPod
- attr_reader :top_specification, :specifications
+
+ # @return {Specification} The specification that describes the pod.
+ #
+ attr_reader :top_specification
+
+ # @return {Specification} The activated specifications of the pod.
+ #
+ attr_reader :specifications
+
+ # @return {Sandbox} The sandbox where the pod is installed.
+ #
attr_reader :sandbox
+ # @param [Specification] specification the first activated specification
+ # of the pod.
+ # @param [Sandbox] sandbox The sandbox where the files of the pod will be
+ # located.
+ # @param [Platform] platform The platform that will be used to build the
+ # pod.
+ #
+ # @todo The local pod should be initialized with all the activated
+ # specifications passed as an array, in order to be able to cache the
+ # computed values. In other words, it should be immutable.
+ #
def initialize(specification, sandbox, platform)
@top_specification, @sandbox = specification.top_level_parent, sandbox
@top_specification.activate_platform(platform)
@specifications = [] << specification
end
+ # Initializes a local pod from the top specification of a podspec file.
+ #
+ # @return [LocalPod] A new local pod.
+ #
def self.from_podspec(podspec, sandbox, platform)
new(Specification.from_file(podspec), sandbox, platform)
end
- # Method to add the specifications sharing the same top level
- # parent. With this information the local pod can determine the
- # paths to clean and avoid duplication in file processing.
+ # Activates a specification or subspecs for the pod.
# Adding specifications is idempotent.
+ #
+ # @param {Specification} spec The specification to add to the pod.
+ #
+ # @raise {Informative} If the specification is not part of the same pod.
+ #
def add_specification(spec)
- raise Informative, "[Local Pod] Attempt to add a specification from another pod" unless spec.top_level_parent == top_specification
+ unless spec.top_level_parent == top_specification
+ raise Informative,
+ "[Local Pod] Attempt to add a specification from another pod"
+ end
spec.activate_platform(platform)
@specifications << spec unless @specifications.include?(spec)
end
+ # @return [Pathname] The root directory of the pod
+ #
def root
@sandbox.root + top_specification.name
end
+ # @return [Array<Specification>] The subspecs activated for the pod.
+ #
+ # @todo It this still being used?
+ #
def subspecs
specifications.reject{|s| s.parent.nil? }
end
+ # @return [String] A string representation of the pod which indicates if
+ # the pods comes from a local source.
+ #
def to_s
result = top_specification.to_s
result << " [LOCAL]" if top_specification.local?
result
end
+ # @return [String] The name of the Pod.
+ #
def name
top_specification.name
end
+ # @return [Platform] The platform that will be used to build the pod.
+ #
def platform
top_specification.active_platform
end
- # Installation methods
+ # @!group Installation
+ # Creates the root path of the pod.
+ #
+ # @return [void]
+ #
def create
root.mkpath unless exists?
end
+ # Whether the root path of the pod exists.
+ #
def exists?
root.exist?
end
+ # Executes a block in the root directory of the Pod.
+ #
+ # @return [void]
+ #
def chdir(&block)
create
Dir.chdir(root, &block)
end
+ # Deletes the pod from the file system.
+ #
+ # @return [void]
+ #
def implode
root.rmtree if exists?
end
- ### Cleaning
+ # @!group Cleaning
- # Public: Deletes any path that is not used by the pod.
+ # Deletes any path that is not used by the pod.
+ #
+ # @return [void]
+ #
def clean
clean_paths.each { |path| FileUtils.rm_rf(path) }
end
- # Public: Finds the absolute paths, including hidden ones, of the files
- # that are not used by the pod and can be safely deleted.
+ # Finds the absolute paths, including hidden ones, of the files
+ # that are not used by the pod and thus can be safely deleted.
+ #
+ # @return [Array<Strings>] The paths that can be deleted.
#
- # Returns an Array of Strings containing the absolute paths.
def clean_paths
cached_used_paths = used_paths.map{ |path| path.to_s }
files = Dir.glob(root + "**/*", File::FNM_DOTMATCH)
+
files.reject! do |candidate|
- candidate.end_with?('.', '..') ||
- cached_used_paths.any? { |path| path.include?(candidate) || candidate.include?(path) }
+ candidate.end_with?('.', '..') || cached_used_paths.any? do |path|
+ path.include?(candidate) || candidate.include?(path)
+ end
end
files
end
- # Public: Finds all the absolute paths used by pod.
+ # @return [Array<Pathname>] The paths of the files used by the pod.
#
- # Returns an Array of Pathnames containing the absolute paths.
def used_paths
- files = source_files(false) + resources(false) + preserve_paths + [ readme_file, license_file, prefix_header_file ]
- files.compact
+ files = [ source_files(false),
+ resources(false),
+ preserve_paths,
+ readme_file,
+ license_file,
+ prefix_header_file ]
+ files.compact!
+ files.flatten!
+ files
end
- ### File attributes
-
- def prefix_header_file
- root + top_specification.prefix_header_file if top_specification.prefix_header_file
- end
+ # @!group Files
+ # @param [Boolean] relative Whether the paths should be returned relative
+ # to the sandbox.
+ #
+ # @return [Array<Pathname>] The paths of the source files.
+ #
def source_files(relative = true)
chained_expanded_paths(:source_files, :glob => '*.{h,m,mm,c,cpp}', :relative_to_sandbox => relative)
end
+ # @param (see #source_files)
+ #
+ # @return [Array<Pathname>] The paths of the header files.
+ #
def header_files
source_files.select { |f| f.extname == '.h' }
end
+ # @param (see #source_files)
+ #
+ # @return [Array<Pathname>] The paths of the resources.
+ #
def resources(relative = true)
chained_expanded_paths(:resources, :relative_to_sandbox => relative)
end
- # TODO: implement case insensitive search
+ # @return [Pathname] The absolute path of the prefix header file
+ #
+ def prefix_header_file
+ root + top_specification.prefix_header_file if top_specification.prefix_header_file
+ end
+
+ # @return [Array<Pathname>] The absolute paths of the files of the pod
+ # that should be preserved.
+ #
def preserve_paths
chained_expanded_paths(:preserve_paths) + expanded_paths(%w[ *.podspec notice* NOTICE* CREDITS* ])
end
+ # @return [Pathname] The automatically detected path of the README
+ # file.
+ #
def readme_file
expanded_paths(%w[ README{*,.*} readme{*,.*} ]).first
end
+ # @return [Pathname] The absolute path of the license file from the
+ # specification or automatically detected.
+ #
def license_file
if top_specification.license && top_specification.license[:file]
root + top_specification.license[:file]
@@ -128,6 +239,9 @@ def license_file
end
end
+ # @return [String] The text of the license of the pod from the
+ # specification or from the license file.
+ #
def license_text
if (license_hash = top_specification.license)
if (result = license_hash[:text])
@@ -150,7 +264,7 @@ def all_specs_public_header_files
specs.map { |s| expanded_paths(s.source_files, :glob => '*.{h}') }.compact.flatten.select { |f| f.extname == '.h' }.uniq
end
- # Integration methods
+ # @!group Target integration
def link_headers
copy_header_mappings.each do |namespaced_path, files|
@@ -182,10 +296,10 @@ def relative_root
root.relative_path_from(@sandbox.root)
end
- # TODO this is being overriden in the RestKit 0.9.4 spec, need to do
+ # @todo this is being overridden in the RestKit 0.9.4 spec, need to do
# something with that, and this method also still exists in Specification.
#
- # This is not overriden anymore in specification refactor and the code
+ # @todo This is not overridden anymore in specification refactor and the code
# Pod::Specification#copy_header_mapping can be moved here.
def copy_header_mappings
search_path_headers = header_files - headers_excluded_from_search_paths
@@ -197,9 +311,13 @@ def copy_header_mappings
end
end
- # returns an hash where the source_files are groupped by specification.
- # If the same file is required by two specifications the one at the
- # higher level in the inheritance chain wins.
+ # Finds the source files that every activate {Specification} requires.
+ #
+ # @note The paths of the files are relative to the sandbox.
+ # @note If the same file is required by two specifications the one at the higher level in the inheritance chain wins.
+ #
+ # @return [Hash{Specification => Array<Pathname>}] The files grouped by {Specification}.
+ #
def sources_files_by_specification
files_by_spec = {}
processed_files = []
@@ -214,14 +332,38 @@ def sources_files_by_specification
files_by_spec
end
+ # @todo merge with #221
+ #
def headers_excluded_from_search_paths
chained_expanded_paths(:exclude_header_search_paths, :glob => '*.h', :relative_to_sandbox => true)
end
+
+ # @!group File Patterns
+
+ # Find all the paths patterns of a each activated specifications and converts them to the actual paths present in the pod.
+ #
+ # @return Array<Pathname> A list of the paths.
+ #
def chained_expanded_paths(accessor, options = {})
specifications.map { |s| expanded_paths(s.send(accessor), options) }.compact.flatten.uniq
end
+ # Converts patterns of paths to the {Pathname} of the files present in the pod.
+ #
+ # @todo implement case insensitive search
+ #
+ # @param [String, FileList, Array<String, Pathname>] patterns The patterns
+ # to expand.
+ # @param [Hash] options the options to used for expanding the paths patterns.
+ # @option options [String] :glob The pattern to use for globing directories.
+ # @option options [Boolean] :relative_to_sandbox Whether the paths should
+ # be returned relative to the sandbox.
+ #
+ # @raise [Informative] If the pod does not exists.
+ #
+ # @return [Array<Pathname>] A list of the paths.
+ #
def expanded_paths(patterns, options = {})
raise Informative, "[Local Pod] Attempt to resolve paths for non existent pod." unless exists?

0 comments on commit c4cb7a4

Please sign in to comment.