Skip to content
Browse files

[Source] Add FileSystemDataProvider

  • Loading branch information...
1 parent a3ffbff commit bbe3f993e55169844213da8af89389d3c0743145 @fabiopelosin fabiopelosin committed
Showing with 315 additions and 0 deletions.
  1. +150 −0 lib/cocoapods-core/source/file_system_data_provider.rb
  2. +165 −0 spec/source/file_system_data_provider_spec.rb
View
150 lib/cocoapods-core/source/file_system_data_provider.rb
@@ -0,0 +1,150 @@
+module Pod
+ class Source
+
+ # Data provider for a `Pod::Source` backed by a repository hosted in the
+ # file system.
+ #
+ class FileSystemDataProvider < AbstractDataProvider
+
+ # @return [Pathname] The path where the source is stored.
+ #
+ attr_reader :repo
+
+ # @param [Pathname, String] repo @see #repo.
+ #
+ def initialize(repo)
+ @repo = Pathname.new(repo)
+ end
+
+ public
+
+ # @group Required methods
+ #-----------------------------------------------------------------------#
+
+ # @return [String] The name of the source.
+ #
+ def name
+ repo.basename.to_s
+ end
+
+ # @return [String] The user friendly type of the source.
+ #
+ def type
+ "file system"
+ end
+
+ # @return [Array<String>] The list of the name of all the Pods known to
+ # the Source.
+ #
+ # @note Using Pathname#children is sensibly slower.
+ #
+ def pods
+ return nil unless specs_dir
+ 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))
+ end
+ 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)
+ return nil unless specs_dir
+ raise ArgumentError, "No name" unless name
+ pod_dir = specs_dir + name
+ return unless pod_dir.exist?
+ pod_dir.children.map do |v|
+ basename = v.basename.to_s
+ basename if v.directory? && basename[0, 1] != '.'
+ end.compact.sort.reverse
+ 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)
+ path = specification_path(name, version)
+ Pod::Specification.from_file(path) if path && path.exist?
+ 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)
+ path = specification_path(name, version)
+ File.open(path, 'r:utf-8') { |f| f.read } if path && path.exist?
+ end
+
+ public
+
+ # @group Other methods
+ #-----------------------------------------------------------------------#
+
+ # 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)
+ raise ArgumentError, "No name" unless name
+ raise ArgumentError, "No version" unless version
+ return nil unless specs_dir
+ path = specs_dir + name + version.to_s
+ specification_path = path + "#{name}.podspec.yaml"
+ specification_path.exist?
+ unless specification_path.exist?
+ specification_path = path + "#{name}.podspec"
+ end
+ specification_path
+ end
+
+ private
+
+ # @group Private Helpers
+ #-----------------------------------------------------------------------#
+
+ # @return [Pathname] The directory where the specs are stored.
+ #
+ # @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.
+ #
+ 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
+ end
+ end
+ @specs_dir
+ end
+
+ #-----------------------------------------------------------------------#
+
+ end
+ end
+end
View
165 spec/source/file_system_data_provider_spec.rb
@@ -0,0 +1,165 @@
+require File.expand_path('../../spec_helper', __FILE__)
+
+module Pod
+ describe Source::FileSystemDataProvider do
+
+ before do
+ path = fixture('spec-repos/test_repo')
+ @sut = Source::FileSystemDataProvider.new(path)
+ end
+
+ #-------------------------------------------------------------------------#
+
+ describe "In general" do
+ it "returns its name" do
+ @sut.name.should == 'test_repo'
+ end
+ end
+
+ #-------------------------------------------------------------------------#
+
+ describe "#pods" do
+ it "returns the available Pods" do
+ @sut.pods.should == ["BananaLib", "Faulty_spec", "JSONKit", "YAMLSpec"]
+ end
+
+ it "returns nil if no Pods could be found" do
+ path = fixture('spec-repos/non_existing')
+ @sut = Source::FileSystemDataProvider.new(path)
+ @sut.pods.should.be.nil
+ end
+
+ it "doesn't include the `.` and the `..` dir entries" do
+ @sut.pods.should.not.include?('.')
+ @sut.pods.should.not.include?('..')
+ end
+
+ it "only consider directories" do
+ File.stubs(:directory?).returns(false)
+ @sut.pods.should == []
+ end
+
+
+ it "uses the `Specs` dir if it is present" do
+ @sut.send(:specs_dir).to_s.should.end_with('test_repo/Specs')
+ end
+
+ it "uses the root of the repo as the specs dir if the `Specs` folder is not present" do
+ repo = fixture('spec-repos/master')
+ @sut = Source::FileSystemDataProvider.new(repo)
+ @sut.send(:specs_dir).to_s.should.end_with('master')
+ end
+ end
+
+ #-------------------------------------------------------------------------#
+
+ describe "#versions" do
+ it "returns the versions for the given Pod" do
+ @sut.versions('JSONKit').should == ["999.999.999", "1.4"]
+ end
+
+ it "returns nil the Pod is unknown" do
+ @sut.versions('Unknown_Pod').should.be.nil
+ end
+
+ it "raises if the name of the Pod is not provided" do
+ should.raise ArgumentError do
+ @sut.versions(nil)
+ end.message.should.match /No name/
+ end
+ end
+
+ #-------------------------------------------------------------------------#
+
+ describe "#specification" do
+ it "returns the specification for the given version of a Pod" do
+ spec = @sut.specification('JSONKit', "1.4")
+ spec.name.should == 'JSONKit'
+ spec.version.to_s.should == '1.4'
+ end
+
+ it "returns nil if the Pod is unknown" do
+ spec = @sut.specification('Unknown_Pod', "1.4")
+ spec.should.be.nil
+ end
+
+ it "returns nil if the version of the Pod doesn't exists" do
+ spec = @sut.specification('JSONKit', "0.99.0")
+ spec.should.be.nil
+ end
+
+ it "raises if the name of the Pod is not provided" do
+ should.raise ArgumentError do
+ @sut.specification(nil, "1.4")
+ end.message.should.match /No name/
+ end
+
+ it "raises if the name of the Pod is not provided" do
+ should.raise ArgumentError do
+ @sut.specification('JSONKit', nil)
+ end.message.should.match /No version/
+ end
+ end
+
+ #-------------------------------------------------------------------------#
+
+ describe "#specification_path" do
+ it "returns the path of a specification" do
+ path = @sut.specification_path('JSONKit', "1.4")
+ path.to_s.should.end_with?('test_repo/Specs/JSONKit/1.4/JSONKit.podspec')
+ end
+
+ it "prefers YAML podspecs if one exists" do
+ Pathname.any_instance.stubs(:exist?).returns(true)
+ path = @sut.specification_path('JSONKit', "1.4")
+ path.to_s.should.end_with?('test_repo/Specs/JSONKit/1.4/JSONKit.podspec.yaml')
+ end
+
+ it "raises if the name of the Pod is not provided" do
+ should.raise ArgumentError do
+ @sut.specification_path(nil, "1.4")
+ end.message.should.match /No name/
+ end
+
+ it "raises if the name of the Pod is not provided" do
+ should.raise ArgumentError do
+ @sut.specification_path('JSONKit', nil)
+ end.message.should.match /No version/
+ end
+ end
+
+ #-------------------------------------------------------------------------#
+
+ describe "#specification_contents" do
+ it "returns the specification given the name and the version" do
+ spec = @sut.specification_contents('JSONKit', "1.4")
+ spec.should.match /s.name += 'JSONKit'\n +s.version += '1.4'/
+ end
+
+ it "returns nil if the Pod is unknown" do
+ spec = @sut.specification_contents('Unknown_Pod', "1.4")
+ spec.should.be.nil
+ end
+
+ it "returns nil if the version of the Pod doesn't exists" do
+ spec = @sut.specification_contents('JSONKit', "0.99.0")
+ spec.should.be.nil
+ end
+
+ it "raises if the name of the Pod is not provided" do
+ should.raise ArgumentError do
+ @sut.specification_contents(nil, "1.4")
+ end.message.should.match /No name/
+ end
+
+ it "raises if the name of the Pod is not provided" do
+ should.raise ArgumentError do
+ @sut.specification_contents('JSONKit', nil)
+ end.message.should.match /No version/
+ end
+ end
+
+ #-------------------------------------------------------------------------#
+
+ end
+end

0 comments on commit bbe3f99

Please sign in to comment.
Something went wrong with that request. Please try again.