cocoapods-dykit 0.2.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 3964bce4d5f9102fbfc4b79cb40768446441b454
4
+ data.tar.gz: 8d4057b36a2d2c5d77719761eb6ba78dbc998d03
5
+ SHA512:
6
+ metadata.gz: 7f5f0bf522eccd081170944711125a6add53bb2ec4543d5a000b2aae7e408c170290daab52e069137418f643d283aa397071af964b451770f402b1142ba66b5f
7
+ data.tar.gz: b457ccbb3b95e6600d7c7d6cffde92ea89ad35172856ccb00d91873814952ff403c99bd58a306a5c2b730f2c3fb6280cb961bc2a44ed8820261f2bf5c7471c10
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ .DS_Store
2
+ pkg
3
+ .idea/
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in cocoapods-dykit.gemspec
4
+ gemspec
5
+
6
+ group :development do
7
+ gem 'cocoapods'
8
+
9
+ gem 'mocha'
10
+ gem 'bacon'
11
+ gem 'mocha-on-bacon'
12
+ gem 'prettybacon'
13
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2018 黄露洋 <huangluyang@douyu.tv>
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,25 @@
1
+ # cocoapods-dykit
2
+
3
+ 绕过 `pod lib lint` 模拟器验证。
4
+
5
+ ## Installation
6
+
7
+ $ sudo gem install cocoapods-dykit -v 0.1.0 -NV
8
+
9
+ ## Usage
10
+
11
+ > 说明:以下命令中 douyu、douyu-beijing、master 为本地 spec 仓库别名,可以通过 `pod repo list` 查看本地有哪些 spec 仓库别名
12
+
13
+ ~~~sh
14
+ # 验证静态库
15
+ $ pod lib dylint --sources=douyu,douyu-beijing,master --use-libraries --allow-warnings
16
+
17
+ # 验证动态库
18
+ pod lib dylint --sources=douyu,douyu-beijing,master --allow-warnings
19
+
20
+ # 推送静态库
21
+ pod repo dypush douyu --use-libraries --allow-warnings --sources=douyu,douyu-beijing,master
22
+
23
+ # 推送动态库
24
+ pod repo dypush douyu --allow-warnings --sources=douyu,douyu-beijing,master
25
+ ~~~
data/Rakefile ADDED
@@ -0,0 +1,13 @@
1
+ require 'bundler/gem_tasks'
2
+
3
+ def specs(dir)
4
+ FileList["spec/#{dir}/*_spec.rb"].shuffle.join(' ')
5
+ end
6
+
7
+ desc 'Runs all the specs'
8
+ task :specs do
9
+ sh "bundle exec bacon #{specs('**')}"
10
+ end
11
+
12
+ task :default => :specs
13
+
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'pod/gem_version.rb'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'cocoapods-dykit'
8
+ spec.version = CocoapodsDylint::VERSION
9
+ spec.authors = ['黄露洋']
10
+ spec.email = ['huangluyang@douyu.tv']
11
+ spec.description = 'Validates a Pod without simulator.'
12
+ spec.summary = 'Validates the Pod using the files in the working directory without simulator.'
13
+ spec.homepage = 'http://gitlab.douyuios.com/douyu-ios/cocoapods-dykit'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.add_dependency "cocoapods", '>= 1.3.1', '< 1.4.0'
22
+ spec.add_development_dependency 'bundler', '~> 1.3'
23
+ spec.add_development_dependency 'rake'
24
+ end
@@ -0,0 +1 @@
1
+ require 'pod/gem_version'
@@ -0,0 +1 @@
1
+ require 'pod/command'
@@ -0,0 +1,2 @@
1
+ require 'pod/command/lib/dylint'
2
+ require 'pod/command/repo/dypush'
@@ -0,0 +1,11 @@
1
+ require 'cocoapods/command/fmwk/create'
2
+ require 'cocoapods/command/fmwk/build'
3
+
4
+ module Pod
5
+ class Command
6
+ class Fmwk < Command
7
+ self.abstract_command = true
8
+ self.summary = 'Develop pods'
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,136 @@
1
+ # require File.expand_path('../validator.rb', __FILE__)
2
+ require 'validator'
3
+ module Pod
4
+ class Command
5
+ # This is an example of a cocoapods plugin adding a top-level subcommand
6
+ # to the 'pod' command.
7
+ #
8
+ # You can also create subcommands of existing or new commands. Say you
9
+ # wanted to add a subcommand to `list` to show newly deprecated pods,
10
+ # (e.g. `pod list deprecated`), there are a few things that would need
11
+ # to change.
12
+ #
13
+ # - move this file to `lib/pod/command/list/deprecated.rb` and update
14
+ # the class to exist in the the Pod::Command::List namespace
15
+ # - change this class to extend from `List` instead of `Command`. This
16
+ # tells the plugin system that it is a subcommand of `list`.
17
+ # - edit `lib/cocoapods_plugins.rb` to require this file
18
+ #
19
+ # @todo Create a PR to add your plugin to CocoaPods/cocoapods.org
20
+ # in the `plugins.json` file, once your plugin is released.
21
+ #
22
+ class Fmwk < Command
23
+ class Create < Fmwk
24
+ self.summary = 'Validates a Pod without simulator'
25
+
26
+ self.description = <<-DESC
27
+ Validates the Pod using the files in the working directory without simulator.
28
+ DESC
29
+
30
+ def self.options
31
+ [
32
+ # ['--quick', 'Lint skips checks that would require to download and build the spec'],
33
+ # ['--allow-warnings', 'Lint validates even if warnings are present'],
34
+ # ['--subspec=NAME', 'Lint validates only the given subspec'],
35
+ # ['--no-subspecs', 'Lint skips validation of subspecs'],
36
+ # ['--no-clean', 'Lint leaves the build directory intact for inspection'],
37
+ # ['--fail-fast', 'Lint stops on the first failing platform or subspec'],
38
+ # ['--use-libraries', 'Lint uses static libraries to install the spec'],
39
+ # ['--sources=https://github.com/artsy/Specs,master', 'The sources from which to pull dependent pods ' \
40
+ # '(defaults to https://github.com/CocoaPods/Specs.git). ' \
41
+ # 'Multiple sources must be comma-delimited.'],
42
+ # ['--private', 'Lint skips checks that apply only to public specs'],
43
+ # ['--swift-version=VERSION', 'The SWIFT_VERSION that should be used to lint the spec. ' \
44
+ # 'This takes precedence over a .swift-version file.'],
45
+ # ['--skip-import-validation', 'Lint skips validating that the pod can be imported'],
46
+ # ['--skip-tests', 'Lint skips building and running tests during validation'],
47
+ ].concat(super)
48
+ end
49
+
50
+ def initialize(argv)
51
+ # @quick = argv.flag?('quick')
52
+ # @allow_warnings = argv.flag?('allow-warnings')
53
+ # @clean = argv.flag?('clean', true)
54
+ # @fail_fast = argv.flag?('fail-fast', false)
55
+ # @subspecs = argv.flag?('subspecs', true)
56
+ # @only_subspec = argv.option('subspec')
57
+ # @use_frameworks = !argv.flag?('use-libraries')
58
+ # @source_urls = argv.option('sources', 'https://github.com/CocoaPods/Specs.git').split(',')
59
+ # @private = argv.flag?('private', false)
60
+ # @swift_version = argv.option('swift-version', nil)
61
+ # @skip_import_validation = argv.flag?('skip-import-validation', false)
62
+ # @skip_tests = argv.flag?('skip-tests', false)
63
+ @framework_names = argv.arguments!
64
+ super
65
+ end
66
+
67
+ def validate!
68
+ super
69
+ end
70
+
71
+ def run
72
+ UI.puts
73
+ podspecs_to_lint.each do |podspec|
74
+ validator = Pod::DyValidator.new(podspec, @source_urls)
75
+ validator.local = true
76
+ validator.quick = @quick
77
+ validator.no_clean = !@clean
78
+ validator.fail_fast = @fail_fast
79
+ validator.allow_warnings = @allow_warnings
80
+ validator.no_subspecs = !@subspecs || @only_subspec
81
+ validator.only_subspec = @only_subspec
82
+ validator.use_frameworks = @use_frameworks
83
+ validator.ignore_public_only_results = @private
84
+ validator.swift_version = @swift_version
85
+ validator.skip_import_validation = @skip_import_validation
86
+ validator.skip_tests = @skip_tests
87
+ validator.validate
88
+
89
+ unless @clean
90
+ UI.puts "Pods workspace available at `#{validator.validation_dir}/App.xcworkspace` for inspection."
91
+ UI.puts
92
+ end
93
+ if validator.validated?
94
+ UI.puts "#{validator.spec.name} passed validation.".green
95
+ else
96
+ spec_name = podspec
97
+ spec_name = validator.spec.name if validator.spec
98
+ message = "#{spec_name} did not pass validation, due to #{validator.failure_reason}."
99
+
100
+ if @clean
101
+ message << "\nYou can use the `--no-clean` option to inspect " \
102
+ 'any issue.'
103
+ end
104
+ raise Informative, message
105
+ end
106
+ end
107
+ end
108
+
109
+ private
110
+
111
+ #----------------------------------------#
112
+
113
+ # !@group Private helpers
114
+
115
+ # @return [Pathname] The path of the podspec found in the current
116
+ # working directory.
117
+ #
118
+ # @raise If no podspec is found.
119
+ # @raise If multiple podspecs are found.
120
+ #
121
+ def podspecs_to_lint
122
+ if !@podspecs_paths.empty?
123
+ Array(@podspecs_paths)
124
+ else
125
+ podspecs = Pathname.glob(Pathname.pwd + '*.podspec{.json,}')
126
+ if podspecs.count.zero?
127
+ raise Informative, 'Unable to find a podspec in the working ' \
128
+ 'directory'
129
+ end
130
+ podspecs
131
+ end
132
+ end
133
+ end
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,136 @@
1
+ # require File.expand_path('../validator.rb', __FILE__)
2
+ require 'validator'
3
+ module Pod
4
+ class Command
5
+ # This is an example of a cocoapods plugin adding a top-level subcommand
6
+ # to the 'pod' command.
7
+ #
8
+ # You can also create subcommands of existing or new commands. Say you
9
+ # wanted to add a subcommand to `list` to show newly deprecated pods,
10
+ # (e.g. `pod list deprecated`), there are a few things that would need
11
+ # to change.
12
+ #
13
+ # - move this file to `lib/pod/command/list/deprecated.rb` and update
14
+ # the class to exist in the the Pod::Command::List namespace
15
+ # - change this class to extend from `List` instead of `Command`. This
16
+ # tells the plugin system that it is a subcommand of `list`.
17
+ # - edit `lib/cocoapods_plugins.rb` to require this file
18
+ #
19
+ # @todo Create a PR to add your plugin to CocoaPods/cocoapods.org
20
+ # in the `plugins.json` file, once your plugin is released.
21
+ #
22
+ class Lib < Command
23
+ class Dylint < Lib
24
+ self.summary = 'Validates a Pod without simulator'
25
+
26
+ self.description = <<-DESC
27
+ Validates the Pod using the files in the working directory without simulator.
28
+ DESC
29
+
30
+ def self.options
31
+ [
32
+ ['--quick', 'Lint skips checks that would require to download and build the spec'],
33
+ ['--allow-warnings', 'Lint validates even if warnings are present'],
34
+ ['--subspec=NAME', 'Lint validates only the given subspec'],
35
+ ['--no-subspecs', 'Lint skips validation of subspecs'],
36
+ ['--no-clean', 'Lint leaves the build directory intact for inspection'],
37
+ ['--fail-fast', 'Lint stops on the first failing platform or subspec'],
38
+ ['--use-libraries', 'Lint uses static libraries to install the spec'],
39
+ ['--sources=https://github.com/artsy/Specs,master', 'The sources from which to pull dependent pods ' \
40
+ '(defaults to https://github.com/CocoaPods/Specs.git). ' \
41
+ 'Multiple sources must be comma-delimited.'],
42
+ ['--private', 'Lint skips checks that apply only to public specs'],
43
+ ['--swift-version=VERSION', 'The SWIFT_VERSION that should be used to lint the spec. ' \
44
+ 'This takes precedence over a .swift-version file.'],
45
+ ['--skip-import-validation', 'Lint skips validating that the pod can be imported'],
46
+ ['--skip-tests', 'Lint skips building and running tests during validation'],
47
+ ].concat(super)
48
+ end
49
+
50
+ def initialize(argv)
51
+ @quick = argv.flag?('quick')
52
+ @allow_warnings = argv.flag?('allow-warnings')
53
+ @clean = argv.flag?('clean', true)
54
+ @fail_fast = argv.flag?('fail-fast', false)
55
+ @subspecs = argv.flag?('subspecs', true)
56
+ @only_subspec = argv.option('subspec')
57
+ @use_frameworks = !argv.flag?('use-libraries')
58
+ @source_urls = argv.option('sources', 'https://github.com/CocoaPods/Specs.git').split(',')
59
+ @private = argv.flag?('private', false)
60
+ @swift_version = argv.option('swift-version', nil)
61
+ @skip_import_validation = argv.flag?('skip-import-validation', false)
62
+ @skip_tests = argv.flag?('skip-tests', false)
63
+ @podspecs_paths = argv.arguments!
64
+ super
65
+ end
66
+
67
+ def validate!
68
+ super
69
+ end
70
+
71
+ def run
72
+ UI.puts
73
+ podspecs_to_lint.each do |podspec|
74
+ validator = Pod::DyValidator.new(podspec, @source_urls)
75
+ validator.local = true
76
+ validator.quick = @quick
77
+ validator.no_clean = !@clean
78
+ validator.fail_fast = @fail_fast
79
+ validator.allow_warnings = @allow_warnings
80
+ validator.no_subspecs = !@subspecs || @only_subspec
81
+ validator.only_subspec = @only_subspec
82
+ validator.use_frameworks = @use_frameworks
83
+ validator.ignore_public_only_results = @private
84
+ validator.swift_version = @swift_version
85
+ validator.skip_import_validation = @skip_import_validation
86
+ validator.skip_tests = @skip_tests
87
+ validator.validate
88
+
89
+ unless @clean
90
+ UI.puts "Pods workspace available at `#{validator.validation_dir}/App.xcworkspace` for inspection."
91
+ UI.puts
92
+ end
93
+ if validator.validated?
94
+ UI.puts "#{validator.spec.name} passed validation.".green
95
+ else
96
+ spec_name = podspec
97
+ spec_name = validator.spec.name if validator.spec
98
+ message = "#{spec_name} did not pass validation, due to #{validator.failure_reason}."
99
+
100
+ if @clean
101
+ message << "\nYou can use the `--no-clean` option to inspect " \
102
+ 'any issue.'
103
+ end
104
+ raise Informative, message
105
+ end
106
+ end
107
+ end
108
+
109
+ private
110
+
111
+ #----------------------------------------#
112
+
113
+ # !@group Private helpers
114
+
115
+ # @return [Pathname] The path of the podspec found in the current
116
+ # working directory.
117
+ #
118
+ # @raise If no podspec is found.
119
+ # @raise If multiple podspecs are found.
120
+ #
121
+ def podspecs_to_lint
122
+ if !@podspecs_paths.empty?
123
+ Array(@podspecs_paths)
124
+ else
125
+ podspecs = Pathname.glob(Pathname.pwd + '*.podspec{.json,}')
126
+ if podspecs.count.zero?
127
+ raise Informative, 'Unable to find a podspec in the working ' \
128
+ 'directory'
129
+ end
130
+ podspecs
131
+ end
132
+ end
133
+ end
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,291 @@
1
+ # require File.expand_path('../../../../validator.rb', __FILE__)
2
+ require 'validator'
3
+ module Pod
4
+ class Command
5
+ # This is an example of a cocoapods plugin adding a top-level subcommand
6
+ # to the 'pod' command.
7
+ #
8
+ # You can also create subcommands of existing or new commands. Say you
9
+ # wanted to add a subcommand to `list` to show newly deprecated pods,
10
+ # (e.g. `pod list deprecated`), there are a few things that would need
11
+ # to change.
12
+ #
13
+ # - move this file to `lib/pod/command/list/deprecated.rb` and update
14
+ # the class to exist in the the Pod::Command::List namespace
15
+ # - change this class to extend from `List` instead of `Command`. This
16
+ # tells the plugin system that it is a subcommand of `list`.
17
+ # - edit `lib/cocoapods_plugins.rb` to require this file
18
+ #
19
+ # @todo Create a PR to add your plugin to CocoaPods/cocoapods.org
20
+ # in the `plugins.json` file, once your plugin is released.
21
+ #
22
+ class Repo < Command
23
+ class Dypush < Repo
24
+ self.summary = 'Push new specifications to a spec-repo'
25
+
26
+ self.description = <<-DESC
27
+ Validates `NAME.podspec` or `*.podspec` in the current working dir,
28
+ creates a directory and version folder for the pod in the local copy of
29
+ `REPO` (~/.cocoapods/repos/[REPO]), copies the podspec file into the
30
+ version directory, and finally it pushes `REPO` to its remote.
31
+ DESC
32
+
33
+ self.arguments = [
34
+ CLAide::Argument.new('REPO', true),
35
+ CLAide::Argument.new('NAME.podspec', false),
36
+ ]
37
+
38
+ def self.options
39
+ [
40
+ ['--allow-warnings', 'Allows pushing even if there are warnings'],
41
+ ['--use-libraries', 'Linter uses static libraries to install the spec'],
42
+ ['--sources=https://github.com/artsy/Specs,master', 'The sources from which to pull dependent pods ' \
43
+ '(defaults to all available repos). ' \
44
+ 'Multiple sources must be comma-delimited.'],
45
+ ['--local-only', 'Does not perform the step of pushing REPO to its remote'],
46
+ ['--no-private', 'Lint includes checks that apply only to public repos'],
47
+ ['--skip-import-validation', 'Lint skips validating that the pod can be imported'],
48
+ ['--skip-tests', 'Lint skips building and running tests during validation'],
49
+ ['--commit-message="Fix bug in pod"', 'Add custom commit message. ' \
50
+ 'Opens default editor if no commit message is specified.'],
51
+ ['--use-json', 'Push JSON spec to repo'],
52
+ ['--swift-version=VERSION', 'The SWIFT_VERSION that should be used when linting the spec. ' \
53
+ 'This takes precedence over a .swift-version file.'],
54
+ ].concat(super)
55
+ end
56
+
57
+ def initialize(argv)
58
+ @allow_warnings = argv.flag?('allow-warnings')
59
+ @local_only = argv.flag?('local-only')
60
+ @repo = argv.shift_argument
61
+ @source = source_for_repo
62
+ @source_urls = argv.option('sources', config.sources_manager.all.map(&:url).join(',')).split(',')
63
+ @podspec = argv.shift_argument
64
+ @use_frameworks = !argv.flag?('use-libraries')
65
+ @private = argv.flag?('private', true)
66
+ @message = argv.option('commit-message')
67
+ @commit_message = argv.flag?('commit-message', false)
68
+ @use_json = argv.flag?('use-json')
69
+ @swift_version = argv.option('swift-version', nil)
70
+ @skip_import_validation = argv.flag?('skip-import-validation', false)
71
+ @skip_tests = argv.flag?('skip-tests', false)
72
+ super
73
+ end
74
+
75
+ def validate!
76
+ super
77
+ help! 'A spec-repo name or url is required.' unless @repo
78
+ unless @source && @source.repo.directory?
79
+ raise Informative,
80
+ "Unable to find the `#{@repo}` repo. " \
81
+ 'If it has not yet been cloned, add it via `pod repo add`.'
82
+ end
83
+ end
84
+
85
+ def run
86
+ open_editor if @commit_message && @message.nil?
87
+ check_if_master_repo
88
+ validate_podspec_files
89
+ check_repo_status
90
+ update_repo
91
+ add_specs_to_repo
92
+ push_repo unless @local_only
93
+ end
94
+
95
+ #---------------------------------------------------------------------#
96
+
97
+ private
98
+
99
+ # @!group Push sub-steps
100
+
101
+ extend Executable
102
+ executable :git
103
+
104
+ # Open default editor to allow users to enter commit message
105
+ #
106
+ def open_editor
107
+ return if ENV['EDITOR'].nil?
108
+
109
+ file = Tempfile.new('cocoapods')
110
+ File.chmod(0777, file.path)
111
+ file.close
112
+
113
+ system("#{ENV['EDITOR']} #{file.path}")
114
+ @message = File.read file.path
115
+ end
116
+
117
+ # Temporary check to ensure that users do not push accidentally private
118
+ # specs to the master repo.
119
+ #
120
+ def check_if_master_repo
121
+ remotes = `git -C "#{repo_dir}" remote -v 2>&1`
122
+ master_repo_urls = [
123
+ 'git@github.com:CocoaPods/Specs.git',
124
+ 'https://github.com/CocoaPods/Specs.git',
125
+ ]
126
+ is_master_repo = master_repo_urls.any? do |url|
127
+ remotes.include?(url)
128
+ end
129
+
130
+ if is_master_repo
131
+ raise Informative, 'To push to the CocoaPods master repo use ' \
132
+ "the `pod trunk push` command.\n\nIf you are using a fork of " \
133
+ 'the master repo for private purposes we recommend to migrate ' \
134
+ 'to a clean private repo. To disable this check remove the ' \
135
+ 'remote pointing to the CocoaPods master repo.'
136
+ end
137
+ end
138
+
139
+ # Performs a full lint against the podspecs.
140
+ #
141
+ def validate_podspec_files
142
+ UI.puts "\nValidating #{'spec'.pluralize(count)}".yellow
143
+ podspec_files.each do |podspec|
144
+ validator = DyValidator.new(podspec, @source_urls)
145
+ validator.allow_warnings = @allow_warnings
146
+ validator.use_frameworks = @use_frameworks
147
+ validator.ignore_public_only_results = @private
148
+ validator.swift_version = @swift_version
149
+ validator.skip_import_validation = @skip_import_validation
150
+ validator.skip_tests = @skip_tests
151
+ begin
152
+ validator.validate
153
+ rescue => e
154
+ raise Informative, "The `#{podspec}` specification does not validate." \
155
+ "\n\n#{e.message}"
156
+ end
157
+ raise Informative, "The `#{podspec}` specification does not validate." unless validator.validated?
158
+ end
159
+ end
160
+
161
+ # Checks that the repo is clean.
162
+ #
163
+ # @raise If the repo is not clean.
164
+ #
165
+ # @todo Add specs for staged and unstaged files.
166
+ #
167
+ # @todo Gracefully handle the case where source is not under git
168
+ # source control.
169
+ #
170
+ # @return [void]
171
+ #
172
+ def check_repo_status
173
+ clean = `git -C "#{repo_dir}" status --porcelain 2>&1` == ''
174
+ raise Informative, "The repo `#{@repo}` at #{UI.path repo_dir} is not clean" unless clean
175
+ end
176
+
177
+ # Updates the git repo against the remote.
178
+ #
179
+ # @return [void]
180
+ #
181
+ def update_repo
182
+ UI.puts "Updating the `#{@repo}' repo\n".yellow
183
+ UI.puts `git -C "#{repo_dir}" pull 2>&1`
184
+ end
185
+
186
+ # Commits the podspecs to the source, which should be a git repo.
187
+ #
188
+ # @note The pre commit hook of the repo is skipped as the podspecs have
189
+ # already been linted.
190
+ #
191
+ # @return [void]
192
+ #
193
+ def add_specs_to_repo
194
+ UI.puts "\nAdding the #{'spec'.pluralize(count)} to the `#{@repo}' repo\n".yellow
195
+ podspec_files.each do |spec_file|
196
+ spec = Pod::Specification.from_file(spec_file)
197
+ output_path = @source.pod_path(spec.name) + spec.version.to_s
198
+ if @message && !@message.empty?
199
+ message = @message
200
+ elsif output_path.exist?
201
+ message = "[Fix] #{spec}"
202
+ elsif output_path.dirname.directory?
203
+ message = "[Update] #{spec}"
204
+ else
205
+ message = "[Add] #{spec}"
206
+ end
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('-C', repo_dir, 'push', 'origin', 'master')
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