git-maintain 0.12.0 → 0.14.2
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 +4 -4
- data/CHANGELOG +23 -0
- data/README.md +14 -14
- data/bin/git-maintain +7 -55
- data/git-maintain-completion.sh +1 -1
- data/lib/{addons → git-maintain/addons}/RDMACore.rb +79 -20
- data/lib/{addons → git-maintain/addons}/git-maintain.rb +61 -6
- data/lib/git-maintain/addons/healthd.rb +73 -0
- data/lib/git-maintain/addons/hpc-testing.rb +102 -0
- data/lib/git-maintain/azure.rb +200 -0
- data/lib/{branch.rb → git-maintain/branch.rb} +356 -237
- data/lib/git-maintain/branch_iterator.rb +148 -0
- data/lib/git-maintain/ci.rb +163 -0
- data/lib/git-maintain/common.rb +117 -0
- data/lib/git-maintain/error.rb +81 -0
- data/lib/{repo.rb → git-maintain/repo.rb} +199 -104
- data/lib/git-maintain/travis.rb +179 -0
- data/lib/git-maintain.rb +2 -0
- metadata +30 -14
- data/lib/azure.rb +0 -98
- data/lib/ci.rb +0 -88
- data/lib/common.rb +0 -259
- data/lib/travis.rb +0 -80
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
# Main module for git-maintain repository maintenance tool.
|
|
2
|
+
module GitMaintain
|
|
3
|
+
# CI adapter class for Travis CI integration.
|
|
4
|
+
class TravisCI < CI
|
|
5
|
+
# Base URL for Travis CI API.
|
|
6
|
+
TRAVIS_URL='https://api.travis-ci.com/'
|
|
7
|
+
|
|
8
|
+
# Initialize TravisCI adapter.
|
|
9
|
+
#
|
|
10
|
+
# @param repo [Repo] The Repo instance
|
|
11
|
+
def initialize(repo)
|
|
12
|
+
super(repo)
|
|
13
|
+
@url = TRAVIS_URL
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
private
|
|
17
|
+
# Get the Travis build status string for a specific commit SHA.
|
|
18
|
+
#
|
|
19
|
+
# @param sha1 [String] Commit SHA
|
|
20
|
+
# @param resp [Hash] API response payload containing branch builds
|
|
21
|
+
# @return [String] Build status string (e.g. 'passed', 'failed')
|
|
22
|
+
def getState(sha1, resp)
|
|
23
|
+
br = findBranch(sha1, resp)
|
|
24
|
+
return "not found" if br == nil
|
|
25
|
+
|
|
26
|
+
return br["state"]
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Fetch the build logs from Travis CI for a specific commit SHA.
|
|
30
|
+
#
|
|
31
|
+
# @param sha1 [String] Commit SHA
|
|
32
|
+
# @param resp [Hash] API response payload
|
|
33
|
+
# @return [String] Build log output text
|
|
34
|
+
# @raise [GitMaintainError] If no build is found for the commit
|
|
35
|
+
def getLog(sha1, resp)
|
|
36
|
+
br = findBranch(sha1, resp)
|
|
37
|
+
raise GitMaintainError.new("Travis build not found") if br == nil
|
|
38
|
+
job_id = br["job_ids"].last().to_s()
|
|
39
|
+
return getJson(@url, "travis_log_" + job_id, 'jobs/' + job_id + '/log', false)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Get the Travis build timestamp for a specific commit SHA.
|
|
43
|
+
#
|
|
44
|
+
# @param sha1 [String] Commit SHA
|
|
45
|
+
# @param resp [Hash] API response payload
|
|
46
|
+
# @return [String] Build started-at timestamp string
|
|
47
|
+
# @raise [GitMaintainError] If no build is found for the commit
|
|
48
|
+
def getTS(sha1, resp)
|
|
49
|
+
br = findBranch(sha1, resp)
|
|
50
|
+
raise GitMaintainError.new("Travis build not found") if br == nil
|
|
51
|
+
return br["started_at"]
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Check if the build status string represents success.
|
|
55
|
+
#
|
|
56
|
+
# @param sha1 [String] Commit SHA
|
|
57
|
+
# @param resp [Hash] API response payload
|
|
58
|
+
# @return [Boolean] True if build passed
|
|
59
|
+
def checkState(sha1, resp)
|
|
60
|
+
return getState(sha1, resp) == "passed"
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Fetch validation branch builds JSON payload from Travis CI API.
|
|
64
|
+
#
|
|
65
|
+
# @return [Hash] JSON API response
|
|
66
|
+
# @raise [GitMaintainError] If API request fails
|
|
67
|
+
def getBrValidJson()
|
|
68
|
+
return getJson(@url, :travis_br_valid, 'repos/' + @repo.remote_valid + '/branches')
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Fetch stable branch builds JSON payload from Travis CI API.
|
|
72
|
+
#
|
|
73
|
+
# @return [Hash] JSON API response
|
|
74
|
+
# @raise [GitMaintainError] If API request fails
|
|
75
|
+
def getBrStableJson()
|
|
76
|
+
return getJson(@url, :travis_br_stable, 'repos/' + @repo.remote_stable + '/branches')
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Find the specific branch build matching the given commit SHA.
|
|
80
|
+
#
|
|
81
|
+
# @param sha1 [String] Commit SHA
|
|
82
|
+
# @param resp [Hash] API response branches payload
|
|
83
|
+
# @return [Hash, nil] Branch build dictionary, or nil if not found
|
|
84
|
+
# @raise [GitMaintainError] If API response is missing expected commit keys
|
|
85
|
+
def findBranch(sha1, resp)
|
|
86
|
+
log(:DEBUG_CI, "Looking for build for #{sha1}")
|
|
87
|
+
resp["branches"].each(){|br|
|
|
88
|
+
commit=resp["commits"].select(){|e| e["id"] == br["commit_id"]}.first()
|
|
89
|
+
raise GitMaintainError.new("Incomplete JSON received from Travis") if commit == nil
|
|
90
|
+
log(:DEBUG_CI, "Found entry for sha #{commit["sha"]}")
|
|
91
|
+
next if commit["sha"] != sha1
|
|
92
|
+
return br
|
|
93
|
+
}
|
|
94
|
+
return nil
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
public
|
|
98
|
+
# Retrieve the validation build state for a specific branch and commit.
|
|
99
|
+
#
|
|
100
|
+
# @param br [Branch] The Branch instance
|
|
101
|
+
# @param sha1 [String] Commit SHA
|
|
102
|
+
# @return [String] Build status string (e.g. 'passed')
|
|
103
|
+
def getValidState(br, sha1)
|
|
104
|
+
return getState(sha1, getBrValidJson())
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# Check if the validation build is successful.
|
|
108
|
+
#
|
|
109
|
+
# @param br [Branch] The Branch instance
|
|
110
|
+
# @param sha1 [String] Commit SHA
|
|
111
|
+
# @return [Boolean] True if build passed
|
|
112
|
+
def checkValidState(br, sha1)
|
|
113
|
+
return checkState(sha1, getBrValidJson())
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# Retrieve the validation build log.
|
|
117
|
+
#
|
|
118
|
+
# @param br [Branch] The Branch instance
|
|
119
|
+
# @param sha1 [String] Commit SHA
|
|
120
|
+
# @return [String] Build log output text
|
|
121
|
+
def getValidLog(br, sha1)
|
|
122
|
+
return getLog(sha1, getBrValidJson())
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
# Retrieve the validation build timestamp.
|
|
126
|
+
#
|
|
127
|
+
# @param br [Branch] The Branch instance
|
|
128
|
+
# @param sha1 [String] Commit SHA
|
|
129
|
+
# @return [String] Build timestamp
|
|
130
|
+
def getValidTS(br, sha1)
|
|
131
|
+
return getTS(sha1, getBrValidJson())
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
# Retrieve the stable build state for a specific branch and commit.
|
|
135
|
+
#
|
|
136
|
+
# @param br [Branch] The Branch instance
|
|
137
|
+
# @param sha1 [String] Commit SHA
|
|
138
|
+
# @return [String] Build status string (e.g. 'passed')
|
|
139
|
+
def getStableState(br, sha1)
|
|
140
|
+
return getState(sha1, getBrStableJson())
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# Check if the stable build is successful.
|
|
144
|
+
#
|
|
145
|
+
# @param br [Branch] The Branch instance
|
|
146
|
+
# @param sha1 [String] Commit SHA
|
|
147
|
+
# @return [Boolean] True if build passed
|
|
148
|
+
def checkStableState(br, sha1)
|
|
149
|
+
return checkState(sha1, getBrStableJson())
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
# Retrieve the stable build log.
|
|
153
|
+
#
|
|
154
|
+
# @param br [Branch] The Branch instance
|
|
155
|
+
# @param sha1 [String] Commit SHA
|
|
156
|
+
# @return [String] Build log output text
|
|
157
|
+
def getStableLog(br, sha1)
|
|
158
|
+
return getLog(sha1, getBrStableJson())
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
# Retrieve the stable build timestamp.
|
|
162
|
+
#
|
|
163
|
+
# @param br [Branch] The Branch instance
|
|
164
|
+
# @param sha1 [String] Commit SHA
|
|
165
|
+
# @return [String] Build timestamp
|
|
166
|
+
def getStableTS(br, sha1)
|
|
167
|
+
return getTS(sha1, getBrStableJson())
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
# Check if the CI build status represents an error/failure.
|
|
171
|
+
#
|
|
172
|
+
# @param br [Branch] The Branch instance
|
|
173
|
+
# @param status [String] CI status string
|
|
174
|
+
# @return [Boolean] True if build errored or failed
|
|
175
|
+
def isErrored(br, status)
|
|
176
|
+
return status == "failed" || status == "errored"
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
end
|
data/lib/git-maintain.rb
ADDED
metadata
CHANGED
|
@@ -1,15 +1,28 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: git-maintain
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.14.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Nicolas Morey-Chaisemartin
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 2026-09-09 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: cli_class_tool
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: 0.4.0
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - ">="
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: 0.4.0
|
|
13
26
|
- !ruby/object:Gem::Dependency
|
|
14
27
|
name: octokit
|
|
15
28
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -38,19 +51,23 @@ files:
|
|
|
38
51
|
- README.md
|
|
39
52
|
- bin/git-maintain
|
|
40
53
|
- git-maintain-completion.sh
|
|
41
|
-
- lib/
|
|
42
|
-
- lib/
|
|
43
|
-
- lib/
|
|
44
|
-
- lib/
|
|
45
|
-
- lib/
|
|
46
|
-
- lib/
|
|
47
|
-
- lib/
|
|
48
|
-
- lib/
|
|
54
|
+
- lib/git-maintain.rb
|
|
55
|
+
- lib/git-maintain/addons/RDMACore.rb
|
|
56
|
+
- lib/git-maintain/addons/git-maintain.rb
|
|
57
|
+
- lib/git-maintain/addons/healthd.rb
|
|
58
|
+
- lib/git-maintain/addons/hpc-testing.rb
|
|
59
|
+
- lib/git-maintain/azure.rb
|
|
60
|
+
- lib/git-maintain/branch.rb
|
|
61
|
+
- lib/git-maintain/branch_iterator.rb
|
|
62
|
+
- lib/git-maintain/ci.rb
|
|
63
|
+
- lib/git-maintain/common.rb
|
|
64
|
+
- lib/git-maintain/error.rb
|
|
65
|
+
- lib/git-maintain/repo.rb
|
|
66
|
+
- lib/git-maintain/travis.rb
|
|
49
67
|
homepage: https://github.com/nmorey/git-maintain
|
|
50
68
|
licenses:
|
|
51
69
|
- GPL-3.0
|
|
52
70
|
metadata: {}
|
|
53
|
-
post_install_message:
|
|
54
71
|
rdoc_options: []
|
|
55
72
|
require_paths:
|
|
56
73
|
- lib
|
|
@@ -65,8 +82,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
65
82
|
- !ruby/object:Gem::Version
|
|
66
83
|
version: '0'
|
|
67
84
|
requirements: []
|
|
68
|
-
rubygems_version:
|
|
69
|
-
signing_key:
|
|
85
|
+
rubygems_version: 4.0.16
|
|
70
86
|
specification_version: 4
|
|
71
87
|
summary: Your ultimate script for maintaining stable branches and releasing your project.
|
|
72
88
|
test_files: []
|
data/lib/azure.rb
DELETED
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
module GitMaintain
|
|
2
|
-
class AzureCI < CI
|
|
3
|
-
AZURE_URL='https://dev.azure.com/'
|
|
4
|
-
|
|
5
|
-
def initialize(repo, stable='', valid='')
|
|
6
|
-
super(repo)
|
|
7
|
-
@url = AZURE_URL
|
|
8
|
-
@stable_org=stable
|
|
9
|
-
@valid_org=valid
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
private
|
|
13
|
-
def getState(sha1, resp)
|
|
14
|
-
br = findBranch(sha1, resp)
|
|
15
|
-
return "not found" if br == nil
|
|
16
|
-
return "started" if br["result"] == nil
|
|
17
|
-
return br["result"].to_s()
|
|
18
|
-
end
|
|
19
|
-
def getLog(sha1, resp)
|
|
20
|
-
str=""
|
|
21
|
-
# br = findBranch(sha1, resp)
|
|
22
|
-
# raise("Travis build not found") if br == nil
|
|
23
|
-
# job_id = br["id"].to_s()
|
|
24
|
-
# logs= getJson(@url, "azure_log_list" + job_id,
|
|
25
|
-
# @repo.name + "/_apis/build/builds/#{job_id}/logs?api-version=5.1")
|
|
26
|
-
# 1.upto(logs["count"]) { |x|
|
|
27
|
-
# log(:DEBUG_CI, "Downloading log file #{x}/#{logs["count"]}")
|
|
28
|
-
# nzstr = getJson(@url, "azure_log_" + job_id + '_' + x.to_s(),
|
|
29
|
-
# @repo.name + "/_apis/build/builds/#{job_id}/logs/#{x}?api-version=5.1", false)
|
|
30
|
-
# # This is zipped. We need to extract it
|
|
31
|
-
# }
|
|
32
|
-
return str
|
|
33
|
-
end
|
|
34
|
-
def getTS(sha1, resp)
|
|
35
|
-
br = findBranch(sha1, resp)
|
|
36
|
-
raise("Travis build not found") if br == nil
|
|
37
|
-
return br["startTime"]
|
|
38
|
-
end
|
|
39
|
-
def checkState(sha1, resp)
|
|
40
|
-
st = getState(sha1, resp)
|
|
41
|
-
return st == "passed" || st == "succeeded"
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def getBrValidJson()
|
|
45
|
-
raise("Validation organisation not provided") if @valid_org == ''
|
|
46
|
-
return getJson(@url + @valid_org + '/',
|
|
47
|
-
:azure_br_valid, @repo.name + '/_apis/build/builds?api-version=5.1')
|
|
48
|
-
end
|
|
49
|
-
def getBrStableJson()
|
|
50
|
-
raise("Stable organisation not provided") if @stable_org == ''
|
|
51
|
-
return getJson(@url + @stable_org + '/',
|
|
52
|
-
:azure_br_stable, @repo.name + '/_apis/build/builds?api-version=5.1')
|
|
53
|
-
end
|
|
54
|
-
def findBranch(sha1, resp)
|
|
55
|
-
log(:DEBUG_CI, "Looking for build for #{sha1}")
|
|
56
|
-
resp["value"].each(){|br|
|
|
57
|
-
commit= br["sourceVersion"]
|
|
58
|
-
raise("Incomplete JSON received from Travis") if commit == nil
|
|
59
|
-
log(:DEBUG_CI, "Found entry for sha #{commit}")
|
|
60
|
-
next if commit != sha1
|
|
61
|
-
return br
|
|
62
|
-
}
|
|
63
|
-
return nil
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
public
|
|
67
|
-
def getValidState(br, sha1)
|
|
68
|
-
return getState(sha1, getBrValidJson())
|
|
69
|
-
end
|
|
70
|
-
def checkValidState(br, sha1)
|
|
71
|
-
return checkState(sha1, getBrValidJson())
|
|
72
|
-
end
|
|
73
|
-
def getValidLog(br, sha1)
|
|
74
|
-
return getLog(sha1, getBrValidJson())
|
|
75
|
-
end
|
|
76
|
-
def getValidTS(br, sha1)
|
|
77
|
-
return getTS(sha1, getBrValidJson())
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
def getStableState(br, sha1)
|
|
81
|
-
return getState(sha1, getBrStableJson())
|
|
82
|
-
end
|
|
83
|
-
def checkStableState(br, sha1)
|
|
84
|
-
return checkState(sha1, getBrStableJson())
|
|
85
|
-
end
|
|
86
|
-
def getStableLog(br, sha1)
|
|
87
|
-
return getLog(sha1, getBrStableJson())
|
|
88
|
-
end
|
|
89
|
-
def getStableTS(br, sha1)
|
|
90
|
-
return getTS(sha1, getBrStableJson())
|
|
91
|
-
end
|
|
92
|
-
def isErrored(br, status)
|
|
93
|
-
# https://docs.microsoft.com/en-us/rest/api/azure/devops/build/builds/list?
|
|
94
|
-
# view=azure-devops-rest-5.1#buildresult
|
|
95
|
-
return status == "failed"
|
|
96
|
-
end
|
|
97
|
-
end
|
|
98
|
-
end
|
data/lib/ci.rb
DELETED
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
module GitMaintain
|
|
2
|
-
class CI
|
|
3
|
-
|
|
4
|
-
def self.load(repo)
|
|
5
|
-
repo_name = File.basename(repo.path)
|
|
6
|
-
return GitMaintain::loadClass(CI, repo_name, repo)
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
def initialize(repo)
|
|
10
|
-
GitMaintain::checkDirectConstructor(self.class)
|
|
11
|
-
|
|
12
|
-
@repo = repo
|
|
13
|
-
@cachedJson={}
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
private
|
|
17
|
-
def log(lvl, str)
|
|
18
|
-
GitMaintain::log(lvl, str)
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def fetch(uri_str, limit = 10)
|
|
22
|
-
# You should choose a better exception.
|
|
23
|
-
raise ArgumentError, 'too many HTTP redirects' if limit == 0
|
|
24
|
-
|
|
25
|
-
response = Net::HTTP.get_response(URI(uri_str))
|
|
26
|
-
|
|
27
|
-
case response
|
|
28
|
-
when Net::HTTPSuccess then
|
|
29
|
-
response
|
|
30
|
-
when Net::HTTPRedirection then
|
|
31
|
-
location = response['location']
|
|
32
|
-
fetch(location, limit - 1)
|
|
33
|
-
else
|
|
34
|
-
response.value
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
def getJson(base_url, query_label, query, json=true)
|
|
38
|
-
return @cachedJson[query_label] if @cachedJson[query_label] != nil
|
|
39
|
-
url = base_url + query
|
|
40
|
-
uri = URI(url)
|
|
41
|
-
log(:INFO, "Querying CI...")
|
|
42
|
-
log(:DEBUG_CI, url)
|
|
43
|
-
response = fetch(uri)
|
|
44
|
-
raise("CI request failed '#{url}'") if response.code.to_s() != '200'
|
|
45
|
-
|
|
46
|
-
if json == true
|
|
47
|
-
@cachedJson[query_label] = JSON.parse(response.body)
|
|
48
|
-
else
|
|
49
|
-
@cachedJson[query_label] = response.body
|
|
50
|
-
end
|
|
51
|
-
return @cachedJson[query_label]
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
public
|
|
55
|
-
def getValidState(br, sha1)
|
|
56
|
-
raise("Unimplemented")
|
|
57
|
-
end
|
|
58
|
-
def checkValidState(br, sha1)
|
|
59
|
-
raise("Unimplemented")
|
|
60
|
-
end
|
|
61
|
-
def getValidLog(br, sha1)
|
|
62
|
-
raise("Unimplemented")
|
|
63
|
-
end
|
|
64
|
-
def getValidTS(br, sha1)
|
|
65
|
-
raise("Unimplemented")
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
def getStableState(br, sha1)
|
|
69
|
-
raise("Unimplemented")
|
|
70
|
-
end
|
|
71
|
-
def checkStableState(br, sha1)
|
|
72
|
-
raise("Unimplemented")
|
|
73
|
-
end
|
|
74
|
-
def getStableLog(br, sha1)
|
|
75
|
-
raise("Unimplemented")
|
|
76
|
-
end
|
|
77
|
-
def getStableTS(br, sha1)
|
|
78
|
-
raise("Unimplemented")
|
|
79
|
-
end
|
|
80
|
-
def emptyCache()
|
|
81
|
-
@cachedJson={}
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
def isErrored(br, status)
|
|
85
|
-
raise("Unimplemented")
|
|
86
|
-
end
|
|
87
|
-
end
|
|
88
|
-
end
|
data/lib/common.rb
DELETED
|
@@ -1,259 +0,0 @@
|
|
|
1
|
-
$LOAD_PATH.push(BACKPORT_LIB_DIR)
|
|
2
|
-
|
|
3
|
-
require 'ci'
|
|
4
|
-
require 'travis'
|
|
5
|
-
require 'azure'
|
|
6
|
-
require 'repo'
|
|
7
|
-
require 'branch'
|
|
8
|
-
|
|
9
|
-
$LOAD_PATH.pop()
|
|
10
|
-
|
|
11
|
-
class String
|
|
12
|
-
# colorization
|
|
13
|
-
@@is_a_tty = nil
|
|
14
|
-
def colorize(color_code)
|
|
15
|
-
@@is_a_tty = STDOUT.isatty() if @@is_a_tty == nil
|
|
16
|
-
if @@is_a_tty then
|
|
17
|
-
return "\e[#{color_code}m#{self}\e[0m"
|
|
18
|
-
else
|
|
19
|
-
return self
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def red
|
|
24
|
-
colorize(31)
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def green
|
|
28
|
-
colorize(32)
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def brown
|
|
32
|
-
colorize(33)
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def blue
|
|
36
|
-
colorize(34)
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def magenta
|
|
40
|
-
colorize(35)
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
module GitMaintain
|
|
45
|
-
class Common
|
|
46
|
-
ACTION_LIST = [ :list_actions ]
|
|
47
|
-
ACTION_HELP = {}
|
|
48
|
-
def self.execAction(opts, action)
|
|
49
|
-
puts GitMaintain::getActionAttr("ACTION_LIST").join("\n")
|
|
50
|
-
end
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
ACTION_CLASS = [ Common, Branch, Repo ]
|
|
54
|
-
@@custom_classes = {}
|
|
55
|
-
@@load_class = []
|
|
56
|
-
@@verbose_log = false
|
|
57
|
-
|
|
58
|
-
def registerCustom(repo_name, classes)
|
|
59
|
-
raise("Multiple class for repo #{repo_name}") if @@custom_classes[repo_name] != nil
|
|
60
|
-
classes[:name] = repo_name if classes[:name] == nil
|
|
61
|
-
@@custom_classes[repo_name] = classes
|
|
62
|
-
end
|
|
63
|
-
module_function :registerCustom
|
|
64
|
-
|
|
65
|
-
def getClass(default_class, repo_name = File.basename(Dir.pwd()))
|
|
66
|
-
custom = @@custom_classes[repo_name]
|
|
67
|
-
if custom != nil && custom[default_class] != nil then
|
|
68
|
-
log(:DEBUG,"Detected custom #{default_class} class for repo '#{repo_name}'")
|
|
69
|
-
return custom[default_class]
|
|
70
|
-
else
|
|
71
|
-
log(:DEBUG,"Detected NO custom #{default_class} classes for repo '#{repo_name}'")
|
|
72
|
-
return default_class
|
|
73
|
-
end
|
|
74
|
-
end
|
|
75
|
-
module_function :getClass
|
|
76
|
-
|
|
77
|
-
def getCustomClasses()
|
|
78
|
-
return @@custom_classes
|
|
79
|
-
end
|
|
80
|
-
module_function :getCustomClasses
|
|
81
|
-
|
|
82
|
-
def loadClass(default_class, repo_name, *more)
|
|
83
|
-
@@load_class.push(default_class)
|
|
84
|
-
obj = GitMaintain::getClass(default_class, repo_name).new(*more)
|
|
85
|
-
@@load_class.pop()
|
|
86
|
-
return obj
|
|
87
|
-
end
|
|
88
|
-
module_function :loadClass
|
|
89
|
-
|
|
90
|
-
# Check that the constructor was called through loadClass
|
|
91
|
-
def checkDirectConstructor(theClass)
|
|
92
|
-
curLoad= @@load_class.last()
|
|
93
|
-
cl = theClass
|
|
94
|
-
while cl != Object
|
|
95
|
-
return if cl == curLoad
|
|
96
|
-
cl = cl.superclass
|
|
97
|
-
end
|
|
98
|
-
raise("Use GitMaintain::loadClass to construct a #{theClass} class")
|
|
99
|
-
end
|
|
100
|
-
module_function :checkDirectConstructor
|
|
101
|
-
|
|
102
|
-
def getActionAttr(attr)
|
|
103
|
-
if Common.const_get(attr).class == Hash
|
|
104
|
-
return ACTION_CLASS.inject({}){|h, x| h.merge(getClass(x).const_get(attr))}
|
|
105
|
-
else
|
|
106
|
-
return ACTION_CLASS.map(){|x| getClass(x).const_get(attr)}.flatten()
|
|
107
|
-
end
|
|
108
|
-
end
|
|
109
|
-
module_function :getActionAttr
|
|
110
|
-
|
|
111
|
-
def setOpts(action, optsParser, opts)
|
|
112
|
-
ACTION_CLASS.each(){|x|
|
|
113
|
-
if x::ACTION_LIST.index(action) != nil &&
|
|
114
|
-
x.singleton_methods().index(:set_opts) != nil then
|
|
115
|
-
matched=true
|
|
116
|
-
x.set_opts(action, optsParser, opts)
|
|
117
|
-
end
|
|
118
|
-
# Try to add repo specific opts
|
|
119
|
-
y = getClass(x)
|
|
120
|
-
if x != y && y::ACTION_LIST.index(action) != nil &&
|
|
121
|
-
y.singleton_methods().index(:set_opts) != nil then
|
|
122
|
-
matched=true
|
|
123
|
-
x.set_opts(action, optsParser, opts) if x.singleton_methods().index(:set_opts) != nil
|
|
124
|
-
y.set_opts(action, optsParser, opts)
|
|
125
|
-
end
|
|
126
|
-
break if matched == true
|
|
127
|
-
}
|
|
128
|
-
end
|
|
129
|
-
module_function :setOpts
|
|
130
|
-
|
|
131
|
-
def checkOpts(opts)
|
|
132
|
-
ACTION_CLASS.each(){|x|
|
|
133
|
-
if x::ACTION_LIST.index(opts[:action]) != nil &&
|
|
134
|
-
x.singleton_methods().index(:check_opts) != nil then
|
|
135
|
-
matched=true
|
|
136
|
-
x.check_opts(opts)
|
|
137
|
-
end
|
|
138
|
-
|
|
139
|
-
# Try to add repo specific opts
|
|
140
|
-
y = getClass(x)
|
|
141
|
-
if x != y && y::ACTION_LIST.index(opts[:action]) != nil &&
|
|
142
|
-
y.singleton_methods().index(:check_opts) != nil then
|
|
143
|
-
matched=true
|
|
144
|
-
x.check_opts(opts) if x.singleton_methods().index(:check_opts) != nil
|
|
145
|
-
y.check_opts(opts)
|
|
146
|
-
end
|
|
147
|
-
break if matched == true
|
|
148
|
-
}
|
|
149
|
-
end
|
|
150
|
-
module_function :checkOpts
|
|
151
|
-
|
|
152
|
-
def execAction(opts, action)
|
|
153
|
-
ACTION_CLASS.each(){|x|
|
|
154
|
-
if x::ACTION_LIST.index(action) != nil
|
|
155
|
-
return x.execAction(opts, action)
|
|
156
|
-
end
|
|
157
|
-
# Try to add repo specific opts
|
|
158
|
-
y = getClass(x)
|
|
159
|
-
if x != y && y::ACTION_LIST.index(opts[:action]) != nil then
|
|
160
|
-
return y.execAction(opts, action)
|
|
161
|
-
end
|
|
162
|
-
}
|
|
163
|
-
end
|
|
164
|
-
module_function :execAction
|
|
165
|
-
|
|
166
|
-
def confirm(opts, msg, ignore_default=false)
|
|
167
|
-
rep = 't'
|
|
168
|
-
while rep != "y" && rep != "n" && rep != '' do
|
|
169
|
-
puts "Do you wish to #{msg} ? (y/N): "
|
|
170
|
-
case (ignore_default == true ? nil : opts[:yn_default])
|
|
171
|
-
when :no
|
|
172
|
-
puts "Auto-replying no due to --no option"
|
|
173
|
-
rep = 'n'
|
|
174
|
-
when :yes
|
|
175
|
-
puts "Auto-replying yes due to --yes option"
|
|
176
|
-
rep = 'y'
|
|
177
|
-
else
|
|
178
|
-
rep = STDIN.gets.chomp()
|
|
179
|
-
end
|
|
180
|
-
end
|
|
181
|
-
return rep
|
|
182
|
-
end
|
|
183
|
-
module_function :confirm
|
|
184
|
-
|
|
185
|
-
def checkLog(opts, br1, br2, action_msg)
|
|
186
|
-
puts "Diff between #{br1} and #{br2}"
|
|
187
|
-
puts `git log --format=oneline #{br1} ^#{br2}`
|
|
188
|
-
return "n" if action_msg.to_s() == ""
|
|
189
|
-
rep = confirm(opts, "#{action_msg} this branch")
|
|
190
|
-
return rep
|
|
191
|
-
end
|
|
192
|
-
module_function :checkLog
|
|
193
|
-
|
|
194
|
-
def showLog(opts, br1, br2)
|
|
195
|
-
log(:INFO, "Diff between #{br1} and #{br2}")
|
|
196
|
-
puts `git log --format=oneline #{br1} ^#{br2}`
|
|
197
|
-
return "n"
|
|
198
|
-
end
|
|
199
|
-
module_function :showLog
|
|
200
|
-
|
|
201
|
-
def _log(lvl, str, out=STDOUT)
|
|
202
|
-
puts("# " + lvl.to_s() + ": " + str)
|
|
203
|
-
end
|
|
204
|
-
module_function :_log
|
|
205
|
-
|
|
206
|
-
def log(lvl, str)
|
|
207
|
-
case lvl
|
|
208
|
-
when :DEBUG
|
|
209
|
-
_log("DEBUG".magenta(), str) if ENV["DEBUG"].to_s() != ""
|
|
210
|
-
when :DEBUG_CI
|
|
211
|
-
_log("DEBUG_CI".magenta(), str) if ENV["DEBUG_CI"].to_s() != ""
|
|
212
|
-
when :VERBOSE
|
|
213
|
-
_log("INFO".blue(), str) if @@verbose_log == true
|
|
214
|
-
when :INFO
|
|
215
|
-
_log("INFO".green(), str)
|
|
216
|
-
when :WARNING
|
|
217
|
-
_log("WARNING".brown(), str)
|
|
218
|
-
when :ERROR
|
|
219
|
-
_log("ERROR".red(), str, STDERR)
|
|
220
|
-
else
|
|
221
|
-
_log(lvl, str)
|
|
222
|
-
end
|
|
223
|
-
end
|
|
224
|
-
module_function :log
|
|
225
|
-
|
|
226
|
-
def crit(msg)
|
|
227
|
-
log(:ERROR, msg)
|
|
228
|
-
raise msg
|
|
229
|
-
end
|
|
230
|
-
module_function :crit
|
|
231
|
-
|
|
232
|
-
def setVerbose(val)
|
|
233
|
-
@@verbose_log = val
|
|
234
|
-
end
|
|
235
|
-
module_function :setVerbose
|
|
236
|
-
end
|
|
237
|
-
$LOAD_PATH.pop()
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
# Load all custom classes
|
|
241
|
-
$LOAD_PATH.push(BACKPORT_LIB_DIR + "/addons/")
|
|
242
|
-
Dir.entries(BACKPORT_LIB_DIR + "/addons/").each(){|entry|
|
|
243
|
-
next if (!File.file?(BACKPORT_LIB_DIR + "/addons/" + entry) || entry !~ /\.rb$/ );
|
|
244
|
-
require entry.sub(/.rb$/, "")
|
|
245
|
-
}
|
|
246
|
-
$LOAD_PATH.pop()
|
|
247
|
-
|
|
248
|
-
if ENV["GIT_MAINTAIN_ADDON_DIR"].to_s() != "" then
|
|
249
|
-
ADDON_DIR=ENV["GIT_MAINTAIN_ADDON_DIR"].to_s()
|
|
250
|
-
if Dir.exist?(ADDON_DIR) then
|
|
251
|
-
$LOAD_PATH.push(ADDON_DIR)
|
|
252
|
-
Dir.entries(ADDON_DIR).each(){|entry|
|
|
253
|
-
next if (!File.file?(ADDON_DIR + "/" + entry) || entry !~ /\.rb$/ );
|
|
254
|
-
require entry.sub(/.rb$/, "")
|
|
255
|
-
}
|
|
256
|
-
$LOAD_PATH.pop()
|
|
257
|
-
end
|
|
258
|
-
end
|
|
259
|
-
|