superscript 0.4.2 → 0.8.0

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
  SHA256:
3
- metadata.gz: e12ad2456097931fa8ae7d7ceb5870ded64f9f13d4602568e3696b9af55b1ae8
4
- data.tar.gz: 920979e9fce25c924a51e83c2b830bafb50532659f2a7fbcb70216dc4e226fa6
3
+ metadata.gz: 0bc0b05122c192f2a84ec91cadc082732fed684193b8188f8199bba45028325a
4
+ data.tar.gz: d984d3bf79427a748d7eff8fe5eb52e9be1b79cf8fa4eb2c296876d1e86619e1
5
5
  SHA512:
6
- metadata.gz: 59c7e83257e769ae2456305fb3c25ae16decc905314a931a1cbf156575775eec38c1ea0c6e30a959868ab58dae48f5e70aa262494e3b75c566bf6b5e3abd9ae6
7
- data.tar.gz: da64fb8f666dd4ff92ddc2d54b7cd4940435f4c8f5bbae5729b23b424feab31d98548fa7cc04ead529963b3a78660c0839b9ee343c880c618a0404ccdd222e59
6
+ metadata.gz: 35ae9ec98919157414db881ab46c8f37038bba5464592539ecb51459d1769d183fa9c734412ca26935444819c0281a8f444d5acbb262bc981511c585a05a439c
7
+ data.tar.gz: 3d17e452859eaea0861b5971dd7f04077689e7920c446a504b6ecacb4034d4092520ba32f99f2b674071376d736cc0f227575f860ca9622eb06b8d27f74e5aee
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- superscript (0.4.2)
4
+ superscript (0.8.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -1,6 +1,22 @@
1
1
  class Go < Superscript::Dsl
2
2
  def go(*args)
3
- puts "Go #{args.join(" ")}"
3
+ self.say "Go #{args.join(" ")}!"
4
+ end
5
+
6
+ def hang
7
+ sleep 9999
8
+ end
9
+
10
+ def say(message)
11
+ puts message
12
+ end
13
+
14
+ def struct
15
+ Struct.new(:name).new("joe")
16
+ end
17
+
18
+ def now
19
+ Time.now
4
20
  end
5
21
 
6
22
  def explode!
@@ -1,3 +1,2 @@
1
- go "gators"
2
-
3
- explode!
1
+ a = struct
2
+ go a.name
@@ -4,11 +4,18 @@ $stdout.sync = true
4
4
 
5
5
  require "bundler/setup"
6
6
  require "superscript"
7
+ require "optparse"
7
8
 
8
- if ARGV.length == 0
9
- puts "USAGE: superscript dsl.rb [script.rb]"
10
- exit 1
11
- end
9
+ options = {
10
+ methods: false,
11
+ on_error_exec: nil
12
+ }
13
+ ARGV << "-h" if ARGV.empty?
14
+
15
+ optparse = OptionParser.new do |opt|
16
+ opt.on('--allow-methods') { |o| options[:methods] = true }
17
+ opt.on('--on-error-exec CMD') { |o| options[:on_error_exec] = o }
18
+ end.parse!
12
19
 
13
20
  best_guess_path = if ARGV[0].start_with? "/"
14
21
  ARGV[0]
@@ -22,13 +29,15 @@ ctx_classname = File.basename(ARGV[0]).split(".").first.capitalize
22
29
  ctx = (eval "#{ctx_classname}").new
23
30
 
24
31
  if ARGV[1]
25
- runner = Superscript::Runner.new ARGV[1]
32
+ runner = Superscript::Runner.new ARGV[1], options
26
33
  runner.run! ctx
27
34
  else
28
- runner = Superscript::Runner.new
35
+ require "readline"
36
+
37
+ runner = Superscript::Runner.new nil, options
29
38
  loop do
30
- print "> "
31
- contents = STDIN.gets
39
+ contents = Readline.readline "> ", true
40
+
32
41
  value = runner.run! ctx, contents: contents
33
42
  puts " => #{value.inspect}"
34
43
  end
@@ -1,7 +1,4 @@
1
1
  module Superscript
2
2
  class Ctx
3
- def method_missing(*args)
4
- ::Superscript.error :ctx_method_missing, "No such command or variable '#{args.first}'"
5
- end
6
3
  end
7
4
  end
@@ -1,31 +1,14 @@
1
- module Superscript
2
- def self.error(where, *args)
3
- puts "-- [ superscript error ] --"
4
- error_message = ""
5
- case where
6
- when :exception
7
- exception = args.first
8
- pp exception
9
- pp exception.backtrace_locations
10
- error_message = exception
11
- when :ctx_method_missing, :tp_singleton_method_added, :tp_command_not_found
12
- error_message = args.first
13
- when :tp_class_define, :tp_module_define
14
- error_message = args.first
15
- else
16
- pp [:unknown_where, where, args]
17
- error_message = args.join(" ")
18
- end
1
+ Signal.trap "TERM" do
2
+ exit 0
3
+ end
19
4
 
20
- puts error_message
21
- if ENV["SUPERSCRIPT_ERROR_EXEC"]
22
- error_exec_pid = spawn ENV["SUPERSCRIPT_ERROR_EXEC"], error_message
23
- Process.wait error_exec_pid
24
- end
25
- exit 1
26
- end
5
+ module Superscript
27
6
  class Runner
28
- def initialize path=nil
7
+ def initialize path=nil, opts={}
8
+ @methods = opts[:methods] || false
9
+ @on_error_exec = opts[:on_error_exec]
10
+
11
+ @armed = false
29
12
  @path = if path
30
13
  path
31
14
  else
@@ -33,32 +16,77 @@ module Superscript
33
16
  end
34
17
  end
35
18
 
19
+ def error!(where, *args)
20
+ puts "-- [ superscript error ] --"
21
+ error_message = ""
22
+ case where
23
+ when :exception
24
+ exception = args.first
25
+ error_message = exception
26
+ when :tp_call_superscript, :tp_call_superscript_global
27
+ error_message = "Can't touch this"
28
+ when :ctx_method_missing, :tp_singleton_method_added, :tp_command_not_found
29
+ error_message = args.first
30
+ when :tp_class_define, :tp_module_define
31
+ error_message = args.first
32
+ else
33
+ pp [:unknown_where, where, args]
34
+ error_message = args.join(" ")
35
+ end
36
+
37
+ puts error_message
38
+ if @on_error_exec
39
+ system("#{@on_error_exec} #{error_message}")
40
+ end
41
+
42
+ unless @path == "<interactive>"
43
+ exit 1
44
+ end
45
+ end
46
+
47
+ def arm!(reason=nil)
48
+ p [:arm!, reason] if ENV["SUPERSCRIPT_DEBUG"]
49
+ @armed = true
50
+ end
51
+ def disarm!(reason=nil)
52
+ p [:disarm!, reason] if ENV["SUPERSCRIPT_DEBUG"]
53
+ @armed = false
54
+ end
55
+
36
56
  def run!(ctx, contents:nil)
37
57
  contents = File.read(@path) unless contents
58
+ $__superscript_none_of_yer_business = self
59
+ ctx.define_singleton_method "method_missing" do |*args|
60
+ $__superscript_none_of_yer_business.error! :ctx_method_missing, "No such command or variable '#{args.first}'"
61
+ end
38
62
 
39
- @armed = false
63
+ disarm! :at_start
40
64
  trace = TracePoint.new do |tp|
41
65
  if ENV["SUPERSCRIPT_DEBUG"]
42
66
  p [@armed, tp.path, tp.lineno, tp.method_id, tp.event, tp.defined_class]
43
67
  end
44
68
 
69
+ if tp.event == :line && tp.path == @path && !@armed
70
+ arm!
71
+ end
72
+
45
73
  if tp.defined_class&.name == "BasicObject" && tp.method_id == :instance_eval
46
74
  if tp.event == :script_compiled
47
- @armed = true
75
+ arm! :script_compiled
48
76
  elsif tp.event == :c_return
49
- @armed = false
77
+ disarm! :script_done
50
78
  end
51
79
  end
52
80
 
53
- if tp.event == :return && tp.defined_class.ancestors.include?(Superscript::Ctx)
54
- @armed = true
81
+ if tp.path == @path && tp.event == :return && tp.defined_class.ancestors.include?(Superscript::Ctx)
82
+ arm! :return_to_script_from_dsl_calling_another_dsl_method
55
83
  end
56
84
 
57
85
  next unless @armed
58
86
 
59
87
  case tp.event
60
88
  when :class
61
- ::Superscript.error :tp_module_define, "Defining modules is not allowed"
89
+ error! :tp_module_define, "Defining modules is not allowed"
62
90
  when :line
63
91
  lines = if tp.path == "<interactive>"
64
92
  contents.split("\n")
@@ -69,19 +97,36 @@ module Superscript
69
97
  line = lines[tp.lineno-1].lstrip
70
98
  puts "< #{tp.path}:#{tp.lineno-1}"
71
99
  puts line
100
+
101
+ if line.match(/\$__superscript_none_of_yer_business/)
102
+ tp.disable
103
+ error! :tp_call_superscript_global
104
+ end
72
105
  when :c_call
73
- # allow calls to these classes
74
- next if ["Array", "String","Float", "Integer"].include? tp.defined_class.name
106
+ # allow calls to these instances
107
+ if tp.defined_class.ancestors.at(1) == Struct
108
+ disarm! :safe_instance
109
+ next
110
+ end
111
+ if ["Array", "String","Float", "Integer"].include? tp.defined_class.name
112
+ disarm! :safe_instance
113
+ next
114
+ end
75
115
 
76
116
  case tp.method_id
77
117
  when :singleton_method_added
118
+ if @methods
119
+ next
120
+ end
121
+ trace.disable
122
+ error! :tp_singleton_method_added, "Deffining methods is not allowed"
123
+ when :method_missing
78
124
  trace.disable
79
- ::Superscript.error :tp_singleton_method_added, "Deffining methods is not allowed"
80
125
  else
81
126
  trace.disable
82
127
  case tp.defined_class.name
83
128
  when "Class"
84
- ::Superscript.error :tp_class_define, "Defining classes is not allowed"
129
+ error! :tp_class_define, "Defining classes is not allowed"
85
130
  else
86
131
  class_name = case tp.defined_class.inspect
87
132
  when "Kernel"
@@ -102,17 +147,31 @@ module Superscript
102
147
  "#{class_name}.#{tp.method_id}"
103
148
  end
104
149
 
105
- ::Superscript.error :tp_command_not_found, "Command not found '#{command_name}'"
150
+ error! :tp_command_not_found, "Command not found '#{command_name}'"
106
151
  end
107
152
  end
108
153
  when :call
154
+ if tp.method_id == :method_missing
155
+ tp.disable
156
+ next
157
+ end
158
+
159
+ if tp.defined_class.ancestors.first.to_s == "#<Class:Superscript>"
160
+ tp.disable
161
+ error! :tp_call_superscript
162
+ end
109
163
  # disable if calling some other file
110
- unless tp.path == @path
111
- @armed = false
164
+ # but do not allow call to Superscript.error etc
165
+ if tp.path != @path
166
+ disarm! :calling_other_file
112
167
  end
113
- if tp.defined_class.ancestors.include? Superscript::Ctx
114
- @armed = false
168
+ tp.defined_class.ancestors.each do |ancestor|
169
+ if ancestor.to_s == "Superscript::Dsl"
170
+ disarm! :dsl_method
171
+ break
172
+ end
115
173
  end
174
+
116
175
  end
117
176
  end
118
177
 
@@ -129,7 +188,7 @@ module Superscript
129
188
  print "#{@path}:#{ex.backtrace_locations.first.lineno} "
130
189
  puts ex.message.split(" for ").first
131
190
  else
132
- ::Superscript.error :exception, ex
191
+ error! :exception, ex
133
192
  end
134
193
  ensure
135
194
  trace.disable
@@ -1,3 +1,3 @@
1
1
  module Superscript
2
- VERSION = "0.4.2"
2
+ VERSION = "0.8.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: superscript
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matti Paksula
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-05-20 00:00:00.000000000 Z
11
+ date: 2020-05-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler