cocoapods 0.16.4 → 0.17.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +108 -0
- data/README.md +3 -3
- data/bin/pod +1 -1
- data/lib/cocoapods.rb +31 -31
- data/lib/cocoapods/command.rb +62 -107
- data/lib/cocoapods/command/inter_process_communication.rb +103 -0
- data/lib/cocoapods/command/list.rb +45 -44
- data/lib/cocoapods/command/outdated.rb +28 -25
- data/lib/cocoapods/command/project.rb +90 -0
- data/lib/cocoapods/command/push.rb +50 -32
- data/lib/cocoapods/command/repo.rb +125 -155
- data/lib/cocoapods/command/search.rb +23 -12
- data/lib/cocoapods/command/setup.rb +103 -64
- data/lib/cocoapods/command/spec.rb +329 -90
- data/lib/cocoapods/config.rb +197 -44
- data/lib/cocoapods/downloader.rb +47 -34
- data/lib/cocoapods/executable.rb +98 -41
- data/lib/cocoapods/external_sources.rb +325 -0
- data/lib/cocoapods/file_list.rb +8 -1
- data/lib/cocoapods/gem_version.rb +7 -0
- data/lib/cocoapods/generator/acknowledgements.rb +71 -7
- data/lib/cocoapods/generator/acknowledgements/markdown.rb +10 -9
- data/lib/cocoapods/generator/acknowledgements/plist.rb +9 -8
- data/lib/cocoapods/generator/copy_resources_script.rb +2 -2
- data/lib/cocoapods/generator/documentation.rb +153 -37
- data/lib/cocoapods/generator/prefix_header.rb +82 -0
- data/lib/cocoapods/generator/target_header.rb +58 -0
- data/lib/cocoapods/generator/xcconfig.rb +130 -0
- data/lib/cocoapods/hooks/installer_representation.rb +123 -0
- data/lib/cocoapods/hooks/library_representation.rb +79 -0
- data/lib/cocoapods/hooks/pod_representation.rb +74 -0
- data/lib/cocoapods/installer.rb +398 -147
- data/lib/cocoapods/installer/analyzer.rb +556 -0
- data/lib/cocoapods/installer/analyzer/sandbox_analyzer.rb +253 -0
- data/lib/cocoapods/installer/file_references_installer.rb +179 -0
- data/lib/cocoapods/installer/pod_source_installer.rb +289 -0
- data/lib/cocoapods/installer/target_installer.rb +307 -112
- data/lib/cocoapods/installer/user_project_integrator.rb +140 -176
- data/lib/cocoapods/installer/user_project_integrator/target_integrator.rb +193 -0
- data/lib/cocoapods/library.rb +195 -0
- data/lib/cocoapods/open_uri.rb +16 -14
- data/lib/cocoapods/project.rb +175 -52
- data/lib/cocoapods/resolver.rb +151 -164
- data/lib/cocoapods/sandbox.rb +276 -54
- data/lib/cocoapods/sandbox/file_accessor.rb +210 -0
- data/lib/cocoapods/sandbox/headers_store.rb +96 -0
- data/lib/cocoapods/sandbox/path_list.rb +178 -0
- data/lib/cocoapods/sources_manager.rb +218 -0
- data/lib/cocoapods/user_interface.rb +82 -18
- data/lib/cocoapods/{command → user_interface}/error_report.rb +5 -5
- data/lib/cocoapods/validator.rb +379 -0
- metadata +74 -55
- data/lib/cocoapods/command/install.rb +0 -55
- data/lib/cocoapods/command/linter.rb +0 -317
- data/lib/cocoapods/command/update.rb +0 -25
- data/lib/cocoapods/dependency.rb +0 -285
- data/lib/cocoapods/downloader/git.rb +0 -276
- data/lib/cocoapods/downloader/http.rb +0 -99
- data/lib/cocoapods/downloader/mercurial.rb +0 -26
- data/lib/cocoapods/downloader/subversion.rb +0 -42
- data/lib/cocoapods/local_pod.rb +0 -620
- data/lib/cocoapods/lockfile.rb +0 -274
- data/lib/cocoapods/platform.rb +0 -127
- data/lib/cocoapods/podfile.rb +0 -551
- data/lib/cocoapods/source.rb +0 -223
- data/lib/cocoapods/specification.rb +0 -579
- data/lib/cocoapods/specification/set.rb +0 -175
- data/lib/cocoapods/specification/statistics.rb +0 -112
- data/lib/cocoapods/user_interface/ui_pod.rb +0 -130
- data/lib/cocoapods/version.rb +0 -26
@@ -1,17 +1,8 @@
|
|
1
1
|
module Pod
|
2
2
|
class Command
|
3
3
|
class List < Command
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
$ pod list
|
8
|
-
|
9
|
-
Lists all available pods.
|
10
|
-
|
11
|
-
$ pod list new
|
12
|
-
|
13
|
-
Lists the pods introduced in the master repository since the last check.}
|
14
|
-
end
|
4
|
+
self.summary = 'List pods'
|
5
|
+
self.description = 'Lists all available pods.'
|
15
6
|
|
16
7
|
def self.options
|
17
8
|
[[
|
@@ -24,51 +15,61 @@ module Pod
|
|
24
15
|
executable :git
|
25
16
|
|
26
17
|
def initialize(argv)
|
27
|
-
@update = argv.
|
28
|
-
@stats = argv.
|
29
|
-
|
30
|
-
super unless argv.empty?
|
18
|
+
@update = argv.flag?('update')
|
19
|
+
@stats = argv.flag?('stats')
|
20
|
+
super
|
31
21
|
end
|
32
22
|
|
33
|
-
def
|
34
|
-
|
23
|
+
def run
|
24
|
+
update_if_necessary!
|
25
|
+
|
26
|
+
sets = SourcesManager.all_sets
|
35
27
|
sets.each { |set| UI.pod(set, :name) }
|
36
28
|
UI.puts "\n#{sets.count} pods were found"
|
37
29
|
end
|
38
30
|
|
39
|
-
def
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
31
|
+
def update_if_necessary!
|
32
|
+
if @update && config.verbose?
|
33
|
+
UI.section("\nUpdating Spec Repositories\n".yellow) do
|
34
|
+
Repo.new(ARGV.new(["update"])).run
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
45
38
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
39
|
+
#-----------------------------------------------------------------------#
|
40
|
+
|
41
|
+
class New < List
|
42
|
+
self.summary = 'Lists pods introduced in the master spec-repo since the last check'
|
43
|
+
|
44
|
+
def run
|
45
|
+
update_if_necessary!
|
46
|
+
|
47
|
+
days = [1,2,3,5,8]
|
48
|
+
dates, groups = {}, {}
|
49
|
+
days.each {|d| dates[d] = Time.now - 60 * 60 * 24 * d}
|
50
|
+
sets = SourcesManager.all_sets
|
51
|
+
creation_dates = Specification::Set::Statistics.instance.creation_dates(sets)
|
52
|
+
|
53
|
+
sets.each do |set|
|
54
|
+
set_date = creation_dates[set.name]
|
55
|
+
days.each do |d|
|
56
|
+
if set_date >= dates[d]
|
57
|
+
groups[d] = [] unless groups[d]
|
58
|
+
groups[d] << set
|
59
|
+
break
|
60
|
+
end
|
53
61
|
end
|
54
62
|
end
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
63
|
+
days.reverse.each do |d|
|
64
|
+
sets = groups[d]
|
65
|
+
next unless sets
|
66
|
+
UI.section("\nPods added in the last #{"day".pluralize(d)}".yellow) do
|
67
|
+
sorted = sets.sort_by {|s| creation_dates[s.name]}
|
68
|
+
sorted.each { |set| UI.pod(set, (@stats ? :stats : :name)) }
|
69
|
+
end
|
62
70
|
end
|
63
71
|
end
|
64
72
|
end
|
65
|
-
|
66
|
-
def run
|
67
|
-
UI.section("\nUpdating Spec Repositories\n".yellow) do
|
68
|
-
Repo.new(ARGV.new(["update"])).run
|
69
|
-
end if @update && config.verbose?
|
70
|
-
@new ? list_new : list_all
|
71
|
-
end
|
72
73
|
end
|
73
74
|
end
|
74
75
|
end
|
@@ -1,47 +1,50 @@
|
|
1
1
|
module Pod
|
2
2
|
class Command
|
3
3
|
class Outdated < Command
|
4
|
-
|
5
|
-
%{Show outdated pods:
|
4
|
+
self.summary = 'Show outdated project dependencies'
|
6
5
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
end
|
6
|
+
self.description = <<-DESC
|
7
|
+
Shows the outdated pods in the current Podfile.lock, but only those from
|
8
|
+
spec repos, not those from local/external sources or `:head` versions.
|
9
|
+
DESC
|
12
10
|
|
13
11
|
def self.options
|
14
12
|
[["--no-update", "Skip running `pod repo update` before install"]].concat(super)
|
15
13
|
end
|
16
14
|
|
17
15
|
def initialize(argv)
|
18
|
-
config.skip_repo_update = argv.
|
19
|
-
super
|
16
|
+
config.skip_repo_update = argv.flag?('update', config.skip_repo_update)
|
17
|
+
super
|
20
18
|
end
|
21
19
|
|
20
|
+
# @todo the command report new dependencies added to the Podfile as
|
21
|
+
# updates.
|
22
|
+
# @todo fix.
|
23
|
+
#
|
22
24
|
def run
|
23
25
|
verify_podfile_exists!
|
24
26
|
verify_lockfile_exists!
|
25
27
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
specs = resolver.specs.select do |spec|
|
37
|
-
names.include?(spec.name) && !spec.version.head?
|
28
|
+
lockfile = config.lockfile
|
29
|
+
pods = lockfile.pod_names
|
30
|
+
updates = []
|
31
|
+
pods.each do |pod_name|
|
32
|
+
set = SourcesManager.search(Dependency.new(pod_name))
|
33
|
+
source_version = set.versions.first
|
34
|
+
lockfile_version = lockfile.version(pod_name)
|
35
|
+
if source_version > lockfile_version
|
36
|
+
updates << [pod_name, lockfile_version, source_version]
|
37
|
+
end
|
38
38
|
end
|
39
39
|
|
40
|
-
if
|
41
|
-
puts "No updates are available.".yellow
|
40
|
+
if updates.empty?
|
41
|
+
UI.puts "No updates are available.".yellow
|
42
42
|
else
|
43
|
-
|
44
|
-
|
43
|
+
UI.section "The following updates are available:" do
|
44
|
+
updates.each do |(name, from_version, to_version)|
|
45
|
+
UI.message "- #{name} #{from_version} -> #{to_version}"
|
46
|
+
end
|
47
|
+
end
|
45
48
|
end
|
46
49
|
end
|
47
50
|
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
module Pod
|
2
|
+
class Command
|
3
|
+
|
4
|
+
# Provides support the common behaviour of the `install` and `update`
|
5
|
+
# commands.
|
6
|
+
#
|
7
|
+
module Project
|
8
|
+
module Options
|
9
|
+
def options
|
10
|
+
[
|
11
|
+
["--no-clean", "Leave SCM dirs like `.git' and `.svn' intact after downloading"],
|
12
|
+
["--no-doc", "Skip documentation generation with appledoc"],
|
13
|
+
["--no-integrate", "Skip integration of the Pods libraries in the Xcode project(s)"],
|
14
|
+
["--no-update", "Skip running `pod repo update` before install"],
|
15
|
+
].concat(super)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.included(base)
|
20
|
+
base.extend Options
|
21
|
+
end
|
22
|
+
|
23
|
+
def initialize(argv)
|
24
|
+
config.clean = argv.flag?('clean', config.clean)
|
25
|
+
config.generate_docs = argv.flag?('doc', config.generate_docs)
|
26
|
+
config.integrate_targets = argv.flag?('integrate', config.integrate_targets)
|
27
|
+
config.skip_repo_update = !argv.flag?('update', !config.skip_repo_update)
|
28
|
+
super
|
29
|
+
end
|
30
|
+
|
31
|
+
# Runs the installer.
|
32
|
+
#
|
33
|
+
# @param [update] whether the installer should be run in update mode.
|
34
|
+
#
|
35
|
+
# @return [void]
|
36
|
+
#
|
37
|
+
def run_install_with_update(update)
|
38
|
+
installer = Installer.new(config.sandbox, config.podfile, config.lockfile)
|
39
|
+
installer.update_mode = update
|
40
|
+
installer.install!
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
#-------------------------------------------------------------------------#
|
45
|
+
|
46
|
+
class Install < Command
|
47
|
+
include Project
|
48
|
+
|
49
|
+
self.summary = 'Install project dependencies'
|
50
|
+
|
51
|
+
self.description = <<-DESC
|
52
|
+
Downloads all dependencies defined in `Podfile' and creates an Xcode
|
53
|
+
Pods library project in `./Pods'.
|
54
|
+
|
55
|
+
The Xcode project file should be specified in your `Podfile` like this:
|
56
|
+
|
57
|
+
xcodeproj 'path/to/XcodeProject'
|
58
|
+
|
59
|
+
If no xcodeproj is specified, then a search for an Xcode project will
|
60
|
+
be made. If more than one Xcode project is found, the command will
|
61
|
+
raise an error.
|
62
|
+
|
63
|
+
This will configure the project to reference the Pods static library,
|
64
|
+
add a build configuration file, and add a post build script to copy
|
65
|
+
Pod resources.
|
66
|
+
DESC
|
67
|
+
|
68
|
+
def run
|
69
|
+
verify_podfile_exists!
|
70
|
+
run_install_with_update(false)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
#-------------------------------------------------------------------------#
|
75
|
+
|
76
|
+
class Update < Command
|
77
|
+
include Project
|
78
|
+
|
79
|
+
self.summary = 'Update outdated project dependencies'
|
80
|
+
|
81
|
+
def run
|
82
|
+
verify_podfile_exists!
|
83
|
+
verify_lockfile_exists!
|
84
|
+
run_install_with_update(true)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
@@ -4,36 +4,40 @@ require 'active_support/core_ext/string/inflections'
|
|
4
4
|
module Pod
|
5
5
|
class Command
|
6
6
|
class Push < Command
|
7
|
-
|
8
|
-
%{Pushing new specifications to a spec-repo:
|
7
|
+
self.summary = 'Push new specifications to a spec-repo'
|
9
8
|
|
10
|
-
|
9
|
+
self.description = <<-DESC
|
10
|
+
Validates NAME.podspec or `*.podspec' in the current working dir, creates
|
11
|
+
a directory and version folder for the pod in the local copy of
|
12
|
+
REPO (~/.cocoapods/[REPO]), copies the podspec file into the version directory,
|
13
|
+
and finally it pushes REPO to its remote.
|
14
|
+
DESC
|
11
15
|
|
12
|
-
|
13
|
-
a directory and version folder for the pod in the local copy of
|
14
|
-
REPO (~/.cocoapods/[REPO]), copies the podspec file into the version directory,
|
15
|
-
and finally it pushes REPO to its remote.}
|
16
|
-
end
|
16
|
+
self.arguments = 'REPO [NAME.podspec]'
|
17
17
|
|
18
18
|
def self.options
|
19
19
|
[ ["--allow-warnings", "Allows to push if warnings are not evitable"],
|
20
20
|
["--local-only", "Does not perform the step of pushing REPO to its remote"] ].concat(super)
|
21
21
|
end
|
22
22
|
|
23
|
-
extend Executable
|
24
|
-
executable :git
|
25
|
-
|
26
23
|
def initialize(argv)
|
27
|
-
@allow_warnings = argv.
|
28
|
-
@local_only = argv.
|
24
|
+
@allow_warnings = argv.flag?('allow-warnings')
|
25
|
+
@local_only = argv.flag?('local-only')
|
29
26
|
@repo = argv.shift_argument
|
30
|
-
if @repo.
|
27
|
+
if @repo.nil?
|
28
|
+
@repo = "master"
|
29
|
+
elsif @repo.end_with? ".podspec"
|
31
30
|
@podspec = @repo
|
32
31
|
@repo = "master"
|
33
32
|
else
|
34
33
|
@podspec = argv.shift_argument
|
35
34
|
end
|
36
|
-
super
|
35
|
+
super
|
36
|
+
end
|
37
|
+
|
38
|
+
def validate!
|
39
|
+
super
|
40
|
+
help! "A spec-repo name is required." unless @repo
|
37
41
|
end
|
38
42
|
|
39
43
|
def run
|
@@ -44,35 +48,39 @@ module Pod
|
|
44
48
|
push_repo unless @local_only
|
45
49
|
end
|
46
50
|
|
51
|
+
#--------------------------------------#
|
52
|
+
|
47
53
|
private
|
48
54
|
|
55
|
+
extend Executable
|
56
|
+
executable :git
|
57
|
+
|
49
58
|
def update_repo
|
50
|
-
UI.puts "Updating the `#{@repo}' repo\n".yellow
|
51
|
-
# show the output of git even if not verbose
|
52
|
-
# TODO: use the `git!' and find a way to show the output in realtime.
|
59
|
+
UI.puts "Updating the `#{@repo}' repo\n".yellow
|
53
60
|
Dir.chdir(repo_dir) { UI.puts `git pull 2>&1` }
|
54
61
|
end
|
55
62
|
|
56
63
|
def push_repo
|
57
|
-
UI.puts "\nPushing the `#{@repo}' repo\n".yellow
|
64
|
+
UI.puts "\nPushing the `#{@repo}' repo\n".yellow
|
58
65
|
Dir.chdir(repo_dir) { UI.puts `git push 2>&1` }
|
59
66
|
end
|
60
67
|
|
61
68
|
def repo_dir
|
62
69
|
dir = config.repos_dir + @repo
|
63
|
-
raise Informative, "
|
70
|
+
raise Informative, "`#{@repo}` repo not found" unless dir.exist?
|
64
71
|
dir
|
65
72
|
end
|
66
73
|
|
74
|
+
# @todo: Add specs for staged and unstaged files.
|
75
|
+
#
|
67
76
|
def check_repo_status
|
68
|
-
# TODO: add specs for staged and unstaged files (tested manually)
|
69
77
|
clean = Dir.chdir(repo_dir) { `git status --porcelain 2>&1` } == ''
|
70
|
-
raise Informative, "
|
78
|
+
raise Informative, "The repo `#{@repo}` is not clean" unless clean
|
71
79
|
end
|
72
80
|
|
73
81
|
def podspec_files
|
74
82
|
files = Pathname.glob(@podspec || "*.podspec")
|
75
|
-
raise Informative, "
|
83
|
+
raise Informative, "Couldn't find any .podspec file in current directory" if files.empty?
|
76
84
|
files
|
77
85
|
end
|
78
86
|
|
@@ -83,18 +91,29 @@ module Pod
|
|
83
91
|
end
|
84
92
|
|
85
93
|
def validate_podspec_files
|
86
|
-
UI.puts "\nValidating #{'spec'.pluralize(count)}".yellow
|
87
|
-
lint_argv = ["lint"]
|
88
|
-
lint_argv << "--only-errors" if @allow_warnings
|
89
|
-
lint_argv << "--silent" if config.silent
|
90
|
-
# all_valid = true
|
94
|
+
UI.puts "\nValidating #{'spec'.pluralize(count)}".yellow
|
91
95
|
podspec_files.each do |podspec|
|
92
|
-
|
96
|
+
validator = Validator.new(podspec)
|
97
|
+
begin
|
98
|
+
validator.validate
|
99
|
+
rescue Exception => e
|
100
|
+
raise Informative, "The `#{podspec}` specification does not validate."
|
101
|
+
end
|
102
|
+
raise Informative, "The `#{podspec}` specification does not validate." unless validator.validated?
|
93
103
|
end
|
94
104
|
end
|
95
105
|
|
106
|
+
# Commits the podspecs to the source, which should be a git repo.
|
107
|
+
#
|
108
|
+
# @note The pre commit hook of the repo is skipped as the podspecs have
|
109
|
+
# already been linted.
|
110
|
+
#
|
111
|
+
# @todo Raise if the source is not under git source control.
|
112
|
+
#
|
113
|
+
# @return [void]
|
114
|
+
#
|
96
115
|
def add_specs_to_repo
|
97
|
-
UI.puts "\nAdding the #{'spec'.pluralize(count)} to the `#{@repo}' repo\n".yellow
|
116
|
+
UI.puts "\nAdding the #{'spec'.pluralize(count)} to the `#{@repo}' repo\n".yellow
|
98
117
|
podspec_files.each do |spec_file|
|
99
118
|
spec = Pod::Specification.from_file(spec_file)
|
100
119
|
output_path = File.join(repo_dir, spec.name, spec.version.to_s)
|
@@ -105,13 +124,12 @@ module Pod
|
|
105
124
|
else
|
106
125
|
message = "[Add] #{spec}"
|
107
126
|
end
|
108
|
-
UI.puts " - #{message}"
|
127
|
+
UI.puts " - #{message}"
|
109
128
|
|
110
129
|
FileUtils.mkdir_p(output_path)
|
111
130
|
FileUtils.cp(Pathname.new(spec.name+'.podspec'), output_path)
|
112
131
|
Dir.chdir(repo_dir) do
|
113
132
|
git!("add #{spec.name}")
|
114
|
-
# Bypass the pre-commit hook because we already performed validation
|
115
133
|
git!("commit --no-verify -m '#{message}'")
|
116
134
|
end
|
117
135
|
end
|
@@ -3,194 +3,164 @@ require 'fileutils'
|
|
3
3
|
module Pod
|
4
4
|
class Command
|
5
5
|
class Repo < Command
|
6
|
-
|
7
|
-
%{Managing spec-repos:
|
6
|
+
self.abstract_command = true
|
8
7
|
|
9
|
-
|
8
|
+
# @todo should not show a usage banner!
|
9
|
+
#
|
10
|
+
self.summary = 'Manage spec-repositories'
|
10
11
|
|
11
|
-
|
12
|
-
|
12
|
+
class Add < Repo
|
13
|
+
self.summary = 'Add a spec repo.'
|
13
14
|
|
14
|
-
|
15
|
+
self.description = <<-DESC
|
16
|
+
Clones `URL` in the local spec-repos directory at `~/.cocoapods`. The
|
17
|
+
remote can later be referred to by `NAME`.
|
18
|
+
DESC
|
15
19
|
|
16
|
-
|
17
|
-
this will update all spec-repos in `~/.cocoapods'.
|
20
|
+
self.arguments = 'NAME URL [BRANCH]'
|
18
21
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
lint all the spec-repos known to CocoaPods.}
|
24
|
-
end
|
25
|
-
|
26
|
-
def self.options
|
27
|
-
[["--only-errors", "Lint presents only the errors"]].concat(super)
|
28
|
-
end
|
22
|
+
def initialize(argv)
|
23
|
+
@name, @url, @branch = argv.shift_argument, argv.shift_argument, argv.shift_argument
|
24
|
+
super
|
25
|
+
end
|
29
26
|
|
30
|
-
|
31
|
-
|
27
|
+
def validate!
|
28
|
+
super
|
29
|
+
unless @name && @url
|
30
|
+
help! "Adding a repo needs a `NAME` and a `URL`."
|
31
|
+
end
|
32
|
+
end
|
32
33
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
34
|
+
def run
|
35
|
+
UI.section("Cloning spec repo `#{@name}` from `#{@url}`#{" (branch `#{@branch}`)" if @branch}") do
|
36
|
+
config.repos_dir.mkpath
|
37
|
+
Dir.chdir(config.repos_dir) { git!("clone '#{@url}' #{@name}") }
|
38
|
+
Dir.chdir(dir) { git!("checkout #{@branch}") } if @branch
|
39
|
+
SourcesManager.check_version_information(dir)
|
38
40
|
end
|
39
|
-
@branch = argv.arguments[3]
|
40
|
-
when 'update'
|
41
|
-
@name = argv.arguments[1]
|
42
|
-
when 'lint'
|
43
|
-
@name = argv.arguments[1]
|
44
|
-
@only_errors = argv.option('--only-errors')
|
45
|
-
else
|
46
|
-
super
|
47
41
|
end
|
48
42
|
end
|
49
43
|
|
50
|
-
|
51
|
-
config.repos_dir + @name
|
52
|
-
end
|
44
|
+
#-----------------------------------------------------------------------#
|
53
45
|
|
54
|
-
|
55
|
-
|
56
|
-
end
|
46
|
+
class Update < Repo
|
47
|
+
self.summary = 'Update a spec repo.'
|
57
48
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
Dir.chdir(dir) { git!("checkout #{@branch}") } if @branch
|
63
|
-
check_versions(dir)
|
64
|
-
end
|
65
|
-
end
|
49
|
+
self.description = <<-DESC
|
50
|
+
Updates the local clone of the spec-repo `NAME`. If `NAME` is omitted
|
51
|
+
this will update all spec-repos in `~/.cocoapods`.
|
52
|
+
DESC
|
66
53
|
|
67
|
-
|
68
|
-
dirs = @name ? [dir] : config.repos_dir.children.select {|c| c.directory?}
|
69
|
-
dirs.each do |dir|
|
70
|
-
UI.section "Updating spec repo `#{dir.basename}'" do
|
71
|
-
Dir.chdir(dir) do
|
72
|
-
`git rev-parse >/dev/null 2>&1`
|
73
|
-
if $?.exitstatus.zero?
|
74
|
-
git!("pull")
|
75
|
-
else
|
76
|
-
UI.message "Not a git repository"
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
80
|
-
check_versions(dir)
|
81
|
-
end
|
82
|
-
end
|
54
|
+
self.arguments = '[NAME]'
|
83
55
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
else
|
88
|
-
dirs = config.repos_dir.children.select {|c| c.directory?}
|
56
|
+
def initialize(argv)
|
57
|
+
@name = argv.shift_argument
|
58
|
+
super
|
89
59
|
end
|
90
|
-
dirs.each do |dir|
|
91
|
-
check_versions(dir)
|
92
|
-
UI.puts "\nLinting spec repo `#{dir.realpath.basename}'\n".yellow
|
93
|
-
podspecs = Pathname.glob( dir + '**/*.podspec')
|
94
|
-
invalid_count = 0
|
95
|
-
|
96
|
-
podspecs.each do |podspec|
|
97
|
-
linter = Linter.new(podspec)
|
98
|
-
linter.quick = true
|
99
|
-
linter.repo_path = dir
|
100
|
-
|
101
|
-
linter.lint
|
102
|
-
|
103
|
-
case linter.result_type
|
104
|
-
when :error
|
105
|
-
invalid_count += 1
|
106
|
-
color = :red
|
107
|
-
should_display = true
|
108
|
-
when :warning
|
109
|
-
color = :yellow
|
110
|
-
should_display = !@only_errors
|
111
|
-
end
|
112
|
-
|
113
|
-
if should_display
|
114
|
-
UI.puts " -> ".send(color) << linter.spec_name
|
115
|
-
print_messages('ERROR', linter.errors)
|
116
|
-
unless @only_errors
|
117
|
-
print_messages('WARN', linter.warnings)
|
118
|
-
print_messages('NOTE', linter.notes)
|
119
|
-
end
|
120
|
-
UI.puts unless config.silent?
|
121
|
-
end
|
122
|
-
end
|
123
|
-
UI.puts "Analyzed #{podspecs.count} podspecs files.\n\n" unless config.silent?
|
124
60
|
|
125
|
-
|
126
|
-
|
127
|
-
else
|
128
|
-
raise Informative, "#{invalid_count} podspecs failed validation."
|
129
|
-
end
|
61
|
+
def run
|
62
|
+
SourcesManager.update(@name, true)
|
130
63
|
end
|
131
64
|
end
|
132
65
|
|
133
|
-
|
134
|
-
return if config.silent?
|
135
|
-
messages.each {|msg| UI.puts " - #{type.ljust(5)} | #{msg}"}
|
136
|
-
end
|
66
|
+
#-----------------------------------------------------------------------#
|
137
67
|
|
138
|
-
|
139
|
-
|
140
|
-
unless is_compatilbe(versions)
|
141
|
-
min, max = versions['min'], versions['max']
|
142
|
-
version_msg = ( min == max ) ? min : "#{min} - #{max}"
|
143
|
-
raise Informative,
|
144
|
-
"\n[!] The `#{dir.basename.to_s}' repo requires CocoaPods #{version_msg}\n".red +
|
145
|
-
"Update Cocoapods, or checkout the appropriate tag in the repo.\n\n"
|
146
|
-
end
|
147
|
-
UI.puts "\nCocoapods #{versions['last']} is available.\n".green if has_update(versions) && config.new_version_message?
|
148
|
-
end
|
68
|
+
class Lint < Repo
|
69
|
+
self.summary = 'Validates all specs in a repo.'
|
149
70
|
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
71
|
+
self.description = <<-DESC
|
72
|
+
Lints the spec-repo `NAME`. If a directory is provided it is assumed
|
73
|
+
to be the root of a repo. Finally, if `NAME` is not provided this
|
74
|
+
will lint all the spec-repos known to CocoaPods.
|
75
|
+
DESC
|
155
76
|
|
156
|
-
|
77
|
+
self.arguments = '[ NAME | DIRECTORY ]'
|
157
78
|
|
158
|
-
|
79
|
+
def self.options
|
80
|
+
[["--only-errors", "Lint presents only the errors"]].concat(super)
|
81
|
+
end
|
159
82
|
|
160
|
-
|
161
|
-
|
162
|
-
|
83
|
+
def initialize(argv)
|
84
|
+
@name = argv.shift_argument
|
85
|
+
@only_errors = argv.flag?('only-errors')
|
86
|
+
super
|
87
|
+
end
|
163
88
|
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
89
|
+
# @todo Part of this logic needs to be ported to cocoapods-core so web
|
90
|
+
# services can validate the repo.
|
91
|
+
#
|
92
|
+
# @todo add UI.print and enable print statements again.
|
93
|
+
#
|
94
|
+
def run
|
95
|
+
if @name
|
96
|
+
dirs = File.exists?(@name) ? [ Pathname.new(@name) ] : [ dir ]
|
97
|
+
else
|
98
|
+
dirs = config.repos_dir.children.select {|c| c.directory?}
|
99
|
+
end
|
100
|
+
dirs.each do |dir|
|
101
|
+
SourcesManager.check_version_information(dir)
|
102
|
+
UI.puts "\nLinting spec repo `#{dir.realpath.basename}`\n".yellow
|
103
|
+
podspecs = Pathname.glob( dir + '**/*.podspec')
|
104
|
+
invalid_count = 0
|
105
|
+
|
106
|
+
messages_by_type = {}
|
107
|
+
podspecs.each do |podspec|
|
108
|
+
# print "\033[K -> #{podspec.relative_path_from(dir)}\r" unless config.silent?
|
109
|
+
validator = Validator.new(podspec)
|
110
|
+
validator.quick = true
|
111
|
+
validator.repo_path = dir
|
112
|
+
validator.only_errors = @only_errors
|
113
|
+
validator.disable_ui_output = true
|
114
|
+
|
115
|
+
validator.validate
|
116
|
+
invalid_count += 1 if validator.result_type == :error
|
117
|
+
unless validator.validated?
|
118
|
+
if @only_errors
|
119
|
+
results = validator.results.select { |r| r.type.to_s == "error" }
|
120
|
+
else
|
121
|
+
results = validator.results
|
122
|
+
end
|
123
|
+
sorted_results = results.sort_by { |r| [r.type.to_s, r.message] }
|
124
|
+
sorted_results.each do |result|
|
125
|
+
name = validator.spec ? validator.spec.name : podspec.relative_path_from(dir)
|
126
|
+
version = validator.spec ? validator.spec.version : 'unknown'
|
127
|
+
messages_by_type[result.type] ||= {}
|
128
|
+
messages_by_type[result.type][result.message] ||= {}
|
129
|
+
messages_by_type[result.type][result.message][name] ||= []
|
130
|
+
messages_by_type[result.type][result.message][name] << version
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
169
134
|
|
170
|
-
|
171
|
-
|
172
|
-
|
135
|
+
# print "\033[K" unless config.silent?
|
136
|
+
messages_by_type.each do |type, names_by_message|
|
137
|
+
names_by_message.each do |message, versions_by_names|
|
138
|
+
color = type == :error ? :red : :yellow
|
139
|
+
UI.puts "[#{type}] #{message}".send(color)
|
140
|
+
versions_by_names.each { |name, versions| UI.puts " - #{name} (#{versions * ', '})" }
|
141
|
+
UI.puts
|
142
|
+
end
|
143
|
+
end
|
173
144
|
|
174
|
-
|
175
|
-
min, max = versions['min'], versions['max']
|
176
|
-
supports_min = !min || bin_version >= Gem::Version.new(min)
|
177
|
-
supports_max = !max || bin_version <= Gem::Version.new(max)
|
178
|
-
supports_min && supports_max
|
179
|
-
end
|
145
|
+
UI.puts "Analyzed #{podspecs.count} podspecs files.\n\n"
|
180
146
|
|
181
|
-
|
182
|
-
|
147
|
+
if invalid_count == 0
|
148
|
+
UI.puts "All the specs passed validation.".green << "\n\n"
|
149
|
+
else
|
150
|
+
raise Informative, "#{invalid_count} podspecs failed validation."
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
183
154
|
end
|
184
155
|
|
185
|
-
|
186
|
-
last = versions['last']
|
187
|
-
last && Gem::Version.new(last) > bin_version
|
188
|
-
end
|
156
|
+
#-----------------------------------------------------------------------#
|
189
157
|
|
190
|
-
|
191
|
-
|
192
|
-
end
|
158
|
+
extend Executable
|
159
|
+
executable :git
|
193
160
|
|
161
|
+
def dir
|
162
|
+
config.repos_dir + @name
|
163
|
+
end
|
194
164
|
end
|
195
165
|
end
|
196
166
|
end
|