shelldon 0.0.1 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- 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
|