ak47 0.2.3 → 0.2.4

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.
data/bin/ak47 CHANGED
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require 'ak47'
4
- Ak47.run(*$*)
4
+ Ak47::CLI.run(*$*)
@@ -5,57 +5,10 @@ require 'optparse'
5
5
 
6
6
  require "ak47/version"
7
7
  require "ak47/runner"
8
+ require 'ak47/cli'
8
9
 
9
10
  module Ak47
10
11
  Reload = Class.new(RuntimeError)
11
-
12
- class << self
13
- def run(*argv)
14
- argv_opts, commands = if argv == ['--help'] or argv == ['-help']
15
- [argv, []]
16
- elsif divider_index = argv.index('--')
17
- [argv[0...divider_index], argv[divider_index.succ...argv.size]]
18
- else
19
- [[], argv]
20
- end
21
-
22
- interval, maximum, error_time = nil, nil, 5
23
- optparse = OptionParser.new do |opts|
24
- opts.banner = "Usage: ak47 [cmd] / ak47 [options] -- [cmd]"
25
- opts.on( '-i', '--interval [FLOAT]', 'Interval before restarting' ) do |i|
26
- interval = Float(i) rescue raise("Interval must be a valid floating point number (e.g. -i0.5)")
27
- raise("Interval must be a positive number") unless interval >= 0
28
- end
29
- opts.on( '-m', '--maximum [FLOAT]', 'Maximum time to wait before restarting' ) do |m|
30
- maximum = Float(m) rescue raise("Maximum must be a valid floating point number (e.g. -m60)")
31
- raise("Maximum must be a positive number") unless maximum >= 0
32
- end
33
- opts.on( '-e', '--error-time [FLOAT]', 'Maximum time to wait before restarting if there was an abnormal status code' ) do |e|
34
- error_time = Float(e) rescue raise("Error time must be a valid floating point number (e.g. -e10)")
35
- raise("Maximum must be a positive number") unless error_time >= 0
36
- end
37
- opts.on( '-h', '--help', 'Display this screen' ) do
38
- puts opts
39
- exit
40
- end
41
- end
42
- optparse.parse!(argv_opts)
43
- watch_dirs = argv_opts
44
- watch_dirs << Dir.pwd if watch_dirs.empty?
45
- watch_dirs.map! { |wd| File.expand_path(wd, Dir.pwd) }
46
-
47
- command = ShellTools.escape(commands).strip
48
- if command.empty?
49
- puts optparse
50
- puts
51
- raise "No command supplied"
52
- end
53
- Runner.new(:watch_dirs => watch_dirs, :maximum => maximum, :interval => interval, :error_time => error_time, :command => command) { exec(command) }.start
54
- rescue
55
- puts $!.message.red
56
- exit 1
57
- end
58
- end
59
12
  end
60
13
 
61
14
  def Ak47(opts = nil, &blk)
@@ -0,0 +1,54 @@
1
+ module Ak47
2
+ module CLI
3
+ def self.run(*argv)
4
+ argv_opts, commands = if argv == ['--help'] or argv == ['-help']
5
+ [argv, []]
6
+ elsif divider_index = argv.index('--')
7
+ [argv[0...divider_index], argv[divider_index.succ...argv.size]]
8
+ else
9
+ [[], argv]
10
+ end
11
+
12
+ interval, maximum, error_time, interrupt = nil, nil, 5, true
13
+ optparse = OptionParser.new do |opts|
14
+ opts.banner = "Usage: ak47 [cmd] / ak47 [options] -- [cmd]"
15
+ opts.on( '-i', '--interval [FLOAT]', 'Interval before restarting' ) do |i|
16
+ interval = Float(i) rescue raise("Interval must be a valid floating point number (e.g. -i0.5)")
17
+ raise("Interval must be a positive number") unless interval >= 0
18
+ end
19
+ opts.on( '-m', '--maximum [FLOAT]', 'Maximum time to wait before restarting' ) do |m|
20
+ maximum = Float(m) rescue raise("Maximum must be a valid floating point number (e.g. -m60)")
21
+ raise("Maximum must be a positive number") unless maximum >= 0
22
+ end
23
+ opts.on( '-e', '--error-time [FLOAT]', 'Maximum time to wait before restarting if there was an abnormal status code' ) do |e|
24
+ error_time = Float(e) rescue raise("Error time must be a valid floating point number (e.g. -e10)")
25
+ raise("Maximum must be a positive number") unless error_time >= 0
26
+ end
27
+ opts.on( '-d', '--dont-interrupt', 'Don\'t interrupt a running process, wait for it to finish before reloading' ) do
28
+ interrupt = false
29
+ end
30
+ opts.on( '-h', '--help', 'Display this screen' ) do
31
+ puts opts
32
+ exit
33
+ end
34
+ end
35
+ optparse.parse!(argv_opts)
36
+ watch_dirs = argv_opts
37
+ watch_dirs << Dir.pwd if watch_dirs.empty?
38
+ watch_dirs.map! { |wd| File.expand_path(wd, Dir.pwd) }
39
+
40
+ command = ShellTools.escape(commands).strip
41
+ if command.empty?
42
+ puts optparse
43
+ puts
44
+ raise "No command supplied"
45
+ end
46
+ Runner.new(:watch_dirs => watch_dirs, :maximum => maximum, :interval => interval, :error_time => error_time, :command => command, :interrupt => interrupt) {
47
+ exec(command)
48
+ }.start
49
+ rescue
50
+ puts $!.message.red
51
+ exit 1
52
+ end
53
+ end
54
+ end
@@ -1,6 +1,6 @@
1
1
  module Ak47
2
2
  class Runner
3
- attr_reader :watch_dirs, :maximum, :interval, :error_time, :command
3
+ attr_reader :watch_dirs, :maximum, :interval, :error_time, :command, :interrupt
4
4
 
5
5
  def initialize(opts = nil, &blk)
6
6
  @watch_dirs = Array(opts && opts[:watch_dirs] || Dir.pwd)
@@ -8,17 +8,27 @@ module Ak47
8
8
  @interval = opts && opts[:interval] || 0.01
9
9
  @error_time = opts && opts[:error_time] || 5
10
10
  @command = opts && opts[:command]
11
+ @interrupt = opts && opts.key?(:interrupt) ? opts[:interrupt] : true
11
12
  @blk = blk
12
13
  end
13
14
 
14
15
  def start
15
16
  listeners = watch_dirs.map {|wd| Guard::Listener.select_and_init(:watchdir => wd, :watch_all_modifications => true) }
17
+ change_detected = false
18
+ running = false
16
19
  listeners.each do |l|
17
- l.on_change { |f| Thread.main.raise Reload, "File system changed" }
20
+ l.on_change { |f|
21
+ if @interrupt
22
+ Thread.main.raise Reload, "File system changed"
23
+ else
24
+ change_detected = true
25
+ Thread.main.raise Reload, "File system changed" unless running
26
+ end
27
+ }
18
28
  Thread.new { l.start }
19
29
  end
20
30
 
21
- at_exit { Process.kill("INT", @pid) rescue nil if @pid }
31
+ at_exit { kill_pid }
22
32
 
23
33
  puts "[Starting ak47 #{VERSION} in #{watch_dirs.join(', ')}]".green
24
34
  loop do
@@ -28,17 +38,30 @@ module Ak47
28
38
  if maximum
29
39
  @thread = Thread.new { sleep maximum; Thread.main.raise Reload, "Cancelled due to maximum time" }
30
40
  end
31
- @pid = fork(&@blk)
32
- _, status = Process.waitpid2(@pid)
41
+ running = true
42
+ change_detected = false
43
+ begin
44
+ @pid = fork(&@blk)
45
+ Process.detach(@pid)
46
+ _, status = Process.waitpid2(@pid)
47
+ ensure
48
+ running = false
49
+ end
33
50
  @thread.kill if @thread
34
51
  if status.success?
35
- puts "[Terminated, waiting for file system change]".green
36
- maximum ? sleep(interval) : sleep
52
+ if change_detected
53
+ puts "[Change detected while previously running]".green
54
+ change_detected = false
55
+ else
56
+ puts "[Terminated, waiting for file system change]".green
57
+ maximum ? sleep(interval) : sleep
58
+ end
37
59
  else
38
60
  puts "[Terminated abnormally (#{status.inspect}), retrying in 5s]".red
39
61
  sleep error_time
40
62
  end
41
63
  rescue Reload => e
64
+ kill_pid
42
65
  sleep interval
43
66
  puts "[Reloading (#{e.message}) #{Time.new.to_s}]".yellow
44
67
  rescue Interrupt
@@ -47,5 +70,33 @@ module Ak47
47
70
  end
48
71
  end
49
72
  end
73
+
74
+ def kill_pid
75
+ if @pid
76
+ begin
77
+ unless wait_pid('INT')
78
+ unless wait_pid('KILL')
79
+ raise "[Unable to kill #{@pid}]"
80
+ end
81
+ end
82
+ rescue Errno::ESRCH
83
+ end
84
+ end
85
+ end
86
+
87
+ def wait_pid(sig)
88
+ count = 0
89
+ while count < 5
90
+ begin
91
+ Process.kill(sig, @pid)
92
+ count += 1
93
+ sleep 1
94
+ rescue Errno::ESRCH
95
+ @pid = nil
96
+ return true
97
+ end
98
+ end
99
+ false
100
+ end
50
101
  end
51
102
  end
@@ -1,3 +1,3 @@
1
1
  module Ak47
2
- VERSION = "0.2.3"
2
+ VERSION = "0.2.4"
3
3
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ak47
3
3
  version: !ruby/object:Gem::Version
4
- hash: 17
4
+ hash: 31
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 2
9
- - 3
10
- version: 0.2.3
9
+ - 4
10
+ version: 0.2.4
11
11
  platform: ruby
12
12
  authors:
13
13
  - Josh Hull
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-01-08 00:00:00 Z
18
+ date: 2012-01-11 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: guard
@@ -80,6 +80,7 @@ files:
80
80
  - ak47.gemspec
81
81
  - bin/ak47
82
82
  - lib/ak47.rb
83
+ - lib/ak47/cli.rb
83
84
  - lib/ak47/runner.rb
84
85
  - lib/ak47/version.rb
85
86
  homepage: ""