Class: GitRestart::Task
- Inherits:
-
Object
- Object
- GitRestart::Task
- Defined in:
- lib/git-restart/task.rb
Overview
This class is used to define “Tasks”. Each task represents a set of commands, which it executes in chronological order, or until a task errors. Additionally, it will kill execution of tasks with a specified kill-signal when an update was detected from GitHub. The failure-status of the tasks can also be reported via Octokit, allowing this to be used as a simple CI or Test system for various languages.
Instance Attribute Summary collapse
-
#active ⇒ Object
Whether or not this task is active.
-
#ci_task ⇒ Object
Defines this as a “CI_Task”.
-
#expect_clean_exit ⇒ Object
Whether or not to report failure if the currently running target has a non-zero exit status after having been killed.
-
#lastStatus ⇒ Object
readonly
The last status-code of this Task.
-
#name ⇒ Object
Name of the Task.
-
#report_status ⇒ Object
Whether or not to report failure/success status to GitHub using Octokit.
-
#signal ⇒ Object
The signal (as String, like Signal.list) to use to kill the process.
-
#status_file ⇒ Object
The file to use to retrieve a single-line status info for the “description” string of the GitHub status.
-
#status_message ⇒ Object
readonly
The last status-message of this task.
-
#targets ⇒ Array<String>
readonly
The array of tasks to execute.
Class Method Summary collapse
- .runner ⇒ Object private
- .runner=(runner) ⇒ Object private
Instance Method Summary collapse
- #_get_statusline ⇒ Object
-
#branch ⇒ String
Name of the current branch.
-
#current_commit ⇒ String
Full SHA of the current commit.
-
#initialize {|_self| ... } ⇒ Task
constructor
Create a new Task.
-
#join ⇒ Object
Wait for this task to finish execution.
-
#modified ⇒ Array<String>
A list of all files that were modified in the commit we are checking.
-
#on_branches(branches) ⇒ Object
Specify which branches to run on.
-
#runner ⇒ GitRestart::Runner
Responsible Runner class.
-
#start ⇒ Object
private
Starts this task.
-
#stop ⇒ Object
private
Stop this task.
-
#triggered? ⇒ Boolean
private
Checks whether or not the current set of modified files would require this task to be (re)started.
-
#valid? ⇒ Boolean
private
Checks whether or not this task has been set up properly.
-
#watch(regEx) ⇒ Object
Use this function to specify which files trigger a restart for this Task Files can be specified as a RegEx, and can be “local/like.this” or “/reference/from/project.root”.
Constructor Details
#initialize {|_self| ... } ⇒ Task
Create a new Task. This function does not take any input values, instead, one has to set the class up inside the block! A validity check will be run directly after yield(), as such, at the very least the name and a valid signal must have been specified!
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 |
# File 'lib/git-restart/task.rb', line 99 def initialize() @statuschange_mutex = Mutex.new(); @targets = Array.new(); @watched = Array.new(); @signal = "INT" @expect_clean_exit = true; @exiting = false; @lastStatus = 0; @chdir = File.dirname(runner().current_task_file); watch(File.basename(runner().current_task_file)); yield(self); valid? @status_file ||= "/tmp/TaskLog_#{@name}_#{current_commit()}"; if(runner().next_tasks[@name]) raise TaskValidityError, "A task of name #{@name} already exists!" else runner().next_tasks[@name] = self; end end |
Instance Attribute Details
#active ⇒ Object
Whether or not this task is active. Usually set via #on_branches, but can be used to manually disable or enable this task based on config files, ENV variables etc.
44 45 46 |
# File 'lib/git-restart/task.rb', line 44 def active @active end |
#ci_task ⇒ Object
Defines this as a “CI_Task”. Such a task will always run on an update, regardless what files changed. Useful if you always want a status report on GitHub.
33 34 35 |
# File 'lib/git-restart/task.rb', line 33 def ci_task @ci_task end |
#expect_clean_exit ⇒ Object
Whether or not to report failure if the currently running target has a non-zero exit status after having been killed. Only makes sense together with report_status
27 28 29 |
# File 'lib/git-restart/task.rb', line 27 def expect_clean_exit @expect_clean_exit end |
#lastStatus ⇒ Object (readonly)
The last status-code of this Task. Used internally.
47 48 49 |
# File 'lib/git-restart/task.rb', line 47 def lastStatus @lastStatus end |
#name ⇒ Object
Name of the Task. Required. Used as unique ID, and to report status to GitHub
35 36 37 |
# File 'lib/git-restart/task.rb', line 35 def name @name end |
#report_status ⇒ Object
Whether or not to report failure/success status to GitHub using Octokit
29 30 31 |
# File 'lib/git-restart/task.rb', line 29 def report_status @report_status end |
#signal ⇒ Object
The signal (as String, like Signal.list) to use to kill the process. Can be nil to disable killing
23 24 25 |
# File 'lib/git-restart/task.rb', line 23 def signal @signal end |
#status_file ⇒ Object
The file to use to retrieve a single-line status info for the “description” string of the GitHub status. Only the last non-indented line is used, which allows the output of Minitest to be used directly.
39 40 41 |
# File 'lib/git-restart/task.rb', line 39 def status_file @status_file end |
#status_message ⇒ Object (readonly)
The last status-message of this task. Used internally.
49 50 51 |
# File 'lib/git-restart/task.rb', line 49 def @status_message end |
#targets ⇒ Array<String> (readonly)
The array of tasks to execute. Each target will be executed in the given order via Process.spawn.
19 20 21 |
# File 'lib/git-restart/task.rb', line 19 def targets @targets end |
Class Method Details
.runner ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
56 57 58 |
# File 'lib/git-restart/task.rb', line 56 def self.runner() return @runner; end |
.runner=(runner) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
52 53 54 |
# File 'lib/git-restart/task.rb', line 52 def self.runner=(runner) @runner = runner; end |
Instance Method Details
#_get_statusline ⇒ Object
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 |
# File 'lib/git-restart/task.rb', line 168 def _get_statusline() return "No status specified" unless File.exist? @status_file sMsg = "" File.open(@status_file, "r") do |sFile| sFile.each_line do |l| l.chomp! next if l == ""; next if l =~ /^\s+/; sMsg = l; end end return sMsg; end |
#branch ⇒ String
Returns Name of the current branch.
65 66 67 |
# File 'lib/git-restart/task.rb', line 65 def branch() runner().current_branch(); end |
#current_commit ⇒ String
Returns Full SHA of the current commit.
69 70 71 |
# File 'lib/git-restart/task.rb', line 69 def current_commit() runner().current_commit(); end |
#join ⇒ Object
Wait for this task to finish execution. Either by naturally ending, or by being killed.
265 266 267 |
# File 'lib/git-restart/task.rb', line 265 def join() @executionThread.join(); end |
#modified ⇒ Array<String>
Returns A list of all files that were modified in the commit we are checking.
74 75 76 |
# File 'lib/git-restart/task.rb', line 74 def modified() runner().current_modified(); end |
#on_branches(branches) ⇒ Object
Specify which branches to run on. Not needed if “active” is just set to true
89 90 91 92 93 |
# File 'lib/git-restart/task.rb', line 89 def on_branches(branches) [branches].flatten.each do |b| @active |= (b == branch()); end end |
#runner ⇒ GitRestart::Runner
Returns Responsible Runner class.
60 61 62 |
# File 'lib/git-restart/task.rb', line 60 def runner() return self.class.runner(); end |
#start ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Starts this task. Once the task has been started it will run each given target one after another, waiting for each one to finish. If @report_status is set, it will also do just that. Task execution is handled within a thread, meaning that the function itself does not block.
203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 |
# File 'lib/git-restart/task.rb', line 203 def start() puts "Starting Task: #{@name}" if @targets.empty? _report_status(:success, "No tasks to run!"); return end @executionThread = Thread.new do _report_status(:pending); _rm_logfile(); @targets.each do |target| # Mutex to ensure there either is no task running or a PID given @statuschange_mutex.synchronize { break if @exiting = { [:out, :err] => "/tmp/TaskLog_#{@name}_#{current_commit()}" } [:chdir] = @chdir if @chdir @currentPID = Process.spawn(target, ); } status = Process.wait2(@currentPID)[1]; @currentPID = nil; @lastStatus = status.exitstatus(); break unless @lastStatus == 0; end if(@lastStatus == 0) _report_status(:success); _rm_logfile(); elsif(!@exiting || @expect_clean_exit) _report_status(:failure); end end @executionThread.abort_on_exception = true; sleep 0.01 end |
#stop ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Stop this task. Stopping it means immediately killing the currently running target with the specified signal, and not running any further targets. Except when nil is specified as signal, in which case the stop will be ignored!
251 252 253 254 255 256 257 258 259 260 261 |
# File 'lib/git-restart/task.rb', line 251 def stop() puts "Stopping Task: #{@name}" return if @signal.nil? @statuschange_mutex.synchronize { @exiting = true; if(p = @currentPID) Process.kill(@signal, p); end } end |
#triggered? ⇒ Boolean
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Checks whether or not the current set of modified files would require this task to be (re)started. Always returns true if @ci_task is set, or if the runner just has been started using @start_on
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/git-restart/task.rb', line 131 def triggered? return true if modified().nil? return true if @ci_task @watched.each do |regEx| modified().each do |f| if regEx.to_s =~ /^\(\?\-mix:\\\/(.*)\)$/ then return true if f =~ Regexp.new($1); else next unless f =~ /#{Regexp.quote(@chdir)}(.*)/ return true if $1 =~ regEx; end end end return false; end |
#valid? ⇒ Boolean
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Checks whether or not this task has been set up properly. Currently only checks the name and abort signal.
152 153 154 155 156 157 158 159 160 |
# File 'lib/git-restart/task.rb', line 152 def valid?() unless Signal.list[@signal] or @signal.nil? raise TaskValidityError, "The specified kill-signal is not valid!" end unless @name raise TaskValidityError, "A name needs to be set for identification!" end end |
#watch(regEx) ⇒ Object
Use this function to specify which files trigger a restart for this Task Files can be specified as a RegEx, and can be “local/like.this” or “/reference/from/project.root”
80 81 82 83 84 85 86 |
# File 'lib/git-restart/task.rb', line 80 def watch(regEx) if(regEx.is_a? String) regEx = Regexp.quote(regEx); end @watched << Regexp.new(regEx); end |