runfile 0.11.2 → 0.12.0.pre.rc1
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/README.md +19 -52
- data/bin/run +0 -1
- data/bin/run! +0 -1
- data/lib/runfile/docopt_helper.rb +5 -6
- data/lib/runfile/dsl.rb +0 -45
- data/lib/runfile/refinements.rb +22 -0
- data/lib/runfile/runfile_helper.rb +14 -13
- data/lib/runfile/runner.rb +0 -1
- data/lib/runfile/templates/Runfile +7 -5
- data/lib/runfile/terminal.rb +32 -0
- data/lib/runfile/version.rb +1 -1
- data/lib/runfile.rb +2 -3
- metadata +8 -21
- data/lib/runfile/exec.rb +0 -76
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4ee58eaa893425817219f8fa94a2e96a7789363dc3082f3f8c520130357199e6
|
4
|
+
data.tar.gz: 607dc6702aeb3b9ec09f71c88c32292c98f3a0b7c1c6dfefbfbdb1cec02e5738
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: be7893890fc0075e964c49bf3aea294b6337bf5440f0ccea2d56a223439fa7eaa5128cad2d9e8bff57798d77ec55b5c686f10acc7726f2d7b9de6f74d55ca4b7
|
7
|
+
data.tar.gz: b0e1b8aa6a11d96433c8bbcf09d92d3838ff6a7e1959b34542b16286d5248a76d0bf6f83fedb8f6520fe880d60450b65c72a052dcc79e79d4e292972de6b5ba4
|
data/README.md
CHANGED
@@ -1,5 +1,7 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
<div align='center'>
|
2
|
+
<img src='logo.svg' width=280>
|
3
|
+
|
4
|
+
# Runfile - command line for your projects
|
3
5
|
|
4
6
|
[](https://badge.fury.io/rb/runfile)
|
5
7
|
[](https://github.com/DannyBen/runfile/actions?query=workflow%3ATest)
|
@@ -7,11 +9,13 @@ Runfile - If Rake and Docopt had a baby
|
|
7
9
|
|
8
10
|
---
|
9
11
|
|
10
|
-
A beautiful command line application framework
|
11
|
-
Rake-inspired
|
12
|
+
A beautiful command line application framework
|
13
|
+
Rake-inspired - Docopt inside
|
12
14
|
|
13
15
|
---
|
14
16
|
|
17
|
+
</div>
|
18
|
+
|
15
19
|
**Runfile** lets you create command line applications in a way similar
|
16
20
|
to [Rake](https://github.com/ruby/rake), but with the full power of
|
17
21
|
[Docopt](http://docopt.org/) command line options.
|
@@ -21,26 +25,7 @@ You create a `Runfile`, and execute commands with
|
|
21
25
|
|
22
26
|

|
23
27
|
|
24
|
-
|
25
|
-
|
26
|
-
---
|
27
|
-
|
28
|
-
**Upgrade Notice:**
|
29
|
-
If you are upgrading to 0.9.x - the `name` command was replaced
|
30
|
-
with `title`.
|
31
|
-
|
32
|
-
---
|
33
|
-
|
34
|
-
Install
|
35
|
-
--------------------------------------------------
|
36
|
-
|
37
|
-
```shell
|
38
|
-
$ gem install runfile
|
39
|
-
```
|
40
|
-
|
41
|
-
|
42
|
-
Quick Start
|
43
|
-
--------------------------------------------------
|
28
|
+
## Quick Start
|
44
29
|
|
45
30
|
```shell
|
46
31
|
$ run new # create a new Runfile
|
@@ -49,8 +34,7 @@ $ vi Runfile # edit the Runfile
|
|
49
34
|
```
|
50
35
|
|
51
36
|
|
52
|
-
Example
|
53
|
-
--------------------------------------------------
|
37
|
+
## Example
|
54
38
|
|
55
39
|
The most minimal `Runfile` looks like this:
|
56
40
|
|
@@ -63,14 +47,14 @@ end
|
|
63
47
|
|
64
48
|
You can then run it by executing this command:
|
65
49
|
|
66
|
-
```
|
50
|
+
```shell
|
67
51
|
$ run greet Luke
|
68
52
|
Hello Luke
|
69
53
|
```
|
70
54
|
|
71
55
|
Executing `run` without parameters, will show the usage patterns:
|
72
56
|
|
73
|
-
```
|
57
|
+
```shell
|
74
58
|
$ run
|
75
59
|
Usage:
|
76
60
|
run greet <name>
|
@@ -79,7 +63,7 @@ Usage:
|
|
79
63
|
|
80
64
|
Executing `run --help` will show the full help document (docopt)
|
81
65
|
|
82
|
-
```
|
66
|
+
```shell
|
83
67
|
$ run --help
|
84
68
|
Runfile 0.0.0
|
85
69
|
|
@@ -95,30 +79,13 @@ Options:
|
|
95
79
|
Show version
|
96
80
|
```
|
97
81
|
|
82
|
+
## Documentation
|
98
83
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
In addition to the per project `Runfile` files, it is also possible to
|
103
|
-
create global runfiles that are accessible to you only or to anybody on
|
104
|
-
the system.
|
105
|
-
|
106
|
-
When you execute `run`, we will look for files in this order:
|
107
|
-
|
108
|
-
- `Runfile` in the current directory
|
109
|
-
- `*.runfile` in the current directory
|
110
|
-
- `~/runfile/**/*.runfile`
|
111
|
-
- `/etc/runfile/**/*.runfile`
|
112
|
-
|
113
|
-
When you execute `run!`, we will ignore any local Runfile and only search
|
114
|
-
for global (named) runfiles.
|
115
|
-
|
116
|
-
Read more on [Runfile Location and Filename](https://runfile.dannyb.co/Runfile-Location-and-Filename)
|
84
|
+
- [User Guide](https://runfile.dannyb.co/)
|
85
|
+
- [Learn by Example](https://github.com/DannyBen/runfile/tree/master/examples#readme)
|
117
86
|
|
87
|
+
## Contributing / Support
|
118
88
|
|
119
|
-
|
120
|
-
|
89
|
+
If you experience any issue, have a question or a suggestion, or if you wish
|
90
|
+
to contribute, feel free to [open an issue](https://github.com/DannyBen/runfile/issues).
|
121
91
|
|
122
|
-
- [User Guide](https://runfile.dannyb.co)
|
123
|
-
- [Learn by Example](https://github.com/DannyBen/runfile/tree/master/examples)
|
124
|
-
- [Rubydoc](http://www.rubydoc.info/gems/runfile)
|
data/bin/run
CHANGED
data/bin/run!
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'docopt'
|
2
|
-
require 'colsole'
|
3
2
|
|
4
3
|
module Runfile
|
5
4
|
# The DocoptHelper class handles the dynamic generation of the
|
@@ -7,7 +6,7 @@ module Runfile
|
|
7
6
|
# to call Docopt so it returns the parsed arguments or halts with
|
8
7
|
# usage message).
|
9
8
|
class DocoptHelper
|
10
|
-
|
9
|
+
using Refinements
|
11
10
|
|
12
11
|
# The constructor expects to an object that responds to all the
|
13
12
|
# textual details needed to generate a docopt document (name, version,
|
@@ -30,7 +29,7 @@ module Runfile
|
|
30
29
|
# Generate a document based on all the actions, help messages
|
31
30
|
# and options we have collected from the Runfile DSL.
|
32
31
|
def docopt
|
33
|
-
width =
|
32
|
+
width = Terminal.width
|
34
33
|
doc = []
|
35
34
|
doc << (@version ? "#{@name} #{@version}" : "#{@name}")
|
36
35
|
doc << "#{@summary}" if @summary
|
@@ -67,7 +66,7 @@ module Runfile
|
|
67
66
|
doc << "Commands:" unless caption_printed
|
68
67
|
caption_printed = true
|
69
68
|
helpline = " #{action.help}"
|
70
|
-
wrapped = word_wrap
|
69
|
+
wrapped = helpline.word_wrap width
|
71
70
|
doc << " #{action.usage}\n#{wrapped}\n" unless action.usage == false
|
72
71
|
end
|
73
72
|
doc
|
@@ -99,7 +98,7 @@ module Runfile
|
|
99
98
|
base_command = @superspace ? "run #{@superspace}" : "run"
|
100
99
|
@examples.each do |command|
|
101
100
|
helpline = " #{base_command} #{command}"
|
102
|
-
wrapped = word_wrap
|
101
|
+
wrapped = helpline.word_wrap width
|
103
102
|
doc << "#{wrapped}"
|
104
103
|
end
|
105
104
|
doc
|
@@ -113,7 +112,7 @@ module Runfile
|
|
113
112
|
doc << "#{scope}:"
|
114
113
|
values.each do |label, text|
|
115
114
|
helpline = " #{text}"
|
116
|
-
wrapped = word_wrap
|
115
|
+
wrapped = helpline.word_wrap width
|
117
116
|
doc << " #{label}\n#{wrapped}\n"
|
118
117
|
end
|
119
118
|
end
|
data/lib/runfile/dsl.rb
CHANGED
@@ -83,51 +83,6 @@ module Runfile
|
|
83
83
|
Runner.instance.cross_call command_string
|
84
84
|
end
|
85
85
|
|
86
|
-
# Run a command, wait until it is done and continue
|
87
|
-
# run 'rails server'
|
88
|
-
def run(cmd)
|
89
|
-
ExecHandler.instance.run cmd
|
90
|
-
end
|
91
|
-
|
92
|
-
# Run a command, wait until it is done, then exit
|
93
|
-
# run! 'rails server'
|
94
|
-
def run!(cmd)
|
95
|
-
ExecHandler.instance.run! cmd
|
96
|
-
end
|
97
|
-
|
98
|
-
# Run a command in the background, optionally log to a log file and save
|
99
|
-
# the process ID in a pid file
|
100
|
-
# run_bg 'rails server', pid: 'rails', log: 'tmp/log.log'
|
101
|
-
def run_bg(cmd, pid: nil, log: '/dev/null')
|
102
|
-
ExecHandler.instance.run_bg cmd, pid: pid, log: log
|
103
|
-
end
|
104
|
-
|
105
|
-
# Stop a command started with 'run_bg'. Provide the name of he pid file you
|
106
|
-
# used in 'run_bg'
|
107
|
-
# stop_bg 'rails'
|
108
|
-
def stop_bg(pid)
|
109
|
-
ExecHandler.instance.stop_bg pid
|
110
|
-
end
|
111
|
-
|
112
|
-
# Set a block to be called before each run. The block should return
|
113
|
-
# the command to run, since this is intended to let the block modify
|
114
|
-
# the command if it needs to.
|
115
|
-
# before_run do |command|
|
116
|
-
# puts "BEFORE #{command}"
|
117
|
-
# command
|
118
|
-
# end
|
119
|
-
def before_run(&block)
|
120
|
-
ExecHandler.instance.before_run(&block)
|
121
|
-
end
|
122
|
-
|
123
|
-
# Set a block to be called after each run
|
124
|
-
# before_run do |command|
|
125
|
-
# puts "AFTER #{command}"
|
126
|
-
# end
|
127
|
-
def after_run(&block)
|
128
|
-
ExecHandler.instance.after_run(&block)
|
129
|
-
end
|
130
|
-
|
131
86
|
# Also allow to use 'endcommand' instead of 'command' to end
|
132
87
|
# a command namespace definition
|
133
88
|
alias_method :endcommand, :command
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Runfile
|
2
|
+
module Refinements
|
3
|
+
refine String do
|
4
|
+
def word_wrap(length = nil)
|
5
|
+
text = self
|
6
|
+
|
7
|
+
length ||= Terminal.width
|
8
|
+
lead = text[/^\s*/]
|
9
|
+
text.strip!
|
10
|
+
length -= lead.length
|
11
|
+
text.split("\n").collect! do |line|
|
12
|
+
if line.length > length
|
13
|
+
line.gsub!(/([^\s]{#{length}})([^\s$])/, "\\1 \\2")
|
14
|
+
line.gsub(/(.{1,#{length}})(\s+|$)/, "#{lead}\\1\n").rstrip
|
15
|
+
else
|
16
|
+
"#{lead}#{line}"
|
17
|
+
end
|
18
|
+
end * "\n"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -8,6 +8,7 @@ module Runfile
|
|
8
8
|
# 2. Creating new runfiles (`run new`)
|
9
9
|
# 3. Showing a list of found system runfiles in a colorful help
|
10
10
|
class RunfileHelper
|
11
|
+
using Refinements
|
11
12
|
include SettingsMixin
|
12
13
|
|
13
14
|
# Handle the case when `run` is called without a Runfile
|
@@ -72,14 +73,14 @@ module Runfile
|
|
72
73
|
|
73
74
|
# Show some helpful tips, and a list of available runfiles
|
74
75
|
def show_make_help(runfiles, compact=false)
|
75
|
-
|
76
|
+
puts "Runfile engine v#{Runfile::VERSION}" unless compact
|
76
77
|
if runfiles.size < 3 and !compact
|
77
|
-
|
78
|
+
puts "\nTip: Type 'run new' or 'run new name' to create a runfile.\nFor global access, place named.runfiles in ~/runfile/ or in /etc/runfile/."
|
78
79
|
end
|
79
80
|
if runfiles.empty?
|
80
|
-
|
81
|
+
puts "\nRunfile not found."
|
81
82
|
else
|
82
|
-
|
83
|
+
puts ""
|
83
84
|
compact ? say_runfile_usage(runfiles) : say_runfile_list(runfiles)
|
84
85
|
end
|
85
86
|
end
|
@@ -110,14 +111,14 @@ module Runfile
|
|
110
111
|
def say_runfile_list(runfiles)
|
111
112
|
runfile_paths = runfiles.map { |f| File.dirname f }
|
112
113
|
max = runfile_paths.max_by(&:length).size
|
113
|
-
width =
|
114
|
+
width = Terminal.width
|
114
115
|
runfiles.each do |f|
|
115
116
|
f[/([^\/]+).runfile$/]
|
116
117
|
command = "run #{$1}"
|
117
118
|
spacer_size = width - max - command.size - 6
|
118
119
|
spacer_size = [1, spacer_size].max
|
119
120
|
spacer = '.' * spacer_size
|
120
|
-
|
121
|
+
puts " #{command} #{spacer} #{File.dirname f}"
|
121
122
|
end
|
122
123
|
end
|
123
124
|
|
@@ -125,19 +126,19 @@ module Runfile
|
|
125
126
|
def say_runfile_usage(runfiles)
|
126
127
|
runfiles_as_columns = get_runfiles_as_columns runfiles
|
127
128
|
|
128
|
-
|
129
|
-
|
130
|
-
|
129
|
+
puts "#{settings.intro}\n" if settings.intro
|
130
|
+
puts "Usage: run <file>"
|
131
|
+
puts runfiles_as_columns
|
131
132
|
|
132
133
|
show_shortcuts if settings.shortcuts
|
133
134
|
end
|
134
135
|
|
135
136
|
# Prints a friendly output of the shortcut list
|
136
137
|
def show_shortcuts
|
137
|
-
|
138
|
+
puts "\nShortcuts:"
|
138
139
|
max = settings.shortcuts.keys.max_by(&:length).length
|
139
140
|
settings.shortcuts.each_pair do |shortcut, command|
|
140
|
-
|
141
|
+
puts " #{shortcut.rjust max} : #{command}"
|
141
142
|
end
|
142
143
|
end
|
143
144
|
|
@@ -145,10 +146,10 @@ module Runfile
|
|
145
146
|
# current terminal width
|
146
147
|
def get_runfiles_as_columns(runfiles)
|
147
148
|
namelist = runfile_names runfiles
|
148
|
-
width =
|
149
|
+
width = Terminal.width
|
149
150
|
max = namelist.max_by(&:length).length
|
150
151
|
message = " " + namelist.map {|f| f.ljust max+1 }.join(' ')
|
151
|
-
word_wrap
|
152
|
+
message.word_wrap width
|
152
153
|
end
|
153
154
|
|
154
155
|
def runfile_names(runfiles)
|
data/lib/runfile/runner.rb
CHANGED
@@ -174,7 +174,6 @@ module Runfile
|
|
174
174
|
if settings.shortcuts and settings.shortcuts[possible_candidate]
|
175
175
|
shortcut_value = settings.shortcuts[argv[0]]
|
176
176
|
expanded = shortcut_value.split ' '
|
177
|
-
say "!txtblu!# #{possible_candidate} > #{shortcut_value}"
|
178
177
|
argv.shift
|
179
178
|
argv = expanded + argv
|
180
179
|
end
|
@@ -2,13 +2,15 @@ title "Greeter"
|
|
2
2
|
summary "A sample Runfile"
|
3
3
|
version "0.1.0"
|
4
4
|
|
5
|
-
usage "hello [<name> --
|
5
|
+
usage "hello [<name> --shout]"
|
6
6
|
help "Say hello"
|
7
|
-
option "-
|
7
|
+
option "-s --shout", "Greet louder"
|
8
8
|
action :hello do |args|
|
9
|
-
|
10
|
-
|
9
|
+
message = "Hello #{args['<name>']}"
|
10
|
+
|
11
|
+
if args['--shout']
|
12
|
+
puts message.upcase
|
11
13
|
else
|
12
|
-
|
14
|
+
puts message
|
13
15
|
end
|
14
16
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# This file provides some terminal related utilities (extracted from Colsole)
|
2
|
+
|
3
|
+
module Runfile
|
4
|
+
class Terminal
|
5
|
+
class << self
|
6
|
+
def size(default = [80,30])
|
7
|
+
if (ENV['COLUMNS'] =~ /^\d+$/) && (ENV['LINES'] =~ /^\d+$/)
|
8
|
+
result = [ENV['COLUMNS'].to_i, ENV['LINES'].to_i]
|
9
|
+
elsif (RUBY_PLATFORM =~ /java/ || (!STDIN.tty? && ENV['TERM'])) && command_exist?('tput')
|
10
|
+
result = [`tput cols 2>&1`.to_i, `tput lines 2>&1`.to_i]
|
11
|
+
elsif STDIN.tty? && command_exist?('stty')
|
12
|
+
result = `stty size 2>&1`.scan(/\d+/).map { |s| s.to_i }.reverse
|
13
|
+
else
|
14
|
+
result = default
|
15
|
+
end
|
16
|
+
result = default unless result[0].is_a? Integer and result[1].is_a? Integer and result[0] > 0 and result[1] > 0
|
17
|
+
result
|
18
|
+
end
|
19
|
+
|
20
|
+
def width
|
21
|
+
size[0]
|
22
|
+
end
|
23
|
+
|
24
|
+
def command_exist?(command)
|
25
|
+
ENV['PATH'].split(File::PATH_SEPARATOR).any? do |dir|
|
26
|
+
File.exist?(File.join dir, command) or File.exist?(File.join dir, "#{command}.exe")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/lib/runfile/version.rb
CHANGED
data/lib/runfile.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
require 'runfile/version'
|
2
|
+
require 'runfile/terminal'
|
3
|
+
require 'runfile/refinements'
|
2
4
|
require 'runfile/settings'
|
3
5
|
require 'runfile/setup'
|
4
6
|
require 'runfile/docopt_helper'
|
@@ -6,6 +8,3 @@ require 'runfile/runfile_helper'
|
|
6
8
|
require 'runfile/action'
|
7
9
|
require 'runfile/runner'
|
8
10
|
require 'runfile/dsl'
|
9
|
-
require 'runfile/exec'
|
10
|
-
|
11
|
-
require 'byebug' if ENV['BYEBUG']
|
metadata
CHANGED
@@ -1,29 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: runfile
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.12.0.pre.rc1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Danny Ben Shitrit
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-09-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: colsole
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - "~>"
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '0.5'
|
20
|
-
type: :runtime
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - "~>"
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '0.5'
|
27
13
|
- !ruby/object:Gem::Dependency
|
28
14
|
name: docopt
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|
@@ -54,12 +40,13 @@ files:
|
|
54
40
|
- lib/runfile/action.rb
|
55
41
|
- lib/runfile/docopt_helper.rb
|
56
42
|
- lib/runfile/dsl.rb
|
57
|
-
- lib/runfile/
|
43
|
+
- lib/runfile/refinements.rb
|
58
44
|
- lib/runfile/runfile_helper.rb
|
59
45
|
- lib/runfile/runner.rb
|
60
46
|
- lib/runfile/settings.rb
|
61
47
|
- lib/runfile/setup.rb
|
62
48
|
- lib/runfile/templates/Runfile
|
49
|
+
- lib/runfile/terminal.rb
|
63
50
|
- lib/runfile/version.rb
|
64
51
|
homepage: https://github.com/DannyBen/runfile
|
65
52
|
licenses:
|
@@ -77,14 +64,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
77
64
|
requirements:
|
78
65
|
- - ">="
|
79
66
|
- !ruby/object:Gem::Version
|
80
|
-
version: 2.
|
67
|
+
version: 2.4.0
|
81
68
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
82
69
|
requirements:
|
83
|
-
- - "
|
70
|
+
- - ">"
|
84
71
|
- !ruby/object:Gem::Version
|
85
|
-
version:
|
72
|
+
version: 1.3.1
|
86
73
|
requirements: []
|
87
|
-
rubygems_version: 3.
|
74
|
+
rubygems_version: 3.2.25
|
88
75
|
signing_key:
|
89
76
|
specification_version: 4
|
90
77
|
summary: If Rake and Docopt had a baby
|
data/lib/runfile/exec.rb
DELETED
@@ -1,76 +0,0 @@
|
|
1
|
-
require 'singleton'
|
2
|
-
|
3
|
-
module Runfile
|
4
|
-
|
5
|
-
# This class provides methods for easily and politely run shell commands
|
6
|
-
# through a Runfile action.
|
7
|
-
# It is mainly a convenient wrapper around `system` and `exec` and it also
|
8
|
-
# adds functions for running background tasks with ease.
|
9
|
-
class ExecHandler
|
10
|
-
include Singleton
|
11
|
-
|
12
|
-
# Run a command, wait until it is done and continue
|
13
|
-
def run(cmd)
|
14
|
-
cmd = @before_run_block.call(cmd) if @before_run_block
|
15
|
-
return false unless cmd
|
16
|
-
say "!txtgrn!> #{cmd}" unless Runfile.quiet
|
17
|
-
system cmd
|
18
|
-
@after_run_block.call(cmd) if @after_run_block
|
19
|
-
end
|
20
|
-
|
21
|
-
# Run a command, wait until it is done, then exit
|
22
|
-
def run!(cmd)
|
23
|
-
cmd = @before_run_block.call(cmd) if @before_run_block
|
24
|
-
return false unless cmd
|
25
|
-
say "!txtgrn!> #{cmd}" unless Runfile.quiet
|
26
|
-
exec cmd
|
27
|
-
end
|
28
|
-
|
29
|
-
# Run a command in the background, optionally log to a log file and save
|
30
|
-
# the process ID in a pid file
|
31
|
-
def run_bg(cmd, pid: nil, log: '/dev/null')
|
32
|
-
cmd = @before_run_block.call(cmd) if @before_run_block
|
33
|
-
return false unless cmd
|
34
|
-
full_cmd = "exec #{cmd} >#{log} 2>&1"
|
35
|
-
say "!txtgrn!> #{full_cmd}" unless Runfile.quiet
|
36
|
-
process = IO.popen "exec #{cmd} >#{log} 2>&1"
|
37
|
-
File.write pidfile(pid), process.pid if pid
|
38
|
-
@after_run_block.call(cmd) if @after_run_block
|
39
|
-
return process.pid
|
40
|
-
end
|
41
|
-
|
42
|
-
# Stop a command started with 'run_bg'. Provide the name of he pid file you
|
43
|
-
# used in 'run_bg'
|
44
|
-
def stop_bg(pid)
|
45
|
-
file = pidfile(pid)
|
46
|
-
if File.exist? file
|
47
|
-
pid = File.read file
|
48
|
-
File.delete file
|
49
|
-
run "kill -s TERM #{pid}"
|
50
|
-
else
|
51
|
-
say "!txtred!PID file not found." unless Runfile.quiet
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
# Set a block to be called before each run
|
56
|
-
def before_run(&block)
|
57
|
-
@before_run_block = block
|
58
|
-
end
|
59
|
-
|
60
|
-
# Set a block to be called after each run
|
61
|
-
def after_run(&block)
|
62
|
-
@after_run_block = block
|
63
|
-
end
|
64
|
-
|
65
|
-
private
|
66
|
-
|
67
|
-
def pid_dir
|
68
|
-
defined?(Runfile.pid_dir) ? Runfile.pid_dir : nil
|
69
|
-
end
|
70
|
-
|
71
|
-
def pidfile(pid)
|
72
|
-
pid_dir ? "#{pid_dir}/#{pid}.pid" : "#{pid}.pid"
|
73
|
-
end
|
74
|
-
|
75
|
-
end
|
76
|
-
end
|