junoser 0.7.2 → 0.7.3

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.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +8 -0
  3. data/Gemfile +10 -0
  4. data/Gemfile.lock +36 -6
  5. data/Rakefile +6 -3
  6. data/bin/console +4 -3
  7. data/exe/junoser +6 -5
  8. data/exe/junoser-squash +9 -6
  9. data/junoser.gemspec +15 -17
  10. data/lib/junoser/cli.rb +2 -2
  11. data/lib/junoser/development.rb +2 -0
  12. data/lib/junoser/display/config_store.rb +12 -12
  13. data/lib/junoser/display/enumerable.rb +6 -4
  14. data/lib/junoser/display/set.rb +15 -17
  15. data/lib/junoser/display/structure.rb +7 -7
  16. data/lib/junoser/display.rb +2 -0
  17. data/lib/junoser/input.rb +11 -10
  18. data/lib/junoser/js_ruler.rb +74 -66
  19. data/lib/junoser/parser.rb +156 -0
  20. data/lib/junoser/rule_tree/node.rb +3 -1
  21. data/lib/junoser/rule_tree/parser.rb +11 -8
  22. data/lib/junoser/rule_tree.rb +2 -0
  23. data/lib/junoser/ruler.rb +190 -170
  24. data/lib/junoser/squash.rb +16 -14
  25. data/lib/junoser/transformer.rb +9 -8
  26. data/lib/junoser/version.rb +3 -1
  27. data/lib/junoser/xsd/base.rb +15 -14
  28. data/lib/junoser/xsd/choice.rb +10 -9
  29. data/lib/junoser/xsd/complex_type.rb +13 -11
  30. data/lib/junoser/xsd/element.rb +34 -36
  31. data/lib/junoser/xsd/enumeration.rb +9 -8
  32. data/lib/junoser/xsd/parsable.rb +2 -0
  33. data/lib/junoser/xsd/restriction.rb +15 -13
  34. data/lib/junoser/xsd/sequence.rb +11 -8
  35. data/lib/junoser/xsd/simple_content.rb +6 -4
  36. data/lib/junoser/xsd/simple_type.rb +7 -5
  37. data/lib/junoser/xsd/union.rb +6 -4
  38. data/lib/junoser.rb +2 -0
  39. data/lib/underscorable.rb +10 -5
  40. metadata +5 -65
  41. data/.github/dependabot.yml +0 -6
  42. data/.github/workflows/test-linux.yaml +0 -30
  43. data/.gitignore +0 -11
  44. data/.pre-commit-config.yaml +0 -7
  45. data/commitlint.config.js +0 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 54f09e05dbba47b559c3a8ba68644a5648b646719830ca573fad81821b7aa6e6
4
- data.tar.gz: d8c0cd5221c4d534bbf3b3986bef228e47c3db44cfe9d3dc9977e70a3ade15dd
3
+ metadata.gz: 2e6df480657c3d5918488f74cce4fb003d9f8b5472957d328966d77fc95a1ffe
4
+ data.tar.gz: 8dd2431e38b33a0f2364610f62960d6dfc6c4117a94bbc4b86b3b39e1b1f46af
5
5
  SHA512:
6
- metadata.gz: 262a923cabcf89668f1b1cb73a773662971fc2b577abb314196fd27a458da801a7ac78740fe31b500652787af7a338fe3906fb569eb12f7363832353289dc3c1
7
- data.tar.gz: 0b01ef6de4abefa8234a5cdfdae9320ad690ea90f9544fbeefb82198195f89eb82c66fb966305a4c813ff9f166cb60280a3de0f0523df5f3a6c02c68935f3dba
6
+ metadata.gz: 04a55401f9bcadfae291d179df38fd4c024947593b8c6c3910898edcd54ef549712378c3dc188a24bf45a5b968a1a545bc8079387a61551ce6e0d81f08e95d6d
7
+ data.tar.gz: 0b2695675044a3d3393522294f9f1863c2aab48126697a249134eb097a0338c878cf58fde4f200cbb19f7b7ddf9f43c2459bd72ba23614b1774d03088d56fcdb
data/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ ## [0.7.3] - 2025-10-02
2
+
3
+ ### Added
4
+
5
+ * Newly supported syntax for vSRX
6
+ * "chassis high-availability"
7
+
8
+
1
9
  ## [0.7.2] - 2025-04-22
2
10
 
3
11
  ### Fixed
data/Gemfile CHANGED
@@ -1,4 +1,14 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source 'https://rubygems.org'
2
4
 
3
5
  # Specify your gem's dependencies in junoser.gemspec
4
6
  gemspec
7
+
8
+ group :development do
9
+ gem 'bundler', '~> 2.0'
10
+ gem 'nokogiri'
11
+ gem 'rake', '~> 13.0'
12
+ gem 'rubocop'
13
+ gem 'test-unit'
14
+ end
data/Gemfile.lock CHANGED
@@ -1,22 +1,51 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- junoser (0.7.2)
4
+ junoser (0.7.3)
5
5
  parslet
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
- mini_portile2 (2.8.8)
11
- nokogiri (1.18.8)
10
+ ast (2.4.3)
11
+ json (2.15.0)
12
+ language_server-protocol (3.17.0.5)
13
+ lint_roller (1.1.0)
14
+ mini_portile2 (2.8.9)
15
+ nokogiri (1.18.10)
12
16
  mini_portile2 (~> 2.8.2)
13
17
  racc (~> 1.4)
18
+ parallel (1.27.0)
19
+ parser (3.3.9.0)
20
+ ast (~> 2.4.1)
21
+ racc
14
22
  parslet (2.0.0)
15
23
  power_assert (2.0.5)
24
+ prism (1.5.1)
16
25
  racc (1.8.1)
17
- rake (13.2.1)
18
- test-unit (3.6.8)
26
+ rainbow (3.1.1)
27
+ rake (13.3.0)
28
+ regexp_parser (2.11.3)
29
+ rubocop (1.81.1)
30
+ json (~> 2.3)
31
+ language_server-protocol (~> 3.17.0.2)
32
+ lint_roller (~> 1.1.0)
33
+ parallel (~> 1.10)
34
+ parser (>= 3.3.0.2)
35
+ rainbow (>= 2.2.2, < 4.0)
36
+ regexp_parser (>= 2.9.3, < 3.0)
37
+ rubocop-ast (>= 1.47.1, < 2.0)
38
+ ruby-progressbar (~> 1.7)
39
+ unicode-display_width (>= 2.4.0, < 4.0)
40
+ rubocop-ast (1.47.1)
41
+ parser (>= 3.3.7.2)
42
+ prism (~> 1.4)
43
+ ruby-progressbar (1.13.0)
44
+ test-unit (3.7.0)
19
45
  power_assert
46
+ unicode-display_width (3.2.0)
47
+ unicode-emoji (~> 4.1)
48
+ unicode-emoji (4.1.0)
20
49
 
21
50
  PLATFORMS
22
51
  ruby
@@ -26,7 +55,8 @@ DEPENDENCIES
26
55
  junoser!
27
56
  nokogiri
28
57
  rake (~> 13.0)
58
+ rubocop
29
59
  test-unit
30
60
 
31
61
  BUNDLED WITH
32
- 2.6.2
62
+ 2.6.9
data/Rakefile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'bundler/gem_tasks'
2
4
  require 'junoser/development'
3
5
  require 'nokogiri'
@@ -9,9 +11,9 @@ rule_path = File.join(__dir__, 'tmp/rule.rb')
9
11
  ruby_parser_path = File.join(__dir__, 'lib/junoser/parser.rb')
10
12
  js_parser_path = File.join(__dir__, 'tmp/junos.js')
11
13
 
12
- def open_files(input, output, &block)
13
- i = open(input)
14
- o = open(output, 'w')
14
+ def open_files(input, output)
15
+ i = File.open(input)
16
+ o = File.open(output, 'w')
15
17
 
16
18
  yield i, o
17
19
 
@@ -71,6 +73,7 @@ namespace :rule do
71
73
  task :tree, [:path] do |_, args|
72
74
  if args.path
73
75
  raise "File not found: #{args.path}" unless File.exist?(args.path)
76
+
74
77
  Junoser::RuleTree::Parser.new(File.read(args.path)).print
75
78
  else
76
79
  Junoser::RuleTree::Parser.new($stdin.read).print
data/bin/console CHANGED
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
- require "bundler/setup"
4
- require "junoser"
4
+ require 'bundler/setup'
5
+ require 'junoser'
5
6
 
6
7
  # You can add fixtures and/or initialization code here to make experimenting
7
8
  # with your gem easier. You can also use a different console, if you like.
@@ -10,5 +11,5 @@ require "junoser"
10
11
  # require "pry"
11
12
  # Pry.start
12
13
 
13
- require "irb"
14
+ require 'irb'
14
15
  IRB.start
data/exe/junoser CHANGED
@@ -1,13 +1,14 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
4
+ require 'English'
3
5
  require 'optparse'
4
6
  require 'pathname'
5
7
 
6
- $: << File.expand_path('../../lib', Pathname.new(__FILE__).realpath)
8
+ $LOAD_PATH << File.expand_path('../../lib', Pathname.new(__FILE__).realpath)
7
9
 
8
10
  require 'junoser'
9
11
 
10
-
11
12
  command = nil
12
13
  opts = OptionParser.new do |opts|
13
14
  opts.banner = 'junoser: an juniper configuration parser'
@@ -41,11 +42,11 @@ opts.parse!
41
42
 
42
43
  case command
43
44
  when :check
44
- abort unless Junoser::Cli.commit_check($<)
45
+ abort unless Junoser::Cli.commit_check($DEFAULT_INPUT)
45
46
  when :display_set
46
- puts Junoser::Cli.display_set($<)
47
+ puts Junoser::Cli.display_set($DEFAULT_INPUT)
47
48
  when :struct
48
- puts Junoser::Cli.struct($<)
49
+ puts Junoser::Cli.struct($DEFAULT_INPUT)
49
50
  else
50
51
  puts opts
51
52
  abort
data/exe/junoser-squash CHANGED
@@ -1,8 +1,11 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'English'
2
5
  require 'optparse'
3
6
  require 'pathname'
4
7
 
5
- $: << File.expand_path('../../lib', Pathname.new(__FILE__).realpath)
8
+ $LOAD_PATH << File.expand_path('../../lib', Pathname.new(__FILE__).realpath)
6
9
  require 'junoser/squash'
7
10
 
8
11
  command = :squash
@@ -17,9 +20,9 @@ opts = OptionParser.new do |opts|
17
20
  end
18
21
  opts.parse!
19
22
  case command
20
- when :squash
21
- puts Junoser::Squash.new($<).transform
22
- else
23
- puts opts
24
- abort
23
+ when :squash
24
+ puts Junoser::Squash.new($DEFAULT_INPUT).transform
25
+ else
26
+ puts opts
27
+ abort
25
28
  end
data/junoser.gemspec CHANGED
@@ -1,31 +1,29 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
3
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
5
  require 'junoser/version'
5
6
 
6
7
  Gem::Specification.new do |spec|
7
- spec.name = "junoser"
8
+ spec.name = 'junoser'
8
9
  spec.version = Junoser::VERSION
9
- spec.authors = ["Shintaro Kojima"]
10
- spec.email = ["goodies@codeout.net"]
10
+ spec.authors = ['Shintaro Kojima']
11
+ spec.email = ['goodies@codeout.net']
11
12
 
12
- spec.summary = %q{PEG parser for JUNOS configuration.}
13
- spec.description = %q{PEG parser to vefiry and translate into different formats for JUNOS configuration.}
14
- spec.homepage = "https://github.com/codeout/junoser"
13
+ spec.summary = 'PEG parser for JUNOS configuration.'
14
+ spec.description = 'PEG parser to vefiry and translate into different formats for JUNOS configuration.'
15
+ spec.homepage = 'https://github.com/codeout/junoser'
15
16
 
16
17
  # Specify which files should be added to the gem when it is released.
17
18
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
18
- spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
19
- `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features|example)/}) }
19
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
20
+ `git ls-files -z *`.split("\x0").reject { |f| f.match(%r{^(test/|example/|commitlint)}) }
20
21
  end
21
- spec.bindir = "exe"
22
+ spec.bindir = 'exe'
22
23
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
23
- spec.require_paths = ["lib"]
24
+ spec.require_paths = ['lib']
24
25
 
25
- spec.add_dependency "parslet"
26
+ spec.add_dependency 'parslet'
26
27
 
27
- spec.add_development_dependency "bundler", "~> 2.0"
28
- spec.add_development_dependency "rake", "~> 13.0"
29
- spec.add_development_dependency "nokogiri"
30
- spec.add_development_dependency "test-unit"
28
+ spec.metadata['rubygems_mfa_required'] = 'true'
31
29
  end
data/lib/junoser/cli.rb CHANGED
@@ -1,9 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'parslet'
2
4
  require 'junoser/display'
3
5
  require 'junoser/input'
4
6
  require 'junoser/parser'
5
7
 
6
-
7
8
  module Junoser
8
9
  module Cli
9
10
  class << self
@@ -37,7 +38,6 @@ module Junoser
37
38
  end
38
39
  end
39
40
 
40
-
41
41
  private
42
42
 
43
43
  def commit_check_structured(config)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'underscorable'
2
4
  require 'junoser/xsd/parsable'
3
5
  require 'junoser/ruler'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'forwardable'
2
4
 
3
5
  module Junoser
@@ -9,7 +11,7 @@ module Junoser
9
11
 
10
12
  attr_accessor :deactivated
11
13
 
12
- def initialize(depth=0)
14
+ def initialize(depth = 0)
13
15
  @hash = {}
14
16
  @depth = depth
15
17
  @deactivated = false
@@ -19,7 +21,7 @@ module Junoser
19
21
  store = self
20
22
 
21
23
  join_arg(str).split("\n").each_with_index do |element, index|
22
- store[element] ||= self.class.new(index+1)
24
+ store[element] ||= self.class.new(index + 1)
23
25
  store = store[element]
24
26
  end
25
27
  end
@@ -36,13 +38,11 @@ module Junoser
36
38
  end
37
39
  else
38
40
  statement, store = inverse_match(deactivated_line)
39
- if statement
40
- store.deactivated = true
41
- end
41
+ store.deactivated = true if statement
42
42
  end
43
43
  end
44
44
 
45
- def each_with_inactive(str='', &block)
45
+ def each_with_inactive(str = '')
46
46
  each do |k, v|
47
47
  k = "inactive: #{k}" if v.deactivated
48
48
  yield k, v, str
@@ -52,7 +52,7 @@ module Junoser
52
52
  end
53
53
 
54
54
  def to_s
55
- each_with_inactive('', &method(:hash_item_to_s))
55
+ each_with_inactive(+'', &method(:hash_item_to_s))
56
56
  end
57
57
 
58
58
  def_delegators :@hash, :[], :[]=, :each, :empty?
@@ -61,17 +61,17 @@ module Junoser
61
61
 
62
62
  def hash_item_to_s(key, value, str)
63
63
  if value.empty?
64
- str << OFFSET*@depth << "#{key};\n"
64
+ str << (OFFSET * @depth) << "#{key};\n"
65
65
  else
66
- str << OFFSET*@depth << "#{key} {\n"
66
+ str << (OFFSET * @depth) << "#{key} {\n"
67
67
  str << value.to_s.chop << "\n"
68
- str << OFFSET*@depth << "}\n"
68
+ str << (OFFSET * @depth) << "}\n"
69
69
  end
70
70
  end
71
71
 
72
72
  def join_arg(str)
73
- str.gsub!(/\narg\((.*)\)$/) { " #$1" }
74
- str.gsub!(/arg\((.*)\)/) { "#$1" }
73
+ str.gsub!(/\narg\((.*)\)$/) { " #{::Regexp.last_match(1)}" }
74
+ str.gsub!(/arg\((.*)\)/) { ::Regexp.last_match(1).to_s }
75
75
  str
76
76
  end
77
77
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'junoser/display/config_store'
2
4
 
3
5
  module Junoser
@@ -20,10 +22,10 @@ module Junoser
20
22
  value.in_then = true if key == 'then'
21
23
  value.in_group = true if key =~ /^group /
22
24
 
23
- if in_from && ['next-header', 'port', 'protocol'].include?(key) ||
24
- in_then && key == 'origin' ||
25
- in_group && key == 'type'
26
- str << Junoser::Display::ConfigStore::OFFSET * @depth << "#{key} #{value.to_enum};\n"
25
+ if (in_from && %w[next-header port protocol].include?(key)) ||
26
+ (in_then && key == 'origin') ||
27
+ (in_group && key == 'type')
28
+ str << (Junoser::Display::ConfigStore::OFFSET * @depth) << "#{key} #{value.to_enum};\n"
27
29
  else
28
30
  super
29
31
  end
@@ -1,3 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'English'
1
4
  require 'parslet'
2
5
  require 'junoser/input'
3
6
 
@@ -9,7 +12,7 @@ module Junoser
9
12
  end
10
13
 
11
14
  def transform
12
- result = ''
15
+ result = +''
13
16
 
14
17
  process do |current_stack, str|
15
18
  result << transform_line(current_stack, str) << "\n"
@@ -18,11 +21,11 @@ module Junoser
18
21
  result
19
22
  end
20
23
 
21
- def commit_check(&block)
24
+ def commit_check
22
25
  begin
23
26
  lines = transform
24
- rescue
25
- $stderr.puts $!
27
+ rescue StandardError
28
+ warn $ERROR_INFO
26
29
  return false
27
30
  end
28
31
 
@@ -30,24 +33,23 @@ module Junoser
30
33
  parser.parse_lines(lines)
31
34
  end
32
35
 
33
-
34
36
  private
35
37
 
36
- def process(&block)
38
+ def process
37
39
  stack = []
38
40
 
39
41
  Junoser::Input.new(@input).read.split("\n").each do |line|
40
42
  case line
41
43
  when /(?!.*})(.*){/
42
- stack.push $1.strip
44
+ stack.push ::Regexp.last_match(1).strip
43
45
  when /}\s*$/
44
46
  stack.pop
45
47
  when /((?!\[).*)\[(.*)\];/
46
- $2.split("\s").each do |i|
47
- yield stack, "#{$1.strip} #{i}"
48
+ ::Regexp.last_match(2).split.each do |i|
49
+ yield stack, "#{::Regexp.last_match(1).strip} #{i}"
48
50
  end
49
51
  when /(.*);/
50
- yield stack, $1
52
+ yield stack, ::Regexp.last_match(1)
51
53
  else
52
54
  raise "ERROR: unknown statement: #{line}"
53
55
  end
@@ -56,22 +58,18 @@ module Junoser
56
58
 
57
59
  def transform_line(current_stack, str)
58
60
  statements = []
59
- current_statement = ''
61
+ current_statement = +''
60
62
 
61
63
  current_stack.each do |stack|
62
64
  stack.gsub! 'replace: ', ''
63
65
 
64
- if stack.gsub!('inactive: ', '')
65
- statements << "deactivate #{current_statement}#{stack}"
66
- end
66
+ statements << "deactivate #{current_statement}#{stack}" if stack.gsub!('inactive: ', '')
67
67
  current_statement << "#{stack} "
68
68
  end
69
69
 
70
70
  str.gsub! 'replace: ', ''
71
71
 
72
- if str.gsub!('inactive: ', '')
73
- statements << "deactivate #{current_statement}#{str}"
74
- end
72
+ statements << "deactivate #{current_statement}#{str}" if str.gsub!('inactive: ', '')
75
73
 
76
74
  statements.unshift "set #{current_statement}#{str}"
77
75
  statements.join("\n")
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'junoser/input'
2
4
  require 'junoser/display/config_store'
3
5
  require 'junoser/parser'
@@ -27,21 +29,19 @@ module Junoser
27
29
  end
28
30
 
29
31
  if line =~ /^deactivate *(.*)/
30
- deactivated_lines << "#$1 #{apply_groups}".strip
32
+ deactivated_lines << "#{::Regexp.last_match(1)} #{apply_groups}".strip
31
33
  next
32
34
  end
33
35
 
34
36
  transformed = transform.apply(parser.parse(line))
35
37
  raise "ERROR: Failed to parse \"#{line}\"" unless transformed.is_a?(String)
36
38
 
37
- if apply_groups
38
- transformed << "\n#{apply_groups}"
39
- end
39
+ transformed << "\n#{apply_groups}" if apply_groups
40
40
 
41
41
  @config << transformed
42
42
  end
43
43
 
44
- deactivated_lines.each {|l| @config.deactivate l }
44
+ deactivated_lines.each { |l| @config.deactivate l }
45
45
 
46
46
  @config.to_s
47
47
  end
@@ -49,8 +49,8 @@ module Junoser
49
49
  private
50
50
 
51
51
  def trim_apply_groups(line)
52
- line.gsub! /\s+(apply-groups(-except)?\s+.*)/, ''
53
- return $1
52
+ line.gsub!(/\s+(apply-groups(-except)?\s+.*)/, '')
53
+ ::Regexp.last_match(1)
54
54
  end
55
55
  end
56
56
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'junoser/display/set'
2
4
  require 'junoser/display/structure'
3
5
 
data/lib/junoser/input.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Junoser
2
4
  class Input
3
5
  def initialize(io_or_string)
@@ -8,27 +10,26 @@ module Junoser
8
10
  content = if @io_or_string.respond_to?(:read)
9
11
  @io_or_string.read
10
12
  else
11
- @io_or_string.to_s
13
+ +@io_or_string.to_s
12
14
  end
13
15
 
14
16
  content = remove_blank_and_comment_line(content)
15
17
  content = unify_carriage_return(content)
16
- content = unify_square_brackets(content)
18
+ unify_square_brackets(content)
17
19
  end
18
20
 
19
-
20
21
  private
21
22
 
22
23
  # As for comment line, a trailing comment after configuration will be processed by parslet
23
24
  def remove_blank_and_comment_line(str)
24
- str.gsub! /^\s*#.*/, ''
25
- str.gsub! /^\s*\/\*((?!\*\/).)*\*\//m, ''
26
- str.gsub! /\n\s*/, "\n"
25
+ str.gsub!(/^\s*#.*/, '')
26
+ str.gsub!(%r{^\s*/\*((?!\*/).)*\*/}m, '')
27
+ str.gsub!(/\n\s*/, "\n")
27
28
  str.strip
28
29
  end
29
30
 
30
31
  def unify_carriage_return(str)
31
- str.gsub! /\r\n?/, "\n"
32
+ str.gsub!(/\r\n?/, "\n")
32
33
  str
33
34
  end
34
35
 
@@ -38,12 +39,12 @@ module Junoser
38
39
 
39
40
  open_brackets = 0
40
41
  str.split("\n").each do |line|
41
- raise "ERROR: invalid statement: #{line}" if open_brackets < 0
42
+ raise "ERROR: invalid statement: #{line}" if open_brackets.negative?
42
43
 
43
- if open_brackets == 0
44
+ if open_brackets.zero?
44
45
  lines << line
45
46
  else
46
- lines.last << " " << line
47
+ lines.last << ' ' << line
47
48
  end
48
49
 
49
50
  open_brackets += line.count('[') - line.count(']')