shelldon 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +43 -0
- data/LICENSE.txt +21 -0
- data/README.md +138 -0
- data/Rakefile +1 -0
- data/bin/shelldon +8 -0
- data/build_and_install.sh +3 -0
- data/lib/Exceptions/error_factory.rb +26 -0
- data/lib/cli.rb +19 -0
- data/lib/command/command.rb +134 -0
- data/lib/command/command_list.rb +72 -0
- data/lib/config/config.rb +85 -0
- data/lib/config/config_factory.rb +41 -0
- data/lib/config/param.rb +54 -0
- data/lib/config/param/boolean_param.rb +28 -0
- data/lib/config/param/number_param.rb +7 -0
- data/lib/config/param/string_param.rb +8 -0
- data/lib/config/param_factory.rb +75 -0
- data/lib/defaults/commands.rb +0 -0
- data/lib/dsl.rb +21 -0
- data/lib/file_management/config_file_manager.rb +34 -0
- data/lib/file_management/file_manager.rb +20 -0
- data/lib/file_management/history_file.rb +34 -0
- data/lib/file_management/yaml_manager.rb +16 -0
- data/lib/helpers/timer.rb +17 -0
- data/lib/opts/opt_factory.rb +30 -0
- data/lib/opts/opts.rb +13 -0
- data/lib/shell/shell.rb +167 -0
- data/lib/shell/shell_factory.rb +38 -0
- data/lib/shell/shell_index.rb +33 -0
- data/lib/shelldon.rb +26 -0
- data/lib/shelldon/version.rb +3 -0
- data/shelldon.gemspec +28 -0
- data/test_shell/Gemfile +3 -0
- data/test_shell/Gemfile.lock +20 -0
- data/test_shell/run.sh +3 -0
- data/test_shell/simple_shell.rb +106 -0
- data/test_shell/test_shell.rb +82 -0
- data/test_shell/useful_commands.rb +11 -0
- metadata +130 -0
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
|
3
|
+
module Shelldon
|
4
|
+
class Config
|
5
|
+
attr_reader :opts
|
6
|
+
attr_accessor :on_opts, :config_file_manager
|
7
|
+
|
8
|
+
def initialize(shell)
|
9
|
+
@shell = shell
|
10
|
+
@opt_arr = []
|
11
|
+
@on_opts = {}
|
12
|
+
@config = {}
|
13
|
+
end
|
14
|
+
|
15
|
+
def opts=(arr)
|
16
|
+
@opts ||= arr
|
17
|
+
end
|
18
|
+
|
19
|
+
def setup
|
20
|
+
load_config_file
|
21
|
+
end
|
22
|
+
|
23
|
+
def register(param)
|
24
|
+
fail StandardError if @config.key?(param.name)
|
25
|
+
@config[param.name] = param
|
26
|
+
end
|
27
|
+
|
28
|
+
def [](key)
|
29
|
+
@config.key?(key) ? @config[key].val : nil
|
30
|
+
end
|
31
|
+
|
32
|
+
def find(key)
|
33
|
+
@config.key?(key) ? @config[key] : nil
|
34
|
+
end
|
35
|
+
|
36
|
+
def []=(key, val)
|
37
|
+
check_param(key, true)
|
38
|
+
@config[key].val = (val)
|
39
|
+
end
|
40
|
+
|
41
|
+
def set(key, val)
|
42
|
+
@config[key].set(val)
|
43
|
+
end
|
44
|
+
|
45
|
+
def to_a
|
46
|
+
@config.map { |k, v| [k, v.pretty] }.sort_by(&:first)
|
47
|
+
end
|
48
|
+
|
49
|
+
def to_hash
|
50
|
+
Hash[@config.map { |_, param| [param.name, param.val] }]
|
51
|
+
end
|
52
|
+
|
53
|
+
def check_param(key, raise = false)
|
54
|
+
if @config.key?(key.to_sym)
|
55
|
+
true
|
56
|
+
else
|
57
|
+
raise ? fail(StandardError) : false
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def to_yaml
|
62
|
+
to_hash.to_yaml
|
63
|
+
end
|
64
|
+
|
65
|
+
def import(hash)
|
66
|
+
# We load all of the params in first without validation, to avoid param dependency issues
|
67
|
+
# Then we validate them all
|
68
|
+
hash.each do |k, v|
|
69
|
+
key = k.to_sym
|
70
|
+
@config.key?(key) ? set(key, v) : fail(StandardError)
|
71
|
+
end
|
72
|
+
hash.each do |k, _|
|
73
|
+
@config[k].valid? unless @config[k].val == @config[k].default
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def load_config_file
|
78
|
+
import(@config_file_manager.import) if @config_file_manager
|
79
|
+
end
|
80
|
+
|
81
|
+
def save
|
82
|
+
@config_file_manager.export if @config_file_manager
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Shelldon
|
2
|
+
class ConfigFactory
|
3
|
+
def self.create(shell, &block)
|
4
|
+
ConfigFactory.new(shell, &block)
|
5
|
+
end
|
6
|
+
|
7
|
+
def initialize(shell, &block)
|
8
|
+
@shell = shell
|
9
|
+
@config = Shelldon::Config.new(@shell)
|
10
|
+
instance_eval(&block)
|
11
|
+
@shell.config = @config
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def config_file(filepath)
|
17
|
+
filepath = Pathname.new(filepath)
|
18
|
+
@config.config_file_manager = Shelldon::ConfigFileManager.new(@shell, filepath)
|
19
|
+
end
|
20
|
+
|
21
|
+
def param(name, &block)
|
22
|
+
ParamFactory.create(@config, name, &block)
|
23
|
+
end
|
24
|
+
|
25
|
+
def on_opt(opt, &block)
|
26
|
+
if @config.on_opts.has_key(opt)
|
27
|
+
@config.on_opts[opt] << block
|
28
|
+
else
|
29
|
+
@config.on_opts[opt] = [block]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def timeout(i)
|
34
|
+
param :timeout do
|
35
|
+
type :number
|
36
|
+
default i
|
37
|
+
pretty { Time.at(val).utc.strftime('%H:%M:%S') }
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/config/param.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
module Shelldon
|
2
|
+
class Param
|
3
|
+
attr_accessor :pretty, :default, :opt, :validator, :adjustor, :error
|
4
|
+
attr_reader :name
|
5
|
+
|
6
|
+
def self.create(name, &block)
|
7
|
+
ParamFactory.create(name, &block)
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize(name)
|
11
|
+
@name = name
|
12
|
+
@default = nil
|
13
|
+
end
|
14
|
+
|
15
|
+
def val
|
16
|
+
if @val.nil?
|
17
|
+
if Shelldon.opts.key?(@opt)
|
18
|
+
Shelldon.opts[@opt]
|
19
|
+
else
|
20
|
+
@default
|
21
|
+
end
|
22
|
+
else
|
23
|
+
@val
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def val=(value)
|
28
|
+
value = instance_exec(value, &adjustor) if adjustor
|
29
|
+
valid?(value) ? @val = value : fail(StandardError)
|
30
|
+
end
|
31
|
+
|
32
|
+
def set(value)
|
33
|
+
value = instance_exec(value, &adjustor) if adjustor
|
34
|
+
@val = value
|
35
|
+
end
|
36
|
+
|
37
|
+
def pretty
|
38
|
+
if @pretty
|
39
|
+
instance_exec(val, &@pretty)
|
40
|
+
else
|
41
|
+
val.to_s
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def valid?(value = @val)
|
46
|
+
return true if validator.nil?
|
47
|
+
if instance_exec(value, &validator)
|
48
|
+
true
|
49
|
+
else
|
50
|
+
@error ? fail(@error) : false
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Shelldon
|
2
|
+
class BooleanParam < Param
|
3
|
+
def initialize(name)
|
4
|
+
@validator ||= proc { |v| v.is_a?(TrueClass) || v.is_a?(FalseClass) }
|
5
|
+
super
|
6
|
+
end
|
7
|
+
|
8
|
+
def fix_val(v)
|
9
|
+
if valid?(v) || v.nil?
|
10
|
+
v
|
11
|
+
elsif v.is_a?(String)
|
12
|
+
return true if v == true || v =~ (/(true|t|yes|y|1)$/i)
|
13
|
+
return false if v == false || v.blank? || v =~ (/(false|f|no|n|0)$/i)
|
14
|
+
fail(ArgumentError, "invalid value for Boolean: \"#{v}\"")
|
15
|
+
else
|
16
|
+
v ? true : false
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def val=(v)
|
21
|
+
@val = fix_val(v)
|
22
|
+
end
|
23
|
+
|
24
|
+
def toggle
|
25
|
+
@val = !@val
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'config/param/string_param'
|
2
|
+
|
3
|
+
module Shelldon
|
4
|
+
class ParamFactory
|
5
|
+
attr_writer :default, :opt
|
6
|
+
|
7
|
+
def self.create(config, name, &block)
|
8
|
+
new(config, name, &block)
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(config, name, &block)
|
12
|
+
@config = config
|
13
|
+
@name = name
|
14
|
+
instance_eval(&block) if block_given?
|
15
|
+
register
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def default(default_value)
|
21
|
+
@default = default_value
|
22
|
+
end
|
23
|
+
|
24
|
+
def opt(opt)
|
25
|
+
@opt = opt
|
26
|
+
end
|
27
|
+
|
28
|
+
def register
|
29
|
+
manufacture
|
30
|
+
if @param
|
31
|
+
@param.pretty = @pretty_proc if @pretty_proc
|
32
|
+
@param.default = @default unless @default.nil?
|
33
|
+
@param.opt = @opt if @opt
|
34
|
+
@param.error = @error if @error
|
35
|
+
@param.validator = @validator if @validator
|
36
|
+
@param.adjustor = @adjustor if @adjustor
|
37
|
+
@config.register(@param)
|
38
|
+
else
|
39
|
+
fail StandardError
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def pretty(&block)
|
44
|
+
@pretty_proc = block
|
45
|
+
end
|
46
|
+
|
47
|
+
def validate(error = nil, &block)
|
48
|
+
@error = error if error
|
49
|
+
@validator = block
|
50
|
+
end
|
51
|
+
|
52
|
+
def adjust(&block)
|
53
|
+
@adjustor = block
|
54
|
+
end
|
55
|
+
|
56
|
+
def manufacture
|
57
|
+
case @type
|
58
|
+
when :string, :str
|
59
|
+
@param = Shelldon::StringParam.new(@name)
|
60
|
+
when :boolean, :bool
|
61
|
+
@param = Shelldon::BooleanParam.new(@name)
|
62
|
+
when :array, :arr
|
63
|
+
@param = Shelldon::ArrayParam.new(@name)
|
64
|
+
when :number, :num
|
65
|
+
@param = Shelldon::NumberParam.new(@name)
|
66
|
+
else
|
67
|
+
@param = Shelldon::StringParam.new(@name)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def type(t)
|
72
|
+
@type = t.to_sym
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
File without changes
|
data/lib/dsl.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
module Shelldon
|
2
|
+
def self.[](key)
|
3
|
+
ShellIndex.instance[key.to_sym]
|
4
|
+
end
|
5
|
+
|
6
|
+
def self.<<(shell)
|
7
|
+
ShellIndex.instance << shell if shell.is_a?(Shelldon::Shell)
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.shell(name = (:default), &block)
|
11
|
+
ShellFactory.new(name.to_sym, &block)
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.opts=(opts_arr)
|
15
|
+
Shelldon::Opts.instance.set(opts_arr)
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.opts
|
19
|
+
Shelldon::Opts.instance.opts
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
module Shelldon
|
4
|
+
class ConfigFileManager < YamlManager
|
5
|
+
def initialize(shell, config_file)
|
6
|
+
@shell = shell
|
7
|
+
@config_file = config_file
|
8
|
+
end
|
9
|
+
|
10
|
+
def ensure_dir(dir)
|
11
|
+
FileUtils.mkdir_p(dir)
|
12
|
+
end
|
13
|
+
|
14
|
+
def ensure_file(file)
|
15
|
+
File.open(file, 'w') { |f| f.write({}.to_yaml) } unless File.exist?(file)
|
16
|
+
end
|
17
|
+
|
18
|
+
def export
|
19
|
+
super(@shell.config)
|
20
|
+
end
|
21
|
+
|
22
|
+
def setup
|
23
|
+
@file = @config_file.expand_path
|
24
|
+
@file_dir = @config_file.dirname.expand_path
|
25
|
+
ensure_dir(@file_dir)
|
26
|
+
ensure_file(@file)
|
27
|
+
end
|
28
|
+
|
29
|
+
def import
|
30
|
+
setup
|
31
|
+
super(@file)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
module Shelldon
|
4
|
+
class FileManager
|
5
|
+
def initialize(_file)
|
6
|
+
@file = config_file.expand_path
|
7
|
+
@file_dir = config_file.dirname.expand_path
|
8
|
+
ensure_dir(@file_dir)
|
9
|
+
ensure_file(@file)
|
10
|
+
end
|
11
|
+
|
12
|
+
def ensure_dir(dir)
|
13
|
+
FileUtils.mkdir_p(dir)
|
14
|
+
end
|
15
|
+
|
16
|
+
def ensure_file(file)
|
17
|
+
File.open(file, 'w') { |f| f.write('') } unless File.exist?(file)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Shelldon
|
2
|
+
class HistoryFile < FileManager
|
3
|
+
def initialize(history_file)
|
4
|
+
@file = history_file
|
5
|
+
ensure_dir(Pathname.new(@file).dirname)
|
6
|
+
ensure_file(@file)
|
7
|
+
end
|
8
|
+
|
9
|
+
def load
|
10
|
+
@file = Pathname.new(@file).expand_path
|
11
|
+
hist = File.open(@file, 'r') { |f| f.read }.split("\n")
|
12
|
+
hist.each do |line|
|
13
|
+
# puts line
|
14
|
+
# pp Readline::HISTORY.to_a
|
15
|
+
Readline::HISTORY.push(line)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def <<(line)
|
20
|
+
File.open(@file, 'a') { |f| f.write("#{line}\n") }
|
21
|
+
end
|
22
|
+
|
23
|
+
def save
|
24
|
+
end
|
25
|
+
|
26
|
+
def truncate(lines)
|
27
|
+
File.open(@file, 'w') do
|
28
|
+
arr = f.read.split("\n")
|
29
|
+
last_100 = arr[-lines..-1].join("\n")
|
30
|
+
f.write(last_100)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
|
2
|
+
module Shelldon
|
3
|
+
class YamlManager < FileManager
|
4
|
+
def ensure_file(file)
|
5
|
+
File.open(file, 'w') { |f| f.write({}.to_yaml) } unless File.exist?(file)
|
6
|
+
end
|
7
|
+
|
8
|
+
def export(yaml)
|
9
|
+
File.open(@file, 'w') { |f| f.write(yaml.to_yaml) }
|
10
|
+
end
|
11
|
+
|
12
|
+
def import(_yaml)
|
13
|
+
YAML.load_file(@file)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|