cocoapods 0.36.0.beta.1 → 0.36.0.beta.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +67 -5
  3. data/bin/pod +11 -10
  4. data/bin/sandbox-pod +1 -1
  5. data/lib/cocoapods.rb +1 -1
  6. data/lib/cocoapods/command/lib.rb +0 -1
  7. data/lib/cocoapods/command/outdated.rb +1 -3
  8. data/lib/cocoapods/command/repo.rb +5 -267
  9. data/lib/cocoapods/command/repo/add.rb +53 -0
  10. data/lib/cocoapods/command/repo/lint.rb +73 -0
  11. data/lib/cocoapods/command/repo/list.rb +95 -0
  12. data/lib/cocoapods/command/repo/remove.rb +36 -0
  13. data/lib/cocoapods/command/repo/update.rb +27 -0
  14. data/lib/cocoapods/command/setup.rb +1 -1
  15. data/lib/cocoapods/command/spec.rb +5 -546
  16. data/lib/cocoapods/command/spec/cat.rb +51 -0
  17. data/lib/cocoapods/command/spec/create.rb +279 -0
  18. data/lib/cocoapods/command/spec/edit.rb +87 -0
  19. data/lib/cocoapods/command/spec/lint.rb +105 -0
  20. data/lib/cocoapods/command/spec/which.rb +43 -0
  21. data/lib/cocoapods/downloader.rb +0 -2
  22. data/lib/cocoapods/external_sources/podspec_source.rb +13 -3
  23. data/lib/cocoapods/gem_version.rb +1 -1
  24. data/lib/cocoapods/generator/copy_resources_script.rb +22 -11
  25. data/lib/cocoapods/generator/embed_frameworks_script.rb +3 -0
  26. data/lib/cocoapods/generator/header.rb +3 -3
  27. data/lib/cocoapods/generator/target_environment_header.rb +1 -1
  28. data/lib/cocoapods/generator/xcconfig/aggregate_xcconfig.rb +7 -7
  29. data/lib/cocoapods/generator/xcconfig/public_pod_xcconfig.rb +1 -1
  30. data/lib/cocoapods/hooks_manager.rb +4 -4
  31. data/lib/cocoapods/installer.rb +17 -4
  32. data/lib/cocoapods/installer/analyzer.rb +19 -12
  33. data/lib/cocoapods/installer/pod_source_installer.rb +1 -1
  34. data/lib/cocoapods/installer/target_installer.rb +1 -1
  35. data/lib/cocoapods/installer/target_installer/aggregate_target_installer.rb +9 -8
  36. data/lib/cocoapods/installer/user_project_integrator/target_integrator.rb +2 -2
  37. data/lib/cocoapods/sandbox.rb +0 -2
  38. data/lib/cocoapods/sandbox/headers_store.rb +1 -1
  39. data/lib/cocoapods/sources_manager.rb +8 -7
  40. data/lib/cocoapods/target.rb +1 -1
  41. data/lib/cocoapods/target/aggregate_target.rb +1 -0
  42. data/lib/cocoapods/target/pod_target.rb +1 -1
  43. data/lib/cocoapods/user_interface/error_report.rb +10 -0
  44. data/lib/cocoapods/validator.rb +15 -4
  45. metadata +17 -6
@@ -0,0 +1,53 @@
1
+ module Pod
2
+ class Command
3
+ class Repo < Command
4
+ class Add < Repo
5
+ self.summary = 'Add a spec repo.'
6
+
7
+ self.description = <<-DESC
8
+ Clones `URL` in the local spec-repos directory at `~/.cocoapods/repos/`. The
9
+ remote can later be referred to by `NAME`.
10
+ DESC
11
+
12
+ self.arguments = [
13
+ CLAide::Argument.new('NAME', true),
14
+ CLAide::Argument.new('URL', true),
15
+ CLAide::Argument.new('BRANCH', false),
16
+ ]
17
+
18
+ def self.options
19
+ [
20
+ ['--shallow', 'Create a shallow clone (fast clone, but no push capabilities)'],
21
+ ].concat(super)
22
+ end
23
+
24
+ def initialize(argv)
25
+ @shallow = argv.flag?('shallow', false)
26
+ @name, @url, @branch = argv.shift_argument, argv.shift_argument, argv.shift_argument
27
+ super
28
+ end
29
+
30
+ def validate!
31
+ super
32
+ unless @name && @url
33
+ help! 'Adding a repo needs a `NAME` and a `URL`.'
34
+ end
35
+ end
36
+
37
+ def run
38
+ prefix = @shallow ? 'Creating shallow clone of' : 'Cloning'
39
+ UI.section("#{prefix} spec repo `#{@name}` from `#{@url}`#{" (branch `#{@branch}`)" if @branch}") do
40
+ config.repos_dir.mkpath
41
+ Dir.chdir(config.repos_dir) do
42
+ command = "clone '#{@url}' #{@name}"
43
+ command << ' --depth=1' if @shallow
44
+ git!(command)
45
+ end
46
+ Dir.chdir(dir) { git!("checkout #{@branch}") } if @branch
47
+ SourcesManager.check_version_information(dir)
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,73 @@
1
+ module Pod
2
+ class Command
3
+ class Repo < Command
4
+ class Lint < Repo
5
+ self.summary = 'Validates all specs in a repo.'
6
+
7
+ self.description = <<-DESC
8
+ Lints the spec-repo `NAME`. If a directory is provided it is assumed
9
+ to be the root of a repo. Finally, if `NAME` is not provided this
10
+ will lint all the spec-repos known to CocoaPods.
11
+ DESC
12
+
13
+ self.arguments = [
14
+ CLAide::Argument.new(%w(NAME DIRECTORY), false),
15
+ ]
16
+
17
+ def self.options
18
+ [['--only-errors', 'Lint presents only the errors']].concat(super)
19
+ end
20
+
21
+ def initialize(argv)
22
+ @name = argv.shift_argument
23
+ @only_errors = argv.flag?('only-errors')
24
+ super
25
+ end
26
+
27
+ # @todo Part of this logic needs to be ported to cocoapods-core so web
28
+ # services can validate the repo.
29
+ #
30
+ # @todo add UI.print and enable print statements again.
31
+ #
32
+ def run
33
+ if @name
34
+ dirs = File.exist?(@name) ? [Pathname.new(@name)] : [dir]
35
+ else
36
+ dirs = config.repos_dir.children.select(&:directory?)
37
+ end
38
+ dirs.each do |dir|
39
+ SourcesManager.check_version_information(dir)
40
+ UI.puts "\nLinting spec repo `#{dir.realpath.basename}`\n".yellow
41
+
42
+ validator = Source::HealthReporter.new(dir)
43
+ validator.pre_check do |_name, _version|
44
+ UI.print '.'
45
+ end
46
+ report = validator.analyze
47
+ UI.puts
48
+ UI.puts
49
+
50
+ report.pods_by_warning.each do |message, versions_by_name|
51
+ UI.puts "-> #{message}".yellow
52
+ versions_by_name.each { |name, versions| UI.puts " - #{name} (#{versions * ', '})" }
53
+ UI.puts
54
+ end
55
+
56
+ report.pods_by_error.each do |message, versions_by_name|
57
+ UI.puts "-> #{message}".red
58
+ versions_by_name.each { |name, versions| UI.puts " - #{name} (#{versions * ', '})" }
59
+ UI.puts
60
+ end
61
+
62
+ UI.puts "Analyzed #{report.analyzed_paths.count} podspecs files.\n\n"
63
+ if report.pods_by_error.count.zero?
64
+ UI.puts 'All the specs passed validation.'.green << "\n\n"
65
+ else
66
+ raise Informative, "#{report.pods_by_error.count} podspecs failed validation."
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,95 @@
1
+ module Pod
2
+ class Command
3
+ class Repo < Command
4
+ class List < Repo
5
+ self.summary = 'List repos'
6
+
7
+ self.description = <<-DESC
8
+ List the repos from the local spec-repos directory at `~/.cocoapods/repos/.`
9
+ DESC
10
+
11
+ def self.options
12
+ [['--count-only', 'Show the total number of repos']].concat(super)
13
+ end
14
+
15
+ def initialize(argv)
16
+ @count_only = argv.flag?('count-only')
17
+ super
18
+ end
19
+
20
+ # @output Examples:
21
+ #
22
+ # master
23
+ # - type: git (origin)
24
+ # - URL: https://github.com/CocoaPods/Specs.git
25
+ # - path: /Users/lascorbe/.cocoapods/repos/master
26
+ #
27
+ # test
28
+ # - type: local copy
29
+ # - path: /Users/lascorbe/.cocoapods/repos/test
30
+ #
31
+ def run
32
+ sources = SourcesManager.all
33
+ print_sources(sources) unless @count_only
34
+ print_count_of_sources(sources)
35
+ end
36
+
37
+ private
38
+
39
+ # Pretty-prints the source at the given path.
40
+ #
41
+ # @param [String,Pathname] path
42
+ # The path of the source to be printed.
43
+ #
44
+ # @return [void]
45
+ #
46
+ def print_source_at_path(path)
47
+ Dir.chdir(path) do
48
+ if SourcesManager.git_repo?(path)
49
+ remote_name = branch_remote_name(branch_name)
50
+ if remote_name
51
+ UI.puts "- Type: git (#{remote_name})"
52
+ url = url_of_git_repo(remote_name)
53
+ UI.puts "- URL: #{url}"
54
+ else
55
+ UI.puts '- Type: git (no remote information available)'
56
+ end
57
+ else
58
+ UI.puts '- Type: local copy'
59
+ end
60
+ UI.puts "- Path: #{path}"
61
+ end
62
+ end
63
+
64
+ # Pretty-prints the given sources.
65
+ #
66
+ # @param [Array<Source>] sources
67
+ # The sources that should be printed.
68
+ #
69
+ # @return [void]
70
+ #
71
+ def print_sources(sources)
72
+ sources.each do |source|
73
+ UI.title source.name do
74
+ print_source_at_path source.repo
75
+ end
76
+ end
77
+ UI.puts "\n"
78
+ end
79
+
80
+ # Pretty-prints the number of sources.
81
+ #
82
+ # @param [Array<Source>] sources
83
+ # The sources whose count should be printed.
84
+ #
85
+ # @return [void]
86
+ #
87
+ def print_count_of_sources(sources)
88
+ number_of_repos = sources.length
89
+ repo_string = number_of_repos != 1 ? 'repos' : 'repo'
90
+ UI.puts "#{number_of_repos} #{repo_string}".green
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,36 @@
1
+ module Pod
2
+ class Command
3
+ class Repo < Command
4
+ class Remove < Repo
5
+ self.summary = 'Remove a spec repo'
6
+
7
+ self.description = <<-DESC
8
+ Deletes the remote named `NAME` from the local spec-repos directory at `~/.cocoapods/repos/.`
9
+ DESC
10
+
11
+ self.arguments = [
12
+ CLAide::Argument.new('NAME', true),
13
+ ]
14
+
15
+ def initialize(argv)
16
+ @name = argv.shift_argument
17
+ super
18
+ end
19
+
20
+ def validate!
21
+ super
22
+ help! 'Deleting a repo needs a `NAME`.' unless @name
23
+ help! "repo #{@name} does not exist" unless File.directory?(dir)
24
+ help! "You do not have permission to delete the #{@name} repository." \
25
+ 'Perhaps try prefixing this command with sudo.' unless File.writable?(dir)
26
+ end
27
+
28
+ def run
29
+ UI.section("Removing spec repo `#{@name}`") do
30
+ FileUtils.rm_rf(dir)
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,27 @@
1
+ module Pod
2
+ class Command
3
+ class Repo < Command
4
+ class Update < Repo
5
+ self.summary = 'Update a spec repo.'
6
+
7
+ self.description = <<-DESC
8
+ Updates the local clone of the spec-repo `NAME`. If `NAME` is omitted
9
+ this will update all spec-repos in `~/.cocoapods/repos`.
10
+ DESC
11
+
12
+ self.arguments = [
13
+ CLAide::Argument.new('NAME', false),
14
+ ]
15
+
16
+ def initialize(argv)
17
+ @name = argv.shift_argument
18
+ super
19
+ end
20
+
21
+ def run
22
+ SourcesManager.update(@name, true)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -41,7 +41,7 @@ module Pod
41
41
  end
42
42
  end
43
43
 
44
- UI.puts "Setup completed".green
44
+ UI.puts 'Setup completed'.green
45
45
  end
46
46
 
47
47
  #--------------------------------------#
@@ -1,6 +1,11 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  require 'active_support/core_ext/string/inflections'
4
+ require 'cocoapods/command/spec/create'
5
+ require 'cocoapods/command/spec/lint'
6
+ require 'cocoapods/command/spec/which'
7
+ require 'cocoapods/command/spec/cat'
8
+ require 'cocoapods/command/spec/edit'
4
9
 
5
10
  module Pod
6
11
  class Command
@@ -10,319 +15,6 @@ module Pod
10
15
 
11
16
  #-----------------------------------------------------------------------#
12
17
 
13
- class Create < Spec
14
- self.summary = 'Create spec file stub.'
15
-
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
20
-
21
- self.arguments = [
22
- CLAide::Argument.new(%w(NAME https://github.com/USER/REPO), false),
23
- ]
24
-
25
- def initialize(argv)
26
- @name_or_url, @url = argv.shift_argument, argv.shift_argument
27
- super
28
- end
29
-
30
- def validate!
31
- super
32
- help! 'A pod name or repo URL is required.' unless @name_or_url
33
- end
34
-
35
- def run
36
- if repo_id_match = (@url || @name_or_url).match(/github.com\/([^\/\.]*\/[^\/\.]*)\.*/)
37
- repo_id = repo_id_match[1]
38
- data = github_data_for_template(repo_id)
39
- data[:name] = @name_or_url if @url
40
- UI.puts semantic_versioning_notice(repo_id, data[:name]) if data[:version] == '0.0.1'
41
- else
42
- data = default_data_for_template(@name_or_url)
43
- end
44
- spec = spec_template(data)
45
- (Pathname.pwd + "#{data[:name]}.podspec").open('w') { |f| f << spec }
46
- UI.puts "\nSpecification created at #{data[:name]}.podspec".green
47
- end
48
- end
49
-
50
- #-----------------------------------------------------------------------#
51
-
52
- class Lint < Spec
53
- self.summary = 'Validates a spec file.'
54
-
55
- self.description = <<-DESC
56
- Validates `NAME.podspec`. If a `DIRECTORY` is provided, it validates
57
- the podspec files found, including subfolders. In case
58
- the argument is omitted, it defaults to the current working dir.
59
- DESC
60
-
61
- self.arguments = [
62
- CLAide::Argument.new(%w(NAME.podspec DIRECTORY http://PATH/NAME.podspec), false, true),
63
- ]
64
-
65
- def self.options
66
- [['--quick', 'Lint skips checks that would require to download and build the spec'],
67
- ['--allow-warnings', 'Lint validates even if warnings are present'],
68
- ['--subspec=NAME', 'Lint validates only the given subspec'],
69
- ['--no-subspecs', 'Lint skips validation of subspecs'],
70
- ['--no-clean', 'Lint leaves the build directory intact for inspection'],
71
- ['--use-frameworks', 'Lint uses frameworks to install the spec'],
72
- ['--sources=https://github.com/artsy/Specs', 'The sources from which to pull dependant pods ' \
73
- '(defaults to https://github.com/CocoaPods/Specs.git). '\
74
- 'Multiple sources must be comma-delimited.']].concat(super)
75
- end
76
-
77
- def initialize(argv)
78
- @quick = argv.flag?('quick')
79
- @allow_warnings = argv.flag?('allow-warnings')
80
- @clean = argv.flag?('clean', true)
81
- @subspecs = argv.flag?('subspecs', true)
82
- @only_subspec = argv.option('subspec')
83
- @use_frameworks = argv.flag?('use-frameworks')
84
- @source_urls = argv.option('sources', 'https://github.com/CocoaPods/Specs.git').split(',')
85
- @podspecs_paths = argv.arguments!
86
- super
87
- end
88
-
89
- def run
90
- UI.puts
91
- invalid_count = 0
92
- podspecs_to_lint.each do |podspec|
93
- validator = Validator.new(podspec, @source_urls)
94
- validator.quick = @quick
95
- validator.no_clean = !@clean
96
- validator.allow_warnings = @allow_warnings
97
- validator.no_subspecs = !@subspecs || @only_subspec
98
- validator.only_subspec = @only_subspec
99
- validator.use_frameworks = @use_frameworks
100
- validator.validate
101
- invalid_count += 1 unless validator.validated?
102
-
103
- unless @clean
104
- UI.puts "Pods project available at `#{validator.validation_dir}/Pods/Pods.xcodeproj` for inspection."
105
- UI.puts
106
- end
107
- end
108
-
109
- count = podspecs_to_lint.count
110
- UI.puts "Analyzed #{count} #{'podspec'.pluralize(count)}.\n\n"
111
- if invalid_count == 0
112
- lint_passed_message = count == 1 ? "#{podspecs_to_lint.first.basename} passed validation." : 'All the specs passed validation.'
113
- UI.puts lint_passed_message.green << "\n\n"
114
- else
115
- raise Informative, count == 1 ? 'The spec did not pass validation.' : "#{invalid_count} out of #{count} specs failed validation."
116
- end
117
- podspecs_tmp_dir.rmtree if podspecs_tmp_dir.exist?
118
- end
119
-
120
- private
121
-
122
- def podspecs_to_lint
123
- @podspecs_to_lint ||= begin
124
- files = []
125
- @podspecs_paths << '.' if @podspecs_paths.empty?
126
- @podspecs_paths.each do |path|
127
- if path =~ /https?:\/\//
128
- require 'open-uri'
129
- output_path = podspecs_tmp_dir + File.basename(path)
130
- output_path.dirname.mkpath
131
- open(path) do |io|
132
- output_path.open('w') { |f| f << io.read }
133
- end
134
- files << output_path
135
- elsif (pathname = Pathname.new(path)).directory?
136
- files += Pathname.glob(pathname + '**/*.podspec{.json,}')
137
- raise Informative, 'No specs found in the current directory.' if files.empty?
138
- else
139
- files << (pathname = Pathname.new(path))
140
- raise Informative, "Unable to find a spec named `#{path}'." unless pathname.exist? && path.include?('.podspec')
141
- end
142
- end
143
- files
144
- end
145
- end
146
-
147
- def podspecs_tmp_dir
148
- Pathname(File.join(Pathname.new('/tmp').realpath, '/CocoaPods/Lint_podspec'))
149
- end
150
- end
151
-
152
- #-----------------------------------------------------------------------#
153
-
154
- class Which < Spec
155
- self.summary = 'Prints the path of the given spec.'
156
-
157
- self.description = <<-DESC
158
- Prints the path of the .podspec file(s) whose name matches `QUERY`
159
- DESC
160
-
161
- self.arguments = [
162
- CLAide::Argument.new('QUERY', false),
163
- ]
164
-
165
- def self.options
166
- [
167
- ['--regex', 'Interpret the `QUERY` as a regular expression'],
168
- ['--show-all', 'Print all versions of the given podspec'],
169
- ].concat(super)
170
- end
171
-
172
- def initialize(argv)
173
- @use_regex = argv.flag?('regex')
174
- @show_all = argv.flag?('show-all')
175
- @query = argv.shift_argument
176
- @query = @query.gsub('.podspec', '') unless @query.nil?
177
- super
178
- end
179
-
180
- def validate!
181
- super
182
- help! 'A podspec name is required.' unless @query
183
- validate_regex!(@query) if @use_regex
184
- end
185
-
186
- def run
187
- query = @use_regex ? @query : Regexp.escape(@query)
188
- UI.puts get_path_of_spec(query, @show_all)
189
- end
190
- end
191
-
192
- #-----------------------------------------------------------------------#
193
-
194
- class Cat < Spec
195
- self.summary = 'Prints a spec file.'
196
-
197
- self.description = <<-DESC
198
- Prints the content of the podspec(s) whose name matches `QUERY` to standard output.
199
- DESC
200
-
201
- self.arguments = [
202
- CLAide::Argument.new('QUERY', false),
203
- ]
204
-
205
- def self.options
206
- [
207
- ['--regex', 'Interpret the `QUERY` as a regular expression'],
208
- ['--show-all', 'Pick from all versions of the given podspec']
209
- ].concat(super)
210
- end
211
-
212
- def initialize(argv)
213
- @use_regex = argv.flag?('regex')
214
- @show_all = argv.flag?('show-all')
215
- @query = argv.shift_argument
216
- @query = @query.gsub('.podspec', '') unless @query.nil?
217
- super
218
- end
219
-
220
- def validate!
221
- super
222
- help! 'A podspec name is required.' unless @query
223
- validate_regex!(@query) if @use_regex
224
- end
225
-
226
- def run
227
- query = @use_regex ? @query : Regexp.escape(@query)
228
- filepath = if @show_all
229
- specs = get_path_of_spec(query, @show_all).split(/\n/)
230
- index = choose_from_array(specs, "Which spec would you like to print [1-#{ specs.count }]? ")
231
- specs[index]
232
- else
233
- get_path_of_spec(query)
234
- end
235
-
236
- UI.puts File.read(filepath)
237
- end
238
- end
239
-
240
- #-----------------------------------------------------------------------#
241
-
242
- class Edit < Spec
243
- self.summary = 'Edit a spec file.'
244
-
245
- self.description = <<-DESC
246
- Opens the podspec matching `QUERY` to be edited.
247
- DESC
248
-
249
- self.arguments = [
250
- CLAide::Argument.new('QUERY', false),
251
- ]
252
-
253
- def self.options
254
- [
255
- ['--regex', 'Interpret the `QUERY` as a regular expression'],
256
- ['--show-all', 'Pick from all versions of the given podspec']
257
- ].concat(super)
258
- end
259
-
260
- def initialize(argv)
261
- @use_regex = argv.flag?('regex')
262
- @show_all = argv.flag?('show-all')
263
- @query = argv.shift_argument
264
- @query = @query.gsub('.podspec', '') unless @query.nil?
265
- super
266
- end
267
-
268
- def validate!
269
- super
270
- help! 'A podspec name is required.' unless @query
271
- validate_regex!(@query) if @use_regex
272
- end
273
-
274
- def run
275
- query = @use_regex ? @query : Regexp.escape(@query)
276
- if @show_all
277
- specs = get_path_of_spec(query, @show_all).split(/\n/)
278
- message = "Which spec would you like to edit [1-#{specs.count}]? "
279
- index = choose_from_array(specs, message)
280
- filepath = specs[index]
281
- else
282
- filepath = get_path_of_spec(query)
283
- end
284
-
285
- exec_editor(filepath.to_s) if File.exist? filepath
286
- raise Informative, "#{ filepath } doesn't exist."
287
- end
288
-
289
- # Thank you homebrew
290
- def which(cmd)
291
- dir = ENV['PATH'].split(':').find { |p| File.executable? File.join(p, cmd) }
292
- Pathname.new(File.join(dir, cmd)) unless dir.nil?
293
- end
294
-
295
- def which_editor
296
- editor = ENV['EDITOR']
297
- # If an editor wasn't set, try to pick a sane default
298
- return editor unless editor.nil?
299
-
300
- # Find Sublime Text 2
301
- return 'subl' if which 'subl'
302
- # Find Textmate
303
- return 'mate' if which 'mate'
304
- # Find # BBEdit / TextWrangler
305
- return 'edit' if which 'edit'
306
- # Default to vim
307
- return 'vim' if which 'vim'
308
-
309
- raise Informative, "Failed to open editor. Set your 'EDITOR' environment variable."
310
- end
311
-
312
- def exec_editor(*args)
313
- return if args.to_s.empty?
314
- safe_exec(which_editor, *args)
315
- end
316
-
317
- def safe_exec(cmd, *args)
318
- # This buys us proper argument quoting and evaluation
319
- # of environment variables in the cmd parameter.
320
- exec('/bin/sh', '-i', '-c', cmd + ' "$@"', '--', *args)
321
- end
322
- end
323
-
324
- #-----------------------------------------------------------------------#
325
-
326
18
  # @todo some of the following methods can probably move to one of the
327
19
  # subclasses.
328
20
 
@@ -432,239 +124,6 @@ module Pod
432
124
 
433
125
  [best_source.specification(set.name, best_version), best_source]
434
126
  end
435
-
436
- #--------------------------------------#
437
-
438
- # Templates and GitHub information retrieval for spec create
439
- #
440
- # @todo It would be nice to have a template class that accepts options
441
- # and uses the default ones if not provided.
442
- # @todo The template is outdated.
443
-
444
- def default_data_for_template(name)
445
- data = {}
446
- data[:name] = name
447
- data[:version] = '0.0.1'
448
- data[:summary] = "A short description of #{name}."
449
- data[:homepage] = "http://EXAMPLE/#{name}"
450
- data[:author_name] = `git config --get user.name`.strip
451
- data[:author_email] = `git config --get user.email`.strip
452
- data[:source_url] = "http://EXAMPLE/#{name}.git"
453
- data[:ref_type] = ':tag'
454
- data[:ref] = '0.0.1'
455
- data
456
- end
457
-
458
- def github_data_for_template(repo_id)
459
- repo = GitHub.repo(repo_id)
460
- raise Informative, "Unable to fetch data for `#{repo_id}`" unless repo
461
- user = GitHub.user(repo['owner']['login'])
462
- raise Informative, "Unable to fetch data for `#{repo['owner']['login']}`" unless user
463
- data = {}
464
-
465
- data[:name] = repo['name']
466
- data[:summary] = (repo['description'] || '').gsub(/["]/, '\"')
467
- data[:homepage] = (repo['homepage'] && !repo['homepage'].empty?) ? repo['homepage'] : repo['html_url']
468
- data[:author_name] = user['name'] || user['login']
469
- data[:author_email] = user['email'] || 'email@address.com'
470
- data[:source_url] = repo['clone_url']
471
-
472
- data.merge suggested_ref_and_version(repo)
473
- end
474
-
475
- def suggested_ref_and_version(repo)
476
- tags = GitHub.tags(repo['html_url']).map { |tag| tag['name'] }
477
- versions_tags = {}
478
- tags.each do |tag|
479
- clean_tag = tag.gsub(/^v(er)? ?/, '')
480
- versions_tags[Gem::Version.new(clean_tag)] = tag if Gem::Version.correct?(clean_tag)
481
- end
482
- version = versions_tags.keys.sort.last || '0.0.1'
483
- data = { :version => version }
484
- if version == '0.0.1'
485
- branches = GitHub.branches(repo['html_url'])
486
- master_name = repo['master_branch'] || 'master'
487
- master = branches.find { |branch| branch['name'] == master_name }
488
- raise Informative, "Unable to find any commits on the master branch for the repository `#{repo['html_url']}`" unless master
489
- data[:ref_type] = ':commit'
490
- data[:ref] = master['commit']['sha']
491
- else
492
- data[:ref_type] = ':tag'
493
- data[:ref] = versions_tags[version]
494
- end
495
- data
496
- end
497
-
498
- def spec_template(data)
499
- <<-SPEC
500
- #
501
- # Be sure to run `pod spec lint #{data[:name]}.podspec' to ensure this is a
502
- # valid spec and to remove all comments including this before submitting the spec.
503
- #
504
- # To learn more about Podspec attributes see http://docs.cocoapods.org/specification.html
505
- # To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/
506
- #
507
-
508
- Pod::Spec.new do |s|
509
-
510
- # ――― Spec Metadata ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
511
- #
512
- # These will help people to find your library, and whilst it
513
- # can feel like a chore to fill in it's definitely to your advantage. The
514
- # summary should be tweet-length, and the description more in depth.
515
- #
516
-
517
- s.name = "#{data[:name]}"
518
- s.version = "#{data[:version]}"
519
- s.summary = "#{data[:summary]}"
520
-
521
- s.description = <<-DESC
522
- A longer description of #{data[:name]} in Markdown format.
523
-
524
- * Think: Why did you write this? What is the focus? What does it do?
525
- * CocoaPods will be using this to generate tags, and improve search results.
526
- * Try to keep it short, snappy and to the point.
527
- * Finally, don't worry about the indent, CocoaPods strips it!
528
- DESC
529
-
530
- s.homepage = "#{data[:homepage]}"
531
- # s.screenshots = "www.example.com/screenshots_1.gif", "www.example.com/screenshots_2.gif"
532
-
533
-
534
- # ――― Spec License ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
535
- #
536
- # Licensing your code is important. See http://choosealicense.com for more info.
537
- # CocoaPods will detect a license file if there is a named LICENSE*
538
- # Popular ones are 'MIT', 'BSD' and 'Apache License, Version 2.0'.
539
- #
540
-
541
- s.license = "MIT (example)"
542
- # s.license = { :type => "MIT", :file => "FILE_LICENSE" }
543
-
544
-
545
- # ――― Author Metadata ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
546
- #
547
- # Specify the authors of the library, with email addresses. Email addresses
548
- # of the authors are extracted from the SCM log. E.g. $ git log. CocoaPods also
549
- # accepts just a name if you'd rather not provide an email address.
550
- #
551
- # Specify a social_media_url where others can refer to, for example a twitter
552
- # profile URL.
553
- #
554
-
555
- s.author = { "#{data[:author_name]}" => "#{data[:author_email]}" }
556
- # Or just: s.author = "#{data[:author_name]}"
557
- # s.authors = { "#{data[:author_name]}" => "#{data[:author_email]}" }
558
- # s.social_media_url = "http://twitter.com/#{data[:author_name]}"
559
-
560
- # ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
561
- #
562
- # If this Pod runs only on iOS or OS X, then specify the platform and
563
- # the deployment target. You can optionally include the target after the platform.
564
- #
565
-
566
- # s.platform = :ios
567
- # s.platform = :ios, "5.0"
568
-
569
- # When using multiple platforms
570
- # s.ios.deployment_target = "5.0"
571
- # s.osx.deployment_target = "10.7"
572
-
573
-
574
- # ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
575
- #
576
- # Specify the location from where the source should be retrieved.
577
- # Supports git, hg, bzr, svn and HTTP.
578
- #
579
-
580
- s.source = { :git => "#{data[:source_url]}", #{data[:ref_type]} => "#{data[:ref]}" }
581
-
582
-
583
- # ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
584
- #
585
- # CocoaPods is smart about how it includes source code. For source files
586
- # giving a folder will include any swift, h, m, mm, c & cpp files.
587
- # For header files it will include any header in the folder.
588
- # Not including the public_header_files will make all headers public.
589
- #
590
-
591
- s.source_files = "Classes", "Classes/**/*.{h,m}"
592
- s.exclude_files = "Classes/Exclude"
593
-
594
- # s.public_header_files = "Classes/**/*.h"
595
-
596
-
597
- # ――― Resources ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
598
- #
599
- # A list of resources included with the Pod. These are copied into the
600
- # target bundle with a build phase script. Anything else will be cleaned.
601
- # You can preserve files from being cleaned, please don't preserve
602
- # non-essential files like tests, examples and documentation.
603
- #
604
-
605
- # s.resource = "icon.png"
606
- # s.resources = "Resources/*.png"
607
-
608
- # s.preserve_paths = "FilesToSave", "MoreFilesToSave"
609
-
610
-
611
- # ――― Project Linking ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
612
- #
613
- # Link your library with frameworks, or libraries. Libraries do not include
614
- # the lib prefix of their name.
615
- #
616
-
617
- # s.framework = "SomeFramework"
618
- # s.frameworks = "SomeFramework", "AnotherFramework"
619
-
620
- # s.library = "iconv"
621
- # s.libraries = "iconv", "xml2"
622
-
623
-
624
- # ――― Project Settings ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
625
- #
626
- # If your library depends on compiler flags you can set them in the xcconfig hash
627
- # where they will only apply to your library. If you depend on other Podspecs
628
- # you can include multiple dependencies to ensure it works.
629
-
630
- # s.requires_arc = true
631
-
632
- # s.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SDKROOT)/usr/include/libxml2" }
633
- # s.dependency "JSONKit", "~> 1.4"
634
-
635
- end
636
- SPEC
637
- end
638
-
639
- def semantic_versioning_notice(repo_id, repo)
640
- <<-EOS
641
-
642
- #{'――― MARKDOWN TEMPLATE ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――'.reversed}
643
-
644
- I’ve recently added [#{repo}](https://github.com/CocoaPods/Specs/tree/master/#{repo}) to the [CocoaPods](https://github.com/CocoaPods/CocoaPods) package manager repo.
645
-
646
- CocoaPods is a tool for managing dependencies for OSX and iOS Xcode projects and provides a central repository for iOS/OSX libraries. This makes adding libraries to a project and updating them extremely easy and it will help users to resolve dependencies of the libraries they use.
647
-
648
- However, #{repo} doesn't have any version tags. I’ve added the current HEAD as version 0.0.1, but a version tag will make dependency resolution much easier.
649
-
650
- [Semantic version](http://semver.org) tags (instead of plain commit hashes/revisions) allow for [resolution of cross-dependencies](https://github.com/CocoaPods/Specs/wiki/Cross-dependencies-resolution-example).
651
-
652
- In case you didn’t know this yet; you can tag the current HEAD as, for instance, version 1.0.0, like so:
653
-
654
- ```
655
- $ git tag -a 1.0.0 -m "Tag release 1.0.0"
656
- $ git push --tags
657
- ```
658
-
659
- #{'――― TEMPLATE END ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――'.reversed}
660
-
661
- #{'[!] This repo does not appear to have semantic version tags.'.yellow}
662
-
663
- After commiting the specification, consider opening a ticket with the template displayed above:
664
- - link: https://github.com/#{repo_id}/issues/new
665
- - title: Please add semantic version tags
666
- EOS
667
- end
668
127
  end
669
128
  end
670
129
  end