mysh 0.6.9 → 0.6.11

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: dc2ce1a31750c110022b543778cb28e70b4f2456
4
- data.tar.gz: e5f15032fa38956e7f06be1f8cc92ce5de7feba9
3
+ metadata.gz: 1aaea546a90b6d110dd8910757083c385a7e72d5
4
+ data.tar.gz: 4f82d70adf3479acf12ee7a670c6d3a247326777
5
5
  SHA512:
6
- metadata.gz: 4484f3c07c6ac22a7ccba4b29dd87116926f0731d4b9c54bd54ecefcefcea8676c8fe111d7f7c98be1331ed7ea17798af7d3566ef064d94d879fae89619001fa
7
- data.tar.gz: 7c4a82903c595abd907bd02285051bbb0805481fa54b65f3993359fea6c24376d6f58646f3400ddc9aab36c636fde249d9265c94960339c365954bdad01f9f42
6
+ metadata.gz: 5b6d81b4a6cce7307a7b1262ad4125afb1cc1c0083a2c128543ff43211bd3be70bf4c3372f43a01b1225b4668d077b3b29cac51c29741313c0ae757510398e3a
7
+ data.tar.gz: 1aff82db1052b83caf85b0e09f006eebebf80a0b0782da66660b09586fabe1527bdd72f4760c47eaa2a4387a5f16447acc6ce588f364101d3a692736c628bad1
data/README.md CHANGED
@@ -26,7 +26,7 @@ See the original article at:
26
26
  (http://www.blackbytes.info/2016/07/writing-a-shell-in-ruby/)
27
27
 
28
28
  Oh, and one other little thing. A survey of the mysh reveals that it currently
29
- contains 2291 lines of code. It seems that there has been some growth beyond
29
+ contains 2188 lines of code. It seems that there has been some growth beyond
30
30
  the 25 lines in the original article.
31
31
 
32
32
  ## Installation
@@ -907,7 +907,7 @@ on the optional parms.
907
907
  ###### "string".preprocess(context=mysh_default_context)
908
908
  Process the string for embedded variables and handlebars. By default,
909
909
  any embedded ruby is evaluated in the mysh global expression binding. However,
910
- another BindingWrapper instance may be passed to access an alternative binding.
910
+ another binding may be passed to access an alternative execution environment.
911
911
 
912
912
  ###### "string".to_host_spec
913
913
  Given a string with a file spec, to_host_spec adjusts that string so that it is
data/lib/mysh.rb CHANGED
@@ -1,17 +1,16 @@
1
1
  # coding: utf-8
2
2
 
3
- # mysh -- MY SHell -- a Ruby/Rails inspired command line shell.
3
+ # mysh -- MY SHell -- a Ruby inspired command line shell.
4
4
 
5
+ require 'pp'
5
6
  require 'English'
6
7
  require 'in_array'
7
8
  require 'pause_output'
8
9
  require 'format_output'
9
10
 
10
11
  require_relative 'mysh/exceptions'
11
- require_relative 'mysh/binding_wrapper'
12
12
  require_relative 'mysh/input_wrapper'
13
13
  require_relative 'mysh/user_input'
14
- require_relative 'mysh/expression'
15
14
  require_relative 'mysh/internal'
16
15
  require_relative 'mysh/quick'
17
16
  require_relative 'mysh/external'
@@ -22,7 +21,7 @@ require_relative 'mysh/pre_processor'
22
21
  require_relative 'mysh/process'
23
22
  require_relative 'mysh/globalize'
24
23
  require_relative 'mysh/init'
25
-
24
+ require_relative 'mysh/expression'
26
25
  require_relative 'mysh/version'
27
26
 
28
27
  #The Mysh (MY SHell) module. A container for mysh and its functionality.
@@ -43,3 +42,5 @@ end
43
42
  if __FILE__ == $0
44
43
  Mysh.run(ARGV) #Run a shell if this file is run directly.
45
44
  end
45
+
46
+ $VERBOSE = nil
@@ -1,66 +1,46 @@
1
1
  # coding: utf-8
2
2
 
3
- require 'pp'
4
3
  require_relative 'expression/lineage'
5
4
 
6
- #* mysh/expression.rb -- The mysh ruby expression processor.
7
- #<br>Endemic Code Smells
8
- #* :reek:ModuleInitialize -- False positive
5
+ # Endemic Code Smells :reek:ModuleInitialize -- False positive
9
6
  module Mysh
10
7
 
11
- #Set up some popular constants
8
+ # Set up some popular constants
12
9
  E = Math::E
13
10
  PI = Math::PI
14
11
 
15
- #Reset the state of the execution hosting environment.
16
- #<br>Endemic Code Smells
17
- # :reek:TooManyStatements -- False positive
12
+ $mysh_exec_result = nil
13
+
14
+ # Reset the state of the execution hosting environment.
15
+ # Endemic Code Smells :reek:TooManyStatements -- False positive
18
16
  def self.reset_host
19
17
  exec_class = Class.new do
20
18
 
21
19
  include Math
22
20
 
23
- #Set up a new execution environment
21
+ # Set up a new execution environment
24
22
  def initialize
25
- $mysh_exec_result = nil
26
- $mysh_exec_binding = mysh_binding
27
- end
28
-
29
- #Do the actual work of executing an expression.
30
- #<br>Note:
31
- #* The expression string always begins with an '=' character.
32
- def execute(expression)
33
- pp $mysh_exec_binding.eval("$mysh_exec_result" + expression)
34
- :expression
23
+ $mysh_exec_binding = binding
35
24
  end
36
25
 
37
- #Return a simple message for less convoluted error messages.
26
+ # Return a simple message for less convoluted error messages.
38
27
  def inspect
39
28
  "exec_host"
40
29
  end
41
30
 
42
- #Evaluate the string in the my shell context.
43
- def mysh_eval(str)
44
- $mysh_exec_binding.eval(str)
45
- end
46
-
47
31
  private
48
32
 
49
- #Get the previous result
33
+ # Get the previous result
50
34
  def result
51
35
  $mysh_exec_result
52
36
  end
53
37
 
54
- #Reset the state of the execution host.
38
+ # Reset the state of the execution host.
55
39
  def reset
56
40
  Mysh.reset_host
57
41
  nil
58
42
  end
59
43
 
60
- #Create a binding for mysh to execute expressions in.
61
- def mysh_binding
62
- binding
63
- end
64
44
  end
65
45
 
66
46
  $mysh_exec_host = exec_class.new
data/lib/mysh/external.rb CHANGED
@@ -22,7 +22,7 @@ module Mysh
22
22
  Mysh.process_file(file_name)
23
23
  :mysh_script
24
24
  elsif ext == '.txt'
25
- show_handlebar_file(file_name, BindingWrapper.new(binding))
25
+ show_handlebar_file(file_name, binding)
26
26
  :internal
27
27
  end
28
28
  end
@@ -27,4 +27,17 @@ class Object
27
27
  err.to_s
28
28
  end
29
29
 
30
+ # Get the latest version for the named gem. Patched code.
31
+ def latest_version_for(name, fetcher=nil)
32
+ dependency = Gem::Dependency.new(name)
33
+ fetcher ||= Gem::SpecFetcher.new
34
+
35
+ if specs = fetcher.spec_for_dependency(dependency)[0][-1]
36
+ spec = specs[0]
37
+ spec && spec.version
38
+ else
39
+ "<Not found in repository>"
40
+ end
41
+ end
42
+
30
43
  end
@@ -2,21 +2,20 @@
2
2
 
3
3
  require_relative 'handlebars/string'
4
4
 
5
- #* user_input/handlebars.rb -- Handlebar embedded ruby support.
5
+ # Handlebar embedded ruby support.
6
6
  class Object
7
7
 
8
- #Show a file with embedded ruby handlebars.
9
- #<br>Note:
10
- #The message receiver is the evaluation host for the handlebar code.
11
- def show_handlebar_file(name, evaluator = $mysh_exec_host)
8
+ private
9
+
10
+ # Show a file with embedded ruby handlebars.
11
+ # Note: The message receiver is the evaluation host for the handlebar code.
12
+ def show_handlebar_file(name, evaluator = $mysh_exec_binding)
12
13
  puts eval_handlebar_file(name, evaluator)
13
14
  end
14
15
 
15
- #Expand a file with embedded ruby handlebars.
16
- #<br>Note:
17
- #The message receiver is the evaluation host for the handlebar code.
18
- #<br>Endemic Code Smells
19
- #* :reek:UtilityFunction
16
+ # Expand a file with embedded ruby handlebars.
17
+ # Note: The message receiver is the evaluation host for the handlebar code.
18
+ # Endemic Code Smells :reek:UtilityFunction
20
19
  def eval_handlebar_file(name, evaluator)
21
20
  IO.read(name).preprocess(evaluator)
22
21
  end
@@ -1,22 +1,36 @@
1
1
  # coding: utf-8
2
2
 
3
- #Monkey patches for Mysh handlebars
3
+ # Monkey patches for Mysh handlebars
4
4
  class String
5
5
 
6
- #Evaluate any variable substitutions in the input.
7
- def eval_handlebars(evaluator=$mysh_exec_host)
8
- gsub(/{{.*?}}/m) do |match|
9
- code = match[2...-2]
10
- silent = code.end_with?("#")
11
- result = evaluator.mysh_eval(code)
6
+ # Evaluate any variable substitutions in the input.
7
+ def eval_handlebars(evaluator=$mysh_exec_binding)
8
+ string, text, buffer = self, "", []
12
9
 
13
- (result unless silent).to_s
10
+ until string.empty?
11
+ text, code, string = string.partition(/{{.*?}}/m)
12
+
13
+ if not text.empty?
14
+ text = text.gsub(/\\[{}]/) {|found| found[1]}
15
+ buffer << "_m_<<#{text.inspect};"
16
+ elsif buffer.empty?
17
+ buffer << ""
18
+ end
19
+
20
+ unless code.empty?
21
+ if code[-3] == "#"
22
+ buffer << "#{code[2...-3]};"
23
+ else
24
+ buffer << "_m_<<(#{code[2...-2]}).to_s;"
25
+ end
26
+ end
14
27
  end
15
- end
16
28
 
17
- #Process quoted brace characters
18
- def eval_quoted_braces
19
- gsub(/\\[\{\}]/) {|found| found[1]}
29
+ if buffer.length > 1
30
+ evaluator.eval("_m_ = '';" + buffer.join + "_m_")
31
+ else
32
+ text
33
+ end
20
34
  end
21
35
 
22
36
  end
@@ -30,6 +30,17 @@ those cases, simply end the expression with a '#' character. For example:
30
30
  mysh>echo \{\{ "not embedded" #\}\} \{\{ "embedded" \}\}
31
31
  embedded
32
32
 
33
+ A common use for not embedded code snippets is to act as the control
34
+ structures. For example:
35
+
36
+ \{\{ 3.times do |i| #\}\} The count is: \{\{ i+1 \}\}
37
+ \{\{ end #\}\}
38
+
39
+ Yields the following output:
40
+
41
+ {{ 3.times do |i| #}} The count is: {{ i+1 }}
42
+ {{ end #}}
43
+
33
44
  Finally, it may be that it is desired to embed braces into a text file or
34
45
  the command line. In that case precede the brace with a backslash character
35
46
  like: \\{ or \\}
@@ -18,7 +18,7 @@ module Mysh
18
18
  Mysh.process_file(file_name)
19
19
  :internal
20
20
  elsif file_ext == '.txt'
21
- show_handlebar_file(file_name, BindingWrapper.new(binding))
21
+ show_handlebar_file(file_name, binding)
22
22
  :internal
23
23
  elsif file_ext == '.rb'
24
24
  load file_name
@@ -8,14 +8,12 @@ module Mysh
8
8
 
9
9
  # Execute the @env shell command.
10
10
  def process_command(_args)
11
- print WORKING unless @ran_once
11
+ print WORKING
12
12
  Gem.refresh
13
13
 
14
14
  puts "Key mysh environment information.", "",
15
15
  info.format_output_bullets, "",
16
16
  path.format_output_bullets, ""
17
-
18
- @ran_once = true
19
17
  end
20
18
 
21
19
  private
@@ -28,7 +26,7 @@ module Mysh
28
26
  ["installed", Gem::Specification.find_all_by_name("mysh")
29
27
  .map{|s| s.version.to_s}
30
28
  .join(", ")],
31
- ["latest", insouciant {Gem.latest_version_for("mysh").to_s}],
29
+ ["latest", insouciant {latest_version_for("mysh").to_s}],
32
30
  ["init file", $mysh_init_file.to_host_spec],
33
31
  ["user", ENV['USER']],
34
32
  ["home", (ENV['HOME'] || "").to_host_spec],
@@ -8,7 +8,7 @@ module Mysh
8
8
 
9
9
  #Execute the @gem shell command.
10
10
  def process_command(input)
11
- print WORKING unless @ran_once
11
+ print WORKING
12
12
  Gem.refresh
13
13
 
14
14
  args = input.cooked_body.split(" ")[1..-1]
@@ -19,7 +19,6 @@ module Mysh
19
19
  specific(args)
20
20
  end
21
21
 
22
- @ran_once = true
23
22
  end
24
23
 
25
24
  private
@@ -61,7 +60,7 @@ module Mysh
61
60
 
62
61
  # Get gem info on the specified gems
63
62
  def specific(args)
64
- details = []
63
+ fetcher, details = Gem::SpecFetcher.new, []
65
64
 
66
65
  args.each do |gem_name|
67
66
  version_list = Gem::Specification.find_all_by_name(gem_name)
@@ -69,7 +68,7 @@ module Mysh
69
68
  .join(", ")
70
69
  details << [gem_name, version_list]
71
70
 
72
- latest = insouciant {latest_version_for(gem_name).to_s}
71
+ latest = insouciant {latest_version_for(gem_name, fetcher).to_s}
73
72
  details << ["latest", latest]
74
73
  details << [" ", " "]
75
74
  end
@@ -78,18 +77,6 @@ module Mysh
78
77
  details.format_output_bullets
79
78
  end
80
79
 
81
- # Get the latest version for the named gem. Patched code.
82
- def latest_version_for(name)
83
- dependency = Gem::Dependency.new(name)
84
- fetcher = Gem::SpecFetcher.fetcher
85
- if specs = fetcher.spec_for_dependency(dependency)[0][-1]
86
- spec = specs[0]
87
- spec && spec.version
88
- else
89
- "<Not found in repository>"
90
- end
91
- end
92
-
93
80
  end
94
81
 
95
82
  desc = 'Get information about the current gem support or ' +
@@ -8,13 +8,11 @@ module Mysh
8
8
 
9
9
  #Execute the @term shell command.
10
10
  def process_command(_args)
11
- print WORKING unless @ran_once
11
+ print WORKING
12
12
  Gem.refresh
13
13
 
14
14
  puts "Key term information.", "",
15
15
  info.format_output_bullets, ""
16
-
17
- @ran_once = true
18
16
  end
19
17
 
20
18
  private
@@ -22,18 +20,20 @@ module Mysh
22
20
  # Get the info
23
21
  # Endemic Code Smells :reek:UtilityFunction
24
22
  def info
23
+ fetcher = Gem::SpecFetcher.new
24
+
25
25
  [["about", MiniReadline::DESCRIPTION],
26
26
  ["version", MiniReadline::VERSION],
27
27
  ["installed", Gem::Specification.find_all_by_name("mini_readline")
28
28
  .map{|s| s.version.to_s}
29
29
  .join(", ")],
30
- ["latest", insouciant {Gem.latest_version_for("mini_readline").to_s}],
30
+ ["latest", insouciant {latest_version_for("mini_readline", fetcher).to_s}],
31
31
  ["about", MiniTerm::DESCRIPTION],
32
32
  ["version", MiniTerm::VERSION],
33
33
  ["installed", Gem::Specification.find_all_by_name("mini_term")
34
34
  .map{|s| s.version.to_s}
35
35
  .join(", ")],
36
- ["latest", insouciant {Gem.latest_version_for("mini_term").to_s}],
36
+ ["latest", insouciant {latest_version_for("mini_term", fetcher).to_s}],
37
37
  ["platform", MiniTerm::TERM_PLATFORM.inspect],
38
38
  ["term type", MiniTerm::TERM_TYPE.inspect],
39
39
  ["columns", MiniTerm.width.to_s],
@@ -45,8 +45,6 @@ module Mysh
45
45
  ]
46
46
  end
47
47
 
48
-
49
-
50
48
  end
51
49
 
52
50
  desc = 'Get information about the console. See ?term for more.'
@@ -12,7 +12,7 @@ module Mysh
12
12
  file_name = args.shift
13
13
 
14
14
  if file_name
15
- show_handlebar_file(file_name, BindingWrapper.new(binding))
15
+ show_handlebar_file(file_name, binding)
16
16
  else
17
17
  fail "A text file must be specified."
18
18
  end
@@ -4,8 +4,8 @@
4
4
  class String
5
5
 
6
6
  #The mysh string pre-processor stack.
7
- def preprocess(evaluator=$mysh_exec_host)
8
- self.eval_variables.eval_handlebars(evaluator).eval_quoted_braces
7
+ def preprocess(evaluator=$mysh_exec_binding)
8
+ self.eval_variables.eval_handlebars(evaluator)
9
9
  end
10
10
 
11
11
  end
data/lib/mysh/quick.rb CHANGED
@@ -9,10 +9,16 @@ module Mysh
9
9
  QUICK['!'] = lambda {|input| HISTORY_COMMAND.process_quick_command(input)}
10
10
  QUICK['#'] = lambda {|input| MYSH_COMMENT.process_command(input)}
11
11
  QUICK['%'] = lambda {|input| TIMED_COMMAND.process_command(input)}
12
- QUICK['='] = lambda {|input| $mysh_exec_host.execute(input.raw.preprocess)}
13
12
  QUICK['?'] = lambda {|input| HELP_COMMAND.process_quick_command(input)}
14
13
  QUICK['@'] = lambda {|input| SHOW_COMMAND.process_quick_command(input)}
15
14
 
15
+ QUICK['='] = lambda do |input|
16
+ cmd = "$mysh_exec_result=(" + input.raw[1..-1].preprocess + ")"
17
+ puts cmd if MNV[:debug].extract_boolean
18
+ pp $mysh_exec_binding.eval(cmd)
19
+ :expression
20
+ end
21
+
16
22
  #Try to execute the inputing as a quick command.
17
23
  def self.try_execute_quick(input)
18
24
  QUICK[input.quick_command].call(input)
data/lib/mysh/version.rb CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Mysh
4
4
  #The version string of MY SHell.
5
- VERSION = "0.6.9"
5
+ VERSION = "0.6.11"
6
6
 
7
7
  #A brief summary of this gem.
8
8
  SUMMARY = "mysh -- a Ruby inspired command line shell."
data/samples/show.txt CHANGED
@@ -9,3 +9,5 @@ Args = {{ args.inspect }}
9
9
  ["Squares", Array.new(count){|i| (i+1)**2} ],
10
10
  ["Cubes", Array.new(count){|i| (i+1)**3} ]].format_output_bullets }}
11
11
 
12
+ {{ 10.times do |i| #}} Let's count: {{ i+1 }}
13
+ {{ end #}}
@@ -19,7 +19,6 @@ class MyShellTester < Minitest::Test
19
19
  assert_equal(Class, Mysh::ActionPool.class)
20
20
  assert_equal(Module, Mysh::MNV.class)
21
21
  assert_equal(Class, Mysh::Keeper.class)
22
- assert_equal(Class, Mysh::BindingWrapper.class)
23
22
  assert_equal(Class, Mysh::InputWrapper.class)
24
23
 
25
24
  assert_equal(Mysh::ActionPool, Mysh::COMMANDS.class)
@@ -44,13 +43,13 @@ class MyShellTester < Minitest::Test
44
43
 
45
44
  def test_handlebars
46
45
  assert_equal("ABC 123 DEF",
47
- "ABC {{ (1..3).to_a.join }} DEF".eval_handlebars)
46
+ "ABC {{ (1..3).to_a.join }} DEF".preprocess)
48
47
 
49
- assert_equal("ABC", "{{ 'ABC' }}".eval_handlebars)
50
- assert_equal("", "{{ 'ABC' #}}".eval_handlebars)
48
+ assert_equal("ABC", "{{ 'ABC' }}".preprocess)
49
+ assert_equal("", "{{ 'ABC' #}}".preprocess)
51
50
 
52
- assert_equal("{{ 'ABC' }}", "\\{\\{ 'ABC' \\}\\}".eval_quoted_braces)
53
- assert_equal("{{A}}", "{{ '{'+'{A}'+'}' }}".eval_handlebars.eval_quoted_braces)
51
+ assert_equal("{{ 'ABC' }}", "\\{\\{ 'ABC' \\}\\}".preprocess)
52
+ assert_equal("{{A}}", "{{ '{'+'{A}'+'}' }}".preprocess)
54
53
  end
55
54
 
56
55
  def test_command_parsing
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.6.9
4
+ version: 0.6.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Camilleri
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-12-22 00:00:00.000000000 Z
11
+ date: 2018-12-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -193,7 +193,6 @@ files:
193
193
  - README.md
194
194
  - bin/mysh
195
195
  - lib/mysh.rb
196
- - lib/mysh/binding_wrapper.rb
197
196
  - lib/mysh/exceptions.rb
198
197
  - lib/mysh/expression.rb
199
198
  - lib/mysh/expression/lineage.rb
@@ -1,21 +0,0 @@
1
- # coding: utf-8
2
-
3
- #* mysh/internal/binding_wrapper.rb -- An action compatible wrapper for a binding.
4
- module Mysh
5
-
6
- #* mysh/internal/binding_wrapper.rb -- An action compatible wrapper for a binding.
7
- class BindingWrapper
8
-
9
- #Setup a binding wrapper
10
- def initialize(binding)
11
- @exec_binding = binding
12
- end
13
-
14
- #Evaluate the string in the wrapped context.
15
- def mysh_eval(str)
16
- @exec_binding.eval(str)
17
- end
18
-
19
- end
20
-
21
- end