junoser 0.7.1 → 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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +20 -0
- data/Gemfile +10 -0
- data/Gemfile.lock +36 -6
- data/Rakefile +6 -3
- data/bin/console +4 -3
- data/exe/junoser +6 -5
- data/exe/junoser-squash +9 -6
- data/junoser.gemspec +15 -17
- data/lib/junoser/cli.rb +2 -2
- data/lib/junoser/development.rb +2 -0
- data/lib/junoser/display/config_store.rb +12 -12
- data/lib/junoser/display/enumerable.rb +6 -4
- data/lib/junoser/display/set.rb +15 -17
- data/lib/junoser/display/structure.rb +7 -7
- data/lib/junoser/display.rb +2 -0
- data/lib/junoser/input.rb +11 -10
- data/lib/junoser/js_ruler.rb +74 -66
- data/lib/junoser/parser.rb +160 -12
- data/lib/junoser/rule_tree/node.rb +3 -1
- data/lib/junoser/rule_tree/parser.rb +11 -8
- data/lib/junoser/rule_tree.rb +2 -0
- data/lib/junoser/ruler.rb +193 -170
- data/lib/junoser/squash.rb +16 -14
- data/lib/junoser/transformer.rb +9 -8
- data/lib/junoser/version.rb +3 -1
- data/lib/junoser/xsd/base.rb +15 -14
- data/lib/junoser/xsd/choice.rb +10 -9
- data/lib/junoser/xsd/complex_type.rb +13 -11
- data/lib/junoser/xsd/element.rb +34 -36
- data/lib/junoser/xsd/enumeration.rb +9 -8
- data/lib/junoser/xsd/parsable.rb +2 -0
- data/lib/junoser/xsd/restriction.rb +15 -13
- data/lib/junoser/xsd/sequence.rb +11 -8
- data/lib/junoser/xsd/simple_content.rb +6 -4
- data/lib/junoser/xsd/simple_type.rb +7 -5
- data/lib/junoser/xsd/union.rb +6 -4
- data/lib/junoser.rb +2 -0
- data/lib/underscorable.rb +10 -5
- metadata +5 -65
- data/.github/dependabot.yml +0 -6
- data/.github/workflows/test-linux.yaml +0 -30
- data/.gitignore +0 -11
- data/.pre-commit-config.yaml +0 -7
- data/commitlint.config.js +0 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2e6df480657c3d5918488f74cce4fb003d9f8b5472957d328966d77fc95a1ffe
|
4
|
+
data.tar.gz: 8dd2431e38b33a0f2364610f62960d6dfc6c4117a94bbc4b86b3b39e1b1f46af
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 04a55401f9bcadfae291d179df38fd4c024947593b8c6c3910898edcd54ef549712378c3dc188a24bf45a5b968a1a545bc8079387a61551ce6e0d81f08e95d6d
|
7
|
+
data.tar.gz: 0b2695675044a3d3393522294f9f1863c2aab48126697a249134eb097a0338c878cf58fde4f200cbb19f7b7ddf9f43c2459bd72ba23614b1774d03088d56fcdb
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,23 @@
|
|
1
|
+
## [0.7.3] - 2025-10-02
|
2
|
+
|
3
|
+
### Added
|
4
|
+
|
5
|
+
* Newly supported syntax for vSRX
|
6
|
+
* "chassis high-availability"
|
7
|
+
|
8
|
+
|
9
|
+
## [0.7.2] - 2025-04-22
|
10
|
+
|
11
|
+
### Fixed
|
12
|
+
|
13
|
+
* A Nokogiri's [security vulnerability](https://github.com/codeout/junoser/security/dependabot/19)
|
14
|
+
* The argument of commands below should be a regular expression
|
15
|
+
* "system login class foo allow-commands-regexps"
|
16
|
+
* "system login class foo deny-commands-regexps"
|
17
|
+
* "system login class foo allow-configuration-regexps"
|
18
|
+
* "system login class foo deny-configuration-regexps"
|
19
|
+
|
20
|
+
|
1
21
|
## [0.7.1] - 2025-02-03
|
2
22
|
|
3
23
|
### Added
|
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.
|
4
|
+
junoser (0.7.3)
|
5
5
|
parslet
|
6
6
|
|
7
7
|
GEM
|
8
8
|
remote: https://rubygems.org/
|
9
9
|
specs:
|
10
|
-
|
11
|
-
|
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
|
-
|
18
|
-
|
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.
|
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
|
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
|
4
|
-
require
|
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
|
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
|
-
|
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
|
-
|
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
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
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
|
-
#
|
2
|
-
|
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 =
|
8
|
+
spec.name = 'junoser'
|
8
9
|
spec.version = Junoser::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
10
|
+
spec.authors = ['Shintaro Kojima']
|
11
|
+
spec.email = ['goodies@codeout.net']
|
11
12
|
|
12
|
-
spec.summary =
|
13
|
-
spec.description =
|
14
|
-
spec.homepage =
|
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(
|
19
|
-
`git ls-files -z
|
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 =
|
22
|
+
spec.bindir = 'exe'
|
22
23
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
23
|
-
spec.require_paths = [
|
24
|
+
spec.require_paths = ['lib']
|
24
25
|
|
25
|
-
spec.add_dependency
|
26
|
+
spec.add_dependency 'parslet'
|
26
27
|
|
27
|
-
spec.
|
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)
|
data/lib/junoser/development.rb
CHANGED
@@ -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=''
|
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
|
64
|
+
str << (OFFSET * @depth) << "#{key};\n"
|
65
65
|
else
|
66
|
-
str << OFFSET
|
66
|
+
str << (OFFSET * @depth) << "#{key} {\n"
|
67
67
|
str << value.to_s.chop << "\n"
|
68
|
-
str << OFFSET
|
68
|
+
str << (OFFSET * @depth) << "}\n"
|
69
69
|
end
|
70
70
|
end
|
71
71
|
|
72
72
|
def join_arg(str)
|
73
|
-
str.gsub!(/\narg\((.*)\)$/) { "
|
74
|
-
str.gsub!(/arg\((.*)\)/) {
|
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 && [
|
24
|
-
|
25
|
-
|
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
|
data/lib/junoser/display/set.rb
CHANGED
@@ -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
|
24
|
+
def commit_check
|
22
25
|
begin
|
23
26
|
lines = transform
|
24
|
-
rescue
|
25
|
-
$
|
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
|
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
|
44
|
+
stack.push ::Regexp.last_match(1).strip
|
43
45
|
when /}\s*$/
|
44
46
|
stack.pop
|
45
47
|
when /((?!\[).*)\[(.*)\];/
|
46
|
-
|
47
|
-
yield stack, "#{
|
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,
|
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 << "
|
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!
|
53
|
-
|
52
|
+
line.gsub!(/\s+(apply-groups(-except)?\s+.*)/, '')
|
53
|
+
::Regexp.last_match(1)
|
54
54
|
end
|
55
55
|
end
|
56
56
|
end
|
data/lib/junoser/display.rb
CHANGED
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
|
-
|
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
|
-
|
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!
|
25
|
-
str.gsub!
|
26
|
-
str.gsub!
|
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!
|
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
|
42
|
+
raise "ERROR: invalid statement: #{line}" if open_brackets.negative?
|
42
43
|
|
43
|
-
if open_brackets
|
44
|
+
if open_brackets.zero?
|
44
45
|
lines << line
|
45
46
|
else
|
46
|
-
lines.last <<
|
47
|
+
lines.last << ' ' << line
|
47
48
|
end
|
48
49
|
|
49
50
|
open_brackets += line.count('[') - line.count(']')
|