cocoapods 0.5.1 → 0.6.0.rc1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.md +229 -2
- data/README.md +50 -20
- data/bin/pod +3 -2
- data/lib/cocoapods.rb +23 -9
- data/lib/cocoapods/command.rb +71 -30
- data/lib/cocoapods/command/error_report.rb +102 -0
- data/lib/cocoapods/command/install.rb +27 -19
- data/lib/cocoapods/command/list.rb +51 -8
- data/lib/cocoapods/command/presenter.rb +61 -0
- data/lib/cocoapods/command/presenter/cocoa_pod.rb +123 -0
- data/lib/cocoapods/command/push.rb +102 -0
- data/lib/cocoapods/command/repo.rb +70 -14
- data/lib/cocoapods/command/search.rb +7 -10
- data/lib/cocoapods/command/setup.rb +76 -15
- data/lib/cocoapods/command/spec.rb +581 -97
- data/lib/cocoapods/config.rb +23 -26
- data/lib/cocoapods/dependency.rb +86 -40
- data/lib/cocoapods/downloader.rb +30 -18
- data/lib/cocoapods/downloader/git.rb +125 -15
- data/lib/cocoapods/downloader/http.rb +73 -0
- data/lib/cocoapods/downloader/mercurial.rb +3 -9
- data/lib/cocoapods/downloader/subversion.rb +3 -9
- data/lib/cocoapods/executable.rb +26 -3
- data/lib/cocoapods/generator/acknowledgements.rb +37 -0
- data/lib/cocoapods/generator/acknowledgements/markdown.rb +38 -0
- data/lib/cocoapods/generator/acknowledgements/plist.rb +63 -0
- data/lib/cocoapods/generator/copy_resources_script.rb +8 -4
- data/lib/cocoapods/generator/documentation.rb +99 -0
- data/lib/cocoapods/generator/dummy_source.rb +14 -0
- data/lib/cocoapods/installer.rb +140 -109
- data/lib/cocoapods/installer/target_installer.rb +78 -83
- data/lib/cocoapods/installer/user_project_integrator.rb +162 -0
- data/lib/cocoapods/local_pod.rb +240 -0
- data/lib/cocoapods/platform.rb +41 -18
- data/lib/cocoapods/podfile.rb +234 -21
- data/lib/cocoapods/project.rb +67 -0
- data/lib/cocoapods/resolver.rb +62 -32
- data/lib/cocoapods/sandbox.rb +63 -0
- data/lib/cocoapods/source.rb +42 -20
- data/lib/cocoapods/specification.rb +294 -271
- data/lib/cocoapods/specification/set.rb +10 -28
- data/lib/cocoapods/specification/statistics.rb +112 -0
- metadata +124 -11
- data/lib/cocoapods/xcodeproj_pods.rb +0 -111
data/lib/cocoapods/config.rb
CHANGED
@@ -10,16 +10,23 @@ module Pod
|
|
10
10
|
@instance = instance
|
11
11
|
end
|
12
12
|
|
13
|
-
attr_accessor :repos_dir, :project_root, :project_pods_root
|
14
|
-
|
15
|
-
|
16
|
-
|
13
|
+
attr_accessor :repos_dir, :project_root, :project_pods_root
|
14
|
+
attr_accessor :clean, :verbose, :silent
|
15
|
+
attr_accessor :generate_docs, :doc_install
|
16
|
+
attr_accessor :integrate_targets
|
17
|
+
attr_accessor :git_cache_size
|
18
|
+
|
19
|
+
alias_method :clean?, :clean
|
20
|
+
alias_method :verbose?, :verbose
|
21
|
+
alias_method :silent?, :silent
|
22
|
+
alias_method :generate_docs?, :generate_docs
|
23
|
+
alias_method :doc_install?, :doc_install
|
24
|
+
alias_method :integrate_targets?, :integrate_targets
|
17
25
|
|
18
26
|
def initialize
|
19
27
|
@repos_dir = Pathname.new(File.expand_path("~/.cocoapods"))
|
20
|
-
@
|
21
|
-
@
|
22
|
-
@silent = false
|
28
|
+
@verbose = @silent = false
|
29
|
+
@clean = @generate_docs = @doc_install = @integrate_targets = true
|
23
30
|
end
|
24
31
|
|
25
32
|
def project_root
|
@@ -31,13 +38,7 @@ module Pod
|
|
31
38
|
end
|
32
39
|
|
33
40
|
def project_podfile
|
34
|
-
|
35
|
-
@project_podfile = project_root + 'Podfile'
|
36
|
-
unless @project_podfile.exist?
|
37
|
-
@project_podfile = project_root.glob('*.podspec').first
|
38
|
-
end
|
39
|
-
end
|
40
|
-
@project_podfile
|
41
|
+
@project_podfile ||= project_root + 'Podfile'
|
41
42
|
end
|
42
43
|
|
43
44
|
def headers_symlink_root
|
@@ -45,25 +46,21 @@ module Pod
|
|
45
46
|
end
|
46
47
|
|
47
48
|
# Returns the spec at the pat returned from `project_podfile`.
|
48
|
-
def
|
49
|
-
|
50
|
-
if project_podfile
|
51
|
-
if project_podfile.basename.to_s == 'Podfile'
|
52
|
-
@rootspec = Podfile.from_file(project_podfile)
|
53
|
-
else
|
54
|
-
@rootspec = Specification.from_file(project_podfile)
|
55
|
-
end
|
56
|
-
end
|
49
|
+
def podfile
|
50
|
+
@podfile ||= begin
|
51
|
+
Podfile.from_file(project_podfile) if project_podfile.exist?
|
57
52
|
end
|
58
|
-
@rootspec
|
59
53
|
end
|
54
|
+
attr_writer :podfile
|
60
55
|
|
61
56
|
def ios?
|
62
|
-
|
57
|
+
# TODO: deprecate in 0.7
|
58
|
+
podfile.target_definitions[:default].platform == :ios if podfile
|
63
59
|
end
|
64
60
|
|
65
61
|
def osx?
|
66
|
-
|
62
|
+
# TODO: deprecate in 0.7
|
63
|
+
podfile.target_definitions[:default].platform == :osx if podfile
|
67
64
|
end
|
68
65
|
|
69
66
|
module Mixin
|
data/lib/cocoapods/dependency.rb
CHANGED
@@ -1,14 +1,12 @@
|
|
1
1
|
module Gem
|
2
2
|
end
|
3
3
|
require 'rubygems/dependency'
|
4
|
+
require 'open-uri'
|
4
5
|
|
5
6
|
module Pod
|
6
7
|
class Dependency < Gem::Dependency
|
7
|
-
attr_accessor :only_part_of_other_pod
|
8
|
-
alias_method :only_part_of_other_pod?, :only_part_of_other_pod
|
9
|
-
|
10
|
-
attr_accessor :external_spec_source
|
11
8
|
|
9
|
+
attr_reader :external_source
|
12
10
|
attr_accessor :specification
|
13
11
|
|
14
12
|
def initialize(*name_and_version_requirements, &block)
|
@@ -19,7 +17,7 @@ module Pod
|
|
19
17
|
|
20
18
|
elsif !name_and_version_requirements.empty? && block.nil?
|
21
19
|
if name_and_version_requirements.last.is_a?(Hash)
|
22
|
-
@
|
20
|
+
@external_source = ExternalSources.from_params(name_and_version_requirements[0].split('/').first, name_and_version_requirements.pop)
|
23
21
|
end
|
24
22
|
super(*name_and_version_requirements)
|
25
23
|
|
@@ -27,19 +25,24 @@ module Pod
|
|
27
25
|
raise Informative, "A dependency needs either a name and version requirements, " \
|
28
26
|
"a source hash, or a block which defines a podspec."
|
29
27
|
end
|
30
|
-
@only_part_of_other_pod = false
|
31
28
|
end
|
32
29
|
|
33
30
|
def ==(other)
|
34
|
-
super &&
|
35
|
-
@only_part_of_other_pod == other.only_part_of_other_pod &&
|
36
|
-
(@specification ? @specification == other.specification : @external_spec_source == other.external_spec_source)
|
31
|
+
super && (@specification ? @specification == other.specification : @external_source == other.external_source)
|
37
32
|
end
|
38
33
|
|
39
34
|
def subspec_dependency?
|
40
35
|
@name.include?('/')
|
41
36
|
end
|
42
37
|
|
38
|
+
def inline?
|
39
|
+
@inline_podspec
|
40
|
+
end
|
41
|
+
|
42
|
+
def external?
|
43
|
+
!@external_source.nil?
|
44
|
+
end
|
45
|
+
|
43
46
|
# In case this is a dependency for a subspec, e.g. 'RestKit/Networking',
|
44
47
|
# this returns 'RestKit', which is what the Pod::Source needs to know to
|
45
48
|
# retrieve the correct Set from disk.
|
@@ -58,11 +61,9 @@ module Pod
|
|
58
61
|
|
59
62
|
def to_s
|
60
63
|
version = ''
|
61
|
-
if
|
62
|
-
version <<
|
63
|
-
|
64
|
-
version << ", tag `#{source[:tag]}'" if source[:tag]
|
65
|
-
elsif @inline_podspec
|
64
|
+
if external?
|
65
|
+
version << @external_source.description
|
66
|
+
elsif inline?
|
66
67
|
version << "defined in Podfile"
|
67
68
|
elsif @version_requirements != Gem::Requirement.default
|
68
69
|
version << @version_requirements.to_s
|
@@ -70,32 +71,8 @@ module Pod
|
|
70
71
|
version.empty? ? @name : "#{@name} (#{version})"
|
71
72
|
end
|
72
73
|
|
73
|
-
|
74
|
-
|
75
|
-
def specification
|
76
|
-
@specification ||= begin
|
77
|
-
if @external_spec_source
|
78
|
-
config = Config.instance
|
79
|
-
pod_root = config.project_pods_root + @name
|
80
|
-
spec = nil
|
81
|
-
if @external_spec_source[:podspec]
|
82
|
-
config.project_pods_root.mkpath
|
83
|
-
spec = config.project_pods_root + "#{@name}.podspec"
|
84
|
-
source = @external_spec_source[:podspec]
|
85
|
-
# can be http, file, etc
|
86
|
-
require 'open-uri'
|
87
|
-
puts " * Fetching podspec for `#{@name}' from: #{source}" unless config.silent?
|
88
|
-
open(source) do |io|
|
89
|
-
spec.open('w') { |f| f << io.read }
|
90
|
-
end
|
91
|
-
else
|
92
|
-
puts " * Pre-downloading: `#{@name}'" unless config.silent?
|
93
|
-
Downloader.for_source(pod_root, @external_spec_source).download
|
94
|
-
spec = pod_root + "#{@name}.podspec"
|
95
|
-
end
|
96
|
-
Specification.from_file(spec)
|
97
|
-
end
|
98
|
-
end
|
74
|
+
def specification_from_sandbox(sandbox, platform)
|
75
|
+
@external_source.specification_from_sandbox(sandbox, platform)
|
99
76
|
end
|
100
77
|
|
101
78
|
# Taken from RubyGems 1.3.7
|
@@ -134,5 +111,74 @@ module Pod
|
|
134
111
|
end
|
135
112
|
end
|
136
113
|
|
114
|
+
module ExternalSources
|
115
|
+
def self.from_params(name, params)
|
116
|
+
if params.key?(:git)
|
117
|
+
GitSource.new(name, params)
|
118
|
+
elsif params.key?(:podspec)
|
119
|
+
PodspecSource.new(name, params)
|
120
|
+
else
|
121
|
+
raise Informative, "Unknown external source parameters for #{name}: #{params}"
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
class AbstractExternalSource
|
126
|
+
include Config::Mixin
|
127
|
+
|
128
|
+
attr_reader :name, :params
|
129
|
+
|
130
|
+
def initialize(name, params)
|
131
|
+
@name, @params = name, params
|
132
|
+
end
|
133
|
+
|
134
|
+
def specification_from_sandbox(sandbox, platform)
|
135
|
+
if local_pod = sandbox.installed_pod_named(name, platform)
|
136
|
+
local_pod.top_specification
|
137
|
+
else
|
138
|
+
copy_external_source_into_sandbox(sandbox)
|
139
|
+
local_pod = sandbox.installed_pod_named(name, platform)
|
140
|
+
local_pod.clean if config.clean? && local_pod.exists?
|
141
|
+
local_pod.top_specification
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def ==(other_source)
|
146
|
+
return if other_source.nil?
|
147
|
+
name == other_source.name && params == other_source.params
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
class GitSource < AbstractExternalSource
|
152
|
+
def copy_external_source_into_sandbox(sandbox)
|
153
|
+
puts " * Pre-downloading: '#{name}'" unless config.silent?
|
154
|
+
Downloader.for_target(sandbox.root + name, @params).tap do |downloader|
|
155
|
+
downloader.download
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
def description
|
160
|
+
"from `#{@params[:git]}'".tap do |description|
|
161
|
+
description << ", commit `#{@params[:commit]}'" if @params[:commit]
|
162
|
+
description << ", tag `#{@params[:tag]}'" if @params[:tag]
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
# can be http, file, etc
|
168
|
+
class PodspecSource < AbstractExternalSource
|
169
|
+
def copy_external_source_into_sandbox(sandbox)
|
170
|
+
output_path = sandbox.root + "Local Podspecs/#{name}.podspec"
|
171
|
+
output_path.dirname.mkpath
|
172
|
+
puts " * Fetching podspec for `#{name}' from: #{@params[:podspec]}" unless config.silent?
|
173
|
+
open(@params[:podspec]) do |io|
|
174
|
+
output_path.open('w') { |f| f << io.read }
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
def description
|
179
|
+
"from `#{@params[:podspec]}'"
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
137
183
|
end
|
138
184
|
end
|
data/lib/cocoapods/downloader.rb
CHANGED
@@ -1,34 +1,46 @@
|
|
1
|
+
require 'uri'
|
2
|
+
|
1
3
|
module Pod
|
2
4
|
class Downloader
|
3
5
|
autoload :Git, 'cocoapods/downloader/git'
|
6
|
+
autoload :GitHub, 'cocoapods/downloader/git'
|
4
7
|
autoload :Mercurial, 'cocoapods/downloader/mercurial'
|
5
8
|
autoload :Subversion, 'cocoapods/downloader/subversion'
|
9
|
+
autoload :Http, 'cocoapods/downloader/http'
|
6
10
|
|
7
11
|
extend Executable
|
8
12
|
|
9
|
-
def self.
|
10
|
-
|
11
|
-
|
12
|
-
Git.new(pod_root, url, options)
|
13
|
-
elsif url = options.delete(:hg)
|
14
|
-
Mercurial.new(pod_root, url, options)
|
15
|
-
elsif url = options.delete(:svn)
|
16
|
-
Subversion.new(pod_root, url, options)
|
17
|
-
else
|
18
|
-
raise "Unsupported download strategy `#{source.inspect}'."
|
19
|
-
end
|
13
|
+
def self.for_pod(pod)
|
14
|
+
spec = pod.top_specification
|
15
|
+
for_target(pod.root, spec.source.dup)
|
20
16
|
end
|
21
17
|
|
22
|
-
attr_reader :
|
18
|
+
attr_reader :target_path, :url, :options
|
23
19
|
|
24
|
-
def initialize(
|
25
|
-
@
|
20
|
+
def initialize(target_path, url, options)
|
21
|
+
@target_path, @url, @options = target_path, url, options
|
22
|
+
@target_path.mkpath
|
26
23
|
end
|
27
24
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
25
|
+
private
|
26
|
+
|
27
|
+
def self.for_target(target_path, options)
|
28
|
+
options = options.dup
|
29
|
+
if url = options.delete(:git)
|
30
|
+
if url.to_s =~ /github.com/
|
31
|
+
GitHub.new(target_path, url, options)
|
32
|
+
else
|
33
|
+
Git.new(target_path, url, options)
|
34
|
+
end
|
35
|
+
elsif url = options.delete(:hg)
|
36
|
+
Mercurial.new(target_path, url, options)
|
37
|
+
elsif url = options.delete(:svn)
|
38
|
+
Subversion.new(target_path, url, options)
|
39
|
+
elsif url = options.delete(:http)
|
40
|
+
Http.new(target_path, url, options)
|
41
|
+
else
|
42
|
+
raise "Unsupported download strategy `#{options.inspect}'."
|
43
|
+
end
|
32
44
|
end
|
33
45
|
end
|
34
46
|
end
|
@@ -1,46 +1,156 @@
|
|
1
|
+
require 'open-uri'
|
2
|
+
require 'tempfile'
|
3
|
+
require 'zlib'
|
4
|
+
require 'digest/sha1'
|
5
|
+
|
1
6
|
module Pod
|
2
7
|
class Downloader
|
3
8
|
class Git < Downloader
|
9
|
+
include Config::Mixin
|
4
10
|
executable :git
|
5
11
|
|
12
|
+
MAX_CACHE_SIZE = 500
|
13
|
+
|
6
14
|
def download
|
7
|
-
|
8
|
-
if
|
15
|
+
create_cache unless cache_exist?
|
16
|
+
puts '-> Cloning git repo' if config.verbose?
|
17
|
+
if options[:tag]
|
9
18
|
download_tag
|
10
|
-
elsif
|
19
|
+
elsif options[:commit]
|
11
20
|
download_commit
|
12
21
|
else
|
13
22
|
download_head
|
14
23
|
end
|
24
|
+
removed_cached_repos_if_needed
|
25
|
+
end
|
26
|
+
|
27
|
+
def create_cache
|
28
|
+
puts "-> Creating cache git repo (#{cache_path})" if config.verbose?
|
29
|
+
cache_path.rmtree if cache_path.exist?
|
30
|
+
cache_path.mkpath
|
31
|
+
git "clone '#{url}' #{cache_path}"
|
32
|
+
end
|
33
|
+
|
34
|
+
def removed_cached_repos_if_needed
|
35
|
+
return unless caches_dir.exist?
|
36
|
+
Dir.chdir(caches_dir) do
|
37
|
+
repos = Pathname.new(caches_dir).children.select { |c| c.directory? }.sort_by(&:ctime)
|
38
|
+
while caches_size >= MAX_CACHE_SIZE && !repos.empty?
|
39
|
+
dir = repos.shift
|
40
|
+
puts '->'.yellow << " Removing git cache for `#{origin_url(dir)}'" if config.verbose?
|
41
|
+
dir.rmtree
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def cache_path
|
47
|
+
@cache_path ||= caches_dir + "#{Digest::SHA1.hexdigest(url.to_s)}"
|
48
|
+
end
|
49
|
+
|
50
|
+
def cache_exist?
|
51
|
+
cache_path.exist? && origin_url(cache_path).to_s == url.to_s
|
52
|
+
end
|
53
|
+
|
54
|
+
def origin_url(dir)
|
55
|
+
Dir.chdir(dir) { `git config remote.origin.url`.chomp }
|
56
|
+
end
|
57
|
+
|
58
|
+
def caches_dir
|
59
|
+
Pathname.new(File.expand_path("~/Library/Caches/CocoaPods/Git"))
|
60
|
+
end
|
61
|
+
|
62
|
+
def clone_url
|
63
|
+
cache_path
|
64
|
+
end
|
65
|
+
|
66
|
+
def caches_size
|
67
|
+
# expressed in Mb
|
68
|
+
`du -cm`.split("\n").last.to_i
|
69
|
+
end
|
70
|
+
|
71
|
+
def update_cache
|
72
|
+
puts "-> Updating cache git repo (#{cache_path})" if config.verbose?
|
73
|
+
Dir.chdir(cache_path) do
|
74
|
+
git "reset --hard HEAD"
|
75
|
+
git "clean -d -x -f"
|
76
|
+
git "pull"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def ref_exists?(ref)
|
81
|
+
Dir.chdir(cache_path) { git "rev-list --max-count=1 #{ref}" }
|
82
|
+
$? == 0
|
83
|
+
end
|
84
|
+
|
85
|
+
def ensure_ref_exists(ref)
|
86
|
+
return if ref_exists?(ref)
|
87
|
+
# Skip pull if not needed
|
88
|
+
update_cache
|
89
|
+
raise Informative, "[!] Cache unable to find git reference `#{ref}' for `#{url}'.".red unless ref_exists?(ref)
|
15
90
|
end
|
16
91
|
|
17
92
|
def download_head
|
18
|
-
|
93
|
+
update_cache
|
94
|
+
git "clone '#{clone_url}' '#{target_path}'"
|
19
95
|
end
|
20
96
|
|
21
97
|
def download_tag
|
22
|
-
|
23
|
-
Dir.chdir(
|
98
|
+
ensure_ref_exists(options[:tag])
|
99
|
+
Dir.chdir(target_path) do
|
24
100
|
git "init"
|
25
|
-
git "remote add origin '#{
|
26
|
-
git "fetch origin tags/#{
|
101
|
+
git "remote add origin '#{clone_url}'"
|
102
|
+
git "fetch origin tags/#{options[:tag]}"
|
27
103
|
git "reset --hard FETCH_HEAD"
|
28
104
|
git "checkout -b activated-pod-commit"
|
29
105
|
end
|
30
106
|
end
|
31
107
|
|
32
108
|
def download_commit
|
33
|
-
|
34
|
-
|
35
|
-
|
109
|
+
ensure_ref_exists(options[:commit])
|
110
|
+
git "clone '#{clone_url}' '#{target_path}'"
|
111
|
+
Dir.chdir(target_path) do
|
112
|
+
git "checkout -b activated-pod-commit #{options[:commit]}"
|
36
113
|
end
|
37
114
|
end
|
115
|
+
end
|
116
|
+
|
117
|
+
class GitHub < Git
|
118
|
+
def download_head
|
119
|
+
download_only? ? download_and_extract_tarball('master') : super
|
120
|
+
end
|
121
|
+
|
122
|
+
def download_tag
|
123
|
+
download_only? ? download_and_extract_tarball(options[:tag]) : super
|
124
|
+
end
|
38
125
|
|
39
|
-
def
|
40
|
-
super
|
41
|
-
|
126
|
+
def download_commit
|
127
|
+
download_only? ? download_and_extract_tarball(options[:commit]) : super
|
128
|
+
end
|
129
|
+
|
130
|
+
def tarball_url_for(id)
|
131
|
+
original_url, username, reponame = *(url.match(/[:\/]([\w\-]+)\/([\w\-]+)\.git/).to_a)
|
132
|
+
"https://github.com/#{username}/#{reponame}/tarball/#{id}"
|
133
|
+
end
|
134
|
+
|
135
|
+
def tmp_path
|
136
|
+
target_path + "tarball.tar.gz"
|
137
|
+
end
|
138
|
+
|
139
|
+
private
|
140
|
+
|
141
|
+
def download_only?
|
142
|
+
@options[:download_only]
|
143
|
+
end
|
144
|
+
|
145
|
+
def download_and_extract_tarball(id)
|
146
|
+
File.open(tmp_path, "w+") do |tmpfile|
|
147
|
+
open tarball_url_for(id) do |archive|
|
148
|
+
tmpfile.write Zlib::GzipReader.new(archive).read
|
149
|
+
end
|
150
|
+
|
151
|
+
system "tar xf #{tmpfile.path} -C #{target_path} --strip-components 1"
|
152
|
+
end
|
42
153
|
end
|
43
154
|
end
|
44
155
|
end
|
45
156
|
end
|
46
|
-
|