dokaz 0.0.4 → 0.0.5

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,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- YmVmYmJhOGQ4YWFjNWM2MDg3ZjIxODcxOGNkYjc0Yjg4ZGY2ODUzOA==
5
- data.tar.gz: !binary |-
6
- YWY4ZGM3MDZmYjQ5ZWJiZmNkZjVmMzc2NWVhZGY5ZjM3YWZjMzJiMQ==
2
+ SHA256:
3
+ metadata.gz: 523736088a32b27b2e16d362c0ebe5cb704eff2153cd6b07a98565b58fd7dc01
4
+ data.tar.gz: c86ec189e60c7eaa6f485ef6b5ee807e5bc245300cff3d759bfb1b9a270b37fd
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- YjQ4YzBlMThjZmJiN2Y0NjQ0MDRjZmMyYTM2Yjg4NjRiOWRlNTk0YzNjNGY5
10
- MmYzNjRmZTRlNjdjNjQ3OWY3YTg2OGNiNDAxZTJjOTdjYjBhMTI0NjNjOWY0
11
- NzkzMmVhZTAzMzA1NzlmNTNjOWFiZjVlYThlMzQ0NGE5NmM2ZGI=
12
- data.tar.gz: !binary |-
13
- MjhkNTU2YWQ3ZTMwN2JlNjMyOTEzNjAzMjRjYzE3MDMyZjEzZmY1Y2RiNGY3
14
- OGRkM2JhZjg5ZjJhZjVhMWY1NDNkZjExM2E5ZDc3ODc4YTY1MDAzYTI1YWY4
15
- NmQ3NmYyNTEyMWRkMWNlY2Q1Mjk2ZDQ0OTAxMDQyM2EwMTk5ZDM=
6
+ metadata.gz: 31c454210e0d3f8dc5ed652975fe24408c76c2004e743acea40b15b9914b102f759d7e569ce3f0b219e876a7ec07e7773e8ecc79f36abb18e69ca7c0aa925111
7
+ data.tar.gz: b798d663c0acf6c223a90f638c28dec10b52fb2b0b4112bf95a43371cb1bff2b81cf30ea50d2069d01b0665ddb70646660faa3c36466877ebeca08693aa48e15
data/Changelog.md ADDED
@@ -0,0 +1,5 @@
1
+ # Dokaz Changelog
2
+
3
+ ## 0.0.5 -- 2023-02-12
4
+
5
+ * Make it Ruby 3.1-3.2 compatible (rather hacky, but seem to work)
data/bin/dokaz CHANGED
@@ -5,13 +5,10 @@ require 'slop'
5
5
  $:.unshift 'lib'
6
6
  require 'dokaz'
7
7
 
8
- if File.exists?('.dokaz')
8
+ if File.exist?('.dokaz')
9
9
  ARGV.push(*File.read('.dokaz').split(/\s+/m))
10
10
  end
11
11
 
12
- patterns = []
13
- patterns << ARGV.shift until ARGV.empty? || ARGV.first =~ /^-/
14
-
15
12
  HELP = %Q{
16
13
  Usage: dokaz [patterns] [options]
17
14
 
@@ -26,12 +23,19 @@ Options:
26
23
  --help Shows this message
27
24
  }
28
25
 
26
+ patterns = []
27
+ patterns << ARGV.shift until ARGV.empty? || ARGV.first =~ /^-/
28
+
29
29
  options = Slop.parse do
30
30
  on :r, :require=, "Additional files to require, comma-separated"
31
31
  on :f, :format=, "Output format (spec or show[case])"
32
32
  on :help
33
33
  end
34
34
 
35
+ if patterns.empty?
36
+ patterns.concat(Dir['README.{md,markdown}'])
37
+ end
38
+
35
39
  if patterns.empty? || options.help?
36
40
  puts HELP
37
41
  exit
data/dokaz.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'dokaz'
3
- s.version = '0.0.4'
3
+ s.version = '0.0.5'
4
4
  s.authors = ['Victor Shepelev']
5
5
  s.email = 'zverok.offline@gmail.com'
6
6
  s.homepage = 'https://github.com/zverok/dokaz'
@@ -24,8 +24,11 @@ Gem::Specification.new do |s|
24
24
 
25
25
  s.add_dependency 'ansi'
26
26
  s.add_dependency 'slop', '~> 3'
27
- s.add_dependency 'rouge'
27
+ s.add_dependency 'rouge', '~> 4'
28
28
 
29
29
  s.add_development_dependency 'rspec', '~> 3'
30
30
  s.add_development_dependency 'rspec-its', '~> 1'
31
+
32
+ s.add_development_dependency 'rake'
33
+ s.add_development_dependency 'rubygems-tasks'
31
34
  end
data/examples/README.md CHANGED
@@ -51,13 +51,14 @@ puts a.sum(10)
51
51
  This code throws an error:
52
52
 
53
53
  ```ruby
54
+ # It's a comment, but not seen while evaluating
54
55
  100 / 0
55
56
  ```
56
57
 
57
58
  This code requires additional require:
58
59
 
59
60
  ```ruby
60
- BigDecimal.new("0")
61
+ BigDecimal.new('0')
61
62
  ```
62
63
 
63
64
  Try to run it with option `--require cgi`.
@@ -5,7 +5,7 @@ require 'rouge'
5
5
  class Dokaz
6
6
  class Formatter
7
7
  def initialize
8
- @rouge = Rouge::Formatters::Terminal256.new
8
+ @rouge = Rouge::Formatters::Terminal256.new(Rouge::Themes::Molokai.new)
9
9
  @lexer = Rouge::Lexers::Ruby.new
10
10
  end
11
11
 
@@ -45,7 +45,7 @@ class Dokaz
45
45
  if STDOUT.tty?
46
46
  @rouge.format(@lexer.lex(str))
47
47
  else
48
- code + "\n"
48
+ code
49
49
  end
50
50
  end
51
51
 
@@ -81,13 +81,13 @@ class Dokaz
81
81
  puts
82
82
 
83
83
  @errors.each do |src, e|
84
- print code(src)
84
+ puts code(src)
85
85
  puts( error("#{e.message} (#{e.class})\n " + filter_backtrace(e.backtrace).join("\n ") + "\n"))
86
86
  end
87
87
 
88
88
  puts
89
89
  @errors.each do |code, e|
90
- ln = e.backtrace.first.sub(/:in .*$/, '')
90
+ ln = filter_backtrace(e.backtrace).last.to_s.sub(/:in .*$/, '')
91
91
  puts error("dokaz #{ln}") + comment(" # #{e.message} (#{e.class})")
92
92
  end
93
93
 
@@ -113,15 +113,15 @@ class Dokaz
113
113
  end
114
114
 
115
115
  def output(src, res, out)
116
- print code(src)
116
+ puts code(src)
117
117
  unless out.empty?
118
- puts comment("# Prints: \n# " + out.split("\n").join("\n# "))
118
+ puts comment("# Prints: \n# " + out.split("\n").join("\n# "))
119
119
  end
120
120
  puts comment("# => " + res.inspect.split("\n").join("\n# "))
121
121
  end
122
122
 
123
123
  def output_err(src, e)
124
- print code(src)
124
+ puts code(src)
125
125
  puts comment("# Throws: #{e.message} (#{e.class})")
126
126
  end
127
127
 
data/lib/dokaz/parser.rb CHANGED
@@ -3,10 +3,46 @@ require 'strscan'
3
3
  require 'stringio'
4
4
 
5
5
  class Dokaz
6
+ class Statement
7
+ attr_reader :code, :line, :block
8
+ attr_reader :pre_comment
9
+ attr_accessor :comment
10
+
11
+ def initialize(code, line, block)
12
+ @raw_code, @line, @block = code, line, block
13
+ @comment = ''
14
+
15
+ parse!
16
+ end
17
+
18
+ def empty?
19
+ code.empty?
20
+ end
21
+
22
+ private
23
+
24
+ def parse!
25
+ pre_lines = []
26
+ lines = @raw_code.split("\n")
27
+ while !lines.empty? && (lines.first =~ /^\s*\#/ || lines.first.strip.empty?)
28
+ pre_lines << lines.shift
29
+ @line += 1
30
+ end
31
+ @code = lines.join("\n")
32
+ @pre_comment = pre_lines.reject{|ln| ln.strip.empty?}.join("\n")
33
+ end
34
+ end
35
+
6
36
  class Block
37
+ FakeIRBContext = Struct.new(:local_variables)
38
+
7
39
  attr_reader :code, :line, :file
40
+ attr_reader :statements
41
+
8
42
  def initialize(code, line, file)
9
43
  @code, @line, @file = code, line, file
44
+
45
+ parse!
10
46
  end
11
47
 
12
48
  def end_line
@@ -20,6 +56,35 @@ class Dokaz
20
56
  def inside?(ln)
21
57
  (line..end_line).cover?(ln)
22
58
  end
59
+
60
+ private
61
+
62
+ def parse!
63
+ @statements = []
64
+ lex = RubyLex.new
65
+
66
+ # We do unholy things by reusing IRB's internal helper classes.
67
+ # In 3.2 (ver.1.6), IRB changed them to be more complicated. I only had
68
+ # time to quick-hack it around with fake copies of object IRB use.
69
+ # It might fail anytime, but works on test examples :shrug:
70
+ if IRB::VERSION >= '1.6'
71
+ ctx = FakeIRBContext.new(local_variables: [])
72
+ lex.set_input(SpecIO.new(code), context: ctx)
73
+ lex.each_top_level_statement(ctx) do |st, line_no|
74
+ @statements << Statement.new(st, line + line_no, self)
75
+ end
76
+ else
77
+ lex.set_input(SpecIO.new(code))
78
+ lex.each_top_level_statement do |st, line_no|
79
+ @statements << Statement.new(st, line + line_no, self)
80
+ end
81
+ end
82
+
83
+ @statements.each_cons(2){|s1, s2|
84
+ s1.comment = s2.pre_comment
85
+ }
86
+ @statements.reject!(&:empty?)
87
+ end
23
88
  end
24
89
 
25
90
  class Parser
@@ -28,9 +93,11 @@ class Dokaz
28
93
  end
29
94
 
30
95
  def parse
31
- res = []
96
+ blocks = []
32
97
  ln = 0
98
+
33
99
  scanner = StringScanner.new(File.read(@path))
100
+
34
101
  loop do
35
102
  text = scanner.scan_until(/\n```ruby\n/)
36
103
  break unless text
@@ -38,14 +105,14 @@ class Dokaz
38
105
  ln += text.count("\n")
39
106
  code = scanner.scan_until(/\n```\n/)
40
107
  if !code
41
- res << Block.new(scanner.rest, ln, @path)
108
+ blocks << Block.new(scanner.rest, ln, @path)
42
109
  break
43
110
  end
44
- res << Block.new(code.sub(/```\Z/, ''), ln, @path)
111
+ blocks << Block.new(code.sub(/```\Z/, ''), ln, @path)
45
112
  ln += code.count("\n")
46
113
  end
47
114
 
48
- res
115
+ blocks
49
116
  end
50
117
  end
51
118
  end
data/lib/dokaz.rb CHANGED
@@ -11,6 +11,13 @@ class Dokaz
11
11
  'show' => ShowcaseFormatter,
12
12
  'showcase' => ShowcaseFormatter
13
13
  }
14
+
15
+ class << self
16
+ def before(&block)
17
+ return @before || ->(){} unless block
18
+ @before = block
19
+ end
20
+ end
14
21
 
15
22
  def initialize(patterns, options = {})
16
23
  @blocks = select_blocks(patterns)
@@ -23,6 +30,8 @@ class Dokaz
23
30
  end
24
31
 
25
32
  def run
33
+ self.class.before.call
34
+
26
35
  puts "Running #{@blocks.count} blocks from #{@blocks.map(&:file).uniq.count} files\n\n"
27
36
 
28
37
  @blocks.each do |b|
@@ -36,17 +45,15 @@ class Dokaz
36
45
  private
37
46
 
38
47
  def process_block(block)
39
- lex = RubyLex.new
40
- lex.set_input(SpecIO.new(block.code))
41
- lex.each_top_level_statement do |line, line_no|
48
+ block.statements.each do |st|
42
49
  begin
43
50
  res = nil
44
51
  out = capture_output{
45
- res = eval(line, TOPLEVEL_BINDING, block.file, block.line + line_no)
52
+ res = eval(st.code, TOPLEVEL_BINDING, block.file, st.line)
46
53
  }
47
- @formatter.output(line, res, out)
48
- rescue => e
49
- @formatter.output_err(line, e)
54
+ @formatter.output(st.code, res, out)
55
+ rescue Exception => e
56
+ @formatter.output_err(st.code, e)
50
57
  break
51
58
  end
52
59
  end
metadata CHANGED
@@ -1,85 +1,113 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dokaz
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Victor Shepelev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-06-21 00:00:00.000000000 Z
11
+ date: 2023-02-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ansi
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ! '>='
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ! '>='
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: slop
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ~>
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
33
  version: '3'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ~>
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '3'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rouge
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ! '>='
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '0'
47
+ version: '4'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ! '>='
52
+ - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '0'
54
+ version: '4'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rspec
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ~>
59
+ - - "~>"
60
60
  - !ruby/object:Gem::Version
61
61
  version: '3'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ~>
66
+ - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '3'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rspec-its
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - ~>
73
+ - - "~>"
74
74
  - !ruby/object:Gem::Version
75
75
  version: '1'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - ~>
80
+ - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: '1'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rake
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rubygems-tasks
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
83
111
  description:
84
112
  email: zverok.offline@gmail.com
85
113
  executables:
@@ -87,6 +115,7 @@ executables:
87
115
  extensions: []
88
116
  extra_rdoc_files: []
89
117
  files:
118
+ - Changelog.md
90
119
  - LICENSE.txt
91
120
  - README.md
92
121
  - bin/dokaz
@@ -108,19 +137,17 @@ require_paths:
108
137
  - lib
109
138
  required_ruby_version: !ruby/object:Gem::Requirement
110
139
  requirements:
111
- - - ! '>='
140
+ - - ">="
112
141
  - !ruby/object:Gem::Version
113
142
  version: '0'
114
143
  required_rubygems_version: !ruby/object:Gem::Requirement
115
144
  requirements:
116
- - - ! '>='
145
+ - - ">="
117
146
  - !ruby/object:Gem::Version
118
147
  version: '0'
119
148
  requirements: []
120
- rubyforge_project:
121
- rubygems_version: 2.4.6
149
+ rubygems_version: 3.1.6
122
150
  signing_key:
123
151
  specification_version: 4
124
152
  summary: Use your documentation as a specification
125
153
  test_files: []
126
- has_rdoc: