shelldon 0.0.1 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +11 -0
  3. data/.rubocop.yml +60 -0
  4. data/Gemfile +0 -5
  5. data/README.md +0 -1
  6. data/lib/auto_complete.rb +34 -0
  7. data/lib/command/command.rb +63 -11
  8. data/lib/command/command_list.rb +16 -8
  9. data/lib/command/script.rb +33 -0
  10. data/lib/config/config.rb +13 -4
  11. data/lib/config/config_factory.rb +4 -0
  12. data/lib/config/param.rb +17 -11
  13. data/lib/config/param/boolean_param.rb +1 -1
  14. data/lib/config/param_factory.rb +6 -1
  15. data/lib/dsl.rb +17 -0
  16. data/lib/{Exceptions → exceptions}/error_factory.rb +10 -0
  17. data/lib/exceptions/exceptions.rb +60 -0
  18. data/lib/file_management/config_file_manager.rb +3 -7
  19. data/lib/file_management/history_file.rb +0 -2
  20. data/lib/file_management/yaml_manager.rb +10 -1
  21. data/lib/helpers/confirmation.rb +20 -0
  22. data/lib/helpers/timer.rb +5 -0
  23. data/lib/opts/opt_factory.rb +4 -3
  24. data/lib/opts/opts.rb +1 -1
  25. data/lib/shell/shell.rb +82 -19
  26. data/lib/shell/shell_factory.rb +87 -14
  27. data/lib/shell/shell_index.rb +11 -1
  28. data/lib/shelldon.rb +8 -3
  29. data/lib/shelldon/version.rb +1 -1
  30. data/shelldon.gemspec +15 -8
  31. data/test_shell/Gemfile +1 -2
  32. data/test_shell/Gemfile.lock +7 -6
  33. data/test_shell/dependency_test/Gemfile +2 -0
  34. data/test_shell/dependency_test/Gemfile.lock +21 -0
  35. data/test_shell/dependency_test/dependency_test.rb +20 -0
  36. data/test_shell/dependency_test/dt_commands.rb +66 -0
  37. data/test_shell/dependency_test/dt_config.rb +31 -0
  38. data/test_shell/dependency_test/dt_opts.rb +11 -0
  39. data/test_shell/dependency_test/dt_runner.rb +11 -0
  40. data/test_shell/simple_shell.rb +6 -6
  41. data/test_shell/test_shell.rb +46 -3
  42. data/test_shell/useful_commands.rb +1 -1
  43. metadata +80 -41
  44. data/Gemfile.lock +0 -43
@@ -1,38 +1,111 @@
1
1
  module Shelldon
2
2
  class ShellFactory
3
3
  def initialize(name, &block)
4
- if Shelldon[name]
5
- @shell = Shelldon[name]
6
- else
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 register
13
- Shelldon::ShellIndex << @shell
32
+ def this_shell
33
+ Shelldon[@name]
14
34
  end
15
35
 
16
36
  def shell(&block)
17
- @shell.setup(&block)
37
+ this_shell.setup(&block)
18
38
  end
19
39
 
20
40
  def command(name, &block)
21
- cmd = Shelldon::Command.new(name, @shell.command_list, &block)
22
- @shell.command_list.register(cmd)
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
- Shelldon::ConfigFactory.create(@shell, &block)
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
- OptFactory.new(&block)
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
- cmd = Shelldon::Command.new(:not_found, @shell, &block)
35
- @shell.command_list.register_default(cmd)
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
@@ -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 StandardError
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
@@ -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'
@@ -1,3 +1,3 @@
1
1
  module Shelldon
2
- VERSION = '0.0.1'
2
+ VERSION = '0.0.7'
3
3
  end
@@ -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 = '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"
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
- spec.license = 'MIT'
17
+ spec.license = 'MIT'
18
18
 
19
-
20
- spec.files = Dir["#{File.dirname(__FILE__)}/**/**/**/**/*"].reject { |f| f.match(%r{^(test|spec|features)/}) }
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
@@ -1,3 +1,2 @@
1
+ source 'https://rubygems.org'
1
2
  gem 'shelldon', path: '/Users/wwboynton/repositories/shelldon/'
2
- gem 'getopt'
3
- gem 'byebug'
@@ -1,20 +1,21 @@
1
1
  PATH
2
2
  remote: /Users/wwboynton/repositories/shelldon
3
3
  specs:
4
- shelldon (0.0.1)
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
- byebug (8.2.1)
9
- getopt (1.4.2)
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.10.6
21
+ 1.11.2
@@ -0,0 +1,2 @@
1
+ source 'https://rubygems.org'
2
+ gem 'shelldon', path: '/Users/wwboynton/repositories/shelldon/'
@@ -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
+ Shelldon.shell :test do
2
+ opts do
3
+ opt '--debug', '-d', :boolean
4
+ opt '--help', '-h', :boolean
5
+ end
6
+
7
+ on_opt 'help' do
8
+ puts "Here's some help!"
9
+ exit 0
10
+ end
11
+ 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
@@ -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 'shelldon> ' # This is okay
87
- prompt { "shelldon#{4+2}>" } # This is okay too
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