mysh 0.1.11 → 0.1.12
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +7 -4
- data/lib/mysh.rb +1 -1
- data/lib/mysh/commands/help.rb +17 -15
- data/lib/mysh/commands/help.txt +35 -0
- data/lib/mysh/expression.rb +42 -8
- data/lib/mysh/external_ruby.rb +19 -0
- data/lib/mysh/internal.rb +1 -0
- data/lib/mysh/support/decorate.rb +10 -4
- data/lib/mysh/support/format.rb +25 -8
- data/lib/mysh/support/frame.rb +2 -2
- data/lib/mysh/support/parse.rb +3 -15
- data/lib/mysh/support/text_erb.rb +24 -0
- data/lib/mysh/version.rb +1 -1
- data/test.rb +4 -0
- data/tests/my_shell_tests.rb +11 -0
- metadata +6 -5
- data/lib/mysh/commands/help_head.txt +0 -8
- data/lib/mysh/commands/help_tail.txt +0 -20
- data/lib/mysh/ruby.rb +0 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1658b8c71d6ab5674a8cd4576cc552c8b3fa6904
|
4
|
+
data.tar.gz: 7f8ce8c574a5c959a59bf5b90d64c72fa91776b2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1f4cb448b3a8f3b7e145efdaa4ce7de0550de04cef55009e03a3cd932f2c9dea29a2bf88fb177f0e1476d82790595aaf56affbb62d4c0bdfc4eb6adaa5a1941f
|
7
|
+
data.tar.gz: 675d36eaead283f5d899e7da6949fd09d894496eec25170983db5df34a7b41e0e7cef7f6edfc79775682e88881e60e7211561a82454f0370776e7b0c97d11988
|
data/README.md
CHANGED
@@ -41,14 +41,17 @@ Or install it yourself as:
|
|
41
41
|
The mysh gem includes a simple executable called mysh. When run, the user is
|
42
42
|
presented with a command prompt:
|
43
43
|
|
44
|
-
|
44
|
+
Peter Camilleri@NCC1701G ~
|
45
|
+
$ mysh
|
46
|
+
mysh>
|
45
47
|
|
46
|
-
|
48
|
+
|
49
|
+
This prompt can be used to execute four sorts of commands:
|
47
50
|
|
48
51
|
* Internal commands that are processed directly by mysh
|
49
52
|
* Ruby expressions, which are preceded by the equal (=) sign.
|
50
|
-
* External
|
51
|
-
|
53
|
+
* External ruby source files that are passed on to the Ruby interpreter.
|
54
|
+
* External commands that are passed on to the standard command shell.
|
52
55
|
|
53
56
|
From the mysh help:
|
54
57
|
|
data/lib/mysh.rb
CHANGED
@@ -10,7 +10,7 @@ require 'in_array'
|
|
10
10
|
require_relative 'mysh/smart_source'
|
11
11
|
require_relative 'mysh/expression'
|
12
12
|
require_relative 'mysh/internal'
|
13
|
-
require_relative 'mysh/
|
13
|
+
require_relative 'mysh/external_ruby'
|
14
14
|
require_relative 'mysh/version'
|
15
15
|
|
16
16
|
#The MY SHell module. A container for its functionality.
|
data/lib/mysh/commands/help.rb
CHANGED
@@ -5,23 +5,25 @@ module Mysh
|
|
5
5
|
|
6
6
|
#* exit.rb -- The mysh internal exit command.
|
7
7
|
class InternalCommand
|
8
|
+
#Show a help file
|
9
|
+
def show_help(name)
|
10
|
+
full_name = File.dirname(__FILE__) + name
|
11
|
+
str = IO.read(full_name)
|
12
|
+
puts process_erb_string(str)
|
13
|
+
rescue StandardError, ScriptError => err
|
14
|
+
puts "Error processing file #{full_name}"
|
15
|
+
puts "#{err.class.to_s}: #{err}"
|
16
|
+
end
|
17
|
+
|
18
|
+
HELP = Hash.new(lambda {|args| puts "No help found for #{args[0]}." })
|
19
|
+
|
20
|
+
HELP[nil] = lambda {|_args| show_help('/help.txt') }
|
21
|
+
HELP['math'] = lambda {|_args| show_help('/help_math.txt') }
|
22
|
+
HELP['ruby'] = lambda {|_args| show_help('/help_ruby.txt') }
|
23
|
+
|
8
24
|
#Add the exit command to the library.
|
9
25
|
add('help', 'Display help information for mysh.') do |args|
|
10
|
-
|
11
|
-
puts
|
12
|
-
|
13
|
-
if args.empty?
|
14
|
-
puts IO.read(File.dirname(__FILE__) + '/help_head.txt')
|
15
|
-
InternalCommand.display_items(info)
|
16
|
-
puts IO.read(File.dirname(__FILE__) + '/help_tail.txt')
|
17
|
-
elsif args[0] == 'math'
|
18
|
-
puts IO.read(File.dirname(__FILE__) + '/help_math.txt')
|
19
|
-
elsif args[0] == 'ruby'
|
20
|
-
puts IO.read(File.dirname(__FILE__) + '/help_ruby.txt')
|
21
|
-
else
|
22
|
-
puts "help #{args[0]} ???"
|
23
|
-
end
|
24
|
-
|
26
|
+
instance_exec(args, &HELP[args[0]])
|
25
27
|
end
|
26
28
|
|
27
29
|
add_alias('?', 'help')
|
@@ -0,0 +1,35 @@
|
|
1
|
+
mysh (MY ruby SHell) version: {{ Mysh::VERSION }}
|
2
|
+
|
3
|
+
In mysh, commands fall into one of three broad categories. There are:
|
4
|
+
|
5
|
+
1) Ruby expressions:
|
6
|
+
|
7
|
+
- Any line beginning with an equals "=" sign will be evaluated as a Ruby
|
8
|
+
expression. This allows the mysh command line to serve as a programming,
|
9
|
+
debugging and super-calculator environment.
|
10
|
+
- For more information on ruby expressions use the 'help ruby' command.
|
11
|
+
|
12
|
+
- This environment includes support for advanced mathematical operations.
|
13
|
+
- For more information on this feature, use the 'help math' command.
|
14
|
+
|
15
|
+
2) Internal mysh commands:
|
16
|
+
|
17
|
+
- Internal commands are recognized by name and are executed by mysh directly.
|
18
|
+
- These commands are found in the ".../mysh/lib/mysh/commands" folder.
|
19
|
+
- The following set of commands are supported:
|
20
|
+
|
21
|
+
{{ format_items(InternalCommand.command_info).join("\n") }}
|
22
|
+
|
23
|
+
3) External commands:
|
24
|
+
|
25
|
+
- All other commands are executed by the system using the standard shell or
|
26
|
+
the appropriate ruby interpreter.
|
27
|
+
- If an internal command has the same name as an external command, adding a
|
28
|
+
leading space will force the use of the external command.
|
29
|
+
- If the command has a '.rb' extension, it is executed by the appropriate ruby
|
30
|
+
interpreter. So the command "myfile.rb" is executed as
|
31
|
+
|
32
|
+
{{ RbConfig.ruby }} myfile.rb"
|
33
|
+
|
34
|
+
for this particular system.
|
35
|
+
|
data/lib/mysh/expression.rb
CHANGED
@@ -4,6 +4,8 @@ require 'pp'
|
|
4
4
|
require 'mathn'
|
5
5
|
|
6
6
|
#* expression.rb -- mysh ruby expression processor.
|
7
|
+
#<br>Endemic Code Smells
|
8
|
+
#* :reek:Attribute
|
7
9
|
module Mysh
|
8
10
|
|
9
11
|
#The mysh ruby expression processor.
|
@@ -11,8 +13,37 @@ module Mysh
|
|
11
13
|
|
12
14
|
include Math
|
13
15
|
|
14
|
-
#
|
15
|
-
|
16
|
+
#These variables live here so that they are not part of the mysh
|
17
|
+
#execution environment. This provides a little isolation.
|
18
|
+
class << self
|
19
|
+
attr_accessor :result
|
20
|
+
attr_accessor :exec_fiber
|
21
|
+
attr_accessor :exec_binding
|
22
|
+
attr_accessor :exec_result
|
23
|
+
end
|
24
|
+
|
25
|
+
#Set up a new execution environment
|
26
|
+
#<br>Note
|
27
|
+
#* The exec_result variable is needed because Fiber.yield messes up the
|
28
|
+
# return value on an exception, even if that exception is handled.
|
29
|
+
def initialize
|
30
|
+
ExecHost.result = nil
|
31
|
+
|
32
|
+
ExecHost.exec_fiber = Fiber.new do |cmd|
|
33
|
+
ExecHost.exec_binding = binding
|
34
|
+
|
35
|
+
while true
|
36
|
+
begin
|
37
|
+
ExecHost.exec_result = ExecHost.exec_binding.eval(cmd)
|
38
|
+
rescue StandardError, ScriptError => err
|
39
|
+
ExecHost.exec_result = "#{err.class.to_s}: #{err}"
|
40
|
+
end
|
41
|
+
|
42
|
+
cmd = Fiber.yield
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
16
47
|
|
17
48
|
#Process an expression.
|
18
49
|
def execute(str)
|
@@ -49,12 +80,15 @@ module Mysh
|
|
49
80
|
|
50
81
|
#Execute the string
|
51
82
|
def do_execute(str)
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
83
|
+
ExecHost.exec_fiber.resume("ExecHost.result #{str}")
|
84
|
+
result = ExecHost.exec_result
|
85
|
+
send(result ? :pp : :puts, result)
|
86
|
+
:expression
|
87
|
+
end
|
88
|
+
|
89
|
+
#Get the previous result
|
90
|
+
def result
|
91
|
+
self.class.result
|
58
92
|
end
|
59
93
|
end
|
60
94
|
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
#* external_ruby.rb -- Support for executing Ruby files with the ruby interpreter.
|
4
|
+
module Mysh
|
5
|
+
|
6
|
+
#Try to execute as a Ruby program.
|
7
|
+
def self.ruby_execute(str)
|
8
|
+
cmd = str.split[0]
|
9
|
+
|
10
|
+
if cmd && File.extname(cmd) == '.rb'
|
11
|
+
new_command = "#{RbConfig.ruby} #{str}"
|
12
|
+
puts "=> #{new_command}"
|
13
|
+
system(new_command)
|
14
|
+
:ruby_exec
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
data/lib/mysh/internal.rb
CHANGED
@@ -5,6 +5,7 @@ require_relative 'support/parse'
|
|
5
5
|
require_relative 'support/format'
|
6
6
|
require_relative 'support/frame'
|
7
7
|
require_relative 'support/decorate'
|
8
|
+
require_relative 'support/text_erb'
|
8
9
|
|
9
10
|
#Load up the internal commands!
|
10
11
|
Dir[File.dirname(__FILE__) + '/commands/*.rb'].each {|file| require file }
|
@@ -7,22 +7,28 @@ module Mysh
|
|
7
7
|
class InternalCommand
|
8
8
|
|
9
9
|
#Make the file name fit the local system.
|
10
|
-
def
|
10
|
+
def decorate(name)
|
11
11
|
dress_up_quotes(dress_up_slashes(name))
|
12
12
|
end
|
13
13
|
|
14
|
+
private
|
15
|
+
|
14
16
|
#Dress up slashes and backslashes.
|
15
|
-
def
|
17
|
+
def dress_up_slashes(name)
|
16
18
|
backslash? ? name.gsub("/", "\\") : name
|
17
19
|
end
|
18
20
|
|
19
21
|
#Dress up in quotes if needed.
|
20
|
-
|
22
|
+
#<br>Endemic Code Smells
|
23
|
+
#* :reek:UtilityFunction
|
24
|
+
def dress_up_quotes(name)
|
21
25
|
name[' '] ? "\"#{name}\"" : name
|
22
26
|
end
|
23
27
|
|
24
28
|
#Does this file name use backslashes?
|
25
|
-
|
29
|
+
#<br>Endemic Code Smells
|
30
|
+
#* :reek:UtilityFunction
|
31
|
+
def backslash?
|
26
32
|
MiniReadline::PLATFORM == :windows
|
27
33
|
end
|
28
34
|
|
data/lib/mysh/support/format.rb
CHANGED
@@ -7,33 +7,50 @@ module Mysh
|
|
7
7
|
class InternalCommand
|
8
8
|
|
9
9
|
#Get information on all commands.
|
10
|
-
def self.
|
10
|
+
def self.command_info
|
11
11
|
@commands
|
12
12
|
.values
|
13
|
-
.map {|command| command.
|
13
|
+
.map {|command| command.command_info }
|
14
14
|
.sort {|first, second| first[0] <=> second[0] }
|
15
15
|
end
|
16
16
|
|
17
17
|
#Display an array of items.
|
18
|
-
def
|
18
|
+
def display_items(items)
|
19
|
+
puts format_items(items)
|
20
|
+
puts
|
21
|
+
end
|
22
|
+
|
23
|
+
#Format an array of items.
|
24
|
+
#<br>Endemic Code Smells
|
25
|
+
#* :reek:FeatureEnvy
|
26
|
+
def format_items(items, buffer=[])
|
19
27
|
#Determine the width of the tag area.
|
20
28
|
tag_width = items.max_by {|item| item[0].length}[0].length + 1
|
21
29
|
|
22
30
|
#Display the information.
|
23
|
-
items.each {|item|
|
31
|
+
items.each {|item| format_item(item, buffer, tag_width) }
|
24
32
|
|
25
|
-
|
33
|
+
buffer
|
26
34
|
end
|
27
35
|
|
28
36
|
#Display one item.
|
29
|
-
def
|
37
|
+
def display_item(item, tag_width=nil)
|
38
|
+
puts format_item(item, [], tag_width)
|
39
|
+
puts
|
40
|
+
end
|
41
|
+
|
42
|
+
#Format one item.
|
43
|
+
#<br>Endemic Code Smells
|
44
|
+
#* :reek:UtilityFunction
|
45
|
+
def format_item(item, buffer=[], tag_width)
|
30
46
|
tag = item[0]
|
31
|
-
tag_width ||= tag.length + 1
|
32
47
|
|
33
48
|
item[1].each do |detail|
|
34
|
-
|
49
|
+
buffer << "#{tag.ljust(tag_width)} #{detail}"
|
35
50
|
tag = ""
|
36
51
|
end
|
52
|
+
|
53
|
+
buffer
|
37
54
|
end
|
38
55
|
|
39
56
|
end
|
data/lib/mysh/support/frame.rb
CHANGED
data/lib/mysh/support/parse.rb
CHANGED
@@ -13,11 +13,7 @@ module Mysh
|
|
13
13
|
result, read_point = [], input.chars.each
|
14
14
|
|
15
15
|
loop do
|
16
|
-
|
17
|
-
next_parse_char = read_point.next
|
18
|
-
rescue StopIteration
|
19
|
-
break
|
20
|
-
end
|
16
|
+
next_parse_char = read_point.next
|
21
17
|
|
22
18
|
if next_parse_char == '"'
|
23
19
|
result.concat(get_string(read_point))
|
@@ -38,11 +34,7 @@ module Mysh
|
|
38
34
|
result = ""
|
39
35
|
|
40
36
|
loop do
|
41
|
-
|
42
|
-
next_str_char = read_point.next
|
43
|
-
rescue StopIteration
|
44
|
-
break
|
45
|
-
end
|
37
|
+
next_str_char = read_point.next
|
46
38
|
|
47
39
|
break if next_str_char == '"'
|
48
40
|
|
@@ -59,11 +51,7 @@ module Mysh
|
|
59
51
|
result = first_char
|
60
52
|
|
61
53
|
loop do
|
62
|
-
|
63
|
-
next_parm_char = read_point.next
|
64
|
-
rescue StopIteration
|
65
|
-
break
|
66
|
-
end
|
54
|
+
next_parm_char = read_point.next
|
67
55
|
|
68
56
|
if next_parm_char == '"'
|
69
57
|
return [result].concat(get_string(read_point))
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
#* support/text_erb.rb -- Allow text files to embed ruby code.
|
4
|
+
module Mysh
|
5
|
+
|
6
|
+
#The mysh embedded ruby report formatting.
|
7
|
+
class InternalCommand
|
8
|
+
|
9
|
+
#Process a string with embedded Ruby code.
|
10
|
+
def process_erb_string(str)
|
11
|
+
loop do
|
12
|
+
pre_match, match, post_match = str.partition(/{{.*?}}/m)
|
13
|
+
|
14
|
+
return pre_match if match.empty?
|
15
|
+
|
16
|
+
str = pre_match + eval(match[2...-2]) + post_match
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
data/lib/mysh/version.rb
CHANGED
data/test.rb
ADDED
data/tests/my_shell_tests.rb
CHANGED
@@ -32,4 +32,15 @@ class MyShellTester < Minitest::Test
|
|
32
32
|
|
33
33
|
assert_raises { Mysh::InternalCommand.add_alias('blam', 'shazzam') }
|
34
34
|
end
|
35
|
+
|
36
|
+
def test_handlebars
|
37
|
+
cmd = Mysh::InternalCommand.commands['help']
|
38
|
+
|
39
|
+
assert_equal("ABC 123 DEF",
|
40
|
+
cmd.process_erb_string("ABC {{ (1..3).to_a.join }} DEF"))
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
|
35
46
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mysh
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.12
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Camilleri
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-09-
|
11
|
+
date: 2016-09-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -154,24 +154,25 @@ files:
|
|
154
154
|
- lib/mysh/commands/cd.rb
|
155
155
|
- lib/mysh/commands/exit.rb
|
156
156
|
- lib/mysh/commands/help.rb
|
157
|
-
- lib/mysh/commands/
|
157
|
+
- lib/mysh/commands/help.txt
|
158
158
|
- lib/mysh/commands/help_math.txt
|
159
159
|
- lib/mysh/commands/help_ruby.txt
|
160
|
-
- lib/mysh/commands/help_tail.txt
|
161
160
|
- lib/mysh/commands/history.rb
|
162
161
|
- lib/mysh/expression.rb
|
162
|
+
- lib/mysh/external_ruby.rb
|
163
163
|
- lib/mysh/internal.rb
|
164
|
-
- lib/mysh/ruby.rb
|
165
164
|
- lib/mysh/smart_source.rb
|
166
165
|
- lib/mysh/support/decorate.rb
|
167
166
|
- lib/mysh/support/format.rb
|
168
167
|
- lib/mysh/support/frame.rb
|
169
168
|
- lib/mysh/support/manage.rb
|
170
169
|
- lib/mysh/support/parse.rb
|
170
|
+
- lib/mysh/support/text_erb.rb
|
171
171
|
- lib/mysh/version.rb
|
172
172
|
- mysh.gemspec
|
173
173
|
- rakefile.rb
|
174
174
|
- reek.txt
|
175
|
+
- test.rb
|
175
176
|
- tests/my_shell_tests.rb
|
176
177
|
homepage: http://teuthida-technologies.com/
|
177
178
|
licenses:
|
@@ -1,20 +0,0 @@
|
|
1
|
-
2) Ruby Expression support:
|
2
|
-
|
3
|
-
- Any line beginning with an equals "=" sign will be evaluated as a Ruby
|
4
|
-
expression. This allows the mysh command line to serve as a programming,
|
5
|
-
debugging and super-calculator environment.
|
6
|
-
- For more info use the 'help ruby' command.
|
7
|
-
|
8
|
-
3) Math support:
|
9
|
-
|
10
|
-
- The execution environment includes the Math module.
|
11
|
-
- For more info use the 'help math' command.
|
12
|
-
|
13
|
-
4) External commands:
|
14
|
-
|
15
|
-
- Executed by the system using the standard shell.
|
16
|
-
- To force the use of the external shell, add a leading space to the command.
|
17
|
-
|
18
|
-
Note: If the command has a '.rb' extension it is executed by Ruby.
|
19
|
-
So the command "myfile.rb" is executed as "ruby myfile.rb"
|
20
|
-
|
data/lib/mysh/ruby.rb
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
|
3
|
-
#* ruby.rb -- Support for executing Ruby files with the ruby interpreter.
|
4
|
-
module Mysh
|
5
|
-
|
6
|
-
#Try to execute as a Ruby program.
|
7
|
-
def self.ruby_execute(str)
|
8
|
-
if (command = str.split[0]) && File.extname(command) == '.rb'
|
9
|
-
puts "=> #{new_command = "ruby #{str}"}\n\n"
|
10
|
-
system(new_command)
|
11
|
-
:ruby_exec
|
12
|
-
end
|
13
|
-
|
14
|
-
end
|
15
|
-
|
16
|
-
end
|