cocoapods-RepoPush 0.0.1

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 2bfba2ecc2a8e1eb548d5b35160df9873cff5460fdc74ffd52f6d8515a509c1a
4
+ data.tar.gz: 83571b9389d5199fda6c5591162769c1e99fa1ef41a68ba75886b4f8f56d6090
5
+ SHA512:
6
+ metadata.gz: f2000255490dafd9aa7e1c2bb8296310207a2409be8bf0748991b051fd57b67969cf7a9ee0bc846f03bd705baa96c1102a9f05ea4bb873c8b413c6250d2a818c
7
+ data.tar.gz: b80e3526ee455e5585fe8ea5764d1362f42758fd959bbb0d89f58c699540ade74e1573df5dd5e76bee422471b825437a2146020a1957574b28771eebe727c6b6
@@ -0,0 +1 @@
1
+ require 'cocoapods-RepoPush/gem_version'
@@ -0,0 +1 @@
1
+ require 'cocoapods-RepoPush/command/RepoPush'
@@ -0,0 +1,324 @@
1
+ require 'tempfile'
2
+ require 'fileutils'
3
+ require 'active_support/core_ext/string/inflections'
4
+
5
+ module Pod
6
+ class Command
7
+ # This is an example of a cocoapods plugin adding a top-level subcommand
8
+ # to the 'pod' command.
9
+ #
10
+ # You can also create subcommands of existing or new commands. Say you
11
+ # wanted to add a subcommand to `list` to show newly deprecated pods,
12
+ # (e.g. `pod list deprecated`), there are a few things that would need
13
+ # to change.
14
+ #
15
+ # - move this file to `lib/pod/command/list/deprecated.rb` and update
16
+ # the class to exist in the the Pod::Command::List namespace
17
+ # - change this class to extend from `List` instead of `Command`. This
18
+ # tells the plugin system that it is a subcommand of `list`.
19
+ # - edit `lib/cocoapods_plugins.rb` to require this file
20
+ #
21
+ # @todo Create a PR to add your plugin to CocoaPods/cocoapods.org
22
+ # in the `plugins.json` file, once your plugin is released.
23
+ #
24
+ class Repopush < Command
25
+ self.summary = 'Push new specifications to a spec-repo'
26
+
27
+ self.description = <<-DESC
28
+ Validates `NAME.podspec` or `*.podspec` in the current working dir,
29
+ creates a directory and version folder for the pod in the local copy of
30
+ `REPO` (#{Config.instance.repos_dir}/[REPO]), copies the podspec file into the
31
+ version directory, and finally it pushes `REPO` to its remote.
32
+ DESC
33
+
34
+ self.arguments = [
35
+ CLAide::Argument.new('REPO', true),
36
+ CLAide::Argument.new('NAME.podspec', false),
37
+ ]
38
+
39
+ def self.options
40
+ [
41
+ ['--quick', 'Lint skips checks that would require to download and build the spec'],
42
+ ['--allow-warnings', 'Allows pushing even if there are warnings'],
43
+ ['--use-libraries', 'Linter uses static libraries to install the spec'],
44
+ ['--use-modular-headers', 'Lint uses modular headers during installation'],
45
+ ["--sources=#{Pod::TrunkSource::TRUNK_REPO_URL}", 'The sources from which to pull dependent pods ' \
46
+ '(defaults to all available repos). Multiple sources must be comma-delimited'],
47
+ ['--local-only', 'Does not perform the step of pushing REPO to its remote'],
48
+ ['--no-private', 'Lint includes checks that apply only to public repos'],
49
+ ['--skip-import-validation', 'Lint skips validating that the pod can be imported'],
50
+ ['--skip-tests', 'Lint skips building and running tests during validation'],
51
+ ['--commit-message="Fix bug in pod"', 'Add custom commit message. Opens default editor if no commit ' \
52
+ 'message is specified'],
53
+ ['--use-json', 'Convert the podspec to JSON before pushing it to the repo'],
54
+ ['--swift-version=VERSION', 'The `SWIFT_VERSION` that should be used when linting the spec. ' \
55
+ 'This takes precedence over the Swift versions specified by the spec or a `.swift-version` file'],
56
+ ['--no-overwrite', 'Disallow pushing that would overwrite an existing spec'],
57
+ ['--update-sources', 'Make sure sources are up-to-date before a push'],
58
+ ].concat(super)
59
+ end
60
+
61
+ def initialize(argv)
62
+ @quick = argv.flag?('quick')
63
+ @allow_warnings = argv.flag?('allow-warnings')
64
+ @local_only = argv.flag?('local-only')
65
+ @repo = argv.shift_argument
66
+ @source = source_for_repo
67
+ @source_urls = argv.option('sources', config.sources_manager.all.map(&:url).append(Pod::TrunkSource::TRUNK_REPO_URL).uniq.join(',')).split(',')
68
+ @update_sources = argv.flag?('update-sources')
69
+ @podspec = argv.shift_argument
70
+ @use_frameworks = !argv.flag?('use-libraries')
71
+ @use_modular_headers = argv.flag?('use-modular-headers', false)
72
+ @private = argv.flag?('private', true)
73
+ @message = argv.option('commit-message')
74
+ @commit_message = argv.flag?('commit-message', false)
75
+ @use_json = argv.flag?('use-json')
76
+ @swift_version = argv.option('swift-version', nil)
77
+ @skip_import_validation = argv.flag?('skip-import-validation', false)
78
+ @skip_tests = argv.flag?('skip-tests', false)
79
+ @allow_overwrite = argv.flag?('overwrite', true)
80
+ super
81
+ end
82
+
83
+ def validate!
84
+ super
85
+ help! 'A spec-repo name or url is required.' unless @repo
86
+ unless @source && @source.repo.directory?
87
+ raise Informative,
88
+ "Unable to find the `#{@repo}` repo. " \
89
+ 'If it has not yet been cloned, add it via `pod repo add`.'
90
+ end
91
+ end
92
+
93
+ def run
94
+ open_editor if @commit_message && @message.nil?
95
+ check_if_push_allowed
96
+ update_sources if @update_sources
97
+ validate_podspec_files
98
+ check_repo_status
99
+ update_repo
100
+ add_specs_to_repo
101
+ push_repo unless @local_only
102
+ end
103
+
104
+ #---------------------------------------------------------------------#
105
+ private
106
+
107
+ # @!group Push sub-steps
108
+
109
+ extend Executable
110
+ executable :git
111
+
112
+ # Open default editor to allow users to enter commit message
113
+ #
114
+ def open_editor
115
+ return if ENV['EDITOR'].nil?
116
+
117
+ file = Tempfile.new('cocoapods')
118
+ File.chmod(0777, file.path)
119
+ file.close
120
+
121
+ system("#{ENV['EDITOR']} #{file.path}")
122
+ @message = File.read file.path
123
+ end
124
+
125
+ # Temporary check to ensure that users do not push accidentally private
126
+ # specs to the master repo.
127
+ #
128
+ def check_if_push_allowed
129
+ if @source.is_a?(CDNSource)
130
+ raise Informative, 'Cannot push to a CDN source, as it is read-only.'
131
+ end
132
+
133
+ remotes, = Executable.capture_command('git', %w(remote --verbose), :capture => :merge, :chdir => repo_dir)
134
+ master_repo_urls = [
135
+ 'git@github.com:CocoaPods/Specs.git',
136
+ 'https://github.com/CocoaPods/Specs.git',
137
+ ]
138
+ is_master_repo = master_repo_urls.any? do |url|
139
+ remotes.include?(url)
140
+ end
141
+
142
+ if is_master_repo
143
+ raise Informative, 'To push to the CocoaPods master repo use ' \
144
+ "the `pod trunk push` command.\n\nIf you are using a fork of " \
145
+ 'the master repo for private purposes we recommend to migrate ' \
146
+ 'to a clean private repo. To disable this check remove the ' \
147
+ 'remote pointing to the CocoaPods master repo.'
148
+ end
149
+ end
150
+
151
+ # Performs a full lint against the podspecs.
152
+ #
153
+ def validate_podspec_files
154
+ UI.puts "\nValidating #{'spec'.pluralize(count)}".yellow
155
+ podspec_files.each do |podspec|
156
+ validator = Validator.new(podspec, @source_urls)
157
+ validator.quick = @quick
158
+ validator.allow_warnings = @allow_warnings
159
+ validator.use_frameworks = @use_frameworks
160
+ validator.use_modular_headers = @use_modular_headers
161
+ validator.ignore_public_only_results = @private
162
+ validator.swift_version = @swift_version
163
+ validator.skip_import_validation = @skip_import_validation
164
+ validator.skip_tests = @skip_tests
165
+ begin
166
+ validator.validate
167
+ rescue => e
168
+ raise Informative, "The `#{podspec}` specification does not validate." \
169
+ "\n\n#{e.message}"
170
+ end
171
+ raise Informative, "The `#{podspec}` specification does not validate." unless validator.validated?
172
+ end
173
+ end
174
+
175
+ # Checks that the repo is clean.
176
+ #
177
+ # @raise If the repo is not clean.
178
+ #
179
+ # @todo Add specs for staged and unstaged files.
180
+ #
181
+ # @todo Gracefully handle the case where source is not under git
182
+ # source control.
183
+ #
184
+ # @return [void]
185
+ #
186
+ def check_repo_status
187
+ porcelain_status, = Executable.capture_command('git', %w(status --porcelain), :capture => :merge, :chdir => repo_dir)
188
+ clean = porcelain_status == ''
189
+ raise Informative, "The repo `#{@repo}` at #{UI.path repo_dir} is not clean" unless clean
190
+ end
191
+
192
+ # Updates the git repo against the remote.
193
+ #
194
+ # @return [void]
195
+ #
196
+ def update_repo
197
+ UI.puts "Updating the `#{@repo}' repo\n".yellow
198
+ git!(%W(-C #{repo_dir} pull))
199
+ end
200
+
201
+ # Update sources if present
202
+ #
203
+ # @return [void]
204
+ #
205
+ def update_sources
206
+ return if @source_urls.nil?
207
+ @source_urls.each do |source_url|
208
+ source = config.sources_manager.source_with_name_or_url(source_url)
209
+ dir = source.specs_dir
210
+ UI.puts "Updating a source at #{dir} for #{source}"
211
+ git!(%W(-C #{dir} pull))
212
+ end
213
+ end
214
+
215
+ # Commits the podspecs to the source, which should be a git repo.
216
+ #
217
+ # @note The pre commit hook of the repo is skipped as the podspecs have
218
+ # already been linted.
219
+ #
220
+ # @return [void]
221
+ #
222
+ def add_specs_to_repo
223
+ UI.puts "\nAdding the #{'spec'.pluralize(count)} to the `#{@repo}' repo\n".yellow
224
+ podspec_files.each do |spec_file|
225
+ spec = Pod::Specification.from_file(spec_file)
226
+ output_path = @source.pod_path(spec.name) + spec.version.to_s
227
+ message = if @message && !@message.empty?
228
+ @message
229
+ elsif output_path.exist?
230
+ "[Fix] #{spec}"
231
+ elsif output_path.dirname.directory?
232
+ "[Update] #{spec}"
233
+ else
234
+ "[Add] #{spec}"
235
+ end
236
+
237
+ if output_path.exist? && !@allow_overwrite
238
+ raise Informative, "#{spec} already exists and overwriting has been disabled."
239
+ end
240
+
241
+ FileUtils.mkdir_p(output_path)
242
+
243
+ if @use_json
244
+ json_file_name = "#{spec.name}.podspec.json"
245
+ json_file = File.join(output_path, json_file_name)
246
+ File.open(json_file, 'w') { |file| file.write(spec.to_pretty_json) }
247
+ else
248
+ FileUtils.cp(spec_file, output_path)
249
+ end
250
+
251
+ # only commit if modified
252
+ if repo_git('status', '--porcelain').include?(spec.name)
253
+ UI.puts " - #{message}"
254
+ repo_git('add', spec.name)
255
+ repo_git('commit', '--no-verify', '-m', message)
256
+ else
257
+ UI.puts " - [No change] #{spec}"
258
+ end
259
+ end
260
+ end
261
+
262
+ # Pushes the git repo against the remote.
263
+ #
264
+ # @return [void]
265
+ #
266
+ def push_repo
267
+ UI.puts "\nPushing the `#{@repo}' repo\n".yellow
268
+ repo_git('push', 'origin', 'HEAD')
269
+ end
270
+
271
+ #---------------------------------------------------------------------#
272
+
273
+ private
274
+
275
+ # @!group Private helpers
276
+
277
+ # @return result of calling the git! with args in repo_dir
278
+ #
279
+ def repo_git(*args)
280
+ git!(['-C', repo_dir] + args)
281
+ end
282
+
283
+ # @return [Pathname] The directory of the repository.
284
+ #
285
+ def repo_dir
286
+ @source.specs_dir
287
+ end
288
+
289
+ # @return [Array<Pathname>] The path of the specifications to push.
290
+ #
291
+ def podspec_files
292
+ if @podspec
293
+ path = Pathname(@podspec)
294
+ raise Informative, "Couldn't find #{@podspec}" unless path.exist?
295
+ [path]
296
+ else
297
+ files = Pathname.glob('*.podspec{,.json}')
298
+ raise Informative, "Couldn't find any podspec files in current directory" if files.empty?
299
+ files
300
+ end
301
+ end
302
+
303
+ # @return [Integer] The number of the podspec files to push.
304
+ #
305
+ def count
306
+ podspec_files.count
307
+ end
308
+
309
+ # Returns source for @repo
310
+ #
311
+ # @note If URL is invalid or repo doesn't exist, validate! will throw the error
312
+ #
313
+ # @return [Source]
314
+ #
315
+ def source_for_repo
316
+ config.sources_manager.source_with_name_or_url(@repo) unless @repo.nil?
317
+ rescue
318
+ nil
319
+ end
320
+
321
+ #---------------------------------------------------------------------#
322
+ end
323
+ end
324
+ end
@@ -0,0 +1,3 @@
1
+ module CocoapodsRepopush
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1 @@
1
+ require 'cocoapods-RepoPush/command'
metadata ADDED
@@ -0,0 +1,76 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cocoapods-RepoPush
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - klone
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-01-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: A short description of cocoapods-RepoPush.
42
+ email:
43
+ - zhanglongqing@shizhuang-inc.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - lib/cocoapods-RepoPush.rb
49
+ - lib/cocoapods-RepoPush/command.rb
50
+ - lib/cocoapods-RepoPush/command/RepoPush.rb
51
+ - lib/cocoapods-RepoPush/gem_version.rb
52
+ - lib/cocoapods_plugin.rb
53
+ homepage: https://github.com/EXAMPLE/cocoapods-RepoPush
54
+ licenses:
55
+ - MIT
56
+ metadata: {}
57
+ post_install_message:
58
+ rdoc_options: []
59
+ require_paths:
60
+ - lib
61
+ required_ruby_version: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ required_rubygems_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ requirements: []
72
+ rubygems_version: 3.0.9
73
+ signing_key:
74
+ specification_version: 4
75
+ summary: A longer description of cocoapods-RepoPush.
76
+ test_files: []