Skip to content
This repository
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 220 lines (182 sloc) 5.417 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219
module Pod
  class Specification
    autoload :Set, 'cocoapods/specification/set'

    def self.from_podfile(path)
      if path.exist?
        spec = new
        spec.instance_eval(path.read)
        spec.defined_in_file = path
        spec
      end
    end

    def self.from_podspec(path)
      spec = eval(path.read, nil, path.to_s)
      spec.defined_in_file = path
      spec
    end

    attr_accessor :defined_in_file

    def initialize(&block)
      @dependencies = []
      @xcconfig = {}
      instance_eval(&block) if block_given?
    end

    # Attributes

    def read(name)
      instance_variable_get("@#{name}")
    end

    def name(name)
      @name = name
    end

    def version(version)
      @version = Version.new(version)
    end

    def authors(*names_and_email_addresses)
      list = names_and_email_addresses
      unless list.first.is_a?(Hash)
        authors = list.last.is_a?(Hash) ? list.pop : {}
        list.each { |name| authors[name] = nil }
      end
      @authors = authors || list.first
    end
    alias_method :author, :authors

    def homepage(url)
      @homepage = url
    end

    def summary(summary)
      @summary = summary
      @description ||= summary
    end

    def description(description)
      @description = description
    end

    def part_of(name, *version_requirements)
      part_of_dependency(name, *version_requirements)
      @part_of.only_part_of_other_pod = true
    end

    def part_of_dependency(name, *version_requirements)
      @part_of = dependency(name, *version_requirements)
    end

    def source_files(*patterns)
      @source_files = patterns.map { |p| Pathname.new(p) }
    end

    def source(remote)
      @source = remote
    end

    attr_reader :dependencies
    def dependency(name, *version_requirements)
      dep = Dependency.new(name, *version_requirements)
      @dependencies << dep
      dep
    end

    def xcconfig(hash)
      @xcconfig = hash
    end

    # Not attributes

    include Config::Mixin

    def ==(other)
      self.class === other &&
        @name && @name == other.read(:name) &&
          @version && @version == other.read(:version)
    end

    def dependency_by_name(name)
      @dependencies.find { |d| d.name == name }
    end

    def part_of_specification_set
      if @part_of
        Set.by_specification_name(@part_of.name)
      end
    end

    # Returns the specification for the pod that this pod's source is a part of.
    def part_of_specification
      (set = part_of_specification_set) && set.specification
    end

    def pod_destroot
      return if from_podfile?
      if part_of_other_pod?
        part_of_specification.pod_destroot
      else
        config.project_pods_root + "#{@name}-#{@version}"
      end
    end

    def part_of_other_pod?
      !@part_of.nil?
    end

    def from_podfile?
      @name.nil? && @version.nil?
    end

    def to_s
      if from_podfile?
        "podfile at `#{@defined_in_file}'"
      else
        "`#{@name}' version `#{@version}'"
      end
    end

    def inspect
      "#<#{self.class.name} for #{to_s}>"
    end

    def validate!
      attrs = []
      attrs << "`name'" unless @name
      attrs << "`version'" unless @version
      attrs << "`summary'" unless @summary
      attrs << "`homepage'" unless @homepage
      attrs << "`author(s)'" unless @authors
      attrs << "either `source' or `part_of'" unless @source || @part_of
      attrs << "`source_files'" unless @source_files
      unless attrs.empty?
        raise Informative, "The following required " \
          "#{attrs.size == 1 ? 'attribute is' : 'attributes are'} " \
          "missing: #{attrs.join(", ")}"
      end
    end

    # Install and download hooks

    # Places the activated specification in the project's pods directory.
    #
    # Override this if you need to perform work before or after activating the
    # pod. Eg:
    #
    # Pod::Spec.new do
    # def install!
    # # pre-install
    # super
    # # post-install
    # end
    # end
    def install!
      puts "==> Installing: #{self}" unless config.silent?
      config.project_pods_root.mkpath
      require 'fileutils'
      FileUtils.cp(@defined_in_file, config.project_pods_root)

      # In case this spec is part of another pod's source, we need to dowload
      # the other pod's source.
      (part_of_specification || self).download_if_necessary!
    end

    def download_if_necessary!
      if pod_destroot.exist?
        puts " * Skipping download of #{self}, pod already downloaded" unless config.silent?
      else
        puts " * Downloading: #{self}" unless config.silent?
        download!
      end
    end

    # Downloads the source of the pod and places it in the project's pods
    # directory.
    #
    # Override this if you need to perform work before or after downloading the
    # pod, or if you need to implement custom dowloading. Eg:
    #
    # Pod::Spec.new do
    # def download!
    # # pre-download
    # super # or custom downloading
    # # post-download
    # end
    # end
    def download!
      downloader = Downloader.for_source(pod_destroot, @source)
      downloader.download
      downloader.clean if config.clean
    end

  end

  Spec = Specification
end
Something went wrong with that request. Please try again.