cocoapods 0.16.4 → 0.17.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.
- 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,15 +1,15 @@
|
|
1
1
|
module Pod
|
2
2
|
class Command
|
3
3
|
class Search < Command
|
4
|
-
|
5
|
-
%{Search pods:
|
4
|
+
self.summary = 'Search pods'
|
6
5
|
|
7
|
-
|
6
|
+
self.description = <<-DESC
|
7
|
+
Searches for pods, ignoring case, whose name matches `QUERY'. If the
|
8
|
+
`--full' option is specified, this will also search in the summary and
|
9
|
+
description of the pods.
|
10
|
+
DESC
|
8
11
|
|
9
|
-
|
10
|
-
`--full' option is specified, this will also search in the summary and
|
11
|
-
description of the pods.}
|
12
|
-
end
|
12
|
+
self.arguments = '[QUERY]'
|
13
13
|
|
14
14
|
def self.options
|
15
15
|
[[
|
@@ -19,15 +19,26 @@ module Pod
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def initialize(argv)
|
22
|
-
@full_text_search = argv.
|
23
|
-
@stats = argv.
|
22
|
+
@full_text_search = argv.flag?('full')
|
23
|
+
@stats = argv.flag?('stats')
|
24
24
|
@query = argv.shift_argument
|
25
|
-
super
|
25
|
+
super
|
26
|
+
end
|
27
|
+
|
28
|
+
def validate!
|
29
|
+
super
|
30
|
+
help! "A search query is required." unless @query
|
26
31
|
end
|
27
32
|
|
28
33
|
def run
|
29
|
-
sets =
|
30
|
-
sets.each
|
34
|
+
sets = SourcesManager.search_by_name(@query.strip, @full_text_search)
|
35
|
+
sets.each do |set|
|
36
|
+
begin
|
37
|
+
UI.pod(set, (@stats ? :stats : :normal))
|
38
|
+
rescue DSLError => e
|
39
|
+
UI.warn "Skipping `#{set.name}` because the podspec contains errors."
|
40
|
+
end
|
41
|
+
end
|
31
42
|
end
|
32
43
|
end
|
33
44
|
end
|
@@ -1,18 +1,16 @@
|
|
1
1
|
module Pod
|
2
2
|
class Command
|
3
3
|
class Setup < Command
|
4
|
-
|
5
|
-
%{Setup CocoaPods environment:
|
4
|
+
self.summary = 'Setup the CocoaPods environment'
|
6
5
|
|
7
|
-
|
6
|
+
self.description = <<-DESC
|
7
|
+
Creates a directory at `~/.cocoapods` which will hold your spec-repos.
|
8
|
+
This is where it will create a clone of the public `master` spec-repo from:
|
8
9
|
|
9
|
-
|
10
|
-
This is where it will create a clone of the public `master' spec-repo from:
|
10
|
+
https://github.com/CocoaPods/Specs
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
If the clone already exists, it will ensure that it is up-to-date.}
|
15
|
-
end
|
12
|
+
If the clone already exists, it will ensure that it is up-to-date.
|
13
|
+
DESC
|
16
14
|
|
17
15
|
def self.options
|
18
16
|
[["--push", "Use this option to enable push access once granted"]].concat(super)
|
@@ -22,89 +20,130 @@ module Pod
|
|
22
20
|
executable :git
|
23
21
|
|
24
22
|
def initialize(argv)
|
25
|
-
@push_option = argv.
|
26
|
-
super
|
23
|
+
@push_option = argv.flag?('push')
|
24
|
+
super
|
27
25
|
end
|
28
26
|
|
29
|
-
def
|
30
|
-
|
31
|
-
|
27
|
+
def run
|
28
|
+
UI.section "Setting up CocoaPods master repo" do
|
29
|
+
if master_repo_dir.exist?
|
30
|
+
set_master_repo_url
|
31
|
+
set_master_repo_branch
|
32
|
+
update_master_repo
|
33
|
+
else
|
34
|
+
add_master_repo
|
35
|
+
end
|
36
|
+
enable_pre_commit_hooks
|
37
|
+
end
|
32
38
|
|
33
|
-
|
34
|
-
|
39
|
+
access_type = push? ? "push" : "read-only"
|
40
|
+
UI.puts "Setup completed (#{access_type} access)".green
|
35
41
|
end
|
36
42
|
|
37
|
-
|
38
|
-
'git@github.com:CocoaPods/Specs.git'
|
39
|
-
end
|
43
|
+
#--------------------------------------#
|
40
44
|
|
41
|
-
|
42
|
-
if push?
|
43
|
-
read_write_url
|
44
|
-
else
|
45
|
-
read_only_url
|
46
|
-
end
|
47
|
-
end
|
45
|
+
# @!group Setup steps
|
48
46
|
|
49
|
-
|
50
|
-
|
47
|
+
# Sets the url of the master repo according to whether it is push.
|
48
|
+
#
|
49
|
+
# @return [void]
|
50
|
+
#
|
51
|
+
def set_master_repo_url
|
52
|
+
Dir.chdir(master_repo_dir) do
|
53
|
+
git("remote set-url origin '#{url}'")
|
54
|
+
end
|
51
55
|
end
|
52
56
|
|
53
|
-
|
54
|
-
|
57
|
+
# Adds the master repo from the remote.
|
58
|
+
#
|
59
|
+
# @return [void]
|
60
|
+
#
|
61
|
+
def add_master_repo
|
62
|
+
@command ||= Repo::Add.parse(['master', url, 'master']).run
|
55
63
|
end
|
56
64
|
|
57
|
-
|
58
|
-
|
65
|
+
# Updates the master repo against the remote.
|
66
|
+
#
|
67
|
+
# @return [void]
|
68
|
+
#
|
69
|
+
def update_master_repo
|
70
|
+
SourcesManager.update('master', true)
|
59
71
|
end
|
60
72
|
|
61
|
-
|
62
|
-
|
63
|
-
|
73
|
+
# Sets the repo to the master branch.
|
74
|
+
#
|
75
|
+
# @note This is not needed anymore as it was used for CocoaPods 0.6
|
76
|
+
# release candidates.
|
77
|
+
#
|
78
|
+
# @return [void]
|
79
|
+
#
|
80
|
+
def set_master_repo_branch
|
81
|
+
Dir.chdir(master_repo_dir) do
|
82
|
+
git("checkout master")
|
64
83
|
end
|
65
84
|
end
|
66
85
|
|
67
|
-
|
68
|
-
|
69
|
-
|
86
|
+
# Enables the pre-commit hook of the master repo.
|
87
|
+
#
|
88
|
+
# @note The hook is enabled in this way because the specs run with the
|
89
|
+
# master repo as a submodule.
|
90
|
+
#
|
91
|
+
# @return [void]
|
92
|
+
#
|
93
|
+
def enable_pre_commit_hooks
|
94
|
+
if (master_repo_dir + '.git/hooks').exist?
|
95
|
+
hook = master_repo_dir + '.git/hooks/pre-commit'
|
96
|
+
hook.open('w') { |f| f << "#!/bin/sh\nrake lint" }
|
97
|
+
`chmod +x '#{hook}'`
|
70
98
|
end
|
71
99
|
end
|
72
100
|
|
73
|
-
|
74
|
-
|
101
|
+
#--------------------------------------#
|
102
|
+
|
103
|
+
# @!group Private helpers
|
104
|
+
|
105
|
+
# @return [String] the url to use according to whether push mode should
|
106
|
+
# be enabled.
|
107
|
+
#
|
108
|
+
def url
|
109
|
+
url = (push?) ? read_write_url : read_only_url
|
75
110
|
end
|
76
111
|
|
77
|
-
|
78
|
-
|
112
|
+
# @return [String] the read only url of the master repo.
|
113
|
+
#
|
114
|
+
def read_only_url
|
115
|
+
'https://github.com/CocoaPods/Specs.git'
|
79
116
|
end
|
80
117
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
118
|
+
# @return [String] the read-write url of the master repo.
|
119
|
+
#
|
120
|
+
def read_write_url
|
121
|
+
'git@github.com:CocoaPods/Specs.git'
|
85
122
|
end
|
86
123
|
|
87
|
-
|
88
|
-
|
124
|
+
# Checks if the user asked to setup the master repo in push mode or if
|
125
|
+
# the repo was already in push mode.
|
126
|
+
#
|
127
|
+
# @return [String] whether the master repo should be set up in push mode.
|
128
|
+
#
|
129
|
+
def push?
|
130
|
+
@push ||= (@push_option || master_repo_is_push?)
|
89
131
|
end
|
90
132
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
add_master_repo
|
99
|
-
end
|
100
|
-
# Mainly so the specs run with submodule repos
|
101
|
-
if (dir + '.git/hooks').exist?
|
102
|
-
hook = dir + '.git/hooks/pre-commit'
|
103
|
-
hook.open('w') { |f| f << "#!/bin/sh\nrake lint" }
|
104
|
-
`chmod +x '#{hook}'`
|
105
|
-
end
|
133
|
+
# @return [Bool] if the master repo is already configured in push mode.
|
134
|
+
#
|
135
|
+
def master_repo_is_push?
|
136
|
+
return false unless master_repo_dir.exist?
|
137
|
+
Dir.chdir(master_repo_dir) do
|
138
|
+
url = git('config --get remote.origin.url')
|
139
|
+
url.chomp == read_write_url
|
106
140
|
end
|
107
|
-
|
141
|
+
end
|
142
|
+
|
143
|
+
# @return [Pathname] the directory of the master repo.
|
144
|
+
#
|
145
|
+
def master_repo_dir
|
146
|
+
SourcesManager.master_repo_dir
|
108
147
|
end
|
109
148
|
end
|
110
149
|
end
|
@@ -5,123 +5,356 @@ require 'active_support/core_ext/string/inflections'
|
|
5
5
|
module Pod
|
6
6
|
class Command
|
7
7
|
class Spec < Command
|
8
|
-
|
9
|
-
|
8
|
+
self.abstract_command = true
|
9
|
+
self.summary = 'Manage pod specs'
|
10
10
|
|
11
|
-
|
11
|
+
#-----------------------------------------------------------------------#
|
12
12
|
|
13
|
-
|
14
|
-
|
13
|
+
class Create < Spec
|
14
|
+
self.summary = 'Create spec file stub.'
|
15
15
|
|
16
|
-
|
16
|
+
self.description = <<-DESC
|
17
|
+
Creates a PodSpec, in the current working dir, called `NAME.podspec'.
|
18
|
+
If a GitHub url is passed the spec is prepopulated.
|
19
|
+
DESC
|
17
20
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
21
|
+
self.arguments = '[ NAME | https://github.com/USER/REPO ]'
|
22
|
+
|
23
|
+
def initialize(argv)
|
24
|
+
@name_or_url, @url = argv.shift_argument, argv.shift_argument
|
25
|
+
super
|
26
|
+
end
|
27
|
+
|
28
|
+
def validate!
|
29
|
+
super
|
30
|
+
help! "A pod name or repo URL is required." unless @name_or_url
|
31
|
+
end
|
22
32
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
33
|
+
def run
|
34
|
+
if repo_id_match = (@url || @name_or_url).match(/github.com\/([^\/\.]*\/[^\/\.]*)\.*/)
|
35
|
+
# This is to make sure Faraday doesn't warn the user about the `system_timer` gem missing.
|
36
|
+
old_warn, $-w = $-w, nil
|
37
|
+
begin
|
38
|
+
require 'faraday'
|
39
|
+
ensure
|
40
|
+
$-w = old_warn
|
41
|
+
end
|
42
|
+
require 'octokit'
|
43
|
+
|
44
|
+
repo_id = repo_id_match[1]
|
45
|
+
data = github_data_for_template(repo_id)
|
46
|
+
data[:name] = @name_or_url if @url
|
47
|
+
UI.puts semantic_versioning_notice(repo_id, data[:name]) if data[:version] == '0.0.1'
|
48
|
+
else
|
49
|
+
data = default_data_for_template(@name_or_url)
|
50
|
+
end
|
51
|
+
spec = spec_template(data)
|
52
|
+
(Pathname.pwd + "#{data[:name]}.podspec").open('w') { |f| f << spec }
|
53
|
+
UI.puts "\nSpecification created at #{data[:name]}.podspec".green
|
54
|
+
end
|
28
55
|
end
|
29
56
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
57
|
+
#-----------------------------------------------------------------------#
|
58
|
+
|
59
|
+
class Lint < Spec
|
60
|
+
self.summary = 'Validates a spec file.'
|
61
|
+
|
62
|
+
self.description = <<-DESC
|
63
|
+
Validates `NAME.podspec'. If a directory is provided it validates
|
64
|
+
the podspec files found, including subfolders. In case
|
65
|
+
the argument is omitted, it defaults to the current working dir.
|
66
|
+
DESC
|
67
|
+
|
68
|
+
self.arguments = '[ NAME.podspec | DIRECTORY | http://PATH/NAME.podspec, ... ]'
|
69
|
+
|
70
|
+
def self.options
|
71
|
+
[ ["--quick", "Lint skips checks that would require to download and build the spec"],
|
72
|
+
["--local", "Lint a podspec against the local files contained in its directory"],
|
73
|
+
["--only-errors", "Lint validates even if warnings are present"],
|
74
|
+
["--no-clean", "Lint leaves the build directory intact for inspection"] ].concat(super)
|
75
|
+
end
|
76
|
+
|
77
|
+
def initialize(argv)
|
78
|
+
@quick = argv.flag?('quick')
|
79
|
+
@local = argv.flag?('local')
|
80
|
+
@only_errors = argv.flag?('only-errors')
|
81
|
+
@clean = argv.flag?('clean', true)
|
82
|
+
@podspecs_paths = argv.arguments!
|
44
83
|
super
|
45
84
|
end
|
85
|
+
|
86
|
+
def run
|
87
|
+
UI.puts
|
88
|
+
invalid_count = 0
|
89
|
+
podspecs_to_lint.each do |podspec|
|
90
|
+
validator = Validator.new(podspec)
|
91
|
+
validator.quick = @quick
|
92
|
+
validator.local = @local
|
93
|
+
validator.no_clean = !@clean
|
94
|
+
validator.only_errors = @only_errors
|
95
|
+
validator.validate
|
96
|
+
invalid_count += 1 unless validator.validated?
|
97
|
+
|
98
|
+
unless @clean
|
99
|
+
UI.puts "Pods project available at `#{validator.validation_dir}/Pods/Pods.xcodeproj` for inspection."
|
100
|
+
UI.puts
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
count = podspecs_to_lint.count
|
105
|
+
UI.puts "Analyzed #{count} #{'podspec'.pluralize(count)}.\n\n"
|
106
|
+
if invalid_count == 0
|
107
|
+
lint_passed_message = count == 1 ? "#{podspecs_to_lint.first.basename} passed validation." : "All the specs passed validation."
|
108
|
+
UI.puts lint_passed_message.green << "\n\n"
|
109
|
+
else
|
110
|
+
raise Informative, count == 1 ? "The spec did not pass validation." : "#{invalid_count} out of #{count} specs failed validation."
|
111
|
+
end
|
112
|
+
podspecs_tmp_dir.rmtree if podspecs_tmp_dir.exist?
|
113
|
+
end
|
46
114
|
end
|
47
115
|
|
48
|
-
|
49
|
-
|
116
|
+
#-----------------------------------------------------------------------#
|
117
|
+
|
118
|
+
class Which < Spec
|
119
|
+
self.summary = 'Prints the path of the given spec.'
|
120
|
+
|
121
|
+
self.description = <<-DESC
|
122
|
+
Prints the path of 'NAME.podspec'
|
123
|
+
DESC
|
124
|
+
|
125
|
+
self.arguments = '[ NAME ]'
|
126
|
+
|
127
|
+
def self.options
|
128
|
+
[["--show-all", "Print all versions of the given podspec"]].concat(super)
|
129
|
+
end
|
130
|
+
|
131
|
+
def initialize(argv)
|
132
|
+
@show_all = argv.flag?('show-all')
|
133
|
+
@spec = argv.shift_argument
|
134
|
+
@spec = @spec.gsub('.podspec', '') unless @spec.nil?
|
135
|
+
super
|
136
|
+
end
|
137
|
+
|
138
|
+
def validate!
|
139
|
+
super
|
140
|
+
help! "A podspec name is required." unless @spec
|
141
|
+
end
|
142
|
+
|
143
|
+
def run
|
144
|
+
UI.puts get_path_of_spec(@spec, @show_all)
|
145
|
+
end
|
50
146
|
end
|
51
147
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
148
|
+
#-----------------------------------------------------------------------#
|
149
|
+
|
150
|
+
class Cat < Spec
|
151
|
+
self.summary = 'Prints a spec file.'
|
152
|
+
|
153
|
+
self.description = <<-DESC
|
154
|
+
Prints 'NAME.podspec' to standard output.
|
155
|
+
DESC
|
156
|
+
|
157
|
+
self.arguments = '[ NAME ]'
|
158
|
+
|
159
|
+
def self.options
|
160
|
+
[["--show-all", "Pick from all versions of the given podspec"]].concat(super)
|
161
|
+
end
|
162
|
+
|
163
|
+
def initialize(argv)
|
164
|
+
@show_all = argv.flag?('show-all')
|
165
|
+
@spec = argv.shift_argument
|
166
|
+
@spec = @spec.gsub('.podspec', '') unless @spec.nil?
|
167
|
+
super
|
168
|
+
end
|
169
|
+
|
170
|
+
def validate!
|
171
|
+
super
|
172
|
+
help! "A podspec name is required." unless @spec
|
173
|
+
end
|
174
|
+
|
175
|
+
def run
|
176
|
+
filepath = if @show_all
|
177
|
+
specs = get_path_of_spec(@spec, @show_all).split(/\n/)
|
178
|
+
index = choose_from_array(specs, "Which spec would you like to print [1-#{ specs.count }]? ")
|
179
|
+
specs[index]
|
180
|
+
else
|
181
|
+
get_path_of_spec(@spec)
|
60
182
|
end
|
61
|
-
require 'octokit'
|
62
183
|
|
63
|
-
|
64
|
-
data = github_data_for_template(repo_id)
|
65
|
-
data[:name] = @name_or_url if @url
|
66
|
-
UI.puts semantic_versioning_notice(repo_id, data[:name]) if data[:version] == '0.0.1'
|
67
|
-
else
|
68
|
-
data = default_data_for_template(@name_or_url)
|
184
|
+
UI.puts File.open(filepath).read
|
69
185
|
end
|
70
|
-
spec = spec_template(data)
|
71
|
-
(Pathname.pwd + "#{data[:name]}.podspec").open('w') { |f| f << spec }
|
72
|
-
UI.puts "\nSpecification created at #{data[:name]}.podspec".green
|
73
186
|
end
|
74
187
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
188
|
+
#-----------------------------------------------------------------------#
|
189
|
+
|
190
|
+
class Edit < Spec
|
191
|
+
self.summary = 'Edit a spec file.'
|
192
|
+
|
193
|
+
self.description = <<-DESC
|
194
|
+
Opens 'NAME.podspec' to be edited.
|
195
|
+
DESC
|
196
|
+
|
197
|
+
self.arguments = '[ NAME ]'
|
198
|
+
|
199
|
+
def self.options
|
200
|
+
[["--show-all", "Pick which spec to edit from all avaliable versions of the given podspec"]].concat(super)
|
201
|
+
end
|
202
|
+
|
203
|
+
def initialize(argv)
|
204
|
+
@show_all = argv.flag?('show-all')
|
205
|
+
@spec = argv.shift_argument
|
206
|
+
@spec = @spec.gsub('.podspec', '') unless @spec.nil?
|
207
|
+
super
|
208
|
+
end
|
209
|
+
|
210
|
+
def validate!
|
211
|
+
super
|
212
|
+
help! "A podspec name is required." unless @spec
|
213
|
+
end
|
214
|
+
|
215
|
+
def run
|
216
|
+
filepath = if @show_all
|
217
|
+
specs = get_path_of_spec(@spec, @show_all).split(/\n/)
|
218
|
+
index = choose_from_array(specs, "Which spec would you like to edit [1-#{ specs.count }]? ")
|
219
|
+
specs[index]
|
96
220
|
else
|
97
|
-
|
221
|
+
get_path_of_spec(@spec)
|
98
222
|
end
|
99
223
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
print_messages('WARN', linter.warnings)
|
104
|
-
print_messages('NOTE', linter.notes)
|
224
|
+
exec_editor(filepath.to_s) if File.exists? filepath
|
225
|
+
raise Informative, "#{ filepath } doesn't exist."
|
226
|
+
end
|
105
227
|
|
106
|
-
|
228
|
+
# Thank you homebrew
|
229
|
+
def which(cmd)
|
230
|
+
dir = ENV['PATH'].split(':').find { |p| File.executable? File.join(p, cmd) }
|
231
|
+
Pathname.new(File.join(dir, cmd)) unless dir.nil?
|
107
232
|
end
|
108
233
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
234
|
+
def which_editor
|
235
|
+
editor = ENV['EDITOR']
|
236
|
+
# If an editor wasn't set, try to pick a sane default
|
237
|
+
return editor unless editor.nil?
|
238
|
+
|
239
|
+
# Find Sublime Text 2
|
240
|
+
return 'subl' if which 'subl'
|
241
|
+
# Find Textmate
|
242
|
+
return 'mate' if which 'mate'
|
243
|
+
# Find # BBEdit / TextWrangler
|
244
|
+
return 'edit' if which 'edit'
|
245
|
+
# Default to vim
|
246
|
+
return 'vim' if which 'vim'
|
247
|
+
|
248
|
+
raise Informative, "Failed to open editor. Set your 'EDITOR' environment variable."
|
249
|
+
end
|
250
|
+
|
251
|
+
def exec_editor *args
|
252
|
+
return if args.to_s.empty?
|
253
|
+
safe_exec(which_editor, *args)
|
254
|
+
end
|
255
|
+
|
256
|
+
def safe_exec(cmd, *args)
|
257
|
+
# This buys us proper argument quoting and evaluation
|
258
|
+
# of environment variables in the cmd parameter.
|
259
|
+
exec "/bin/sh", "-i", "-c", cmd + ' "$@"', "--", *args
|
116
260
|
end
|
117
|
-
podspecs_tmp_dir.rmtree if podspecs_tmp_dir.exist?
|
118
261
|
end
|
119
262
|
|
263
|
+
#-----------------------------------------------------------------------#
|
264
|
+
|
265
|
+
# @todo some of the following methods can probably move to one of the
|
266
|
+
# subclasses.
|
267
|
+
|
120
268
|
private
|
121
269
|
|
122
|
-
|
123
|
-
|
124
|
-
|
270
|
+
# @return [Fixnum] the index of the chosen array item
|
271
|
+
#
|
272
|
+
def choose_from_array(array, message)
|
273
|
+
array.each_with_index do |item, index|
|
274
|
+
UI.puts "#{ index + 1 }: #{ item }"
|
275
|
+
end
|
276
|
+
|
277
|
+
print message
|
278
|
+
|
279
|
+
index = STDIN.gets.chomp.to_i - 1
|
280
|
+
if index < 0 || index > array.count
|
281
|
+
raise Informative, "#{ index + 1 } is invalid [1-#{ array.count }]"
|
282
|
+
else
|
283
|
+
index
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
287
|
+
# @param [String] spec
|
288
|
+
# The name of the specification.
|
289
|
+
#
|
290
|
+
# @param [Bool] show_all
|
291
|
+
# Whether the paths for all the versions should be returned or
|
292
|
+
# only the one for the last version.
|
293
|
+
#
|
294
|
+
# @return [Pathname] the absolute path or paths of the given podspec
|
295
|
+
#
|
296
|
+
def get_path_of_spec(spec, show_all = false)
|
297
|
+
sets = SourcesManager.search_by_name(spec)
|
298
|
+
|
299
|
+
if sets.count == 1
|
300
|
+
set = sets.first
|
301
|
+
elsif sets.map(&:name).include?(spec)
|
302
|
+
set = sets.find { |s| s.name == spec }
|
303
|
+
else
|
304
|
+
names = sets.collect(&:name) * ', '
|
305
|
+
raise Informative, "More than one spec found for '#{ spec }':\n#{ names }"
|
306
|
+
end
|
307
|
+
|
308
|
+
unless show_all
|
309
|
+
best_spec, spec_source = spec_and_source_from_set(set)
|
310
|
+
return pathname_from_spec(best_spec, spec_source)
|
311
|
+
end
|
312
|
+
|
313
|
+
return all_paths_from_set(set)
|
314
|
+
end
|
315
|
+
|
316
|
+
# @return [Pathname] the absolute path of the given spec and source
|
317
|
+
#
|
318
|
+
def pathname_from_spec(spec, source)
|
319
|
+
Pathname.new("~/.cocoapods/#{ source }/#{ spec.name }/#{ spec.version }/#{ spec.name }.podspec").expand_path
|
320
|
+
end
|
321
|
+
|
322
|
+
# @return [String] of spec paths one on each line
|
323
|
+
#
|
324
|
+
def all_paths_from_set(set)
|
325
|
+
paths = ""
|
326
|
+
|
327
|
+
sources = set.sources
|
328
|
+
|
329
|
+
sources.each do |source|
|
330
|
+
versions = source.versions(set.name)
|
331
|
+
|
332
|
+
versions.each do |version|
|
333
|
+
spec = source.specification(set.name, version)
|
334
|
+
paths += "#{ pathname_from_spec(spec, source) }\n"
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
338
|
+
paths
|
339
|
+
end
|
340
|
+
|
341
|
+
# @return [Specification, Source] the highest known specification with it's source of the given
|
342
|
+
# set.
|
343
|
+
#
|
344
|
+
def spec_and_source_from_set(set)
|
345
|
+
sources = set.sources
|
346
|
+
|
347
|
+
best_source = sources.first
|
348
|
+
best_version = best_source.versions(set.name).first
|
349
|
+
sources.each do |source|
|
350
|
+
version = source.versions(set.name).first
|
351
|
+
if version > best_version
|
352
|
+
best_source = source
|
353
|
+
best_version = version
|
354
|
+
end
|
355
|
+
end
|
356
|
+
|
357
|
+
return best_source.specification(set.name, best_version), best_source
|
125
358
|
end
|
126
359
|
|
127
360
|
def podspecs_to_lint
|
@@ -154,7 +387,13 @@ module Pod
|
|
154
387
|
Pathname.new('/tmp/CocoaPods/Lint_podspec')
|
155
388
|
end
|
156
389
|
|
157
|
-
|
390
|
+
#--------------------------------------#
|
391
|
+
|
392
|
+
# Templates and github information retrieval for spec create
|
393
|
+
#
|
394
|
+
# @todo It would be nice to have a template class that accepts options
|
395
|
+
# and uses the default ones if not provided.
|
396
|
+
# @todo The template is outdated.
|
158
397
|
|
159
398
|
def default_data_for_template(name)
|
160
399
|
data = {}
|
@@ -230,7 +469,7 @@ Pod::Spec.new do |s|
|
|
230
469
|
s.homepage = "#{data[:homepage]}"
|
231
470
|
|
232
471
|
# Specify the license type. CocoaPods detects automatically the license file if it is named
|
233
|
-
#
|
472
|
+
# 'LICENCE*.*' or 'LICENSE*.*', however if the name is different, specify it.
|
234
473
|
s.license = 'MIT (example)'
|
235
474
|
# s.license = { :type => 'MIT (example)', :file => 'FILE_LICENSE' }
|
236
475
|
#
|