runfile 0.10.3 → 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 +21 -56
- data/bin/run +0 -1
- data/bin/run! +0 -1
- data/lib/runfile/docopt_helper.rb +33 -15
- data/lib/runfile/dsl.rb +12 -45
- data/lib/runfile/refinements.rb +22 -0
- data/lib/runfile/runfile_helper.rb +14 -13
- data/lib/runfile/runner.rb +21 -5
- 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 -22
- 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,18 +1,21 @@
|
|
|
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
|
-
[](https://bettercodehub.com/results/DannyBen/runfile)
|
|
7
|
+
[](https://github.com/DannyBen/runfile/actions?query=workflow%3ATest)
|
|
7
8
|
[](https://codeclimate.com/github/DannyBen/runfile/maintainability)
|
|
8
9
|
|
|
9
10
|
---
|
|
10
11
|
|
|
11
|
-
A beautiful command line application framework
|
|
12
|
-
Rake-inspired
|
|
12
|
+
A beautiful command line application framework
|
|
13
|
+
Rake-inspired - Docopt inside
|
|
13
14
|
|
|
14
15
|
---
|
|
15
16
|
|
|
17
|
+
</div>
|
|
18
|
+
|
|
16
19
|
**Runfile** lets you create command line applications in a way similar
|
|
17
20
|
to [Rake](https://github.com/ruby/rake), but with the full power of
|
|
18
21
|
[Docopt](http://docopt.org/) command line options.
|
|
@@ -20,28 +23,9 @@ to [Rake](https://github.com/ruby/rake), but with the full power of
|
|
|
20
23
|
You create a `Runfile`, and execute commands with
|
|
21
24
|
`run command arguments -and --flags`.
|
|
22
25
|
|
|
23
|
-

|
|
26
|
-
|
|
27
|
-
---
|
|
28
|
-
|
|
29
|
-
**Upgrade Notice:**
|
|
30
|
-
If you are upgrading to 0.9.x - the `name` command was replaced
|
|
31
|
-
with `title`.
|
|
32
|
-
|
|
33
|
-
---
|
|
34
|
-
|
|
35
|
-
Install
|
|
36
|
-
--------------------------------------------------
|
|
37
|
-
|
|
38
|
-
```shell
|
|
39
|
-
$ gem install runfile
|
|
40
|
-
```
|
|
41
|
-
|
|
26
|
+

|
|
42
27
|
|
|
43
|
-
Quick Start
|
|
44
|
-
--------------------------------------------------
|
|
28
|
+
## Quick Start
|
|
45
29
|
|
|
46
30
|
```shell
|
|
47
31
|
$ run new # create a new Runfile
|
|
@@ -50,8 +34,7 @@ $ vi Runfile # edit the Runfile
|
|
|
50
34
|
```
|
|
51
35
|
|
|
52
36
|
|
|
53
|
-
Example
|
|
54
|
-
--------------------------------------------------
|
|
37
|
+
## Example
|
|
55
38
|
|
|
56
39
|
The most minimal `Runfile` looks like this:
|
|
57
40
|
|
|
@@ -64,14 +47,14 @@ end
|
|
|
64
47
|
|
|
65
48
|
You can then run it by executing this command:
|
|
66
49
|
|
|
67
|
-
```
|
|
50
|
+
```shell
|
|
68
51
|
$ run greet Luke
|
|
69
52
|
Hello Luke
|
|
70
53
|
```
|
|
71
54
|
|
|
72
55
|
Executing `run` without parameters, will show the usage patterns:
|
|
73
56
|
|
|
74
|
-
```
|
|
57
|
+
```shell
|
|
75
58
|
$ run
|
|
76
59
|
Usage:
|
|
77
60
|
run greet <name>
|
|
@@ -80,7 +63,7 @@ Usage:
|
|
|
80
63
|
|
|
81
64
|
Executing `run --help` will show the full help document (docopt)
|
|
82
65
|
|
|
83
|
-
```
|
|
66
|
+
```shell
|
|
84
67
|
$ run --help
|
|
85
68
|
Runfile 0.0.0
|
|
86
69
|
|
|
@@ -96,31 +79,13 @@ Options:
|
|
|
96
79
|
Show version
|
|
97
80
|
```
|
|
98
81
|
|
|
82
|
+
## Documentation
|
|
99
83
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
In addition to the per project `Runfile` files, it is also possible to
|
|
104
|
-
create global runfiles that are accessible to you only or to anybody on
|
|
105
|
-
the system.
|
|
106
|
-
|
|
107
|
-
When you execute `run`, we will look for files in this order:
|
|
108
|
-
|
|
109
|
-
- `Runfile` in the current directory
|
|
110
|
-
- `*.runfile` in the current directory
|
|
111
|
-
- `~/runfile/**/*.runfile`
|
|
112
|
-
- `/etc/runfile/**/*.runfile`
|
|
113
|
-
|
|
114
|
-
When you execute `run!`, we will ignore any local Runfile and only search
|
|
115
|
-
for global (named) runfiles.
|
|
116
|
-
|
|
117
|
-
Read more in the [Runfile Location and Filename wiki page](https://github.com/DannyBen/runfile/wiki/Runfile-Location-and-Filename)
|
|
84
|
+
- [User Guide](https://runfile.dannyb.co/)
|
|
85
|
+
- [Learn by Example](https://github.com/DannyBen/runfile/tree/master/examples#readme)
|
|
118
86
|
|
|
87
|
+
## Contributing / Support
|
|
119
88
|
|
|
120
|
-
|
|
121
|
-
|
|
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).
|
|
122
91
|
|
|
123
|
-
- [Learn by Example](https://github.com/DannyBen/runfile/tree/master/examples)
|
|
124
|
-
- [Runfile Command Reference](https://github.com/DannyBen/runfile/wiki/Runfile-Command-Reference)
|
|
125
|
-
- [Wiki](https://github.com/DannyBen/runfile/wiki)
|
|
126
|
-
- [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,
|
|
@@ -22,19 +21,23 @@ module Runfile
|
|
|
22
21
|
@summary = options.summary
|
|
23
22
|
@actions = options.actions
|
|
24
23
|
@options = options.options
|
|
24
|
+
@params = options.params
|
|
25
|
+
@env_vars = options.env_vars
|
|
25
26
|
@examples = options.examples
|
|
26
27
|
end
|
|
27
28
|
|
|
28
29
|
# Generate a document based on all the actions, help messages
|
|
29
30
|
# and options we have collected from the Runfile DSL.
|
|
30
31
|
def docopt
|
|
31
|
-
width =
|
|
32
|
+
width = Terminal.width
|
|
32
33
|
doc = []
|
|
33
34
|
doc << (@version ? "#{@name} #{@version}" : "#{@name}")
|
|
34
35
|
doc << "#{@summary}" if @summary
|
|
35
36
|
doc += docopt_usage
|
|
36
37
|
doc += docopt_commands width
|
|
37
38
|
doc += docopt_options width
|
|
39
|
+
doc += docopt_params width
|
|
40
|
+
doc += docopt_env_vars width
|
|
38
41
|
doc += docopt_examples width
|
|
39
42
|
doc.join "\n"
|
|
40
43
|
end
|
|
@@ -63,7 +66,7 @@ module Runfile
|
|
|
63
66
|
doc << "Commands:" unless caption_printed
|
|
64
67
|
caption_printed = true
|
|
65
68
|
helpline = " #{action.help}"
|
|
66
|
-
wrapped = word_wrap
|
|
69
|
+
wrapped = helpline.word_wrap width
|
|
67
70
|
doc << " #{action.usage}\n#{wrapped}\n" unless action.usage == false
|
|
68
71
|
end
|
|
69
72
|
doc
|
|
@@ -74,17 +77,17 @@ module Runfile
|
|
|
74
77
|
@options['Options'] = {} unless @options['Options']
|
|
75
78
|
@options['Options']['-h --help'] = 'Show this screen'
|
|
76
79
|
@options['Options']['--version'] = 'Show version number' if @version
|
|
80
|
+
section_block @options, width
|
|
81
|
+
end
|
|
77
82
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
end
|
|
87
|
-
doc
|
|
83
|
+
# Return all docopt params for 'Params' section
|
|
84
|
+
def docopt_params(width)
|
|
85
|
+
section_block @params, width
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# Return all docopt params for 'Environment Variables' section
|
|
89
|
+
def docopt_env_vars(width)
|
|
90
|
+
section_block @env_vars, width
|
|
88
91
|
end
|
|
89
92
|
|
|
90
93
|
# Return all docopt lines for the 'Examples' section
|
|
@@ -95,12 +98,27 @@ module Runfile
|
|
|
95
98
|
base_command = @superspace ? "run #{@superspace}" : "run"
|
|
96
99
|
@examples.each do |command|
|
|
97
100
|
helpline = " #{base_command} #{command}"
|
|
98
|
-
wrapped = word_wrap
|
|
101
|
+
wrapped = helpline.word_wrap width
|
|
99
102
|
doc << "#{wrapped}"
|
|
100
103
|
end
|
|
101
104
|
doc
|
|
102
105
|
end
|
|
103
106
|
|
|
107
|
+
# Return a generic block containing scope section (e.g. "Options"),
|
|
108
|
+
# followed by key value paragraphs.
|
|
109
|
+
def section_block(definitions, width)
|
|
110
|
+
doc = []
|
|
111
|
+
definitions.each do |scope, values|
|
|
112
|
+
doc << "#{scope}:"
|
|
113
|
+
values.each do |label, text|
|
|
114
|
+
helpline = " #{text}"
|
|
115
|
+
wrapped = helpline.word_wrap width
|
|
116
|
+
doc << " #{label}\n#{wrapped}\n"
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
doc
|
|
120
|
+
end
|
|
121
|
+
|
|
104
122
|
# Call the docopt handler, which will either return a parsed
|
|
105
123
|
# arguments list, or halt execution and show usage.
|
|
106
124
|
def args(argv)
|
data/lib/runfile/dsl.rb
CHANGED
|
@@ -43,6 +43,18 @@ module Runfile
|
|
|
43
43
|
Runner.instance.add_option flag, text, scope
|
|
44
44
|
end
|
|
45
45
|
|
|
46
|
+
# Add a parameter (can be called multiple times)
|
|
47
|
+
# param 'FOLDER', 'Folder to copy'
|
|
48
|
+
def param(name, text, scope=nil)
|
|
49
|
+
Runner.instance.add_param name, text, scope
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Set an environment variable (can be called multiple times)
|
|
53
|
+
# env_var 'USER', 'Set the user (same as --user)'
|
|
54
|
+
def env_var(name, text, scope = nil)
|
|
55
|
+
Runner.instance.add_env_var name, text, scope
|
|
56
|
+
end
|
|
57
|
+
|
|
46
58
|
# Set an example command (can be called multiple times)
|
|
47
59
|
# example 'server --background'
|
|
48
60
|
def example(text)
|
|
@@ -71,51 +83,6 @@ module Runfile
|
|
|
71
83
|
Runner.instance.cross_call command_string
|
|
72
84
|
end
|
|
73
85
|
|
|
74
|
-
# Run a command, wait until it is done and continue
|
|
75
|
-
# run 'rails server'
|
|
76
|
-
def run(*args)
|
|
77
|
-
ExecHandler.instance.run(*args)
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
# Run a command, wait until it is done, then exit
|
|
81
|
-
# run! 'rails server'
|
|
82
|
-
def run!(*args)
|
|
83
|
-
ExecHandler.instance.run!(*args)
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
# Run a command in the background, optionally log to a log file and save
|
|
87
|
-
# the process ID in a pid file
|
|
88
|
-
# run_bg 'rails server', pid: 'rails', log: 'tmp/log.log'
|
|
89
|
-
def run_bg(*args)
|
|
90
|
-
ExecHandler.instance.run_bg(*args)
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
# Stop a command started with 'run_bg'. Provide the name of he pid file you
|
|
94
|
-
# used in 'run_bg'
|
|
95
|
-
# stop_bg 'rails'
|
|
96
|
-
def stop_bg(*args)
|
|
97
|
-
ExecHandler.instance.stop_bg(*args)
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
# Set a block to be called before each run. The block should return
|
|
101
|
-
# the command to run, since this is intended to let the block modify
|
|
102
|
-
# the command if it needs to.
|
|
103
|
-
# before_run do |command|
|
|
104
|
-
# puts "BEFORE #{command}"
|
|
105
|
-
# command
|
|
106
|
-
# end
|
|
107
|
-
def before_run(&block)
|
|
108
|
-
ExecHandler.instance.before_run(&block)
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
# Set a block to be called after each run
|
|
112
|
-
# before_run do |command|
|
|
113
|
-
# puts "AFTER #{command}"
|
|
114
|
-
# end
|
|
115
|
-
def after_run(&block)
|
|
116
|
-
ExecHandler.instance.after_run(&block)
|
|
117
|
-
end
|
|
118
|
-
|
|
119
86
|
# Also allow to use 'endcommand' instead of 'command' to end
|
|
120
87
|
# a command namespace definition
|
|
121
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
|
@@ -13,7 +13,8 @@ module Runfile
|
|
|
13
13
|
include SettingsMixin
|
|
14
14
|
|
|
15
15
|
attr_accessor :last_usage, :last_help, :name, :version,
|
|
16
|
-
:summary, :namespace, :superspace, :actions, :examples, :options
|
|
16
|
+
:summary, :namespace, :superspace, :actions, :examples, :options,
|
|
17
|
+
:params, :env_vars
|
|
17
18
|
|
|
18
19
|
# Initialize all variables to sensible defaults.
|
|
19
20
|
def initialize
|
|
@@ -23,7 +24,9 @@ module Runfile
|
|
|
23
24
|
@namespace = nil # dsl: command
|
|
24
25
|
@actions = {} # dsl: action
|
|
25
26
|
@options = {} # dsl: option
|
|
27
|
+
@params = {} # dsl: param
|
|
26
28
|
@examples = [] # dsl: example
|
|
29
|
+
@env_vars = {} # dsl: env_var
|
|
27
30
|
@name = "Runfile" # dsl: name
|
|
28
31
|
@version = false # dsl: version
|
|
29
32
|
@summary = false # dsl: summary
|
|
@@ -46,7 +49,7 @@ module Runfile
|
|
|
46
49
|
|
|
47
50
|
# Add an action to the @actions array, and use the last known
|
|
48
51
|
# usage and help messages sent by the DSL.
|
|
49
|
-
def add_action(name, altname=nil, &block)
|
|
52
|
+
def add_action(name, altname = nil, &block)
|
|
50
53
|
if @last_usage.nil?
|
|
51
54
|
@last_usage = altname ? "(#{name}|#{altname})" : name
|
|
52
55
|
end
|
|
@@ -66,12 +69,26 @@ module Runfile
|
|
|
66
69
|
end
|
|
67
70
|
|
|
68
71
|
# Add an option flag and its help text.
|
|
69
|
-
def add_option(flag, text, scope=nil)
|
|
70
|
-
scope
|
|
72
|
+
def add_option(flag, text, scope = nil)
|
|
73
|
+
scope ||= 'Options'
|
|
71
74
|
@options[scope] ||= {}
|
|
72
75
|
@options[scope][flag] = text
|
|
73
76
|
end
|
|
74
77
|
|
|
78
|
+
# Add a patameter and its help text.
|
|
79
|
+
def add_param(name, text, scope = nil)
|
|
80
|
+
scope ||= 'Parameters'
|
|
81
|
+
@params[scope] ||= {}
|
|
82
|
+
@params[scope][name] = text
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# Add env_var command.
|
|
86
|
+
def add_env_var(name, text, scope = nil)
|
|
87
|
+
scope ||= 'Environment Variables'
|
|
88
|
+
@env_vars[scope] ||= {}
|
|
89
|
+
@env_vars[scope][name] = text
|
|
90
|
+
end
|
|
91
|
+
|
|
75
92
|
# Add example command.
|
|
76
93
|
def add_example(command)
|
|
77
94
|
@examples << (@namespace ? "#{@namespace} #{command}" : command)
|
|
@@ -157,7 +174,6 @@ module Runfile
|
|
|
157
174
|
if settings.shortcuts and settings.shortcuts[possible_candidate]
|
|
158
175
|
shortcut_value = settings.shortcuts[argv[0]]
|
|
159
176
|
expanded = shortcut_value.split ' '
|
|
160
|
-
say "!txtblu!# #{possible_candidate} > #{shortcut_value}"
|
|
161
177
|
argv.shift
|
|
162
178
|
argv = expanded + argv
|
|
163
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,15 +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
|
-
|
|
88
|
-
rubygems_version: 2.7.6
|
|
74
|
+
rubygems_version: 3.2.25
|
|
89
75
|
signing_key:
|
|
90
76
|
specification_version: 4
|
|
91
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
|