cocoapods 0.5.1 → 0.6.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +229 -2
- data/README.md +50 -20
- data/bin/pod +3 -2
- data/lib/cocoapods.rb +23 -9
- data/lib/cocoapods/command.rb +71 -30
- data/lib/cocoapods/command/error_report.rb +102 -0
- data/lib/cocoapods/command/install.rb +27 -19
- data/lib/cocoapods/command/list.rb +51 -8
- data/lib/cocoapods/command/presenter.rb +61 -0
- data/lib/cocoapods/command/presenter/cocoa_pod.rb +123 -0
- data/lib/cocoapods/command/push.rb +102 -0
- data/lib/cocoapods/command/repo.rb +70 -14
- data/lib/cocoapods/command/search.rb +7 -10
- data/lib/cocoapods/command/setup.rb +76 -15
- data/lib/cocoapods/command/spec.rb +581 -97
- data/lib/cocoapods/config.rb +23 -26
- data/lib/cocoapods/dependency.rb +86 -40
- data/lib/cocoapods/downloader.rb +30 -18
- data/lib/cocoapods/downloader/git.rb +125 -15
- data/lib/cocoapods/downloader/http.rb +73 -0
- data/lib/cocoapods/downloader/mercurial.rb +3 -9
- data/lib/cocoapods/downloader/subversion.rb +3 -9
- data/lib/cocoapods/executable.rb +26 -3
- data/lib/cocoapods/generator/acknowledgements.rb +37 -0
- data/lib/cocoapods/generator/acknowledgements/markdown.rb +38 -0
- data/lib/cocoapods/generator/acknowledgements/plist.rb +63 -0
- data/lib/cocoapods/generator/copy_resources_script.rb +8 -4
- data/lib/cocoapods/generator/documentation.rb +99 -0
- data/lib/cocoapods/generator/dummy_source.rb +14 -0
- data/lib/cocoapods/installer.rb +140 -109
- data/lib/cocoapods/installer/target_installer.rb +78 -83
- data/lib/cocoapods/installer/user_project_integrator.rb +162 -0
- data/lib/cocoapods/local_pod.rb +240 -0
- data/lib/cocoapods/platform.rb +41 -18
- data/lib/cocoapods/podfile.rb +234 -21
- data/lib/cocoapods/project.rb +67 -0
- data/lib/cocoapods/resolver.rb +62 -32
- data/lib/cocoapods/sandbox.rb +63 -0
- data/lib/cocoapods/source.rb +42 -20
- data/lib/cocoapods/specification.rb +294 -271
- data/lib/cocoapods/specification/set.rb +10 -28
- data/lib/cocoapods/specification/statistics.rb +112 -0
- metadata +124 -11
- data/lib/cocoapods/xcodeproj_pods.rb +0 -111
@@ -0,0 +1,102 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require 'rbconfig'
|
4
|
+
require 'cgi'
|
5
|
+
require 'rubygems'
|
6
|
+
|
7
|
+
module Pod
|
8
|
+
class Command
|
9
|
+
module ErrorReport
|
10
|
+
class << self
|
11
|
+
def report(error)
|
12
|
+
return <<-EOS
|
13
|
+
|
14
|
+
#{'――― MARKDOWN TEMPLATE ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――'.reversed}
|
15
|
+
|
16
|
+
### Report
|
17
|
+
|
18
|
+
* What did you do?
|
19
|
+
|
20
|
+
* What did you expect to happen?
|
21
|
+
|
22
|
+
* What happened instead?
|
23
|
+
|
24
|
+
|
25
|
+
### Stack
|
26
|
+
|
27
|
+
```
|
28
|
+
CocoaPods : #{Pod::VERSION}
|
29
|
+
Ruby : #{RUBY_DESCRIPTION}
|
30
|
+
RubyGems : #{Gem::VERSION}
|
31
|
+
Host : #{host_information}
|
32
|
+
Xcode : #{xcode_information}
|
33
|
+
Ruby lib dir : #{RbConfig::CONFIG['libdir']}
|
34
|
+
Repositories : #{repo_information.join("\n ")}
|
35
|
+
```
|
36
|
+
#{markdown_podfile}
|
37
|
+
### Error
|
38
|
+
|
39
|
+
```
|
40
|
+
#{error.message}
|
41
|
+
#{error.backtrace.join("\n")}
|
42
|
+
```
|
43
|
+
|
44
|
+
#{'――― TEMPLATE END ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――'.reversed}
|
45
|
+
|
46
|
+
#{'[!] Oh no, an error occurred.'.red}
|
47
|
+
#{error_from_podfile(error)}
|
48
|
+
#{'Search for existing github issues similar to yours:'.yellow}
|
49
|
+
#{"https://github.com/CocoaPods/CocoaPods/issues/search?q=#{CGI.escape(error.message)}"}
|
50
|
+
|
51
|
+
#{'If none exists, create a ticket, with the template displayed above, on:'.yellow}
|
52
|
+
https://github.com/CocoaPods/CocoaPods/issues/new
|
53
|
+
|
54
|
+
Don't forget to anonymize any private data!
|
55
|
+
|
56
|
+
EOS
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def markdown_podfile
|
62
|
+
return '' unless Config.instance.project_podfile && Config.instance.project_podfile.exist?
|
63
|
+
<<-EOS
|
64
|
+
|
65
|
+
### Podfile
|
66
|
+
|
67
|
+
```ruby
|
68
|
+
#{Config.instance.project_podfile.read.strip}
|
69
|
+
```
|
70
|
+
EOS
|
71
|
+
end
|
72
|
+
|
73
|
+
def error_from_podfile(error)
|
74
|
+
if error.message =~ /Podfile:(\d*)/
|
75
|
+
"\nIt appears to have originated from your Podfile at line #{$1}.\n"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def host_information
|
80
|
+
product, version, build =`sw_vers`.strip.split("\n").map { |line| line.split(":").last.strip }
|
81
|
+
"#{product} #{version} (#{build})"
|
82
|
+
end
|
83
|
+
|
84
|
+
def xcode_information
|
85
|
+
version, build = `xcodebuild -version`.strip.split("\n").map { |line| line.split(" ").last }
|
86
|
+
"#{version} (#{build})"
|
87
|
+
end
|
88
|
+
|
89
|
+
def repo_information
|
90
|
+
Pod::Source.all.map do |source|
|
91
|
+
repo = source.repo
|
92
|
+
Dir.chdir(repo) do
|
93
|
+
url = `git config --get remote.origin.url`.strip
|
94
|
+
sha = `git rev-parse HEAD`.strip
|
95
|
+
"#{repo.basename} - #{url} @ #{sha}"
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -4,45 +4,53 @@ module Pod
|
|
4
4
|
def self.banner
|
5
5
|
%{Installing dependencies of a project:
|
6
6
|
|
7
|
-
$ pod install
|
7
|
+
$ pod install
|
8
8
|
|
9
9
|
Downloads all dependencies defined in `Podfile' and creates an Xcode
|
10
10
|
Pods library project in `./Pods'.
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
12
|
+
The Xcode project file should be specified in your `Podfile` like this:
|
13
|
+
|
14
|
+
xcodeproj 'path/to/XcodeProject'
|
15
|
+
|
16
|
+
If no xcodeproj is specified, then a search for an Xcode project will
|
17
|
+
be made. If more than one Xcode project is found, the command will
|
18
|
+
raise an error.
|
19
|
+
|
20
|
+
This will configure the project to reference the Pods static library,
|
21
|
+
add a build configuration file, and add a post build script to copy
|
22
|
+
Pod resources.
|
17
23
|
}
|
18
24
|
end
|
19
25
|
|
20
26
|
def self.options
|
21
|
-
|
22
|
-
|
23
|
-
|
27
|
+
[
|
28
|
+
["--no-clean", "Leave SCM dirs like `.git' and `.svn' intact after downloading"],
|
29
|
+
["--no-doc", "Skip documentation generation with appledoc"],
|
30
|
+
["--no-integrate", "Skip integration of the Pods libraries in the Xcode project(s)"],
|
31
|
+
["--no-update", "Skip running `pod repo update` before install"],
|
32
|
+
].concat(super)
|
24
33
|
end
|
25
34
|
|
26
35
|
def initialize(argv)
|
27
|
-
config.clean
|
28
|
-
|
29
|
-
|
36
|
+
config.clean = !argv.option('--no-clean')
|
37
|
+
config.generate_docs = !argv.option('--no-doc')
|
38
|
+
config.integrate_targets = !argv.option('--no-integrate')
|
39
|
+
@update_repo = !argv.option('--no-update')
|
30
40
|
super unless argv.empty?
|
31
41
|
end
|
32
42
|
|
33
43
|
def run
|
34
|
-
unless podfile = config.
|
44
|
+
unless podfile = config.podfile
|
35
45
|
raise Informative, "No `Podfile' found in the current working directory."
|
36
46
|
end
|
37
|
-
|
38
|
-
raise Informative, "The specified project `#{@projpath}' does not exist."
|
39
|
-
end
|
47
|
+
|
40
48
|
if @update_repo
|
49
|
+
print_title 'Updating Spec Repositories', true
|
41
50
|
Repo.new(ARGV.new(["update"])).run
|
42
51
|
end
|
43
|
-
|
44
|
-
|
45
|
-
installer.configure_project(@projpath) if @projpath
|
52
|
+
|
53
|
+
Installer.new(podfile).install!
|
46
54
|
end
|
47
55
|
end
|
48
56
|
end
|
@@ -2,24 +2,67 @@ module Pod
|
|
2
2
|
class Command
|
3
3
|
class List < Command
|
4
4
|
def self.banner
|
5
|
-
%{List all pods:
|
5
|
+
%{List all pods:
|
6
6
|
|
7
7
|
$ pod list
|
8
8
|
|
9
|
-
Lists all available pods.
|
9
|
+
Lists all available pods.
|
10
|
+
|
11
|
+
$ pod list new
|
12
|
+
|
13
|
+
Lists the pods introduced in the master repository since the last check.}
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.options
|
17
|
+
[["--update", "Run `pod repo update` before listing"]].concat(Presenter.options).concat(super)
|
10
18
|
end
|
11
19
|
|
20
|
+
extend Executable
|
21
|
+
executable :git
|
22
|
+
|
12
23
|
def initialize(argv)
|
24
|
+
@update = argv.option('--update')
|
25
|
+
@new = argv.option('new')
|
26
|
+
@presenter = Presenter.new(argv)
|
27
|
+
super unless argv.empty?
|
13
28
|
end
|
14
29
|
|
15
|
-
def
|
16
|
-
Source.
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
30
|
+
def list_all
|
31
|
+
sets = Source.all_sets
|
32
|
+
sets.each {|s| puts @presenter.describe(s)}
|
33
|
+
puts "\n#{sets.count} pods were found"
|
34
|
+
end
|
35
|
+
|
36
|
+
def list_new
|
37
|
+
days = [1,2,3,5,8]
|
38
|
+
dates, groups = {}, {}
|
39
|
+
days.each {|d| dates[d] = Time.now - 60 * 60 * 24 * d}
|
40
|
+
sets = Source.all_sets
|
41
|
+
creation_dates = Pod::Specification::Statistics.instance.creation_dates(sets)
|
42
|
+
|
43
|
+
sets.each do |set|
|
44
|
+
set_date = creation_dates[set.name]
|
45
|
+
days.each do |d|
|
46
|
+
if set_date >= dates[d]
|
47
|
+
groups[d] = [] unless groups[d]
|
48
|
+
groups[d] << set
|
49
|
+
break
|
50
|
+
end
|
21
51
|
end
|
22
52
|
end
|
53
|
+
days.reverse.each do |d|
|
54
|
+
sets = groups[d]
|
55
|
+
next unless sets
|
56
|
+
puts "\nPods added in the last #{d == 1 ? 'day' : "#{d} days"}".yellow
|
57
|
+
sets.sort_by {|s| creation_dates[s.name]}.each {|s| puts @presenter.describe(s)}
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def run
|
62
|
+
puts "\nUpdating Spec Repositories\n".yellow if @update && config.verbose?
|
63
|
+
Repo.new(ARGV.new(["update"])).run if @update
|
64
|
+
@new ? list_new : list_all
|
65
|
+
puts
|
23
66
|
end
|
24
67
|
end
|
25
68
|
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Pod
|
2
|
+
class Command
|
3
|
+
class Presenter
|
4
|
+
def self.options
|
5
|
+
[["--stats", "Show additional stats (like GitHub watchers and forks)"]]
|
6
|
+
end
|
7
|
+
|
8
|
+
autoload :CocoaPod, 'cocoapods/command/presenter/cocoa_pod'
|
9
|
+
|
10
|
+
def initialize(argv)
|
11
|
+
@stats = argv.option('--stats')
|
12
|
+
end
|
13
|
+
|
14
|
+
def render(array)
|
15
|
+
result = "\n"
|
16
|
+
seats.each {|s| puts describe(s)}
|
17
|
+
result
|
18
|
+
end
|
19
|
+
|
20
|
+
def describe(set)
|
21
|
+
pod = CocoaPod.new(set)
|
22
|
+
result = "\n--> #{pod.name} (#{pod.versions})\n".green
|
23
|
+
result << wrap_string(pod.summary)
|
24
|
+
result << detail('Homepage', pod.homepage)
|
25
|
+
result << detail('Source', pod.source_url)
|
26
|
+
if @stats
|
27
|
+
result << detail('Pushed', pod.github_last_activity)
|
28
|
+
result << detail('Authors', pod.authors) if pod.authors =~ /,/
|
29
|
+
result << detail('Author', pod.authors) if pod.authors !~ /,/
|
30
|
+
result << detail('License', pod.license)
|
31
|
+
result << detail('Platform', pod.platform)
|
32
|
+
result << detail('Watchers', pod.github_watchers)
|
33
|
+
result << detail('Forks', pod.github_forks)
|
34
|
+
end
|
35
|
+
result << detail('Sub specs', pod.subspecs)
|
36
|
+
result
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
# adapted from http://blog.macromates.com/2006/wrapping-text-with-regular-expressions/
|
42
|
+
def wrap_string(txt, col = 80, indentation = 4)
|
43
|
+
indent = ' ' * indentation
|
44
|
+
txt.strip.gsub(/(.{1,#{col}})( +|$)\n?|(.{#{col}})/, indent + "\\1\\3\n")
|
45
|
+
end
|
46
|
+
|
47
|
+
def detail(title, value)
|
48
|
+
return '' if !value
|
49
|
+
''.tap do |t|
|
50
|
+
t << " - #{title}:".ljust(16)
|
51
|
+
if value.class == Array
|
52
|
+
separator = "\n - "
|
53
|
+
t << separator << value.join(separator)
|
54
|
+
else
|
55
|
+
t << value.to_s << "\n"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
module Pod
|
2
|
+
class Command
|
3
|
+
class Presenter
|
4
|
+
class CocoaPod
|
5
|
+
attr_accessor :set
|
6
|
+
|
7
|
+
def initialize(set)
|
8
|
+
@set = set
|
9
|
+
end
|
10
|
+
|
11
|
+
# set information
|
12
|
+
def name
|
13
|
+
@set.name
|
14
|
+
end
|
15
|
+
|
16
|
+
def version
|
17
|
+
@set.versions.last
|
18
|
+
end
|
19
|
+
|
20
|
+
def versions
|
21
|
+
@set.versions.reverse.join(", ")
|
22
|
+
end
|
23
|
+
|
24
|
+
# specification information
|
25
|
+
def spec
|
26
|
+
@set.specification
|
27
|
+
end
|
28
|
+
|
29
|
+
def authors
|
30
|
+
oxfordify spec.authors.keys
|
31
|
+
end
|
32
|
+
|
33
|
+
def homepage
|
34
|
+
spec.homepage
|
35
|
+
end
|
36
|
+
|
37
|
+
def description
|
38
|
+
spec.description
|
39
|
+
end
|
40
|
+
|
41
|
+
def summary
|
42
|
+
spec.summary
|
43
|
+
end
|
44
|
+
|
45
|
+
def source_url
|
46
|
+
spec.source.reject {|k,_| k == :commit || k == :tag }.values.first
|
47
|
+
end
|
48
|
+
|
49
|
+
def platform
|
50
|
+
spec.available_platforms.sort { |a,b| a.to_s.downcase <=> b.to_s.downcase }.join(' - ')
|
51
|
+
end
|
52
|
+
|
53
|
+
def license
|
54
|
+
spec.license[:type] if spec.license
|
55
|
+
end
|
56
|
+
|
57
|
+
# will return array of all subspecs (recursevly) or nil
|
58
|
+
def subspecs
|
59
|
+
(spec.recursive_subspecs.any? && spec.recursive_subspecs) || nil
|
60
|
+
end
|
61
|
+
|
62
|
+
# Statistics information
|
63
|
+
def creation_date
|
64
|
+
Pod::Specification::Statistics.instance.creation_date(@set)
|
65
|
+
end
|
66
|
+
|
67
|
+
def github_watchers
|
68
|
+
Pod::Specification::Statistics.instance.github_watchers(@set)
|
69
|
+
end
|
70
|
+
|
71
|
+
def github_forks
|
72
|
+
Pod::Specification::Statistics.instance.github_forks(@set)
|
73
|
+
end
|
74
|
+
|
75
|
+
def github_last_activity
|
76
|
+
distance_from_now_in_words(Pod::Specification::Statistics.instance.github_pushed_at(@set))
|
77
|
+
end
|
78
|
+
|
79
|
+
def ==(other)
|
80
|
+
self.class === other && @set == other.set
|
81
|
+
end
|
82
|
+
|
83
|
+
def eql?(other)
|
84
|
+
self.class === other && name.eql?(other.name)
|
85
|
+
end
|
86
|
+
|
87
|
+
def hash
|
88
|
+
name.hash
|
89
|
+
end
|
90
|
+
|
91
|
+
private
|
92
|
+
def oxfordify words
|
93
|
+
if words.size < 3
|
94
|
+
words.join ' and '
|
95
|
+
else
|
96
|
+
"#{words[0..-2].join(', ')}, and #{words.last}"
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def distance_from_now_in_words(from_time)
|
101
|
+
return nil unless from_time
|
102
|
+
from_time = Time.parse(from_time)
|
103
|
+
to_time = Time.now
|
104
|
+
distance_in_days = (((to_time - from_time).abs)/60/60/24).round
|
105
|
+
|
106
|
+
case distance_in_days
|
107
|
+
when 0..7
|
108
|
+
"less than a week ago"
|
109
|
+
when 8..29
|
110
|
+
"#{distance_in_days} days ago"
|
111
|
+
when 30..45
|
112
|
+
"1 month ago"
|
113
|
+
when 46..365
|
114
|
+
"#{(distance_in_days.to_f / 30).round} months ago"
|
115
|
+
else
|
116
|
+
"more than a year ago"
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
module Pod
|
4
|
+
class Command
|
5
|
+
class Push < Command
|
6
|
+
def self.banner
|
7
|
+
%{Pushing new specifications to a spec-repo:
|
8
|
+
|
9
|
+
$ pod push [REPO]
|
10
|
+
|
11
|
+
Validates `*.podspec' in the current working dir, updates
|
12
|
+
the local copy of the repository named REPO, adds specifications
|
13
|
+
to REPO, and finally it pushes REPO to its remote.}
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.options
|
17
|
+
[["--allow-warnings", "Allows to push if warnings are not evitable"]].concat(super)
|
18
|
+
end
|
19
|
+
|
20
|
+
extend Executable
|
21
|
+
executable :git
|
22
|
+
|
23
|
+
def initialize(argv)
|
24
|
+
@allow_warnings = argv.option('--allow-warnings')
|
25
|
+
@repo = argv.shift_argument
|
26
|
+
super unless argv.empty? && @repo
|
27
|
+
end
|
28
|
+
|
29
|
+
def run
|
30
|
+
validate_podspec_files
|
31
|
+
check_repo_status
|
32
|
+
update_repo
|
33
|
+
add_specs_to_repo
|
34
|
+
push_repo
|
35
|
+
puts
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def update_repo
|
41
|
+
puts "Updating the `#{@repo}' repo\n".yellow unless config.silent
|
42
|
+
# show the output of git even if not verbose
|
43
|
+
Dir.chdir(repo_dir) { puts `git pull 2>&1` }
|
44
|
+
end
|
45
|
+
|
46
|
+
def push_repo
|
47
|
+
puts "\nPushing the `#{@repo}' repo\n".yellow unless config.silent
|
48
|
+
Dir.chdir(repo_dir) { puts `git push 2>&1` }
|
49
|
+
end
|
50
|
+
|
51
|
+
def repo_dir
|
52
|
+
dir = config.repos_dir + @repo
|
53
|
+
raise Informative, "[!] `#{@repo}' repo not found".red unless dir.exist?
|
54
|
+
dir
|
55
|
+
end
|
56
|
+
|
57
|
+
def check_repo_status
|
58
|
+
# TODO: add specs for staged and unstaged files (tested manually)
|
59
|
+
clean = Dir.chdir(repo_dir) { `git status --porcelain 2>&1` } == ''
|
60
|
+
raise Informative, "[!] `#{@repo}' repo not clean".red unless clean
|
61
|
+
end
|
62
|
+
|
63
|
+
def podspec_files
|
64
|
+
files = Pathname.glob("*.podspec")
|
65
|
+
raise Informative, "[!] Couldn't find .podspec file in current directory".red if files.empty?
|
66
|
+
files
|
67
|
+
end
|
68
|
+
|
69
|
+
def validate_podspec_files
|
70
|
+
puts "\nValidating specs".yellow unless config.silent
|
71
|
+
lint_argv = ["lint"]
|
72
|
+
lint_argv << "--only-errors" if @allow_warnings
|
73
|
+
lint_argv << "--silent" if config.silent
|
74
|
+
all_valid = Spec.new(ARGV.new(lint_argv)).run
|
75
|
+
end
|
76
|
+
|
77
|
+
def add_specs_to_repo
|
78
|
+
puts "\nAdding the specs to the #{@repo} repo\n".yellow unless config.silent
|
79
|
+
podspec_files.each do |spec_file|
|
80
|
+
spec = Pod::Specification.from_file(spec_file)
|
81
|
+
output_path = File.join(repo_dir, spec.name, spec.version.to_s)
|
82
|
+
if Pathname.new(output_path).exist?
|
83
|
+
message = "[Fix] #{spec}"
|
84
|
+
elsif Pathname.new(File.join(repo_dir, spec.name)).exist?
|
85
|
+
message = "[Update] #{spec}"
|
86
|
+
else
|
87
|
+
message = "[Add] #{spec}"
|
88
|
+
end
|
89
|
+
puts " - #{message}" unless config.silent
|
90
|
+
|
91
|
+
FileUtils.mkdir_p(output_path)
|
92
|
+
FileUtils.cp(Pathname.new(spec.name+'.podspec'), output_path)
|
93
|
+
Dir.chdir(repo_dir) do
|
94
|
+
git("add #{spec.name}")
|
95
|
+
# Bypass the pre-commit hook because we already performed validation
|
96
|
+
git("commit --no-verify -m '#{message}'")
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|