seeing_is_believing 3.0.0.beta.7 → 3.0.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
  SHA1:
3
- metadata.gz: 866178b03727394e7c24c5cfbaa48ea4edbca4e1
4
- data.tar.gz: cfe4540e781ec9aa65b79a950d8760058136a85d
3
+ metadata.gz: c0318721dea2259939dac9f239eaf465f9a7d605
4
+ data.tar.gz: a9c3681770369df1da596a736c266ff51624603e
5
5
  SHA512:
6
- metadata.gz: 514947858dab6b669eeb25f8b729e330d9435b438f2821073a56a12226451710a54f775415591e56c8673d071e276c102ec7ca001f4f6f2ce03fe9d2f1282b7b
7
- data.tar.gz: 341dea9e96e9e1c57565254830f5f22648bcd2b9363d492b1a8718dddc54e30861c449d5374f3822e7ef7c88ce89ea107c79e5049c7e216a35a88c3b8440f735
6
+ metadata.gz: 06109b5b546f05c712f17d3856fb5faf8e41579a00758dd3fe05a4bec5dd12028a532c6429529db257a15aebfe4bee5a574999f714f0ac2e22ab1986eafc267c
7
+ data.tar.gz: 12f47cae8b1613713ec81bc66a7156d89ed15a967b8c1b3a54af4bdc520cb25541bf2327cadf452eef2da14f4cf35ec4cd103c4718a3319ecbd1bdc035e076a4
data/.travis.yml CHANGED
@@ -1,9 +1,8 @@
1
1
  language: ruby
2
- install: gem install bundler && bundle install --standalone --binstubs bundle/bin
2
+ before_install: gem install bundler
3
+ install: rake install
3
4
  script: bundle exec rake ci
4
5
  rvm:
5
- - 1.9.3
6
- - 2.0.0
7
6
  - 2.1.2
8
7
  - 2.2.0
9
- - 2.3.0
8
+ - 2.3.1
data/Gemfile CHANGED
@@ -1,2 +1,3 @@
1
1
  source 'http://rubygems.org'
2
2
  gemspec
3
+ gem 'pry'
data/Rakefile CHANGED
@@ -1,9 +1,14 @@
1
- require 'bundler'
2
-
3
1
  desc 'Have Bundler setup a standalone environment -- run tests in this, b/c its faster and safer'
4
2
  task :install do
5
- # Running without rubygems # http://myronmars.to/n/dev-blog/2012/03/faster-test-boot-times-with-bundler-standalone
6
- sh 'bundle install --standalone --binstubs bundle/bin'
3
+ `which bundle`
4
+ unless $?.success?
5
+ sh 'gem', 'install', 'bundler'
6
+ end
7
+
8
+ unless Dir.exist? 'bundle'
9
+ # Running without rubygems # http://myronmars.to/n/dev-blog/2012/03/faster-test-boot-times-with-bundler-standalone
10
+ sh 'bundle', 'install', '--standalone', '--binstubs', 'bundle/bin'
11
+ end
7
12
  end
8
13
 
9
14
  desc 'Remove generated and irrelevant files'
@@ -24,12 +29,19 @@ end
24
29
 
25
30
  desc 'Run specs'
26
31
  task spec: :bundle do
27
- sh 'ruby', '--disable-gem', *Bundler.load.specs.flat_map(&:full_require_paths).flat_map { |p| ['-I', p ] }, '-S', 'bundle/bin/mrspec'
32
+ require 'bundler'
33
+ sh 'ruby', '--disable-gem',
34
+ *Bundler.load.specs.flat_map(&:full_require_paths).flat_map { |p| ['-I', p ] },
35
+ '-S', 'bundle/bin/mrspec'
28
36
  end
29
37
 
30
38
  desc 'Run cukes'
31
39
  task cuke: :bundle do
32
- sh 'ruby', '--disable-gem', *Bundler.load.specs.flat_map(&:full_require_paths).flat_map { |p| ['-I', p ] }, '-S', 'bundle/bin/cucumber', '--tags', '~@not-implemented'
40
+ require 'bundler'
41
+ sh 'ruby', '--disable-gem',
42
+ *Bundler.load.specs.flat_map(&:full_require_paths).flat_map { |p| ['-I', p ] },
43
+ '-S', 'bundle/bin/cucumber',
44
+ '--tags', '~@not-implemented'
33
45
  end
34
46
 
35
47
  desc 'Run all specs and cukes'
data/Readme.md CHANGED
@@ -6,17 +6,34 @@ Seeing Is Believing
6
6
 
7
7
  Evaluates Ruby code, recording the results of each line.
8
8
  Integrates with any extensible editor (I've integrated it with many already, see [the list](https://github.com/JoshCheek/seeing_is_believing#editor-integration)).
9
+ If you like Swift Playgrounds, you'll like SiB.
9
10
 
10
11
  ![example](https://s3.amazonaws.com/josh.cheek/images/scratch/sib-example1.gif)
11
12
 
12
13
  Watch a [longer video](http://vimeo.com/73866851).
13
14
 
14
- Works in Ruby 1.9, 2.0, 2.1, 2.2, rubinius (I **think**, need to make better tests), still trying to get it working with Jruby.
15
+
16
+ Install
17
+ =======
18
+
19
+ Requires Ruby >= 2.1
20
+
21
+ ```sh
22
+ $ gem install seeing_is_believing
23
+ ```
24
+
25
+ Verify the install with
26
+
27
+ ```sh
28
+ $ seeing_is_believing -e '1 + 1'
29
+ 1 + 1 # => 2
30
+ ```
31
+
15
32
 
16
33
  Use The Binary
17
34
  ==============
18
35
 
19
- `cat simple_example.rb`
36
+ Given the file `simple_example.rb`
20
37
 
21
38
  ```ruby
22
39
  5.times do |i|
@@ -24,25 +41,29 @@ Use The Binary
24
41
  end
25
42
  ```
26
43
 
27
- `seeing_is_believing simple_example.rb`
44
+ `$ seeing_is_believing simple_example.rb` will print:
45
+
28
46
  ```ruby
47
+
29
48
  5.times do |i| # => 5
30
49
  i * 2 # => 0, 2, 4, 6, 8
31
50
  end # => 5
32
51
  ```
33
52
 
53
+
34
54
  Use The Lib
35
55
  ===========
36
56
 
37
57
  ```ruby
38
58
  require 'seeing_is_believing'
39
- believer = SeeingIsBelieving.new("[:a, :b, :c].each do |i|
59
+
60
+ # There are a lot of options you can pass here, including a custom handler
61
+ handler = SeeingIsBelieving.call("[:a, :b, :c].each do |i|
40
62
  i.upcase
41
63
  end")
64
+ result = handler.result
42
65
 
43
- result = believer.call # => #<SIB::Result @results={1=>#<SIB:Line["[:a, :b, :c]"] no exception>, 2=>#<SIB:Line[":A", ":B", ":C"] no exception>, 3=>#<SIB:Line["[:a, :b, :c]"] no exception>}\n @stdout=""\n @stderr=""\n @exitstatus=0\n @bug_in_sib=nil>
44
-
45
- result[2] # => #<SIB:Line[":A", ":B", ":C"] no exception>
66
+ result[2] # => [":A", ":B", ":C"]
46
67
  result[2][0] # => ":A"
47
68
  result[2][1] # => ":B"
48
69
  result[2][2] # => ":C"
@@ -53,12 +74,6 @@ result.stderr # => ""
53
74
  result.exception # => nil
54
75
  ```
55
76
 
56
- Install
57
- =======
58
-
59
- Currently requires Ruby 1.9 or 2.x
60
-
61
- $ gem install seeing_is_believing
62
77
 
63
78
 
64
79
  Editor Integration
@@ -69,20 +84,44 @@ Editor Integration
69
84
  * [TextMate 1](https://github.com/JoshCheek/text_mate_1-seeing-is_believing)
70
85
  * [TextMate 2](https://github.com/JoshCheek/text_mate_2-seeing-is_believing) (TM2 is actually looking really nice these days -- Josh Cheek, 18 Feb 2015)
71
86
 
87
+
72
88
  Vim
73
- ===
89
+ ---
74
90
 
75
- I didn't write either of these, but they both support Seeing Is Believing. I've looked through the code, it works reasonably. One of them, I wound up having to edit the installed package, don't remember which.
91
+ These packages support SiB:
76
92
 
77
- * [vim-ruby-xmpfilter](https://github.com/t9md/vim-ruby-xmpfilter)
78
93
  * [vim-seeing-is-believing](https://github.com/hwartig/vim-seeing-is-believing)
94
+ * [vim-ruby-xmpfilter](https://github.com/t9md/vim-ruby-xmpfilter)
95
+
96
+ Personally, I had difficulty with them, but this configuration has gotten me pretty far:
97
+
98
+ ```viml
99
+ " ===== Seeing Is Believing =====
100
+ " Assumes you have a Ruby with SiB available in the PATH
101
+ " If it doesn't work, you may need to `gem install seeing_is_believing -v 3.0.0.beta.6`
102
+ " ...yeah, current release is a beta, which won't auto-install
103
+
104
+ " Annotate every line
105
+ nmap <leader>b :%!seeing_is_believing --timeout 12 --line-length 500 --number-of-captures 300 --alignment-strategy chunk<CR>;
106
+ " Annotate marked lines
107
+ nmap <leader>n :%.!seeing_is_believing --timeout 12 --line-length 500 --number-of-captures 300 --alignment-strategy chunk --xmpfilter-style<CR>;
108
+ " Remove annotations
109
+ nmap <leader>c :%.!seeing_is_believing --clean<CR>;
110
+ " Mark the current line for annotation
111
+ nmap <leader>m A # => <Esc>
112
+ " Mark the highlighted lines for annotation
113
+ vmap <leader>m :norm A # => <Esc>
114
+ ```
115
+
79
116
 
80
117
  Emacs Integration
81
- =================
118
+ -----------------
82
119
 
83
120
  You can use my friend's configuration [file](https://github.com/jcinnamond/seeing-is-believing).
121
+ You can see him use it in [this](http://brightonruby.com/2016/the-point-of-objects-john-cinnamond/?utm_source=rubyweekly&utm_medium=email)
122
+ presentation at 10 minutes.
84
123
 
85
- Or, adding this function to your Emacs configuration will get you pretty far:
124
+ Alternatively, adding this function to your Emacs configuration will get you pretty far:
86
125
 
87
126
  ```scheme
88
127
  (defun seeing-is-believing ()
@@ -100,6 +139,13 @@ You can now call `seeing-is-believing` to replace the current region
100
139
  or current buffer contents with the output of running it through
101
140
  `seeing_is_believing`.
102
141
 
142
+
143
+ Features
144
+ ========
145
+
146
+ Check the [features](features) directory.
147
+
148
+
103
149
  Known Issues
104
150
  ============
105
151
 
@@ -108,15 +154,22 @@ Known Issues
108
154
  This code will be wrapped. But using the value is **syntactically** invalid in Ruby, because it constitutes a "void value expression" (aka a pointless timesink and the cause of many bugs in SiB).
109
155
  Unfortunately, I can't easily check it to seee if it's void since it's not in the parsed AST. But it's so edge that I don't think it's worth worrying about.
110
156
 
111
- Version 2
112
- =========
157
+ Setting up Development
158
+ ======================
113
159
 
114
- Feature complete, I'll fix bugs in it until version 3 is released, though
160
+ * Make sure you have Ruby (I use [chruby](https://github.com/postmodern/chruby) and [ruby-install](https://github.com/postmodern/ruby-install) for this).
161
+ * Make sure you have bundler and rake (`gem install bundler rake`)
162
+ * Fork the repo (there's a button on Github)
163
+ * Clone your fork (`git clone git@github.com:YOUR_GITHUB_NAME/seeing_is_believing.git`)
164
+ * Install the dependencies (`rake install`) This approach is painful, but it means the test suite is like 30s instead of 5min.
165
+ * Get a list of rake tasks (`rake -T`)
166
+ * Run the full test suite (`rake`)
167
+ * Run the rspec tests `bundle exec rspec` from here you can pass options you want, such as a tag for the tests you're interested in.
168
+ * Run the Cucumber tests `bundle exec cucumber` (these literally invoke the executable, as a user would)
115
169
 
116
- Version 3
117
- =========
118
170
 
119
- These need to be done before release:
171
+ Some stuff that might happen one day
172
+ ====================================
120
173
 
121
174
  * Add default to number of captures (1000), require user to explicitly set it to infinity
122
175
  * Expose markers via the CLI
@@ -127,10 +180,6 @@ These need to be done before release:
127
180
  rather than having to figure out all the compmlex ecosystem around installing
128
181
  * Would be nice to have real integration with Emacs
129
182
  * Would be nice to support Ruby Mine
130
-
131
- Version 4
132
- =========
133
-
134
183
  * How about if begin/rescue/end was able to record the result on the rescue section
135
184
  * How about if you could configure which kinds of results you were interested in
136
185
  (e.g. turn on/off recording of method definitions, and other results)
@@ -145,6 +194,8 @@ Version 4
145
194
  Could have fallback strategies, so e.g. `-s min=40,fallback=line`
146
195
  * Package Ruby with the editor downloads so that they don't require you to know so fkn much to set it up.
147
196
  * Allow user to set marker
197
+ * Maybe rename xmpfilter style, not many people know what that is, so the name doesn't help users
198
+
148
199
 
149
200
  Inspiration
150
201
  ===========
@@ -153,10 +204,6 @@ Inspiration
153
204
  * Bret Victor's completely inspiring talk [Inventing on Principle](https://www.youtube.com/watch?v=PUv66718DII).
154
205
  * My 8th Light mentor, [Doug Bradbury](http://blog.8thlight.com/doug-bradbury/archive.html) who asked me to make it for his Kids Ruby sessions (I don't think we ever finished integrating it, though >.<)
155
206
 
156
- Interestingly, [Swift playground](https://www.youtube.com/watch?v=oY6nQS3MiF8&t=25m51s)
157
- are very similar (though better integrated since they cerce you into using xcode).
158
- Released about a year and a half before them, but maybe I should take advantage of
159
- their marketing anyway: Swift Playgrounds for Ruby!! :P
160
207
 
161
208
  Shout outs
162
209
  ==========
@@ -258,8 +258,6 @@ Feature: Running the binary successfully
258
258
  """
259
259
  And the exit status is 0
260
260
 
261
-
262
- @not-implemented
263
261
  Scenario: Fork records data in parent and child, parent exec does not affect it.
264
262
  Given the file "fork_exec_parent.rb":
265
263
  """
@@ -268,7 +266,7 @@ Feature: Running the binary successfully
268
266
  :parent
269
267
  exec 'echo', 'hello'
270
268
  else
271
- sleep 1
269
+ sleep 1 #
272
270
  :child
273
271
  end
274
272
  :child
@@ -283,15 +281,14 @@ Feature: Running the binary successfully
283
281
  :parent # => :parent
284
282
  exec 'echo', 'hello'
285
283
  else
286
- sleep 1 # => 1
284
+ sleep 1 #
287
285
  :child # => :child
288
- end
286
+ end # => :child
289
287
  :child # => :child
290
288
 
291
289
  # >> hello
292
290
  """
293
291
 
294
- @not-implemented
295
292
  Scenario: Fork records data in parent and child, child exec does not affect it.
296
293
  Given the file "fork_exec_child.rb":
297
294
  """
@@ -317,7 +314,7 @@ Feature: Running the binary successfully
317
314
  else
318
315
  :child # => :child
319
316
  exec 'echo', 'hello'
320
- end
317
+ end # => :parent
321
318
  :parent # => :parent
322
319
 
323
320
  # >> hello
@@ -123,7 +123,12 @@ class SeeingIsBelieving
123
123
  self.help_screen = Binary.help_screen_extended(markers)
124
124
 
125
125
  when '-g', '--debug'
126
- self.debug = true
126
+ self.debug = true
127
+
128
+ when '--debug-to'
129
+ next_arg.call arg, "a filename" do |filename|
130
+ self.debug = filename
131
+ end
127
132
 
128
133
  when '-d', '--line-length'
129
134
  extract_positive_int_for.call arg do |n|
@@ -237,10 +242,14 @@ class SeeingIsBelieving
237
242
  lib_options.event_handler = EventStream::Handlers::StreamJsonEvents.new(stdout)
238
243
  end
239
244
 
240
- if debug?
241
- self.debugger = Debugger.new stream: stderr, colour: true
242
- self.lib_options.debugger = debugger
245
+ case debug
246
+ when String
247
+ debug_file = File.open(debug, 'a').tap { |f| f.sync = true }
248
+ self.debugger = Debugger.new stream: debug_file, colour: false
249
+ when true
250
+ self.debugger = Debugger.new stream: stderr, colour: stderr.tty?
243
251
  end
252
+ self.lib_options.debugger = debugger
244
253
 
245
254
  if filename && body
246
255
  add_error("Cannot give a program body and a filename to get the program body from.")
@@ -11,6 +11,7 @@
11
11
  # read the wrong file... of course, since we rewrite the file,
12
12
  # its body will be incorrect, anyway.
13
13
 
14
+ require 'rbconfig'
14
15
  require 'timeout'
15
16
  require 'seeing_is_believing/error'
16
17
  require 'seeing_is_believing/result'
@@ -74,9 +75,11 @@ class SeeingIsBelieving
74
75
  end
75
76
 
76
77
  def set_back_to_initial_conditions
77
- @was_backed_up ?
78
- File.rename(backup_filename, filename) :
78
+ if @was_backed_up
79
+ File.rename(backup_filename, filename)
80
+ else
79
81
  File.delete(filename)
82
+ end
80
83
  end
81
84
 
82
85
  def write_program_to_file
@@ -97,32 +100,33 @@ class SeeingIsBelieving
97
100
  # setup environment variables
98
101
  env = ENV.to_hash.merge 'SIB_VARIABLES.MARSHAL.B64' =>
99
102
  [Marshal.dump(
100
- event_stream_fd: child_eventstream.to_i,
103
+ event_stream_fd: 4,
101
104
  max_line_captures: max_line_captures,
102
105
  num_lines: program.lines.count,
103
106
  filename: filename
104
107
  )].pack('m0')
105
108
 
106
109
  # evaluate the code in a child process
107
- opts = { in: child_stdin,
108
- out: child_stdout,
109
- err: child_stderr,
110
- child_eventstream => child_eventstream }
111
- child = Process.detach Kernel.spawn(env, *popen_args, opts)
110
+ opts = {
111
+ 4 => child_eventstream,
112
+ in: child_stdin,
113
+ out: child_stdout,
114
+ err: child_stderr,
115
+ pgroup: true, # run it in its own process group so we can SIGINT the whole group
116
+ }
117
+ child_pid = Kernel.spawn(env, *popen_args, opts)
118
+ child_pgid = Process.getpgid(child_pid)
112
119
 
113
120
  # close child streams b/c they won't emit EOF
114
121
  # until both child and parent references are closed
115
- child_eventstream.close
116
- child_stdout.close
117
- child_stderr.close
118
- child_stdin.close
122
+ close_streams(child_eventstream, child_stdout, child_stderr, child_stdin)
119
123
  stdin.sync = true
120
124
 
121
- # send stdin
122
- Thread.new {
125
+ # send stdin (char at a time b/c input could come from a stream)
126
+ Thread.new do
123
127
  provided_input.each_char { |char| stdin.write char }
124
128
  stdin.close
125
- }
129
+ end
126
130
 
127
131
  # set up the event consumer
128
132
  consumer = EventStream::Consumer.new(events: eventstream, stdout: stdout, stderr: stderr)
@@ -130,16 +134,17 @@ class SeeingIsBelieving
130
134
 
131
135
  # wait for completion
132
136
  Timeout.timeout timeout_seconds do
133
- exitstatus = child.value.exitstatus
134
- consumer.process_exitstatus exitstatus
137
+ Process.wait child_pid
138
+ consumer.process_exitstatus($?.exitstatus)
135
139
  consumer_thread.join
136
140
  end
137
141
  rescue Timeout::Error
138
- Process.kill "KILL", child.pid
139
142
  consumer.process_timeout timeout_seconds
140
- consumer_thread.join # finish consuming events
141
143
  ensure
142
- [stdin, stdout, stderr, eventstream].each { |io| io.close unless io.closed? }
144
+ allow_error(Errno::ESRCH) { Process.kill "-INT", child_pgid } # negative makes it apply to the group
145
+ allow_error(Errno::ECHILD) { Process.wait child_pid } # I can't tell if this actually works, or just creates enough of a delay for the OS to finish cleaning up the thread
146
+ consumer_thread.join
147
+ close_streams(stdin, stdout, stderr, eventstream)
143
148
  end
144
149
 
145
150
  def popen_args
@@ -151,5 +156,14 @@ class SeeingIsBelieving
151
156
  *require_flags, # users can inject files to be required
152
157
  filename]
153
158
  end
159
+
160
+ def allow_error(error)
161
+ yield
162
+ rescue error
163
+ end
164
+
165
+ def close_streams(*streams)
166
+ streams.each { |io| io.close unless io.closed? }
167
+ end
154
168
  end
155
169
  end