runfile 0.12.0 → 1.0.0.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 +108 -37
- data/bin/runn +5 -0
- data/examples/default-action/runfile +9 -0
- data/examples/default-action-2/runfile +11 -0
- data/examples/default-action-2/server.runfile +6 -0
- data/examples/different-name/runfile.rb +8 -0
- data/examples/example/runfile +10 -0
- data/examples/example-multiline/runfile +16 -0
- data/examples/execute/runfile +14 -0
- data/examples/execute/server.runfile +11 -0
- data/examples/full/runfile +24 -0
- data/examples/import/more_tasks/spec.runfile +7 -0
- data/examples/import/runfile +10 -0
- data/examples/import/tasks/server.runfile +13 -0
- data/examples/minimal/runfile +4 -0
- data/examples/multiple-runfiles/runfile +11 -0
- data/examples/multiple-runfiles/server.runfile +13 -0
- data/examples/named-only/deploy.runfile +7 -0
- data/examples/named-only/server.runfile +11 -0
- data/examples/naval-fate/runfile +47 -0
- data/examples/shortcut/runfile +31 -0
- data/lib/runfile/action.rb +40 -14
- data/lib/runfile/concerns/dsl.rb +132 -0
- data/lib/runfile/concerns/inspectable.rb +13 -0
- data/lib/runfile/concerns/renderable.rb +16 -0
- data/lib/runfile/entrypoint.rb +50 -0
- data/lib/runfile/exceptions.rb +13 -0
- data/lib/runfile/gem_finder.rb +29 -0
- data/lib/runfile/initiator.rb +87 -0
- data/lib/runfile/meta.rb +65 -0
- data/lib/runfile/runner.rb +10 -173
- data/lib/runfile/templates/runfile +13 -0
- data/lib/runfile/userfile.rb +111 -0
- data/lib/runfile/version.rb +2 -2
- data/lib/runfile/views/initiator.gtx +28 -0
- data/lib/runfile/views/userfile.gtx +93 -0
- data/lib/runfile.rb +13 -10
- metadata +98 -24
- data/bin/run +0 -10
- data/bin/run! +0 -16
- data/lib/runfile/compatibility.rb +0 -84
- data/lib/runfile/docopt_helper.rb +0 -128
- data/lib/runfile/dsl.rb +0 -90
- data/lib/runfile/refinements.rb +0 -22
- data/lib/runfile/runfile_helper.rb +0 -165
- data/lib/runfile/settings.rb +0 -34
- data/lib/runfile/setup.rb +0 -19
- data/lib/runfile/templates/Runfile +0 -16
- data/lib/runfile/terminal.rb +0 -32
@@ -0,0 +1,111 @@
|
|
1
|
+
require 'shellwords'
|
2
|
+
|
3
|
+
module Runfile
|
4
|
+
# Represents a single runfile.
|
5
|
+
class Userfile
|
6
|
+
include Renderable
|
7
|
+
include Inspectable
|
8
|
+
include DSL
|
9
|
+
|
10
|
+
attr_reader :code, :name, :path
|
11
|
+
attr_writer :context
|
12
|
+
alias action_prefix name
|
13
|
+
|
14
|
+
class << self
|
15
|
+
def load_file(path)
|
16
|
+
if masterfile? path
|
17
|
+
name = nil
|
18
|
+
else
|
19
|
+
name = File.basename path, '.runfile'
|
20
|
+
path = "#{path}.runfile" unless path.end_with? '.runfile'
|
21
|
+
end
|
22
|
+
|
23
|
+
code = File.read path
|
24
|
+
new code, name: name, path: path
|
25
|
+
end
|
26
|
+
|
27
|
+
def masterfile?(path)
|
28
|
+
Meta::MASTERFILE_NAMES.include? path
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def initialize(code = nil, name: nil, path: nil)
|
33
|
+
@code = code
|
34
|
+
@name = name
|
35
|
+
@path = path
|
36
|
+
|
37
|
+
return unless @code
|
38
|
+
|
39
|
+
if path
|
40
|
+
instance_eval @code, @path
|
41
|
+
else
|
42
|
+
instance_eval @code
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def inspectable
|
47
|
+
{ name: name, path: path }
|
48
|
+
end
|
49
|
+
|
50
|
+
def run(argv = [])
|
51
|
+
found_delegate = delegate argv[0]
|
52
|
+
if found_delegate
|
53
|
+
found_delegate.run argv
|
54
|
+
else
|
55
|
+
run_local argv
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def context
|
60
|
+
@context ||= {}
|
61
|
+
end
|
62
|
+
|
63
|
+
def implicit_title
|
64
|
+
title || name
|
65
|
+
end
|
66
|
+
|
67
|
+
# Returns an array of actions that have help defined
|
68
|
+
def commands
|
69
|
+
actions.values.select(&:help)
|
70
|
+
end
|
71
|
+
|
72
|
+
def delegates
|
73
|
+
@delegates ||= (name ? {} : meta.external_files)
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
def find_action(args)
|
79
|
+
acts = actions.values
|
80
|
+
acts.find { |a| args[a.name] } ||
|
81
|
+
acts.find { |a| args[a.shortcut] } ||
|
82
|
+
acts.find { |a| args[a.prefix] } ||
|
83
|
+
actions[:default]
|
84
|
+
end
|
85
|
+
|
86
|
+
def run_local(argv)
|
87
|
+
Runner.run docopt, argv: argv, version: version do |args|
|
88
|
+
action = find_action(args)
|
89
|
+
raise ActionNotFound, 'Cannot find action. Is it properly defined?' unless action
|
90
|
+
|
91
|
+
action.run args
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def delegate(name)
|
96
|
+
return nil unless delegates.has_key? name
|
97
|
+
|
98
|
+
result = delegates[name]
|
99
|
+
result.context = contexts[name]
|
100
|
+
result
|
101
|
+
end
|
102
|
+
|
103
|
+
def meta
|
104
|
+
@meta ||= Meta.new
|
105
|
+
end
|
106
|
+
|
107
|
+
def docopt
|
108
|
+
@docopt ||= render 'userfile', context: self
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
data/lib/runfile/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
1
|
module Runfile
|
2
|
-
VERSION =
|
3
|
-
end
|
2
|
+
VERSION = '1.0.0.rc1'
|
3
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
> Runfile
|
2
|
+
>
|
3
|
+
> Local command line for your projects
|
4
|
+
>
|
5
|
+
> Usage:
|
6
|
+
> run new
|
7
|
+
> run example [NAME]
|
8
|
+
> run --help | -h
|
9
|
+
> run --version
|
10
|
+
>
|
11
|
+
> Commands:
|
12
|
+
> nb`new`
|
13
|
+
> Create a new runfile in the current directory
|
14
|
+
>
|
15
|
+
> nb`example`
|
16
|
+
> Copy one of the examples to the current directory
|
17
|
+
> Run without arguments to see the list of examples
|
18
|
+
>
|
19
|
+
> Options:
|
20
|
+
> --help, -h
|
21
|
+
> Show this message
|
22
|
+
>
|
23
|
+
> --version
|
24
|
+
> Show version number
|
25
|
+
>
|
26
|
+
> Documentation:
|
27
|
+
> bu`https://runfile.dannyb.co`
|
28
|
+
>
|
@@ -0,0 +1,93 @@
|
|
1
|
+
if implicit_title
|
2
|
+
= implicit_title
|
3
|
+
>
|
4
|
+
end
|
5
|
+
|
6
|
+
if summary
|
7
|
+
= implicit_title ? word_wrap(" #{summary}") : word_wrap(summary)
|
8
|
+
>
|
9
|
+
end
|
10
|
+
|
11
|
+
> Usage:
|
12
|
+
actions.each do |name, action|
|
13
|
+
action.implicit_usages.each do |usage|
|
14
|
+
= " run #{usage}".rstrip
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
delegates.keys.each do |name|
|
19
|
+
= " run #{name}"
|
20
|
+
end
|
21
|
+
|
22
|
+
if delegates.any?
|
23
|
+
> run [COMMAND] (--help | -h)
|
24
|
+
elsif name
|
25
|
+
> run {{ name }} (--help | -h)
|
26
|
+
else
|
27
|
+
> run (--help | -h)
|
28
|
+
end
|
29
|
+
|
30
|
+
if version
|
31
|
+
> run --version
|
32
|
+
end
|
33
|
+
>
|
34
|
+
|
35
|
+
if commands.any? || delegates.any?
|
36
|
+
> Commands:
|
37
|
+
commands.each do |action|
|
38
|
+
= " nb`#{action.names.join(', ')}`"
|
39
|
+
= word_wrap " #{action.help}"
|
40
|
+
>
|
41
|
+
end
|
42
|
+
|
43
|
+
delegates.each do |name, userfile|
|
44
|
+
summary = userfile.summary || userfile.title ||
|
45
|
+
"Run nu`run #{name} --help` for more information"
|
46
|
+
|
47
|
+
= " nb`#{name}`"
|
48
|
+
= word_wrap " #{summary}"
|
49
|
+
>
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
if params.any?
|
54
|
+
> Parameters:
|
55
|
+
params.each do |name, help|
|
56
|
+
= " #{name}"
|
57
|
+
= word_wrap " #{help}"
|
58
|
+
>
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
> Options:
|
63
|
+
options.each do |name, help|
|
64
|
+
= " #{name}"
|
65
|
+
= word_wrap " #{help}"
|
66
|
+
>
|
67
|
+
end
|
68
|
+
> --help, -h
|
69
|
+
> Show this message
|
70
|
+
>
|
71
|
+
if version
|
72
|
+
> --version
|
73
|
+
> Show version number
|
74
|
+
>
|
75
|
+
end
|
76
|
+
|
77
|
+
if env_vars.any?
|
78
|
+
> Environment Variables:
|
79
|
+
env_vars.each do |name, help|
|
80
|
+
= " #{name}"
|
81
|
+
= word_wrap " #{help}"
|
82
|
+
end
|
83
|
+
>
|
84
|
+
end
|
85
|
+
|
86
|
+
|
87
|
+
if examples.any?
|
88
|
+
> Examples:
|
89
|
+
examples.each do |text|
|
90
|
+
= word_wrap " #{text}"
|
91
|
+
end
|
92
|
+
>
|
93
|
+
end
|
data/lib/runfile.rb
CHANGED
@@ -1,10 +1,13 @@
|
|
1
|
-
require '
|
2
|
-
require '
|
3
|
-
require '
|
4
|
-
require '
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
1
|
+
require 'gtx'
|
2
|
+
require 'docopt'
|
3
|
+
require 'colsole'
|
4
|
+
require 'requires'
|
5
|
+
|
6
|
+
requires 'runfile/exceptions'
|
7
|
+
requires 'runfile/concerns'
|
8
|
+
requires 'runfile'
|
9
|
+
|
10
|
+
if ENV['BYEBUG']
|
11
|
+
require 'byebug'
|
12
|
+
require 'lp'
|
13
|
+
end
|
metadata
CHANGED
@@ -1,54 +1,127 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: runfile
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0.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: 2023-01-25 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.8.2
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '2.0'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 0.8.2
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '2.0'
|
13
33
|
- !ruby/object:Gem::Dependency
|
14
34
|
name: docopt
|
15
35
|
requirement: !ruby/object:Gem::Requirement
|
16
36
|
requirements:
|
17
37
|
- - "~>"
|
18
38
|
- !ruby/object:Gem::Version
|
19
|
-
version: '0.
|
39
|
+
version: '0.6'
|
40
|
+
type: :runtime
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - "~>"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0.6'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: gtx
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0.1'
|
20
54
|
type: :runtime
|
21
55
|
prerelease: false
|
22
56
|
version_requirements: !ruby/object:Gem::Requirement
|
23
57
|
requirements:
|
24
58
|
- - "~>"
|
25
59
|
- !ruby/object:Gem::Version
|
26
|
-
version: '0.
|
27
|
-
|
28
|
-
|
60
|
+
version: '0.1'
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: requires
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0.2'
|
68
|
+
- - "<"
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: '2.0'
|
71
|
+
type: :runtime
|
72
|
+
prerelease: false
|
73
|
+
version_requirements: !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0.2'
|
78
|
+
- - "<"
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: '2.0'
|
81
|
+
description: Build expressive command line utilities for your projects.
|
29
82
|
email: db@dannyben.com
|
30
83
|
executables:
|
31
|
-
-
|
32
|
-
- run!
|
84
|
+
- runn
|
33
85
|
extensions: []
|
34
86
|
extra_rdoc_files: []
|
35
87
|
files:
|
36
88
|
- README.md
|
37
|
-
- bin/
|
38
|
-
-
|
89
|
+
- bin/runn
|
90
|
+
- examples/default-action-2/runfile
|
91
|
+
- examples/default-action-2/server.runfile
|
92
|
+
- examples/default-action/runfile
|
93
|
+
- examples/different-name/runfile.rb
|
94
|
+
- examples/example-multiline/runfile
|
95
|
+
- examples/example/runfile
|
96
|
+
- examples/execute/runfile
|
97
|
+
- examples/execute/server.runfile
|
98
|
+
- examples/full/runfile
|
99
|
+
- examples/import/more_tasks/spec.runfile
|
100
|
+
- examples/import/runfile
|
101
|
+
- examples/import/tasks/server.runfile
|
102
|
+
- examples/minimal/runfile
|
103
|
+
- examples/multiple-runfiles/runfile
|
104
|
+
- examples/multiple-runfiles/server.runfile
|
105
|
+
- examples/named-only/deploy.runfile
|
106
|
+
- examples/named-only/server.runfile
|
107
|
+
- examples/naval-fate/runfile
|
108
|
+
- examples/shortcut/runfile
|
39
109
|
- lib/runfile.rb
|
40
110
|
- lib/runfile/action.rb
|
41
|
-
- lib/runfile/
|
42
|
-
- lib/runfile/
|
43
|
-
- lib/runfile/
|
44
|
-
- lib/runfile/
|
45
|
-
- lib/runfile/
|
111
|
+
- lib/runfile/concerns/dsl.rb
|
112
|
+
- lib/runfile/concerns/inspectable.rb
|
113
|
+
- lib/runfile/concerns/renderable.rb
|
114
|
+
- lib/runfile/entrypoint.rb
|
115
|
+
- lib/runfile/exceptions.rb
|
116
|
+
- lib/runfile/gem_finder.rb
|
117
|
+
- lib/runfile/initiator.rb
|
118
|
+
- lib/runfile/meta.rb
|
46
119
|
- lib/runfile/runner.rb
|
47
|
-
- lib/runfile/
|
48
|
-
- lib/runfile/
|
49
|
-
- lib/runfile/templates/Runfile
|
50
|
-
- lib/runfile/terminal.rb
|
120
|
+
- lib/runfile/templates/runfile
|
121
|
+
- lib/runfile/userfile.rb
|
51
122
|
- lib/runfile/version.rb
|
123
|
+
- lib/runfile/views/initiator.gtx
|
124
|
+
- lib/runfile/views/userfile.gtx
|
52
125
|
homepage: https://github.com/DannyBen/runfile
|
53
126
|
licenses:
|
54
127
|
- MIT
|
@@ -57,6 +130,7 @@ metadata:
|
|
57
130
|
changelog_uri: https://github.com/DannyBen/runfile/blob/master/CHANGELOG.md
|
58
131
|
source_code_uri: https://github.com/DannyBen/runfile
|
59
132
|
bug_tracker_uri: https://github.com/DannyBen/runfile/issues
|
133
|
+
rubygems_mfa_required: 'true'
|
60
134
|
post_install_message:
|
61
135
|
rdoc_options: []
|
62
136
|
require_paths:
|
@@ -65,15 +139,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
65
139
|
requirements:
|
66
140
|
- - ">="
|
67
141
|
- !ruby/object:Gem::Version
|
68
|
-
version: 2.
|
142
|
+
version: '2.7'
|
69
143
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
70
144
|
requirements:
|
71
|
-
- - "
|
145
|
+
- - ">"
|
72
146
|
- !ruby/object:Gem::Version
|
73
|
-
version:
|
147
|
+
version: 1.3.1
|
74
148
|
requirements: []
|
75
|
-
rubygems_version: 3.
|
149
|
+
rubygems_version: 3.4.5
|
76
150
|
signing_key:
|
77
151
|
specification_version: 4
|
78
|
-
summary:
|
152
|
+
summary: Local command line for your projects
|
79
153
|
test_files: []
|
data/bin/run
DELETED
data/bin/run!
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
# This is needed in cases when you are running "run!" from a folder
|
4
|
-
# that contains a Gemfile on a machine with RVM.
|
5
|
-
# It will disable attempting to run in the current context
|
6
|
-
# Source: https://rvm.io/integration/bundler
|
7
|
-
ENV['NOEXEC_DISABLE'] = '1'
|
8
|
-
|
9
|
-
require 'runfile'
|
10
|
-
|
11
|
-
# for dev
|
12
|
-
# require File.dirname(__FILE__) + "/../lib/runfile"
|
13
|
-
|
14
|
-
include Runfile::DSL
|
15
|
-
|
16
|
-
Runfile::Runner.instance.execute ARGV, false
|
@@ -1,84 +0,0 @@
|
|
1
|
-
# This file provides a compatibility layer for version 0.12.0 so that
|
2
|
-
# all the Colsole methods (say, resay...) and ExecHandler methods
|
3
|
-
# (run, run_bg...) are still available
|
4
|
-
# Simply require 'runfile/compatibility' to have the same functionality
|
5
|
-
# as older versions.
|
6
|
-
#
|
7
|
-
# Notes:
|
8
|
-
# - You need to have the colsole gem installed
|
9
|
-
# - Requiring this file also includes it (see the end of the file).
|
10
|
-
# - This functinality will be removed in future versions
|
11
|
-
# - More info: https://github.com/DannyBen/runfile/pull/46
|
12
|
-
require 'colsole'
|
13
|
-
|
14
|
-
module Runfile
|
15
|
-
module Compatibilty
|
16
|
-
include Colsole
|
17
|
-
|
18
|
-
# Run a command, wait until it is done and continue
|
19
|
-
def run(cmd)
|
20
|
-
cmd = @before_run_block.call(cmd) if @before_run_block
|
21
|
-
return false unless cmd
|
22
|
-
say "!txtgrn!> #{cmd}" unless Runfile.quiet
|
23
|
-
system cmd
|
24
|
-
@after_run_block.call(cmd) if @after_run_block
|
25
|
-
end
|
26
|
-
|
27
|
-
# Run a command, wait until it is done, then exit
|
28
|
-
def run!(cmd)
|
29
|
-
cmd = @before_run_block.call(cmd) if @before_run_block
|
30
|
-
return false unless cmd
|
31
|
-
say "!txtgrn!> #{cmd}" unless Runfile.quiet
|
32
|
-
exec cmd
|
33
|
-
end
|
34
|
-
|
35
|
-
# Run a command in the background, optionally log to a log file and save
|
36
|
-
# the process ID in a pid file
|
37
|
-
def run_bg(cmd, pid: nil, log: '/dev/null')
|
38
|
-
cmd = @before_run_block.call(cmd) if @before_run_block
|
39
|
-
return false unless cmd
|
40
|
-
full_cmd = "exec #{cmd} >#{log} 2>&1"
|
41
|
-
say "!txtgrn!> #{full_cmd}" unless Runfile.quiet
|
42
|
-
process = IO.popen "exec #{cmd} >#{log} 2>&1"
|
43
|
-
File.write pidfile(pid), process.pid if pid
|
44
|
-
@after_run_block.call(cmd) if @after_run_block
|
45
|
-
return process.pid
|
46
|
-
end
|
47
|
-
|
48
|
-
# Stop a command started with 'run_bg'. Provide the name of he pid file you
|
49
|
-
# used in 'run_bg'
|
50
|
-
def stop_bg(pid)
|
51
|
-
file = pidfile(pid)
|
52
|
-
if File.exist? file
|
53
|
-
pid = File.read file
|
54
|
-
File.delete file
|
55
|
-
run "kill -s TERM #{pid}"
|
56
|
-
else
|
57
|
-
say "!txtred!PID file not found." unless Runfile.quiet
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
# Set a block to be called before each run
|
62
|
-
def before_run(&block)
|
63
|
-
@before_run_block = block
|
64
|
-
end
|
65
|
-
|
66
|
-
# Set a block to be called after each run
|
67
|
-
def after_run(&block)
|
68
|
-
@after_run_block = block
|
69
|
-
end
|
70
|
-
|
71
|
-
private
|
72
|
-
|
73
|
-
def pid_dir
|
74
|
-
defined?(Runfile.pid_dir) ? Runfile.pid_dir : nil
|
75
|
-
end
|
76
|
-
|
77
|
-
def pidfile(pid)
|
78
|
-
pid_dir ? "#{pid_dir}/#{pid}.pid" : "#{pid}.pid"
|
79
|
-
end
|
80
|
-
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
include Runfile::Compatibilty
|
@@ -1,128 +0,0 @@
|
|
1
|
-
require 'docopt'
|
2
|
-
|
3
|
-
module Runfile
|
4
|
-
# The DocoptHelper class handles the dynamic generation of the
|
5
|
-
# docopt document and the docopt part of the execution (meaning,
|
6
|
-
# to call Docopt so it returns the parsed arguments or halts with
|
7
|
-
# usage message).
|
8
|
-
class DocoptHelper
|
9
|
-
using Refinements
|
10
|
-
|
11
|
-
# The constructor expects to an object that responds to all the
|
12
|
-
# textual details needed to generate a docopt document (name, version,
|
13
|
-
# summary, options) and an array of Action objects.
|
14
|
-
# The superspace argument will be the name of runfile, in case we
|
15
|
-
# are running a named.runfile. It is only needed to generate the
|
16
|
-
# proper `run superspace (-h|--help|--version)` line
|
17
|
-
def initialize(options)
|
18
|
-
@superspace = options.superspace
|
19
|
-
@name = options.name
|
20
|
-
@version = options.version
|
21
|
-
@summary = options.summary
|
22
|
-
@actions = options.actions
|
23
|
-
@options = options.options
|
24
|
-
@params = options.params
|
25
|
-
@env_vars = options.env_vars
|
26
|
-
@examples = options.examples
|
27
|
-
end
|
28
|
-
|
29
|
-
# Generate a document based on all the actions, help messages
|
30
|
-
# and options we have collected from the Runfile DSL.
|
31
|
-
def docopt
|
32
|
-
width = Terminal.width
|
33
|
-
doc = []
|
34
|
-
doc << (@version ? "#{@name} #{@version}" : "#{@name}")
|
35
|
-
doc << "#{@summary}" if @summary
|
36
|
-
doc += docopt_usage
|
37
|
-
doc += docopt_commands width
|
38
|
-
doc += docopt_options width
|
39
|
-
doc += docopt_params width
|
40
|
-
doc += docopt_env_vars width
|
41
|
-
doc += docopt_examples width
|
42
|
-
doc.join "\n"
|
43
|
-
end
|
44
|
-
|
45
|
-
# Return all docopt lines for the 'Usage' section
|
46
|
-
def docopt_usage
|
47
|
-
doc = ["\nUsage:"];
|
48
|
-
@actions.each do |_name, action|
|
49
|
-
doc << " run #{action.usage}" unless action.usage == false
|
50
|
-
end
|
51
|
-
basic_flags = @version ? "(-h|--help|--version)" : "(-h|--help)"
|
52
|
-
if @superspace
|
53
|
-
doc << " run #{@superspace} #{basic_flags}\n"
|
54
|
-
else
|
55
|
-
doc << " run #{basic_flags}\n"
|
56
|
-
end
|
57
|
-
doc
|
58
|
-
end
|
59
|
-
|
60
|
-
# Return all docopt lines for the 'Commands' section
|
61
|
-
def docopt_commands(width)
|
62
|
-
doc = []
|
63
|
-
caption_printed = false
|
64
|
-
@actions.each do |_name, action|
|
65
|
-
action.help or next
|
66
|
-
doc << "Commands:" unless caption_printed
|
67
|
-
caption_printed = true
|
68
|
-
helpline = " #{action.help}"
|
69
|
-
wrapped = helpline.word_wrap width
|
70
|
-
doc << " #{action.usage}\n#{wrapped}\n" unless action.usage == false
|
71
|
-
end
|
72
|
-
doc
|
73
|
-
end
|
74
|
-
|
75
|
-
# Return all docopt lines for the various 'Options' sections
|
76
|
-
def docopt_options(width)
|
77
|
-
@options['Options'] = {} unless @options['Options']
|
78
|
-
@options['Options']['-h --help'] = 'Show this screen'
|
79
|
-
@options['Options']['--version'] = 'Show version number' if @version
|
80
|
-
section_block @options, width
|
81
|
-
end
|
82
|
-
|
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
|
91
|
-
end
|
92
|
-
|
93
|
-
# Return all docopt lines for the 'Examples' section
|
94
|
-
def docopt_examples(width)
|
95
|
-
return [] if @examples.empty?
|
96
|
-
|
97
|
-
doc = ["Examples:"]
|
98
|
-
base_command = @superspace ? "run #{@superspace}" : "run"
|
99
|
-
@examples.each do |command|
|
100
|
-
helpline = " #{base_command} #{command}"
|
101
|
-
wrapped = helpline.word_wrap width
|
102
|
-
doc << "#{wrapped}"
|
103
|
-
end
|
104
|
-
doc
|
105
|
-
end
|
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
|
-
|
122
|
-
# Call the docopt handler, which will either return a parsed
|
123
|
-
# arguments list, or halt execution and show usage.
|
124
|
-
def args(argv)
|
125
|
-
Docopt.docopt(docopt, version: @version, argv:argv)
|
126
|
-
end
|
127
|
-
end
|
128
|
-
end
|