seeing_is_believing 3.0.0.beta.4 → 3.0.0.beta.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +0 -8
  3. data/Rakefile +1 -1
  4. data/Readme.md +65 -25
  5. data/bin/seeing_is_believing +1 -0
  6. data/docs/sib-streaming.gif +0 -0
  7. data/features/deprecated-flags.feature +62 -2
  8. data/features/errors.feature +12 -7
  9. data/features/examples.feature +143 -4
  10. data/features/flags.feature +89 -29
  11. data/features/regression.feature +58 -14
  12. data/features/support/env.rb +4 -0
  13. data/features/xmpfilter-style.feature +181 -36
  14. data/lib/seeing_is_believing.rb +44 -33
  15. data/lib/seeing_is_believing/binary.rb +31 -88
  16. data/lib/seeing_is_believing/binary/align_chunk.rb +30 -11
  17. data/lib/seeing_is_believing/binary/annotate_end_of_file.rb +10 -16
  18. data/lib/seeing_is_believing/binary/annotate_every_line.rb +5 -25
  19. data/lib/seeing_is_believing/binary/annotate_marked_lines.rb +136 -0
  20. data/lib/seeing_is_believing/binary/comment_lines.rb +8 -10
  21. data/lib/seeing_is_believing/binary/commentable_lines.rb +20 -26
  22. data/lib/seeing_is_believing/binary/config.rb +392 -0
  23. data/lib/seeing_is_believing/binary/data_structures.rb +57 -0
  24. data/lib/seeing_is_believing/binary/engine.rb +104 -0
  25. data/lib/seeing_is_believing/binary/{comment_formatter.rb → format_comment.rb} +6 -6
  26. data/lib/seeing_is_believing/binary/remove_annotations.rb +29 -28
  27. data/lib/seeing_is_believing/binary/rewrite_comments.rb +42 -43
  28. data/lib/seeing_is_believing/code.rb +105 -49
  29. data/lib/seeing_is_believing/debugger.rb +6 -5
  30. data/lib/seeing_is_believing/error.rb +6 -17
  31. data/lib/seeing_is_believing/evaluate_by_moving_files.rb +78 -129
  32. data/lib/seeing_is_believing/event_stream/consumer.rb +114 -64
  33. data/lib/seeing_is_believing/event_stream/events.rb +169 -11
  34. data/lib/seeing_is_believing/event_stream/handlers/debug.rb +57 -0
  35. data/lib/seeing_is_believing/event_stream/handlers/record_exitstatus.rb +18 -0
  36. data/lib/seeing_is_believing/event_stream/handlers/stream_json_events.rb +45 -0
  37. data/lib/seeing_is_believing/event_stream/handlers/update_result.rb +39 -0
  38. data/lib/seeing_is_believing/event_stream/producer.rb +25 -24
  39. data/lib/seeing_is_believing/hash_struct.rb +206 -0
  40. data/lib/seeing_is_believing/result.rb +20 -3
  41. data/lib/seeing_is_believing/the_matrix.rb +20 -12
  42. data/lib/seeing_is_believing/version.rb +1 -1
  43. data/lib/seeing_is_believing/wrap_expressions.rb +55 -115
  44. data/lib/seeing_is_believing/wrap_expressions_with_inspect.rb +14 -0
  45. data/seeing_is_believing.gemspec +1 -1
  46. data/spec/binary/alignment_specs.rb +27 -0
  47. data/spec/binary/comment_lines_spec.rb +3 -2
  48. data/spec/binary/config_spec.rb +657 -0
  49. data/spec/binary/engine_spec.rb +97 -0
  50. data/spec/binary/{comment_formatter_spec.rb → format_comment_spec.rb} +2 -2
  51. data/spec/binary/marker_spec.rb +71 -0
  52. data/spec/binary/options_spec.rb +0 -0
  53. data/spec/binary/remove_annotations_spec.rb +31 -18
  54. data/spec/binary/rewrite_comments_spec.rb +26 -11
  55. data/spec/code_spec.rb +190 -6
  56. data/spec/debugger_spec.rb +4 -0
  57. data/spec/evaluate_by_moving_files_spec.rb +38 -20
  58. data/spec/event_stream_spec.rb +265 -116
  59. data/spec/hash_struct_spec.rb +514 -0
  60. data/spec/seeing_is_believing_spec.rb +108 -46
  61. data/spec/spec_helper.rb +9 -0
  62. data/spec/wrap_expressions_spec.rb +207 -172
  63. metadata +30 -18
  64. data/docs/for-presentations +0 -33
  65. data/lib/seeing_is_believing/binary/annotate_xmpfilter_style.rb +0 -128
  66. data/lib/seeing_is_believing/binary/interpret_flags.rb +0 -156
  67. data/lib/seeing_is_believing/binary/parse_args.rb +0 -263
  68. data/lib/seeing_is_believing/event_stream/update_result.rb +0 -24
  69. data/lib/seeing_is_believing/inspect_expressions.rb +0 -21
  70. data/lib/seeing_is_believing/parser_helpers.rb +0 -82
  71. data/spec/binary/interpret_flags_spec.rb +0 -332
  72. data/spec/binary/parse_args_spec.rb +0 -415
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: seeing_is_believing
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0.beta.4
4
+ version: 3.0.0.beta.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Josh Cheek
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-01-06 00:00:00.000000000 Z
11
+ date: 2015-01-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: parser
@@ -16,7 +16,7 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '2.2'
19
+ version: 2.2.0.2
20
20
  - - "<"
21
21
  - !ruby/object:Gem::Version
22
22
  version: '3.0'
@@ -26,7 +26,7 @@ dependencies:
26
26
  requirements:
27
27
  - - ">="
28
28
  - !ruby/object:Gem::Version
29
- version: '2.2'
29
+ version: 2.2.0.2
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
32
  version: '3.0'
@@ -124,8 +124,8 @@ files:
124
124
  - Readme.md
125
125
  - bin/seeing_is_believing
126
126
  - docs/example.gif
127
- - docs/for-presentations
128
127
  - docs/frog-brown.png
128
+ - docs/sib-streaming.gif
129
129
  - features/deprecated-flags.feature
130
130
  - features/errors.feature
131
131
  - features/examples.feature
@@ -140,12 +140,13 @@ files:
140
140
  - lib/seeing_is_believing/binary/align_line.rb
141
141
  - lib/seeing_is_believing/binary/annotate_end_of_file.rb
142
142
  - lib/seeing_is_believing/binary/annotate_every_line.rb
143
- - lib/seeing_is_believing/binary/annotate_xmpfilter_style.rb
144
- - lib/seeing_is_believing/binary/comment_formatter.rb
143
+ - lib/seeing_is_believing/binary/annotate_marked_lines.rb
145
144
  - lib/seeing_is_believing/binary/comment_lines.rb
146
145
  - lib/seeing_is_believing/binary/commentable_lines.rb
147
- - lib/seeing_is_believing/binary/interpret_flags.rb
148
- - lib/seeing_is_believing/binary/parse_args.rb
146
+ - lib/seeing_is_believing/binary/config.rb
147
+ - lib/seeing_is_believing/binary/data_structures.rb
148
+ - lib/seeing_is_believing/binary/engine.rb
149
+ - lib/seeing_is_believing/binary/format_comment.rb
149
150
  - lib/seeing_is_believing/binary/remove_annotations.rb
150
151
  - lib/seeing_is_believing/binary/rewrite_comments.rb
151
152
  - lib/seeing_is_believing/code.rb
@@ -154,20 +155,26 @@ files:
154
155
  - lib/seeing_is_believing/evaluate_by_moving_files.rb
155
156
  - lib/seeing_is_believing/event_stream/consumer.rb
156
157
  - lib/seeing_is_believing/event_stream/events.rb
158
+ - lib/seeing_is_believing/event_stream/handlers/debug.rb
159
+ - lib/seeing_is_believing/event_stream/handlers/record_exitstatus.rb
160
+ - lib/seeing_is_believing/event_stream/handlers/stream_json_events.rb
161
+ - lib/seeing_is_believing/event_stream/handlers/update_result.rb
157
162
  - lib/seeing_is_believing/event_stream/producer.rb
158
- - lib/seeing_is_believing/event_stream/update_result.rb
159
163
  - lib/seeing_is_believing/hard_core_ensure.rb
160
- - lib/seeing_is_believing/inspect_expressions.rb
161
- - lib/seeing_is_believing/parser_helpers.rb
164
+ - lib/seeing_is_believing/hash_struct.rb
162
165
  - lib/seeing_is_believing/result.rb
163
166
  - lib/seeing_is_believing/the_matrix.rb
164
167
  - lib/seeing_is_believing/version.rb
165
168
  - lib/seeing_is_believing/wrap_expressions.rb
169
+ - lib/seeing_is_believing/wrap_expressions_with_inspect.rb
166
170
  - seeing_is_believing.gemspec
167
- - spec/binary/comment_formatter_spec.rb
171
+ - spec/binary/alignment_specs.rb
168
172
  - spec/binary/comment_lines_spec.rb
169
- - spec/binary/interpret_flags_spec.rb
170
- - spec/binary/parse_args_spec.rb
173
+ - spec/binary/config_spec.rb
174
+ - spec/binary/engine_spec.rb
175
+ - spec/binary/format_comment_spec.rb
176
+ - spec/binary/marker_spec.rb
177
+ - spec/binary/options_spec.rb
171
178
  - spec/binary/remove_annotations_spec.rb
172
179
  - spec/binary/rewrite_comments_spec.rb
173
180
  - spec/code_spec.rb
@@ -175,6 +182,7 @@ files:
175
182
  - spec/evaluate_by_moving_files_spec.rb
176
183
  - spec/event_stream_spec.rb
177
184
  - spec/hard_core_ensure_spec.rb
185
+ - spec/hash_struct_spec.rb
178
186
  - spec/seeing_is_believing_spec.rb
179
187
  - spec/spec_helper.rb
180
188
  - spec/wrap_expressions_spec.rb
@@ -250,10 +258,13 @@ test_files:
250
258
  - features/regression.feature
251
259
  - features/support/env.rb
252
260
  - features/xmpfilter-style.feature
253
- - spec/binary/comment_formatter_spec.rb
261
+ - spec/binary/alignment_specs.rb
254
262
  - spec/binary/comment_lines_spec.rb
255
- - spec/binary/interpret_flags_spec.rb
256
- - spec/binary/parse_args_spec.rb
263
+ - spec/binary/config_spec.rb
264
+ - spec/binary/engine_spec.rb
265
+ - spec/binary/format_comment_spec.rb
266
+ - spec/binary/marker_spec.rb
267
+ - spec/binary/options_spec.rb
257
268
  - spec/binary/remove_annotations_spec.rb
258
269
  - spec/binary/rewrite_comments_spec.rb
259
270
  - spec/code_spec.rb
@@ -261,6 +272,7 @@ test_files:
261
272
  - spec/evaluate_by_moving_files_spec.rb
262
273
  - spec/event_stream_spec.rb
263
274
  - spec/hard_core_ensure_spec.rb
275
+ - spec/hash_struct_spec.rb
264
276
  - spec/seeing_is_believing_spec.rb
265
277
  - spec/spec_helper.rb
266
278
  - spec/wrap_expressions_spec.rb
@@ -1,33 +0,0 @@
1
- # intro
2
- # show the website!
3
- # omg, what's it do?
4
- # integrates with the editors
5
-
6
- # walk through example of how to use it
7
- # make a user class or something
8
- # show the -n flag
9
-
10
- # features
11
- # iteration
12
- # method and invocations
13
- # multilinezzz
14
- # mutliple levels of nesting (e.g. class definition)
15
- # printing to stdout/stderr, respecting DATA segment
16
- # respecting macros
17
- # exceptions displayed where they occur
18
- # records hash results
19
- # syntax errors
20
- # total fucking failure
21
-
22
- # show the snippets
23
- # s_arb
24
- # s_sinatra
25
- # s_nokogiri
26
- # s_reflection
27
-
28
- # Show how to customize
29
- # --line-length n
30
- # --result-length n
31
- # --alignment-strategy name
32
- # --timeout n
33
- # --debug
@@ -1,128 +0,0 @@
1
- require 'seeing_is_believing/code'
2
-
3
- class SeeingIsBelieving
4
- module Binary
5
- class AnnotateXmpfilterStyle
6
- def self.prepare_body(uncleaned_body, marker_regexes)
7
- require 'seeing_is_believing/binary/remove_annotations'
8
- RemoveAnnotations.call uncleaned_body, false, marker_regexes
9
- end
10
-
11
- def self.expression_wrapper(markers, marker_regexes)
12
- lambda do |program, filename, number_of_captures|
13
- inspect_linenos = []
14
- pp_linenos = []
15
- Code.new(program).inline_comments.each do |c|
16
- next unless c.text[marker_regexes[:value]]
17
- c.whitespace_col == 0 ? pp_linenos << c.line_number - 1
18
- : inspect_linenos << c.line_number
19
- end
20
-
21
- InspectExpressions.call program,
22
- filename,
23
- number_of_captures,
24
- before_all: -> {
25
- # TODO: this is duplicated with the InspectExpressions class
26
- number_of_captures_as_str = number_of_captures.inspect
27
- number_of_captures_as_str = 'Float::INFINITY' if number_of_captures == Float::INFINITY
28
- "require 'pp'; $SiB.filename = #{filename.inspect}; $SiB.max_line_captures = #{number_of_captures_as_str}; $SiB.num_lines = #{program.lines.count}; "
29
- },
30
- after_each: -> line_number {
31
- should_inspect = inspect_linenos.include?(line_number)
32
- should_pp = pp_linenos.include?(line_number)
33
- inspect = "$SiB.record_result(:inspect, #{line_number}, v)"
34
- pp = "$SiB.record_result(:pp, #{line_number}, v) { PP.pp v, '', 74 }" # TODO: Is 74 the right value? Prob not, I think it's 80(default width) - 1(comment width) - 5(" => {"), but if I allow indented `# => `, then that would need to be less than 74 (idk if I actually do this or not, though :P)
35
-
36
- if should_inspect && should_pp then ").tap { |v| #{inspect}; #{pp} }"
37
- elsif should_inspect then ").tap { |v| #{inspect} }"
38
- elsif should_pp then ").tap { |v| #{pp} }"
39
- else ")"
40
- end
41
- }
42
- end
43
- end
44
-
45
- def self.call(body, results, options)
46
- new(body, results, options).call
47
- end
48
-
49
- def initialize(body, results, options={})
50
- @options = options
51
- @body = body
52
- @results = results
53
- end
54
-
55
- # TODO: I think that this should respect the alignment strategy
56
- # and we should just add a new alignment strategy for default xmpfilter style
57
- def call
58
- @new_body ||= begin
59
- # TODO: doesn't currently realign output markers, do we want to do that?
60
- require 'seeing_is_believing/binary/rewrite_comments'
61
- require 'seeing_is_believing/binary/comment_formatter'
62
- always_rewrite = []
63
-
64
- if @results.has_exception?
65
- exception_result = sprintf "%s: %s", @results.exception.class_name, @results.exception.message.gsub("\n", '\n')
66
- exception_lineno = @results.exception.line_number
67
- always_rewrite << exception_lineno
68
- end
69
-
70
- new_body = RewriteComments.call @body, always_rewrite: always_rewrite do |comment|
71
- exception_on_line = exception_lineno == comment.line_number
72
- annotate_this_line = comment.text[value_regex]
73
- pp_annotation = annotate_this_line && comment.whitespace_col.zero?
74
- normal_annotation = annotate_this_line && !pp_annotation
75
- if exception_on_line && annotate_this_line
76
- [comment.whitespace, CommentFormatter.call(comment.text_col, value_marker, exception_result, @options)]
77
- elsif exception_on_line
78
- whitespace = comment.whitespace
79
- whitespace = " " if whitespace.empty?
80
- [whitespace, CommentFormatter.call(comment.line_number, exception_marker, exception_result, @options)]
81
- elsif normal_annotation
82
- result = @results[comment.line_number].map { |result| result.gsub "\n", '\n' }.join(', ')
83
- [comment.whitespace, CommentFormatter.call(comment.text_col, value_marker, result, @options)]
84
- elsif pp_annotation
85
- # result = sprintf "%s: %s", @results.exception.class_name, @results.exception.message.gsub("\n", '\n')
86
- # CommentFormatter.call(line.size, exception_marker, result, options)
87
- # TODO: check that having multiple mult-line output values here looks good (e.g. avdi's example in a loop)
88
- result = @results[comment.line_number-1, :pp].map { |result| result.chomp }.join(', ')
89
- comment_lines = result.each_line.map.with_index do |comment_line, result_offest|
90
- if result_offest == 0
91
- CommentFormatter.call(comment.whitespace_col, value_marker, comment_line.chomp, @options)
92
- else
93
- CommentFormatter.call(comment.whitespace_col, nextline_marker, comment_line.chomp, @options)
94
- end
95
- end
96
- [comment.whitespace, comment_lines.join("\n")]
97
- else
98
- [comment.whitespace, comment.text]
99
- end
100
- end
101
-
102
- require 'seeing_is_believing/binary/annotate_end_of_file'
103
- AnnotateEndOfFile.add_stdout_stderr_and_exceptions_to new_body, @results, @options
104
-
105
- # What's w/ this debugger? maybe this should move higher?
106
- @options.fetch(:debugger).context "OUTPUT"
107
- new_body
108
- end
109
- end
110
-
111
- def value_marker
112
- @value_marker ||= @options.fetch(:markers).fetch(:value)
113
- end
114
-
115
- def nextline_marker
116
- @xnextline_marker ||= ('#' + ' '*value_marker.size.pred)
117
- end
118
-
119
- def exception_marker
120
- @exception_marker ||= @options.fetch(:markers).fetch(:exception)
121
- end
122
-
123
- def value_regex
124
- @value_regex ||= @options.fetch(:marker_regexes).fetch(:value)
125
- end
126
- end
127
- end
128
- end
@@ -1,156 +0,0 @@
1
- # Debugger initialization happens here
2
- require 'seeing_is_believing/debugger'
3
-
4
- # Alignment decision happens here
5
- require 'seeing_is_believing/binary/align_file'
6
- require 'seeing_is_believing/binary/align_line'
7
- require 'seeing_is_believing/binary/align_chunk'
8
-
9
- # Evaluator decision happens here
10
- require 'seeing_is_believing/evaluate_by_moving_files'
11
-
12
- # Annotator decision happens here
13
- require 'seeing_is_believing/binary/annotate_every_line'
14
- require 'seeing_is_believing/binary/annotate_xmpfilter_style'
15
-
16
- class SeeingIsBelieving
17
- module Binary
18
- class InterpretFlags
19
- def self.to_regex(string)
20
- flag_to_bit = {'i' => 0b001, 'x' => 0b010, 'm' => 0b100}
21
- string =~ %r{\A/(.*)/([mxi]*)\Z}
22
- Regexp.new ($1||string),
23
- ($2||"").each_char.inject(0) { |bits, flag| bits|flag_to_bit[flag] }
24
- end
25
-
26
-
27
- def self.attr_predicate(name)
28
- define_method("#{name}?") { predicates.fetch name }
29
- end
30
- attr_predicate :print_version
31
- attr_predicate :inherit_exit_status
32
- attr_predicate :result_as_json
33
- attr_predicate :print_help
34
- attr_predicate :print_cleaned
35
- attr_predicate :provided_filename_dne
36
- attr_predicate :file_is_on_stdin
37
-
38
- def self.attr_attribute(name)
39
- define_method(name) { attributes.fetch name }
40
- end
41
- attr_attribute :annotator
42
- attr_attribute :help_screen
43
- attr_attribute :debugger
44
- attr_attribute :markers
45
- attr_attribute :marker_regexes
46
- attr_attribute :timeout
47
- attr_attribute :filename
48
- attr_attribute :body
49
- attr_attribute :annotator_options
50
- attr_attribute :prepared_body
51
- attr_attribute :lib_options
52
- attr_attribute :errors
53
-
54
- def initialize(flags, stdin, stdout)
55
- # Some simple attributes
56
- self.attributes = {}
57
- attributes[:errors] = flags.fetch(:errors)
58
- attributes[:markers] = flags.fetch(:markers) # TODO: Should probably object-ify these
59
- attributes[:marker_regexes] = flags.fetch(:marker_regexes).each_with_object({}) { |(k, v), rs| rs[k] = self.class.to_regex v }
60
- attributes[:timeout] = flags.fetch(:timeout) # b/c binary prints this out in the error message TODO: rename seconds_until_timeout
61
- attributes[:filename] = flags.fetch(:filename)
62
-
63
- # All predicates
64
- self.predicates = {}
65
- predicates[:print_version] = flags.fetch(:version) # TODO: rename rhs to print_version ?
66
- predicates[:inherit_exit_status] = flags.fetch(:inherit_exit_status)
67
- predicates[:result_as_json] = flags.fetch(:result_as_json)
68
- predicates[:print_help] = !!flags.fetch(:help)
69
- predicates[:print_cleaned] = flags.fetch(:clean) # TODO: Better name on rhs
70
- predicates[:provided_filename_dne] = !!(filename && !File.exist?(filename)) # TODO: Should this just be an error in errors table?
71
- predicates[:file_is_on_stdin] = (!filename && !flags.fetch(:program_from_args))
72
-
73
- # Polymorphism, y'all!
74
- attributes[:annotator] = (flags.fetch(:xmpfilter_style) ? AnnotateXmpfilterStyle : AnnotateEveryLine)
75
- attributes[:help_screen] = flags.fetch(:help) == 'help' ? flags.fetch(:short_help_screen) : flags.fetch(:long_help_screen)
76
- attributes[:debugger] = flags.fetch(:debug) ? Debugger.new(stream: stdout, colour: true) : Debugger.new(stream: nil)
77
- attributes[:body] = ((print_version? || print_help?) && String.new) ||
78
- flags.fetch(:program_from_args) ||
79
- (file_is_on_stdin? && stdin.read) ||
80
- (File.read filename unless provided_filename_dne?) ||
81
- String.new
82
-
83
- # Attributes that depend on predicates
84
- attributes[:prepared_body] = body && annotator.prepare_body(body, marker_regexes)
85
-
86
- # The lib's options (passed to SeeingIsBelieving.new)
87
- attributes[:lib_options] = {
88
- evaluate_with: EvaluateByMovingFiles,
89
- filename: (flags.fetch(:as) || filename),
90
- stdin: (file_is_on_stdin? ? '' : stdin),
91
- require: (['seeing_is_believing/the_matrix'] + flags.fetch(:require)), # TODO: rename requires: files_to_require, or :requires or maybe :to_require
92
- load_path: ([File.expand_path('../../..', __FILE__)] + flags.fetch(:load_path)),
93
- encoding: flags.fetch(:encoding),
94
- timeout: timeout,
95
- debugger: debugger,
96
- number_of_captures: flags.fetch(:number_of_captures), # TODO: Rename to max_number_of_captures
97
- record_expressions: annotator.expression_wrapper(markers, marker_regexes), # TODO: rename to wrap_expressions
98
- }
99
-
100
- # The annotator's options (passed to annotator.call)
101
- attributes[:annotator_options] = {
102
- alignment_strategy: extract_alignment_strategy(flags.fetch(:alignment_strategy), errors),
103
- debugger: debugger,
104
- markers: markers,
105
- marker_regexes: marker_regexes,
106
- max_line_length: flags.fetch(:max_line_length),
107
- max_result_length: flags.fetch(:max_result_length),
108
- }
109
-
110
- # Some error checking
111
- if 1 < flags.fetch(:filenames).size
112
- errors << "Can only have one filename, but had: #{flags.fetch(:filenames).map(&:inspect).join ', '}"
113
- elsif filename && flags.fetch(:program_from_args)
114
- errors << "You passed the program in an argument, but have also specified the filename #{filename.inspect}"
115
- end
116
- end
117
-
118
- def inspect
119
- inspected = "#<#{self.class.name.inspect}\n"
120
- inspected << " --PREDICATES--\n"
121
- predicates.each do |predicate, value|
122
- inspected << inspect_line(sprintf " %-25s %p", predicate.to_s+"?", value)
123
- end
124
- inspected << " --ATTRIBUTES--\n"
125
- attributes.each do |predicate, value|
126
- inspected << inspect_line(sprintf " %-20s %p", predicate.to_s, value)
127
- end
128
- inspected << ">"
129
- inspected
130
- end
131
-
132
- private
133
-
134
- attr_accessor :predicates, :attributes
135
-
136
- def extract_alignment_strategy(strategy_name, errors)
137
- strategies = {'file' => AlignFile, 'chunk' => AlignChunk, 'line' => AlignLine}
138
- if strategies[strategy_name]
139
- strategies[strategy_name]
140
- elsif strategy_name
141
- errors << "alignment-strategy does not know #{strategy_name}, only knows: #{strategies.keys.join(', ')}"
142
- else
143
- errors << "alignment-strategy expected an alignment strategy as the following argument but did not see one"
144
- end
145
- end
146
-
147
- def inspect_line(line)
148
- if line.size < 78
149
- line << "\n"
150
- else
151
- line[0, 75] << "...\n"
152
- end
153
- end
154
- end
155
- end
156
- end
@@ -1,263 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require 'seeing_is_believing/version' # We print the version in the output
4
-
5
- class SeeingIsBelieving
6
- module Binary
7
- class ParseArgs
8
- def self.default_markers
9
- { value: '# => ',
10
- exception: '# ~> ',
11
- stdout: '# >> ',
12
- stderr: '# !> ',
13
- }
14
- end
15
-
16
- # TODO: rename to default_marker_regexes ...or turn into fkn objects
17
- def self.marker_regexes
18
- { value: '^#\s*=>\s*',
19
- exception: '^#\s*~>\s*',
20
- stdout: '^#\s*>>\s*',
21
- stderr: '^#\s*!>\s*',
22
- }
23
- end
24
-
25
- def self.call(args)
26
- new(args).call
27
- end
28
-
29
- def initialize(args)
30
- self.args = args.dup
31
- end
32
-
33
- def call
34
- @result ||= begin
35
- until args.empty?
36
- case (arg = args.shift)
37
- when '-h', '--help' then flags[:help] = 'help'
38
- when '-h+', '--help+' then flags[:help] = 'help+'
39
- when '-c', '--clean' then flags[:clean] = true
40
- when '-v', '--version' then flags[:version] = true
41
- when '-x', '--xmpfilter-style' then flags[:xmpfilter_style] = true
42
- when '-i', '--inherit-exit-status' then flags[:inherit_exit_status] = true
43
- when '-j', '--json' then flags[:result_as_json] = true
44
- when '-g', '--debug' then flags[:debug] = true
45
- when '--safe' then flags[:safe] = true
46
- when '-d', '--line-length' then extract_positive_int_for :max_line_length, arg
47
- when '-D', '--result-length' then extract_positive_int_for :max_result_length, arg
48
- when '-n', '--number-of-captures' then extract_positive_int_for :number_of_captures, arg
49
- when '-t', '--timeout' then extract_non_negative_float_for :timeout, arg
50
- when '-r', '--require' then next_arg("#{arg} expected a filename as the following argument but did not see one") { |filename| flags[:require] << filename }
51
- when '-I', '--load-path' then next_arg("#{arg} expected a directory as the following argument but did not see one") { |dir| flags[:load_path] << dir }
52
- when '-e', '--program' then next_arg("#{arg} expected a program as the following argument but did not see one") { |program| flags[:program_from_args] = program }
53
- when '-a', '--as' then next_arg("#{arg} expected a filename as the following argument but did not see one") { |filename| flags[:as] = filename }
54
- when '-s', '--alignment-strategy' then flags[:alignment_strategy] = args.shift
55
- when /\A-K(.+)/ then flags[:encoding] = $1
56
- when '-K', '--encoding' then next_arg("#{arg} expects an encoding, see `man ruby` for possibile values") { |encoding| flags[:encoding] = encoding }
57
- when '--shebang' then next_arg("#{arg} is deprecated, SiB now uses the Ruby it was invoked with") { |executable| flags[:deprecated_flags] << '--shebang' << executable }
58
- when /^(-.|--.*)$/ then flags[:errors] << "Unknown option: #{arg.inspect}" # unknown flags
59
- when /^-[^-]/ then args.unshift *normalize_shortflags(arg)
60
- else
61
- flags[:filenames] << arg
62
- flags[:filename] = arg
63
- end
64
- end
65
- flags
66
- end
67
- end
68
-
69
-
70
-
71
- private
72
-
73
- attr_accessor :args
74
-
75
- def flags
76
- @flags ||= {
77
- as: nil,
78
- filenames: [],
79
- help: nil,
80
- encoding: nil,
81
- debug: false,
82
- version: false,
83
- clean: false,
84
- xmpfilter_style: false,
85
- inherit_exit_status: false,
86
- program_from_args: nil,
87
- filename: nil,
88
- max_line_length: Float::INFINITY,
89
- max_result_length: Float::INFINITY,
90
- number_of_captures: Float::INFINITY,
91
- timeout: 0, # timeout lib treats this as infinity
92
- errors: [],
93
- require: ['seeing_is_believing/the_matrix'],
94
- load_path: [],
95
- alignment_strategy: 'chunk',
96
- result_as_json: false,
97
- markers: self.class.default_markers,
98
- marker_regexes: self.class.marker_regexes,
99
- short_help_screen: self.class.help_screen(false),
100
- long_help_screen: self.class.help_screen(true),
101
- safe: false,
102
- deprecated_flags: [],
103
- }
104
- end
105
-
106
- def normalize_shortflags(consolidated_shortflag)
107
- shortflags = consolidated_shortflag[1..-1].chars.to_a # to_a for 1.9.3 -.-
108
- plusidx = shortflags.index('+') || 0
109
- if 0 < plusidx
110
- shortflags[plusidx-1] << '+'
111
- shortflags.delete_at plusidx
112
- end
113
- shortflags.map { |flag| "-#{flag}" }
114
- end
115
-
116
- def next_arg(error_message, &success_block)
117
- arg = args.shift
118
- arg ? success_block.call(arg) : (flags[:errors] << error_message)
119
- end
120
-
121
- def extract_positive_int_for(key, flag)
122
- string = args.shift
123
- int = string.to_i
124
- if int.to_s == string && 0 < int
125
- flags[key] = int
126
- else
127
- flags[:errors] << "#{flag} expects a positive integer argument"
128
- end
129
- end
130
-
131
- def extract_non_negative_float_for(key, flag)
132
- float = Float args.shift
133
- raise if float < 0
134
- flags[key] = float
135
- rescue
136
- flags[:errors] << "#{flag} expects a positive float or integer argument"
137
- end
138
- end
139
-
140
- def ParseArgs.help_screen(include_examples, markers=default_markers)
141
- value_marker = markers.fetch(:value)
142
- exception_marker = markers.fetch(:exception)
143
- stdout_marker = markers.fetch(:stdout)
144
- stderr_marker = markers.fetch(:stderr)
145
-
146
- <<FLAGS + if include_examples then <<EXAMPLES else '' end
147
- Usage: seeing_is_believing [options] [filename]
148
-
149
- seeing_is_believing is a program and library that will evaluate a Ruby file and capture/display the results.
150
-
151
- If no filename is provided, the binary will read the program from standard input.
152
-
153
- -d, --line-length n # max length of the entire line (only truncates results, not source lines)
154
- -D, --result-length n # max length of the portion after the "#{value_marker}"
155
- -n, --number-of-captures n # how many results to capture for a given line
156
- if you had 1 million results on a line, it could take a long time to record
157
- and serialize them, you might limit it to 1000 results as an optimization
158
- -s, --alignment-strategy name # select the alignment strategy:
159
- chunk (DEFAULT) => each chunk of code is at the same alignment
160
- file => the entire file is at the same alignment
161
- line => each line is at its own alignment
162
- -t, --timeout n # timeout limit in seconds when evaluating source file (ex. -t 0.3 or -t 3)
163
- -I, --load-path dir # a dir that should be added to the $LOAD_PATH
164
- -r, --require file # additional files to be required before running the program
165
- -e, --program program # Pass the program to execute as an argument
166
- -K, --encoding encoding # sets file encoding, equivalent to Ruby's -Kx (see `man ruby` for valid values)
167
- -a, --as filename # run the program as if it was the specified filename
168
- -c, --clean # remove annotations from previous runs of seeing_is_believing
169
- -g, --debug # print debugging information (useful if program is fucking up, or to better understand what SiB does)
170
- -x, --xmpfilter-style # annotate marked lines instead of every line
171
- -j, --json # print results in json format (i.e. so another program can consume them)
172
- -i, --inherit-exit-status # exit with the exit status of the program being evaluated
173
- --shebang ruby-executable # if you want SiB to use some ruby other than the one in the path
174
- -v, --version # print the version (#{VERSION})
175
- -h, --help # help screen without examples
176
- -h+, --help+ # help screen with examples
177
- FLAGS
178
-
179
- Examples: A few examples, for a more comprehensive set of examples, check out features/flags.feature
180
-
181
- Run the file f.rb
182
- $ echo __FILE__ > f.rb; seeing_is_believing f.rb
183
- __FILE__ #{value_marker}"f.rb"
184
-
185
- Aligning comments
186
- $ ruby -e 'puts "123\\n4\\n\\n567890"' > f.rb
187
-
188
-
189
- $ seeing_is_believing f.rb -s line
190
- 123 #{value_marker}123
191
- 4 #{value_marker}4
192
-
193
- 567890 #{value_marker}567890
194
-
195
-
196
- $ seeing_is_believing f.rb -s chunk
197
- 123 #{value_marker}123
198
- 4 #{value_marker}4
199
-
200
- 567890 #{value_marker}567890
201
-
202
-
203
- $ seeing_is_believing f.rb -s file
204
- 123 #{value_marker}123
205
- 4 #{value_marker}4
206
-
207
- 567890 #{value_marker}567890
208
-
209
- Run against standard input
210
- $ echo '3.times { |i| puts i }' | seeing_is_believing
211
- 2.times { |i| puts i } #{value_marker}2
212
-
213
- #{stdout_marker}0
214
- #{stdout_marker}1
215
-
216
- Run against a library you're working on by fixing the load path
217
- $ seeing_is_believing -I lib f.rb
218
-
219
- Load up some library (can be used in tandem with -I)
220
- $ seeing_is_believing -r pp -e 'pp [[*1..15],[*15..30]]; nil'
221
- pp [[*1..15],[*15..30]]; nil #{value_marker}nil
222
-
223
- #{stdout_marker}[[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
224
- #{stdout_marker} [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]]
225
-
226
- Only update the lines you've marked
227
- $ ruby -e 'puts "1\\n2 # =>\\n3"' | seeing_is_believing -x
228
- 1
229
- 2 #{value_marker}2
230
- 3
231
-
232
- Set a timeout (especially useful if running via an editor)
233
- $ seeing_is_believing -e 'loop { sleep 1 }' -t 3
234
- Timeout Error after 3.0 seconds!
235
-
236
- Set the encoding to utf-8
237
- $ seeing_is_believing -Ku -e '"⛄ "'
238
- "⛄ " #{value_marker}"⛄ "
239
-
240
- The exit status will be 1 if the error is displayable inline
241
- $ seeing_is_believing -e 'raise "omg"'; echo $?
242
- raise "omg" #{exception_marker}RuntimeError: omg
243
- 1
244
-
245
- The exit status will be 2 if the error is not displayable
246
- $ seeing_is_believing -e 'a='; echo $status
247
- -:1: syntax error, unexpected $end
248
- 2
249
-
250
- Run with previous output
251
- $ echo "1+1 #{value_marker}old-value" | seeing_is_believing
252
- 1+1 #{value_marker}2
253
-
254
- $ echo "1+1 #{value_marker}old-value" | seeing_is_believing --clean
255
- 1+1
256
-
257
- If your Ruby binary is named something else (e.g. ruby2.0)
258
- $ ruby2.0 -S seeing_is_believing --shebang ruby2.0 -e '123'
259
- 123 #{value_marker}123
260
- EXAMPLES
261
- end
262
- end
263
- end