cocoapods-publish 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 0be0019880f934bef106db34384a5762f5b4426697ab70b559f1f89e1b45ed2b
4
+ data.tar.gz: 25c491ca2bd69963e2b1228857a81fd5e430c4649c33f548d34beff7ccb9f341
5
+ SHA512:
6
+ metadata.gz: 445fef65083834d5ac291ffc858e18a7d9799c96a0d5a44280b43d95873c5595b77c17ffb1e27d58b219e37249b0b199bae050801367f51bc01bbd60bfd28617
7
+ data.tar.gz: '0191e9af3e1ea0953000e6a24fc8171e3d7bd44e793ca5c807e437aa4aac9e7377a1e30463bedde8708cb4221756a729f43fd67e67c69981fd91db2aaa22cbd6'
@@ -0,0 +1,29 @@
1
+ name: Ruby Gem
2
+
3
+ on:
4
+ push:
5
+ branches: [ stable ]
6
+
7
+ jobs:
8
+ build:
9
+ name: Build + Publish
10
+ runs-on: ubuntu-latest
11
+
12
+ steps:
13
+ - uses: actions/checkout@v2
14
+ - name: Set up Ruby 2.6
15
+ uses: actions/setup-ruby@v1
16
+ with:
17
+ version: 2.6.x
18
+
19
+ - name: Publish to GPR
20
+ run: |
21
+ mkdir -p $HOME/.gem
22
+ touch $HOME/.gem/credentials
23
+ chmod 0600 $HOME/.gem/credentials
24
+ printf -- "---\n:github: Bearer ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
25
+ gem build *.gemspec
26
+ gem push --KEY github --host https://rubygems.pkg.github.com/${OWNER} *.gem
27
+ env:
28
+ GEM_HOST_API_KEY: ${{secrets.GITHUB_TOKEN}}
29
+ OWNER: KassyLab
@@ -0,0 +1,28 @@
1
+ name: Continuous Deployment
2
+
3
+ on:
4
+ push:
5
+ branches: [ stable ]
6
+
7
+ jobs:
8
+ build:
9
+ name: Build + Publish
10
+ runs-on: ubuntu-latest
11
+
12
+ steps:
13
+ - uses: actions/checkout@v2
14
+ - name: Set up Ruby 2.6
15
+ uses: actions/setup-ruby@v1
16
+ with:
17
+ version: 2.6.x
18
+
19
+ - name: Publish to RubyGems
20
+ run: |
21
+ mkdir -p $HOME/.gem
22
+ touch $HOME/.gem/credentials
23
+ chmod 0600 $HOME/.gem/credentials
24
+ printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
25
+ gem build *.gemspec
26
+ gem push *.gem
27
+ env:
28
+ GEM_HOST_API_KEY: ${{secrets.RUBYGEMS_AUTH_TOKEN}}
@@ -0,0 +1,22 @@
1
+ name: Continuous Integration
2
+
3
+ on:
4
+ push:
5
+ branches-ignore: [ stable ]
6
+ pull_request:
7
+ branches-ignore: [ stable ]
8
+
9
+ jobs:
10
+ build:
11
+ name: Build
12
+ runs-on: ubuntu-latest
13
+
14
+ steps:
15
+ - uses: actions/checkout@v2
16
+ - name: Set up Ruby 2.6
17
+ uses: actions/setup-ruby@v1
18
+ with:
19
+ version: 2.6.x
20
+
21
+ - name: Build
22
+ run: gem build *.gemspec
data/.gitignore ADDED
@@ -0,0 +1,56 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /spec/examples.txt
9
+ /test/tmp/
10
+ /test/version_tmp/
11
+ /tmp/
12
+
13
+ # Used by dotenv library to load environment variables.
14
+ # .env
15
+
16
+ # Ignore Byebug command history file.
17
+ .byebug_history
18
+
19
+ ## Specific to RubyMotion:
20
+ .dat*
21
+ .repl_history
22
+ build/
23
+ *.bridgesupport
24
+ build-iPhoneOS/
25
+ build-iPhoneSimulator/
26
+
27
+ ## Specific to RubyMotion (use of CocoaPods):
28
+ #
29
+ # We recommend against adding the Pods directory to your .gitignore. However
30
+ # you should judge for yourself, the pros and cons are mentioned at:
31
+ # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
32
+ #
33
+ # vendor/Pods/
34
+
35
+ ## Documentation cache and generated files:
36
+ /.yardoc/
37
+ /_yardoc/
38
+ /doc/
39
+ /rdoc/
40
+
41
+ ## Environment normalization:
42
+ /.bundle/
43
+ /vendor/bundle
44
+ /lib/bundler/man/
45
+
46
+ # for a library or gem, you might want to ignore these files since the code is
47
+ # intended to run in multiple environments; otherwise, check them in:
48
+ # Gemfile.lock
49
+ # .ruby-version
50
+ # .ruby-gemset
51
+
52
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
53
+ .rvmrc
54
+
55
+ # Used by RuboCop. Remote config files pulled in from inherit_from directive.
56
+ # .rubocop-https?--*
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2020 Kassy Lab
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1 @@
1
+ # cocoapods-publish
@@ -0,0 +1,22 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'cocoapods_publish.rb'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "cocoapods-publish"
8
+ spec.version = Pod::Publish::VERSION
9
+ spec.authors = ["Damien DANGLARD"]
10
+ spec.email = ["damien.danglard@kassylab.com"]
11
+ spec.summary = %q{Publish a Podspec in a Specs repo without linting it ("pod repo push" without linting).}
12
+ spec.homepage = "https://github.com/KassyLab/cocoapods-publish"
13
+ spec.license = "MIT"
14
+
15
+ spec.files = `git ls-files`.split($/)
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_development_dependency "bundler", "~> 1.3"
21
+ spec.add_development_dependency "rake"
22
+ end
@@ -0,0 +1 @@
1
+ require 'pod/command/repo/publish'
@@ -0,0 +1,5 @@
1
+ module Pod
2
+ module Publish
3
+ VERSION = '1.0.0'
4
+ end
5
+ end
@@ -0,0 +1,291 @@
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 Publish < Repo
9
+ self.summary = 'Push new specifications to a spec-repo'
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
+ validate_podspec_files
77
+ check_repo_status
78
+ update_repo
79
+ add_specs_to_repo
80
+ push_repo unless @local_only
81
+ end
82
+
83
+ #---------------------------------------------------------------------#
84
+
85
+ private
86
+
87
+ # @!group Push sub-steps
88
+
89
+ extend Executable
90
+ executable :git
91
+
92
+ # Open default editor to allow users to enter commit message
93
+ #
94
+ def open_editor
95
+ return if ENV['EDITOR'].nil?
96
+
97
+ file = Tempfile.new('cocoapods')
98
+ File.chmod(0777, file.path)
99
+ file.close
100
+
101
+ system("#{ENV['EDITOR']} #{file.path}")
102
+ @message = File.read file.path
103
+ end
104
+
105
+ # Temporary check to ensure that users do not push accidentally private
106
+ # specs to the master repo.
107
+ #
108
+ def check_if_push_allowed
109
+ if @source.is_a?(CDNSource)
110
+ raise Informative, 'Cannot push to a CDN source, as it is read-only.'
111
+ end
112
+
113
+ remotes, = Executable.capture_command('git', %w(remote --verbose), :capture => :merge, :chdir => repo_dir)
114
+ master_repo_urls = [
115
+ 'git@github.com:CocoaPods/Specs.git',
116
+ 'https://github.com/CocoaPods/Specs.git',
117
+ ]
118
+ is_master_repo = master_repo_urls.any? do |url|
119
+ remotes.include?(url)
120
+ end
121
+
122
+ if is_master_repo
123
+ raise Informative, 'To push to the CocoaPods master repo use ' \
124
+ "the `pod trunk push` command.\n\nIf you are using a fork of " \
125
+ 'the master repo for private purposes we recommend to migrate ' \
126
+ 'to a clean private repo. To disable this check remove the ' \
127
+ 'remote pointing to the CocoaPods master repo.'
128
+ end
129
+ end
130
+
131
+ # Performs a full lint against the podspecs.
132
+ #
133
+ def validate_podspec_files
134
+ UI.puts "\nValidating #{'spec'.pluralize(count)}".yellow
135
+ podspec_files.each do |podspec|
136
+ validator = Validator.new(podspec, @source_urls)
137
+ validator.allow_warnings = @allow_warnings
138
+ validator.use_frameworks = @use_frameworks
139
+ validator.use_modular_headers = @use_modular_headers
140
+ validator.ignore_public_only_results = @private
141
+ validator.swift_version = @swift_version
142
+ validator.skip_import_validation = @skip_import_validation
143
+ validator.skip_tests = @skip_tests
144
+ validator.quick = true
145
+ begin
146
+ validator.validate
147
+ rescue => e
148
+ raise Informative, "The `#{podspec}` specification does not validate." \
149
+ "\n\n#{e.message}"
150
+ end
151
+ raise Informative, "The `#{podspec}` specification does not validate." unless validator.validated?
152
+ end
153
+ end
154
+
155
+ # Checks that the repo is clean.
156
+ #
157
+ # @raise If the repo is not clean.
158
+ #
159
+ # @todo Add specs for staged and unstaged files.
160
+ #
161
+ # @todo Gracefully handle the case where source is not under git
162
+ # source control.
163
+ #
164
+ # @return [void]
165
+ #
166
+ def check_repo_status
167
+ porcelain_status, = Executable.capture_command('git', %w(status --porcelain), :capture => :merge, :chdir => repo_dir)
168
+ clean = porcelain_status == ''
169
+ raise Informative, "The repo `#{@repo}` at #{UI.path repo_dir} is not clean" unless clean
170
+ end
171
+
172
+ # Updates the git repo against the remote.
173
+ #
174
+ # @return [void]
175
+ #
176
+ def update_repo
177
+ UI.puts "Updating the `#{@repo}' repo\n".yellow
178
+ git!(%W(-C #{repo_dir} pull))
179
+ end
180
+
181
+ # Commits the podspecs to the source, which should be a git repo.
182
+ #
183
+ # @note The pre commit hook of the repo is skipped as the podspecs have
184
+ # already been linted.
185
+ #
186
+ # @return [void]
187
+ #
188
+ def add_specs_to_repo
189
+ UI.puts "\nAdding the #{'spec'.pluralize(count)} to the `#{@repo}' repo\n".yellow
190
+ podspec_files.each do |spec_file|
191
+ spec = Pod::Specification.from_file(spec_file)
192
+ output_path = @source.pod_path(spec.name) + spec.version.to_s
193
+ message = if @message && !@message.empty?
194
+ @message
195
+ elsif output_path.exist?
196
+ "[Fix] #{spec}"
197
+ elsif output_path.dirname.directory?
198
+ "[Update] #{spec}"
199
+ else
200
+ "[Add] #{spec}"
201
+ end
202
+
203
+ if output_path.exist? && !@allow_overwrite
204
+ raise Informative, "#{spec} already exists and overwriting has been disabled."
205
+ end
206
+
207
+ FileUtils.mkdir_p(output_path)
208
+
209
+ if @use_json
210
+ json_file_name = "#{spec.name}.podspec.json"
211
+ json_file = File.join(output_path, json_file_name)
212
+ File.open(json_file, 'w') { |file| file.write(spec.to_pretty_json) }
213
+ else
214
+ FileUtils.cp(spec_file, output_path)
215
+ end
216
+
217
+ # only commit if modified
218
+ if repo_git('status', '--porcelain').include?(spec.name)
219
+ UI.puts " - #{message}"
220
+ repo_git('add', spec.name)
221
+ repo_git('commit', '--no-verify', '-m', message)
222
+ else
223
+ UI.puts " - [No change] #{spec}"
224
+ end
225
+ end
226
+ end
227
+
228
+ # Pushes the git repo against the remote.
229
+ #
230
+ # @return [void]
231
+ #
232
+ def push_repo
233
+ UI.puts "\nPushing the `#{@repo}' repo\n".yellow
234
+ repo_git('push', 'origin', 'HEAD')
235
+ end
236
+
237
+ #---------------------------------------------------------------------#
238
+
239
+ private
240
+
241
+ # @!group Private helpers
242
+
243
+ # @return result of calling the git! with args in repo_dir
244
+ #
245
+ def repo_git(*args)
246
+ git!(['-C', repo_dir] + args)
247
+ end
248
+
249
+ # @return [Pathname] The directory of the repository.
250
+ #
251
+ def repo_dir
252
+ @source.specs_dir
253
+ end
254
+
255
+ # @return [Array<Pathname>] The path of the specifications to push.
256
+ #
257
+ def podspec_files
258
+ if @podspec
259
+ path = Pathname(@podspec)
260
+ raise Informative, "Couldn't find #{@podspec}" unless path.exist?
261
+ [path]
262
+ else
263
+ files = Pathname.glob('*.podspec{,.json}')
264
+ raise Informative, "Couldn't find any podspec files in current directory" if files.empty?
265
+ files
266
+ end
267
+ end
268
+
269
+ # @return [Integer] The number of the podspec files to push.
270
+ #
271
+ def count
272
+ podspec_files.count
273
+ end
274
+
275
+ # Returns source for @repo
276
+ #
277
+ # @note If URL is invalid or repo doesn't exist, validate! will throw the error
278
+ #
279
+ # @return [Source]
280
+ #
281
+ def source_for_repo
282
+ config.sources_manager.source_with_name_or_url(@repo) unless @repo.nil?
283
+ rescue
284
+ nil
285
+ end
286
+
287
+ #---------------------------------------------------------------------#
288
+ end
289
+ end
290
+ end
291
+ end
metadata ADDED
@@ -0,0 +1,82 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cocoapods-publish
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Damien DANGLARD
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-05-15 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:
42
+ email:
43
+ - damien.danglard@kassylab.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - ".github/workflows/gem-cd-gpr.yml"
49
+ - ".github/workflows/gem-cd-rubygems.yml"
50
+ - ".github/workflows/gem-ci.yml"
51
+ - ".gitignore"
52
+ - LICENSE
53
+ - README.md
54
+ - cocoapods_publish.gemspec
55
+ - lib/cocoapods_plugin.rb
56
+ - lib/cocoapods_publish.rb
57
+ - lib/pod/command/repo/publish.rb
58
+ homepage: https://github.com/KassyLab/cocoapods-publish
59
+ licenses:
60
+ - MIT
61
+ metadata: {}
62
+ post_install_message:
63
+ rdoc_options: []
64
+ require_paths:
65
+ - lib
66
+ required_ruby_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ required_rubygems_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ requirements: []
77
+ rubygems_version: 3.0.3
78
+ signing_key:
79
+ specification_version: 4
80
+ summary: Publish a Podspec in a Specs repo without linting it ("pod repo push" without
81
+ linting).
82
+ test_files: []