shelldon 0.0.1 → 0.0.7
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/.gitignore +11 -0
- data/.rubocop.yml +60 -0
- data/Gemfile +0 -5
- data/README.md +0 -1
- data/lib/auto_complete.rb +34 -0
- data/lib/command/command.rb +63 -11
- data/lib/command/command_list.rb +16 -8
- data/lib/command/script.rb +33 -0
- data/lib/config/config.rb +13 -4
- data/lib/config/config_factory.rb +4 -0
- data/lib/config/param.rb +17 -11
- data/lib/config/param/boolean_param.rb +1 -1
- data/lib/config/param_factory.rb +6 -1
- data/lib/dsl.rb +17 -0
- data/lib/{Exceptions → exceptions}/error_factory.rb +10 -0
- data/lib/exceptions/exceptions.rb +60 -0
- data/lib/file_management/config_file_manager.rb +3 -7
- data/lib/file_management/history_file.rb +0 -2
- data/lib/file_management/yaml_manager.rb +10 -1
- data/lib/helpers/confirmation.rb +20 -0
- data/lib/helpers/timer.rb +5 -0
- data/lib/opts/opt_factory.rb +4 -3
- data/lib/opts/opts.rb +1 -1
- data/lib/shell/shell.rb +82 -19
- data/lib/shell/shell_factory.rb +87 -14
- data/lib/shell/shell_index.rb +11 -1
- data/lib/shelldon.rb +8 -3
- data/lib/shelldon/version.rb +1 -1
- data/shelldon.gemspec +15 -8
- data/test_shell/Gemfile +1 -2
- data/test_shell/Gemfile.lock +7 -6
- data/test_shell/dependency_test/Gemfile +2 -0
- data/test_shell/dependency_test/Gemfile.lock +21 -0
- data/test_shell/dependency_test/dependency_test.rb +20 -0
- data/test_shell/dependency_test/dt_commands.rb +66 -0
- data/test_shell/dependency_test/dt_config.rb +31 -0
- data/test_shell/dependency_test/dt_opts.rb +11 -0
- data/test_shell/dependency_test/dt_runner.rb +11 -0
- data/test_shell/simple_shell.rb +6 -6
- data/test_shell/test_shell.rb +46 -3
- data/test_shell/useful_commands.rb +1 -1
- metadata +80 -41
- data/Gemfile.lock +0 -43
data/lib/shell/shell_factory.rb
CHANGED
@@ -1,38 +1,111 @@
|
|
1
1
|
module Shelldon
|
2
2
|
class ShellFactory
|
3
3
|
def initialize(name, &block)
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
@shell = Shell.new(name)
|
8
|
-
end
|
4
|
+
@name = name
|
5
|
+
setup_vars
|
6
|
+
register(Shell.new(name)) unless Shelldon[name]
|
9
7
|
instance_eval(&block)
|
8
|
+
make_it_rain
|
9
|
+
end
|
10
|
+
|
11
|
+
def setup_vars
|
12
|
+
@new_opts = []
|
13
|
+
@new_configs = []
|
14
|
+
@new_on_opts = []
|
15
|
+
@new_commands = []
|
16
|
+
@new_script_dirs = []
|
17
|
+
end
|
18
|
+
|
19
|
+
def make_it_rain
|
20
|
+
make_opts
|
21
|
+
make_configs
|
22
|
+
make_on_opts
|
23
|
+
make_commands
|
24
|
+
make_scripts
|
25
|
+
make_command_missing
|
26
|
+
end
|
27
|
+
|
28
|
+
def register(shell)
|
29
|
+
Shelldon::ShellIndex << shell
|
10
30
|
end
|
11
31
|
|
12
|
-
def
|
13
|
-
Shelldon
|
32
|
+
def this_shell
|
33
|
+
Shelldon[@name]
|
14
34
|
end
|
15
35
|
|
16
36
|
def shell(&block)
|
17
|
-
|
37
|
+
this_shell.setup(&block)
|
18
38
|
end
|
19
39
|
|
20
40
|
def command(name, &block)
|
21
|
-
|
22
|
-
|
41
|
+
@new_commands << [name, block]
|
42
|
+
end
|
43
|
+
|
44
|
+
def make_commands
|
45
|
+
@new_commands.each do |(name, block)|
|
46
|
+
cmd = Shelldon::Command.new(name, this_shell.command_list, &block)
|
47
|
+
this_shell.command_list.register(cmd)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def script(dir)
|
52
|
+
@new_script_dirs << dir
|
53
|
+
end
|
54
|
+
|
55
|
+
def make_scripts
|
56
|
+
@new_script_dirs.each do |dir|
|
57
|
+
Shelldon::Script.from_dir(dir, this_shell).each do |cmd|
|
58
|
+
this_shell.command_list.register(cmd)
|
59
|
+
end
|
60
|
+
end
|
23
61
|
end
|
24
62
|
|
63
|
+
alias_method :scripts, :script
|
64
|
+
|
25
65
|
def config(&block)
|
26
|
-
|
66
|
+
@new_configs << block
|
67
|
+
end
|
68
|
+
|
69
|
+
def make_configs
|
70
|
+
@new_configs.each do |block|
|
71
|
+
Shelldon::ConfigFactory.create(this_shell, &block)
|
72
|
+
end
|
27
73
|
end
|
28
74
|
|
29
75
|
def opts(&block)
|
30
|
-
|
76
|
+
@new_opts << block
|
77
|
+
end
|
78
|
+
|
79
|
+
def make_opts
|
80
|
+
@new_opts.each { |block| OptFactory.new(@name, &block) }
|
31
81
|
end
|
32
82
|
|
33
83
|
def command_missing(&block)
|
34
|
-
|
35
|
-
|
84
|
+
@new_command_missing = block if block_given?
|
85
|
+
end
|
86
|
+
|
87
|
+
def make_command_missing
|
88
|
+
return unless @new_command_missing
|
89
|
+
cmd = Shelldon::Command.new(:not_found, this_shell, &@new_command_missing.to_proc)
|
90
|
+
this_shell.command_list.register_default(cmd)
|
91
|
+
end
|
92
|
+
|
93
|
+
def on_opt(opt, &block)
|
94
|
+
@new_on_opts << [opt, block]
|
95
|
+
end
|
96
|
+
|
97
|
+
def make_on_opts
|
98
|
+
@new_on_opts.each do |(opt, block)|
|
99
|
+
if this_shell.on_opts.key?(opt)
|
100
|
+
this_shell.on_opts[opt] << block
|
101
|
+
else
|
102
|
+
this_shell.on_opts[opt] = [block]
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def on_pipe(&block)
|
108
|
+
this_shell.on_pipe = block
|
36
109
|
end
|
37
110
|
end
|
38
111
|
end
|
data/lib/shell/shell_index.rb
CHANGED
@@ -22,12 +22,22 @@ module Shelldon
|
|
22
22
|
@shell_index[key.to_sym]
|
23
23
|
end
|
24
24
|
|
25
|
+
def has_key?(key)
|
26
|
+
@shell_index.key?(key)
|
27
|
+
end
|
28
|
+
|
25
29
|
def <<(shell)
|
26
30
|
if shell.is_a?(Shelldon::Shell)
|
31
|
+
@first = shell.name if @shell_index.empty?
|
27
32
|
@shell_index[shell.name] = shell
|
28
33
|
else
|
29
|
-
fail
|
34
|
+
fail Shelldon::NotAShellError
|
30
35
|
end
|
31
36
|
end
|
37
|
+
|
38
|
+
def first?(sym)
|
39
|
+
sym = sym.to_sym unless sym.is_a?(Symbol)
|
40
|
+
sym == @first
|
41
|
+
end
|
32
42
|
end
|
33
43
|
end
|
data/lib/shelldon.rb
CHANGED
@@ -3,20 +3,21 @@ require 'singleton'
|
|
3
3
|
require 'readline'
|
4
4
|
require 'getopt/long'
|
5
5
|
require 'yaml'
|
6
|
-
|
6
|
+
require 'fuzzy_match'
|
7
|
+
require 'shell/shell_index'
|
8
|
+
require 'dsl'
|
7
9
|
require 'shell/shell'
|
8
10
|
require 'config/config'
|
9
11
|
require 'config/param'
|
10
12
|
require 'config/param/string_param'
|
11
13
|
require 'config/param/boolean_param'
|
12
14
|
require 'config/param/number_param'
|
13
|
-
require 'dsl'
|
14
|
-
require 'shell/shell_index'
|
15
15
|
require 'shell/shell_factory'
|
16
16
|
require 'config/config_factory'
|
17
17
|
require 'opts/opt_factory'
|
18
18
|
require 'config/param_factory'
|
19
19
|
require 'command/command'
|
20
|
+
require 'command/script'
|
20
21
|
require 'command/command_list'
|
21
22
|
require 'file_management/file_manager'
|
22
23
|
require 'file_management/yaml_manager'
|
@@ -24,3 +25,7 @@ require 'file_management/config_file_manager'
|
|
24
25
|
require 'exceptions/error_factory'
|
25
26
|
require 'opts/opts'
|
26
27
|
require 'file_management/history_file'
|
28
|
+
require 'helpers/timer'
|
29
|
+
require 'exceptions/exceptions'
|
30
|
+
require 'helpers/confirmation'
|
31
|
+
require 'logger'
|
data/lib/shelldon/version.rb
CHANGED
data/shelldon.gemspec
CHANGED
@@ -4,25 +4,32 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
require 'shelldon/version'
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name
|
8
|
-
spec.version
|
9
|
-
spec.authors
|
10
|
-
spec.email
|
11
|
-
spec.homepage =
|
7
|
+
spec.name = 'shelldon'
|
8
|
+
spec.version = Shelldon::VERSION
|
9
|
+
spec.authors = ['Wesley Boynton']
|
10
|
+
spec.email = ['wes@boynton.io']
|
11
|
+
spec.homepage = 'https://github.com/wwboynton/shelldon'
|
12
12
|
|
13
13
|
spec.summary = 'An expressive DSL for building interactive command-line apps'
|
14
14
|
spec.description = "Shelldon is an expressive DSL for build interactive command-line apps (REPLs)\
|
15
15
|
with minimal effort. It supports all kinds of fun features, like config/history management, \
|
16
16
|
error handling, subcommands, subshells, and more!"
|
17
|
-
|
17
|
+
spec.license = 'MIT'
|
18
18
|
|
19
|
-
|
20
|
-
spec.files =
|
19
|
+
# spec.files = Dir["#{File.dirname(__FILE__)}/**/**/**/**/*"].reject { |f| f.match(%r{^(test|spec|features)/}) }
|
20
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
21
21
|
spec.bindir = 'bin'
|
22
22
|
spec.executables = 'shelldon'
|
23
23
|
spec.require_paths = %w(lib bin)
|
24
24
|
|
25
|
+
# spec.add_runtime_dependency 'terminal-table', '~> 1.10'
|
26
|
+
# spec.add_runtime_dependency 'rb-readline', '~> 0.5.3'
|
27
|
+
spec.add_runtime_dependency 'getopt', '~> 1.4.2'
|
28
|
+
# spec.add_runtime_dependency 'byebug', '~> 8.2.1'
|
29
|
+
spec.add_runtime_dependency 'fuzzy_match'
|
30
|
+
|
25
31
|
spec.add_development_dependency 'bundler', '~> 1.10'
|
26
32
|
spec.add_development_dependency 'rake', '~> 10.0'
|
27
33
|
spec.add_development_dependency 'rubocop', '~> 0.33.0'
|
34
|
+
# spec.add_development_dependency 'byebug', '~> 8.2.1'
|
28
35
|
end
|
data/test_shell/Gemfile
CHANGED
data/test_shell/Gemfile.lock
CHANGED
@@ -1,20 +1,21 @@
|
|
1
1
|
PATH
|
2
2
|
remote: /Users/wwboynton/repositories/shelldon
|
3
3
|
specs:
|
4
|
-
shelldon (0.0.
|
4
|
+
shelldon (0.0.7)
|
5
|
+
fuzzy_match
|
6
|
+
getopt (~> 1.4.2)
|
5
7
|
|
6
8
|
GEM
|
9
|
+
remote: https://rubygems.org/
|
7
10
|
specs:
|
8
|
-
|
9
|
-
getopt (1.4.
|
11
|
+
fuzzy_match (2.1.0)
|
12
|
+
getopt (1.4.3)
|
10
13
|
|
11
14
|
PLATFORMS
|
12
15
|
ruby
|
13
16
|
|
14
17
|
DEPENDENCIES
|
15
|
-
byebug
|
16
|
-
getopt
|
17
18
|
shelldon!
|
18
19
|
|
19
20
|
BUNDLED WITH
|
20
|
-
1.
|
21
|
+
1.11.2
|
@@ -0,0 +1,21 @@
|
|
1
|
+
PATH
|
2
|
+
remote: /Users/wwboynton/repositories/shelldon
|
3
|
+
specs:
|
4
|
+
shelldon (0.0.7)
|
5
|
+
fuzzy_match
|
6
|
+
getopt (~> 1.4.2)
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: https://rubygems.org/
|
10
|
+
specs:
|
11
|
+
fuzzy_match (2.1.0)
|
12
|
+
getopt (1.4.3)
|
13
|
+
|
14
|
+
PLATFORMS
|
15
|
+
ruby
|
16
|
+
|
17
|
+
DEPENDENCIES
|
18
|
+
shelldon!
|
19
|
+
|
20
|
+
BUNDLED WITH
|
21
|
+
1.11.2
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'shelldon'
|
2
|
+
require 'pp'
|
3
|
+
require 'auto_complete'
|
4
|
+
Shelldon.shell :test do
|
5
|
+
command_missing do
|
6
|
+
action { |cmd| puts "No such command \"#{cmd}\"" }
|
7
|
+
end
|
8
|
+
|
9
|
+
shell do
|
10
|
+
prompt 'shelldon> '
|
11
|
+
home '~/.shelldon-test'
|
12
|
+
history true
|
13
|
+
history_file '.shelldon-history'
|
14
|
+
|
15
|
+
errors do
|
16
|
+
accept StandardError
|
17
|
+
# accept(Interrupt) { puts '^C' }
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
Shelldon.shell :test do
|
2
|
+
scripts '~/test/test-scripts'
|
3
|
+
|
4
|
+
command :script do
|
5
|
+
action { '' }
|
6
|
+
scripts '~/test/scripts2'
|
7
|
+
end
|
8
|
+
|
9
|
+
command :arg do
|
10
|
+
help 'Show your args off!'
|
11
|
+
action { |args| puts args }
|
12
|
+
end
|
13
|
+
|
14
|
+
command :blah do
|
15
|
+
action { puts config[:value] }
|
16
|
+
autocomplete %w(dingus dugbus)
|
17
|
+
|
18
|
+
subcommand :swiggity do
|
19
|
+
action { puts 'beh' }
|
20
|
+
end
|
21
|
+
|
22
|
+
subcommand :swag do
|
23
|
+
action { puts 'SWIGGITY SWAG!!!!' }
|
24
|
+
|
25
|
+
subcommand :foobar do
|
26
|
+
action { puts 'BUNGIS' }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
command :help do
|
32
|
+
action { |args| pp command_list.help(args) }
|
33
|
+
help 'Show help. Optionally specify specific command for more information.'
|
34
|
+
usage 'help [cmd]'
|
35
|
+
examples ['help', 'help quit']
|
36
|
+
end
|
37
|
+
|
38
|
+
command :config do
|
39
|
+
help 'Show the configuration of the current session.'
|
40
|
+
usage 'config'
|
41
|
+
|
42
|
+
action do |args|
|
43
|
+
if args.empty?
|
44
|
+
pp config.to_a
|
45
|
+
else
|
46
|
+
param = config.find(args.to_sym)
|
47
|
+
puts "#{param.name}: #{param.val}"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
subcommand :save do
|
52
|
+
help 'Save your current configuration'
|
53
|
+
usage 'config save'
|
54
|
+
action { config.save }
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
command :set do
|
59
|
+
help 'Set a configuration option for the remainder of the session.'
|
60
|
+
|
61
|
+
action do |args|
|
62
|
+
tokens = args.split(' ')
|
63
|
+
config[tokens[0].to_sym] = tokens[1]
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
|
2
|
+
Shelldon.shell :test do
|
3
|
+
config do
|
4
|
+
config_file '.shelldon_config'
|
5
|
+
|
6
|
+
param :debug_mode do
|
7
|
+
type :boolean
|
8
|
+
default false
|
9
|
+
opt 'd'
|
10
|
+
end
|
11
|
+
|
12
|
+
param :'-o' do
|
13
|
+
type :string
|
14
|
+
default 'emacs'
|
15
|
+
adjust { |s| s.to_s.downcase.strip.gsub('vim', 'vi') }
|
16
|
+
validate do |s|
|
17
|
+
return false unless s == 'emacs' || s == 'vi'
|
18
|
+
if s == 'emacs'
|
19
|
+
Readline.emacs_editing_mode; true
|
20
|
+
else
|
21
|
+
Readline.vi_editing_mode; true
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
param :value do
|
27
|
+
type :string
|
28
|
+
default 'This is the default value!'
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# This is a split-up version of the test_shell.rb
|
2
|
+
# It exists so you can screw around with when the different parts are required and ensure that
|
3
|
+
# the order doesn't matter.
|
4
|
+
|
5
|
+
require 'shelldon'
|
6
|
+
require_relative 'dependency_test'
|
7
|
+
require_relative 'dt_commands'
|
8
|
+
require_relative 'dt_opts'
|
9
|
+
require_relative 'dt_config'
|
10
|
+
|
11
|
+
Shelldon[:test].run
|
data/test_shell/simple_shell.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'shelldon'
|
2
2
|
require 'pp'
|
3
3
|
|
4
|
-
Shelldon.shell do
|
4
|
+
Shelldon.shell :test do
|
5
5
|
opts do
|
6
6
|
opt '--myopt', '-m', :boolean
|
7
7
|
end
|
@@ -34,7 +34,6 @@ Shelldon.shell do
|
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
|
-
|
38
37
|
# Here's a simplification of grabbing args for use in an action
|
39
38
|
command :arg do
|
40
39
|
help 'Show your args off!'
|
@@ -64,7 +63,6 @@ Shelldon.shell do
|
|
64
63
|
end
|
65
64
|
end
|
66
65
|
|
67
|
-
|
68
66
|
# This will show all that nice help information we've been defining.
|
69
67
|
# This produces a two-dimensional array, so you could make it into a table with some
|
70
68
|
# table-printing gem if you wanted.
|
@@ -82,9 +80,9 @@ Shelldon.shell do
|
|
82
80
|
|
83
81
|
# LASTLY, define some basic shell properties. The shell will run at the end of this block.
|
84
82
|
shell do
|
85
|
-
# You can make your prompt a string or a block
|
86
|
-
prompt
|
87
|
-
prompt
|
83
|
+
# You can make your prompt a string or a block!
|
84
|
+
# prompt { "shelldon#{4 + 2}> " } # This is okay
|
85
|
+
prompt 'shelldon> ' # This is okay too
|
88
86
|
|
89
87
|
# This is the "home" directory of your shell, used for config files, history files, etc.
|
90
88
|
home '~/.my-test'
|
@@ -104,3 +102,5 @@ Shelldon.shell do
|
|
104
102
|
end
|
105
103
|
end
|
106
104
|
end
|
105
|
+
|
106
|
+
Shelldon[:test].run
|