cocoapods-sync-podspecs 0.1.0

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