git-restart 0.0.3.pre.dev → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/git-restart +11 -3
- data/lib/git-restart/runner.rb +48 -16
- data/lib/git-restart/task.rb +80 -11
- metadata +19 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a6e1ed81be5f1e1b88b5f03998ed168bb3cea967
|
4
|
+
data.tar.gz: 64ecf291feb17510fdaf4e95eb310da327bfa0dd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5fed7452a908ac52db44e2b32ae5d5c773d839ffdeb7f956b44f1dbbbd409fc3e1a7bf4ce8d8587c05bd1a4ee14c5b1acd6c29eaf77c633c98b3c3aa340c7191
|
7
|
+
data.tar.gz: d1779c9e0efedceeb64fc65c34901d659beec6ab3c1cbb80734328a2f9754a76f106343ff7b04f76bd80f79b74a5cef62b4d0d6b2886e28cb1063609ae118e8e
|
data/bin/git-restart
CHANGED
@@ -5,10 +5,18 @@ require 'git-restart/runner.rb'
|
|
5
5
|
|
6
6
|
puts "Starting runner ..."
|
7
7
|
|
8
|
-
|
8
|
+
$taskfiles = Array.new();
|
9
|
+
target = ".gitrun"
|
10
|
+
ARGV.each do |t|
|
11
|
+
if(t =~ /\.gitrun$/)
|
12
|
+
target = t;
|
13
|
+
else
|
14
|
+
$taskfiles << t;
|
15
|
+
end
|
16
|
+
end
|
9
17
|
|
10
|
-
raise ArgumentError, "No valid
|
18
|
+
raise ArgumentError, "No valid runner file specified!" unless File.exist? target
|
11
19
|
|
12
20
|
load target
|
13
21
|
|
14
|
-
GitRestart::Task.runner.mqtt.
|
22
|
+
GitRestart::Task.runner.mqtt.lockAndListen
|
data/lib/git-restart/runner.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
|
2
2
|
require 'mqtt/sub_handler'
|
3
|
+
|
3
4
|
require 'git'
|
5
|
+
require 'octokit'
|
4
6
|
|
5
7
|
require_relative "task.rb"
|
6
8
|
|
@@ -9,12 +11,16 @@ module GitRestart
|
|
9
11
|
attr_accessor :name
|
10
12
|
|
11
13
|
attr_accessor :repo, :branches, :exclude_branches, :start_on
|
14
|
+
attr_accessor :allowed_tasks
|
12
15
|
|
13
16
|
attr_reader :next_tasks
|
14
17
|
attr_reader :current_task_file
|
15
18
|
|
19
|
+
attr_reader :mqtt
|
20
|
+
attr_accessor :octokit
|
21
|
+
|
16
22
|
def current_commit()
|
17
|
-
@git.object("HEAD
|
23
|
+
@git.object("HEAD").sha;
|
18
24
|
end
|
19
25
|
def current_branch()
|
20
26
|
@git.current_branch();
|
@@ -23,9 +29,15 @@ module GitRestart
|
|
23
29
|
@current_modified;
|
24
30
|
end
|
25
31
|
|
26
|
-
def initialize()
|
32
|
+
def initialize(fileList = nil)
|
33
|
+
raise ArgumentError, "File list needs to be nil or an Array!" unless (fileList.is_a? Array or fileList.nil?)
|
34
|
+
|
27
35
|
GitRestart::Task.runner = self;
|
28
36
|
|
37
|
+
@allowed_tasks = Array.new();
|
38
|
+
@allowed_tasks << fileList if(fileList);
|
39
|
+
@allowed_tasks << $taskfiles unless($taskfiles.empty?)
|
40
|
+
|
29
41
|
@current_tasks = Hash.new();
|
30
42
|
@next_tasks = Hash.new();
|
31
43
|
|
@@ -38,16 +50,15 @@ module GitRestart
|
|
38
50
|
|
39
51
|
yield(self);
|
40
52
|
|
53
|
+
@allowed_tasks.flatten!
|
54
|
+
|
41
55
|
@listenedSub = @mqtt.subscribe_to "GitHub/#{@repo}" do |data|
|
42
|
-
puts "Received data: #{data}"
|
43
56
|
begin
|
44
57
|
data = JSON.parse(data, symbolize_names: true);
|
45
58
|
rescue
|
46
59
|
next;
|
47
60
|
end
|
48
61
|
|
49
|
-
puts "Processing data #{data}"
|
50
|
-
|
51
62
|
next unless data[:branch];
|
52
63
|
if(not @branches.empty?)
|
53
64
|
next unless @branches.include? data[:branch];
|
@@ -55,16 +66,29 @@ module GitRestart
|
|
55
66
|
next if @exclude_branches.include? data[:branch];
|
56
67
|
end
|
57
68
|
|
58
|
-
puts "Queueing data!"
|
59
|
-
|
60
69
|
@branchQueue << data;
|
61
70
|
end
|
62
71
|
|
63
72
|
autostart();
|
64
73
|
_start_task_thread();
|
74
|
+
|
75
|
+
at_exit {
|
76
|
+
_stop_all_tasks();
|
77
|
+
}
|
65
78
|
end
|
66
79
|
|
67
80
|
def update_status(name, newStatus, message = nil)
|
81
|
+
puts "Task #{@name} assumed a new status: #{newStatus}#{message ? " MSG:#{message}" : ""}"
|
82
|
+
|
83
|
+
return unless @octokit;
|
84
|
+
|
85
|
+
begin
|
86
|
+
@octokit.create_status(@repo, current_commit(), newStatus, {
|
87
|
+
context: "#{@name}/#{name}".gsub(" ", "_"),
|
88
|
+
description: message,
|
89
|
+
})
|
90
|
+
rescue
|
91
|
+
end
|
68
92
|
end
|
69
93
|
|
70
94
|
def _start_task_thread()
|
@@ -72,8 +96,6 @@ module GitRestart
|
|
72
96
|
loop do
|
73
97
|
newData = @branchQueue.pop;
|
74
98
|
|
75
|
-
puts "Popped data: #{newData}"
|
76
|
-
|
77
99
|
@current_modified = newData[:touched];
|
78
100
|
_switch_to(newData[:branch], newData[:head_commit]);
|
79
101
|
end
|
@@ -106,23 +128,28 @@ module GitRestart
|
|
106
128
|
t.gsub!(/^\.\//,"");
|
107
129
|
@current_task_file = t;
|
108
130
|
|
109
|
-
|
131
|
+
unless(@allowed_tasks.empty?)
|
132
|
+
next unless @allowed_tasks.include? @current_task_file
|
133
|
+
end
|
134
|
+
|
110
135
|
begin
|
111
136
|
load(t);
|
112
137
|
rescue ScriptError, StandardError
|
138
|
+
update_status("File #{t}", :failure, "File could not be parsed!")
|
113
139
|
puts("File #{t} could not be loaded!");
|
114
140
|
rescue GitRestart::TaskValidityError
|
141
|
+
update_status("File #{t}", :failure, "Task-file not configured properly!")
|
115
142
|
puts("Task-File #{t} is not configured properly!");
|
116
143
|
end
|
117
144
|
end
|
118
145
|
|
119
|
-
puts "Finished loading! Next tasks
|
146
|
+
puts "Finished loading! Next tasks: #{@next_tasks.keys}"
|
120
147
|
end
|
121
148
|
|
122
149
|
def _start_next_tasks()
|
123
150
|
_generate_next_tasks();
|
124
151
|
|
125
|
-
puts "
|
152
|
+
puts "\nStarting next tasks!"
|
126
153
|
@next_tasks.each do |name, t|
|
127
154
|
next unless t.active;
|
128
155
|
next unless t.triggered?
|
@@ -133,19 +160,24 @@ module GitRestart
|
|
133
160
|
end
|
134
161
|
|
135
162
|
def _switch_to(branch, commit = nil)
|
136
|
-
puts "
|
137
|
-
|
163
|
+
puts "\n\nSwitching to branch: #{branch}#{commit ? ",commit: #{commit}" : ""}"
|
164
|
+
|
165
|
+
begin
|
166
|
+
@git.fetch();
|
167
|
+
rescue
|
168
|
+
end
|
138
169
|
|
139
170
|
if(branch != current_branch())
|
140
171
|
_stop_all_tasks();
|
141
172
|
else
|
142
173
|
_stop_triggered_tasks();
|
143
174
|
end
|
175
|
+
@git.reset_hard();
|
144
176
|
@git.checkout(branch);
|
145
|
-
@git.reset_hard(commit);
|
146
|
-
|
147
177
|
@git.merge("origin/#{branch}");
|
148
178
|
|
179
|
+
@git.reset_hard(commit);
|
180
|
+
|
149
181
|
_start_next_tasks();
|
150
182
|
end
|
151
183
|
|
data/lib/git-restart/task.rb
CHANGED
@@ -1,27 +1,58 @@
|
|
1
1
|
|
2
|
+
# @author Xasin
|
2
3
|
module GitRestart
|
4
|
+
# The Error-Class used to signal when a Task is set up wrong
|
3
5
|
class TaskValidityError < StandardError
|
4
6
|
end
|
5
7
|
|
8
|
+
# This class is used to define "Tasks". Each task represents
|
9
|
+
# a set of commands, which it executes in chronological order, or until
|
10
|
+
# a task errors.
|
11
|
+
# Additionally, it will kill execution of tasks with a specified kill-signal
|
12
|
+
# when an update was detected from GitHub.
|
13
|
+
# The failure-status of the tasks can also be reported via Octokit, allowing this
|
14
|
+
# to be used as a simple CI or Test system for various languages.
|
6
15
|
class Task
|
16
|
+
# The array of tasks to execute. Each target will be executed in the given
|
17
|
+
# order via `Process.spawn`.
|
18
|
+
# @return [Array<String>]
|
7
19
|
attr_reader :targets
|
8
20
|
|
21
|
+
# The signal (as String, like Signal.list) to use to kill the process.
|
22
|
+
# Can be nil to disable killing
|
9
23
|
attr_accessor :signal
|
24
|
+
# Whether or not to report failure if the currently running target
|
25
|
+
# has a non-zero exit status after having been killed. Only makes sense
|
26
|
+
# together with report_status
|
10
27
|
attr_accessor :expect_clean_exit
|
28
|
+
# Whether or not to report failure/success status to GitHub using Octokit
|
11
29
|
attr_accessor :report_status
|
30
|
+
# Defines this as a "CI_Task". Such a task will always run on an update,
|
31
|
+
# regardless what files changed. Useful if you always want a status report
|
32
|
+
# on GitHub.
|
12
33
|
attr_accessor :ci_task
|
13
|
-
|
14
|
-
|
34
|
+
# Name of the Task. *Required*. Used as *unique* ID, and to report status to GitHub
|
35
|
+
attr_accessor :name
|
36
|
+
# The file to use to retrieve a single-line status info for the "description"
|
37
|
+
# string of the GitHub status. Only the last *non-indented* line is used,
|
38
|
+
# which allows the output of Minitest to be used directly.
|
39
|
+
attr_accessor :status_file
|
40
|
+
|
41
|
+
# Whether or not this task is active. Usually set via #on_branches,
|
42
|
+
# but can be used to manually disable or enable this task based on
|
43
|
+
# config files, ENV variables etc.
|
15
44
|
attr_accessor :active
|
16
45
|
|
46
|
+
# The last status-code of this Task. Used internally.
|
17
47
|
attr_reader :lastStatus
|
48
|
+
# The last status-message of this task. Used internally.
|
18
49
|
attr_reader :status_message
|
19
50
|
|
20
|
-
|
21
|
-
|
51
|
+
# @api private
|
22
52
|
def self.runner=(runner)
|
23
53
|
@runner = runner;
|
24
54
|
end
|
55
|
+
# @api private
|
25
56
|
def self.runner()
|
26
57
|
return @runner;
|
27
58
|
end
|
@@ -32,6 +63,10 @@ module GitRestart
|
|
32
63
|
def branch()
|
33
64
|
runner().current_branch();
|
34
65
|
end
|
66
|
+
def current_commit()
|
67
|
+
runner().current_commit();
|
68
|
+
end
|
69
|
+
|
35
70
|
def modified()
|
36
71
|
runner().current_modified();
|
37
72
|
end
|
@@ -69,6 +104,8 @@ module GitRestart
|
|
69
104
|
|
70
105
|
valid?
|
71
106
|
|
107
|
+
@status_file ||= "/tmp/TaskLog_#{@name}_#{current_commit()}";
|
108
|
+
|
72
109
|
if(runner().next_tasks[@name])
|
73
110
|
raise TaskValidityError, "A task of name #{@name} already exists!"
|
74
111
|
else
|
@@ -82,8 +119,12 @@ module GitRestart
|
|
82
119
|
|
83
120
|
@watched.each do |regEx|
|
84
121
|
modified().each do |f|
|
85
|
-
|
86
|
-
|
122
|
+
if regEx.to_s =~ /^\(\?\-mix:\\\/(.*)\)$/ then
|
123
|
+
return true if f =~ Regexp.new($1);
|
124
|
+
else
|
125
|
+
next unless f =~ /#{Regexp.quote(@chdir)}(.*)/
|
126
|
+
return true if $1 =~ regEx;
|
127
|
+
end
|
87
128
|
end
|
88
129
|
end
|
89
130
|
|
@@ -100,30 +141,55 @@ module GitRestart
|
|
100
141
|
end
|
101
142
|
end
|
102
143
|
|
144
|
+
def _rm_logfile()
|
145
|
+
if File.exist?("/tmp/TaskLog_#{@name}_#{current_commit()}") then
|
146
|
+
File.delete("/tmp/TaskLog_#{@name}_#{current_commit()}");
|
147
|
+
end
|
148
|
+
end
|
149
|
+
def _get_statusline()
|
150
|
+
return "No status specified" unless File.exist? @status_file
|
151
|
+
|
152
|
+
sMsg = ""
|
153
|
+
File.open(@status_file, "r") do |sFile|
|
154
|
+
sFile.each_line do |l|
|
155
|
+
l.chomp!
|
156
|
+
next if l == "";
|
157
|
+
next if l =~ /^\s+/;
|
158
|
+
|
159
|
+
sMsg = l;
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
return sMsg;
|
164
|
+
end
|
165
|
+
|
103
166
|
def _report_status(status, message = nil)
|
104
|
-
|
167
|
+
message ||= _get_statusline();
|
168
|
+
@status_message = message;
|
105
169
|
|
106
170
|
return unless @report_status
|
107
171
|
|
108
172
|
runner().update_status(@name, status, message);
|
109
|
-
puts "Task #{@name} assumed a new status: #{status}#{message ? " MSG:#{message}" : ""}"
|
110
173
|
end
|
111
174
|
private :_report_status
|
112
175
|
|
113
176
|
def start()
|
114
177
|
puts "Starting Task: #{@name}"
|
115
178
|
|
116
|
-
|
117
|
-
|
179
|
+
if @targets.empty?
|
180
|
+
_report_status(:success, "No tasks to run!");
|
181
|
+
return
|
182
|
+
end
|
118
183
|
|
119
184
|
@executionThread = Thread.new do
|
120
185
|
_report_status(:pending);
|
121
186
|
|
187
|
+
_rm_logfile();
|
122
188
|
@targets.each do |target|
|
123
189
|
@statuschange_mutex.synchronize {
|
124
190
|
break if @exiting
|
125
191
|
options = {
|
126
|
-
[:
|
192
|
+
[:out, :err] => "/tmp/TaskLog_#{@name}_#{current_commit()}"
|
127
193
|
}
|
128
194
|
options[:chdir] = @chdir if @chdir
|
129
195
|
|
@@ -139,11 +205,14 @@ module GitRestart
|
|
139
205
|
|
140
206
|
if(@lastStatus == 0)
|
141
207
|
_report_status(:success);
|
208
|
+
_rm_logfile();
|
142
209
|
elsif(!@exiting || @expect_clean_exit)
|
143
210
|
_report_status(:failure);
|
144
211
|
end
|
145
212
|
end
|
146
213
|
@executionThread.abort_on_exception = true;
|
214
|
+
|
215
|
+
sleep 0.01
|
147
216
|
end
|
148
217
|
|
149
218
|
def stop()
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: git-restart
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.3
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Xasin
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-09-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mqtt-sub_handler
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '1.4'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: octokit
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '4.0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '4.0'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: minitest
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -107,12 +121,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
107
121
|
version: '0'
|
108
122
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
109
123
|
requirements:
|
110
|
-
- - "
|
124
|
+
- - ">="
|
111
125
|
- !ruby/object:Gem::Version
|
112
|
-
version:
|
126
|
+
version: '0'
|
113
127
|
requirements: []
|
114
128
|
rubyforge_project:
|
115
|
-
rubygems_version: 2.
|
129
|
+
rubygems_version: 2.5.2.1
|
116
130
|
signing_key:
|
117
131
|
specification_version: 4
|
118
132
|
summary: "(Re)start scripts and monitor them on a GitHub push"
|