Skip to content

Commit

Permalink
Merge dcb2473 into 2f028e0
Browse files Browse the repository at this point in the history
  • Loading branch information
fabiopelosin committed Dec 2, 2013
2 parents 2f028e0 + dcb2473 commit 4f3b8d9
Show file tree
Hide file tree
Showing 15 changed files with 1,458 additions and 247 deletions.
27 changes: 25 additions & 2 deletions lib/cocoapods-core/github.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,34 @@ def self.branches(url)
end
end

private
# Returns the contents of a file or directory in a repository.
#
# @param [String] url @see #repo
#
# @param [#to_s] path
# The path for which the contents are needed.
#
# @param [String] branch
# The branch for which to fetch the contents of the path.
#
# @return [Array] The list of the files and of the directories if the given
# path is a directory.
#
# @return [Hash] The contents of the file (usually base64 encoded).
#
def self.contents(url, path = nil, branch = nil)
if repo_id = normalized_repo_id(url)
request_url = "https://api.github.com/repos/#{repo_id}/contents"
request_url << "/#{path}" if path
request_url << "?ref=#{branch}" if branch
peform_request(request_url)
end
end

#-------------------------------------------------------------------------#
private

# @!group Private helpers
#-------------------------------------------------------------------------#

# Returns the repo ID as it is or converting a GitHub URL.
#
Expand Down
194 changes: 106 additions & 88 deletions lib/cocoapods-core/source.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
require 'cocoapods-core/source/acceptor'
require 'cocoapods-core/source/aggregate'
require 'cocoapods-core/source/health_reporter'
require 'cocoapods-core/source/abstract_data_provider'
require 'cocoapods-core/source/file_system_data_provider'
require 'cocoapods-core/source/github_data_provider'

module Pod

Expand All @@ -16,20 +19,31 @@ module Pod
#
class Source

# @return [Pathname] the location of the repo of the source.
# @return [AbstractDataProvider] the data provider for this source.
#
attr_reader :repo
attr_accessor :data_provider

# @param [Pathname, String] repo @see #repo.
#
def initialize(repo)
@repo = Pathname.new(repo)
def initialize(repo = nil)
# TODO: Temporary solution to aide the transition
if repo.is_a?(String) || repo.is_a?(Pathname)
@data_provider = FileSystemDataProvider.new(repo)
else
@data_provider = repo
end
end

# @return [String] the name of the source.
# @return [String] The name of the source.
#
def name
repo.basename.to_s
data_provider.name
end

# @return [String] The type of the source.
#
def type
data_provider.type
end

alias_method :to_s, :name
Expand All @@ -45,37 +59,27 @@ def <=>(other)
name <=> other.name
end

#-------------------------------------------------------------------------#
# @return [String] A description suitable for debugging.
#
def inspect
"#<#{self.class} name:#{name} type:#{type}>"
end

public

# @!group Queering the source
#-------------------------------------------------------------------------#

# @return [Array<String>] the list of the name of all the Pods.
#
# @note Using Pathname#children is sensibly slower.
#
def pods
specs_dir_as_string = specs_dir.to_s
Dir.entries(specs_dir).select do |entry|
valid_name = !(entry == '.' || entry == '..' || entry == '.git')
valid_name && File.directory?(File.join(specs_dir_as_string, entry))
pods = data_provider.pods
unless pods
raise Informative, "Unable to find the #{data_provider.type} source " \
"named: `#{data_provider.name}`"
end
end

# Returns the set for the Pod with the given name.
#
# @param [String] pod_name
# The name of the Pod.
#
# @return [Sets] the set.
#
def set(pod_name)
Specification::Set.new(pod_name, self)
end

# @return [Array<Sets>] the sets of all the Pods.
#
def pod_sets
pods.map { |pod_name| set(pod_name) }
pods
end

# @return [Array<Version>] all the available versions for the Pod, sorted
Expand All @@ -85,43 +89,21 @@ def pod_sets
# the name of the Pod.
#
def versions(name)
pod_dir = specs_dir + name
return unless pod_dir.exist?
pod_dir.children.map do |v|
basename = v.basename.to_s
Version.new(basename) if v.directory? && basename[0, 1] != '.'
end.compact.sort.reverse
versions = data_provider.versions(name)
versions.map { |version| Version.new(version) } if versions
end

# @return [Specification] the specification for a given version of Pod.
#
# @param @see specification_path
#
def specification(name, version)
Specification.from_file(specification_path(name, version))
end

# Returns the path of the specification with the given name and version.
#
# @param [String] name
# the name of the Pod.
#
# @param [Version,String] version
# the version for the specification.
#
# @return [Pathname] The path of the specification.
#
def specification_path(name, version)
path = specs_dir + name + version.to_s
specification_path = path + "#{name}.podspec.yaml"
unless specification_path.exist?
specification_path = path + "#{name}.podspec"
end
unless specification_path.exist?
raise StandardError, "Unable to find the specification #{name} " \
"(#{version}) in the #{name} source."
spec = data_provider.specification(name, version.to_s)
unless spec
raise Informative, "Unable to find the specification for #{name} " \
"#{version} in the `#{data_provider.name}` source."
end
specification_path
spec
end

# @return [Array<Specification>] all the specifications contained by the
Expand All @@ -139,9 +121,43 @@ def all_specs
specs.flatten.compact
end

#-------------------------------------------------------------------------#
# Returns the set for the Pod with the given name.
#
# @param [String] pod_name
# The name of the Pod.
#
# @return [Sets] the set.
#
def set(pod_name)
Specification::Set.new(pod_name, self)
end

# @return [Array<Sets>] the sets of all the Pods.
#
def pod_sets
pods.map { |pod_name| set(pod_name) }
end

# Returns the path of the specification with the given name and version.
#
# @param [String] name
# the name of the Pod.
#
# @param [Version,String] version
# the version for the specification.
#
# @return [Pathname] The path of the specification.
#
# @todo Remove.
#
def specification_path(name, version)
data_provider.specification_path(name, version)
end

public

# @!group Searching the source
#-------------------------------------------------------------------------#

# @return [Set] a set for a given dependency. The set is identified by the
# name of the dependency and takes into account subspecs.
Expand Down Expand Up @@ -171,18 +187,22 @@ def search(query)
# @note full text search requires to load the specification for each pod,
# hence is considerably slower.
#
# @todo Rename to #search
#
def search_by_name(query, full_text_search = false)
if full_text_search
pod_sets.map do |set|
begin
s = set.specification
text = "#{s.name} #{s.authors} #{s.summary} #{s.description}"
rescue
CoreUI.warn "Skipping `#{set.name}` because the podspec " \
"contains errors."
if data_provider.is_a?(FileSystemDataProvider)
names = pods.select do |pod|
if spec = load_spec_gracefully(pod)
text = "#{spec.name} #{spec.authors}"
text << " #{spec.summary} #{spec.description}"
text.downcase.include?(query.downcase)
end
end
set if text && text.downcase.include?(query.downcase)
end.compact
else
[]
end
names.map { |pod_name| set(pod_name) }
else
names = pods.select { |name| name.downcase.include?(query.downcase) }
names.map { |pod_name| set(pod_name) }
Expand All @@ -205,9 +225,10 @@ def fuzzy_search(query)
end
end

#-------------------------------------------------------------------------#
public

# @!group Representations
#-------------------------------------------------------------------------#

# @return [Hash{String=>{String=>Specification}}] the static representation
# of all the specifications grouped first by name and then by
Expand All @@ -231,29 +252,26 @@ def to_yaml

private

#-------------------------------------------------------------------------#

# @group Private Helpers
#-------------------------------------------------------------------------#

# @return [Pathname] The directory where the specs are stored.
# Loads the specification for the given Pod gracefully.
#
# @note In previous versions of CocoaPods they used to be stored in
# the root of the repo. This lead to issues, especially with
# the GitHub interface and now the are stored in a dedicated
# folder.
# @param [String] name
# the name of the Pod.
#
def specs_dir
unless @specs_dir
specs_sub_dir = repo + 'Specs'
if specs_sub_dir.exist?
@specs_dir = specs_sub_dir
elsif repo.exist?
@specs_dir = repo
else
raise Informative, "Unable to find a source named: `#{name}`"
end
end
@specs_dir
# @return [Specification] The specification for the last version of the
# Pod.
# @return [Nil] If the spec could not be loaded.
#
def load_spec_gracefully(name)
versions = versions(name)
version = versions.sort.last if versions
specification(name, version) if version
rescue Informative
Pod::CoreUI.warn "Skipping `#{name}` because the podspec " \
"contains errors."
nil
end

#-------------------------------------------------------------------------#
Expand Down
71 changes: 71 additions & 0 deletions lib/cocoapods-core/source/abstract_data_provider.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
module Pod
class Source

# Defines the required and the optional methods of a data provider.
#
class AbstractDataProvider

public

# @group Required methods
#-----------------------------------------------------------------------#

# @return [String] The name of the source.
#
def name
raise StandardError, "Abstract method."
end

# @return [String] The user friendly type of the source.
#
def type
raise StandardError, "Abstract method."
end

# @return [Array<String>] The list of the name of all the Pods known to
# the Source.
#
def pods
raise StandardError, "Abstract method."
end

# @return [Array<String>] All the available versions of a given Pod,
# sorted from highest to lowest.
#
# @param [String] name
# The name of the Pod.
#
def versions(name)
raise StandardError, "Abstract method."
end

# @return [Specification] The specification for a given version of a Pod.
#
# @param [String] name
# The name of the Pod.
#
# @param [String] version
# The version of the Pod.
#
def specification(name, version)
raise StandardError, "Abstract method."
end

# @return [Specification] The contents of the specification for a given
# version of a Pod.
#
# @param [String] name
# the name of the Pod.
#
# @param [String] version
# the version of the Pod.
#
def specification_contents(name, version)
raise StandardError, "Abstract method."
end

#-----------------------------------------------------------------------#

end
end
end

0 comments on commit 4f3b8d9

Please sign in to comment.