-
Notifications
You must be signed in to change notification settings - Fork 0
/
submodule.rb
165 lines (142 loc) · 4.13 KB
/
submodule.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
require "submodule/version"
require "rake/tasklib"
require "inifile"
module Submodule
class Task < ::Rake::TaskLib
attr_reader :path
attr_accessor :branch
def initialize
@cwd = Dir.pwd
base = File.basename Dir["*.gemspec"][0], ".gemspec"
if base[0]
base = File.basename Dir["*.gemspec"][0], ".gemspec"
@version_file = "lib/#{base}/version.rb"
end
gitmodules = IniFile.new('./.gitmodules').to_h
@path = gitmodules[gitmodules.keys.first]["path"]
@path = File.expand_path(@path, @cwd)
@submodule_name = gitmodules.keys.first.gsub('submodule ', '').gsub('"', '').gsub('vendor/', '')
@github = gitmodules[gitmodules.keys.first]["url"].gsub('https://github.com/', '').gsub('.git', '')
# TODO: detect default branch
@branch = "master"
yield self if block_given?
define
end
[:test, :after_pull].each do |method|
define_method method do |&block|
instance_variable_set("@#{method}", block)
end
define_method "run_#{method}" do
callback = instance_variable_get("@#{method}")
if callback.respond_to?(:call)
callback.call
else
warn "define #{method}"
end
end
end
private
def define
desc "Update, test and commit submodule #{@submodule_name}"
task "submodule:update" do
git_update
cd path
hash_before = git_hash
git_pull
hash_after = git_hash
if hash_before == hash_after
abort "submodule #{@submodule_name} already up-to-date"
end
run_test
update_version hash_after
cd @cwd
git_add
run_after_pull
git_commit hash_after
end
desc "Test submodule #{@submodule_name}"
task "submodule:test" do
git_update
cd path
run_test
cd @cwd
end
self
end
def git_update
sh "git submodule update --init --recursive"
end
# def my_sh cmd
# puts cmd
# res = `#{cmd}`
# if $? != 0
# abort "Running `#{cmd}' failed. Run this command directly for more detailed output"
# end
# res
# end
def git_pull
sh "git clean -f"
sh "git checkout #{branch}"
sh "git pull"
# res = my_sh "git pull"
# if res =~ /Already up-to-date/
# p res
# abort "submodule #{@submodule_name} already up-to-date"
# end
end
def git_hash
`git rev-parse --verify HEAD`.strip
# http://git-scm.com/book/en/ch2-3.html Table 2-1
# {
# hash: `git rev-parse --verify HEAD`.strip,
# short_hash: ` git log -1 --pretty=format:"%h"`,
# commit_date: ` git log -1 --pretty=format:"%cd"`,
# comment: ` git log -1 --pretty=format:"%s"`
# }
end
def git_add
sh "git add " + path
sh "git add " + @version_file
end
def version_path
File.expand_path(@version_file, @cwd)
end
def version_regexp val = "(.*)", re = true
str = "VERSION = \"#{val}\""
if re
Regexp.new str.gsub(" ", "\s*")
else
str
end
end
def submodule_regexp val = "(.*)", re = true
str = "SUBMODULE = \"#{val}\""
if re
Regexp.new str.gsub(" ", "\s*")
else
str
end
end
def update_version hash
if File.file? version_path
version_info = File.read version_path
version_number = version_regexp.match(version_info)[1]
version_number = version_number.split('.')
# TODO not update if current version not commited yet
version_number[2] = version_number[2].to_i + 1
version_number = version_number.join('.')
version_info.gsub! version_regexp, version_regexp(version_number, false)
version_info.gsub! submodule_regexp, submodule_regexp(hash, false)
File.open version_path, "w" do |f|
f.write version_info
end
else
p "no version file"
end
end
def git_commit hash
message = "update #{@submodule_name} to #{@github}@#{hash}"
sh "git commit -m \"#{message}\""
end
end
end