junoser 0.5.6 → 0.7.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.
@@ -0,0 +1,24 @@
1
+ module Junoser
2
+ module RuleTree
3
+ class Node
4
+ INDENT = ' '
5
+ attr_reader :name, :children
6
+
7
+ def initialize(name)
8
+ @name = name
9
+ @children = []
10
+ end
11
+
12
+ def <<(child)
13
+ @children << child
14
+ end
15
+
16
+ def print(level = 0)
17
+ puts INDENT * level + "- #{@name}"
18
+ @children.each do |child|
19
+ child.print level + 1
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,66 @@
1
+ module Junoser
2
+ module RuleTree
3
+ class Parser
4
+ def initialize(content)
5
+ @content = content
6
+ @nodes = {}
7
+ @root = nil
8
+ end
9
+
10
+ def print
11
+ parse
12
+ @nodes['configuration'].print 0
13
+ end
14
+
15
+ def parse
16
+ rules = content.scan(/^rule\(:([a-z\d_]+)\) do\n(.*?)^end/m)
17
+ root_index = rules.index { |r| r[0] == 'configuration' }
18
+ primitives = rules.map(&:first)
19
+ .then { |r| r[0, root_index] } + %w[any]
20
+
21
+ validate_uniq rules[root_index..].map(&:first)
22
+
23
+ @nodes = Hash[rules[root_index..].map { |name, _| [name, Node.new(name)] }]
24
+ used = Set.new
25
+
26
+ rules[root_index..].map do |name, refs|
27
+ children = refs.split.map { |i| i.strip.gsub(/,$/, '') }
28
+ .reject { |i| primitives.include?(i) }
29
+ .uniq
30
+ used += children
31
+ children.each do |child|
32
+ raise %(Unknown rule: #{child}) unless @nodes[child]
33
+ @nodes[name] << @nodes[child]
34
+ end
35
+ end
36
+
37
+ validate_used @nodes.keys, used.to_a
38
+ end
39
+
40
+ private
41
+
42
+ def content
43
+ @_content ||= @content
44
+ .gsub(%r| */\*.*\*/|, '')
45
+ .gsub(/\.as\(:oneline\)/, '')
46
+ .gsub(/^(?!rule.*).*["#()].*\n/, '')
47
+ .gsub(/ *arg,?\n/, '')
48
+ end
49
+
50
+ def validate_uniq(rules)
51
+ duplicates = rules.group_by(&:itself).select { |_, v| v.count > 1 }.keys
52
+ return if duplicates.empty?
53
+
54
+ raise %(Duplicated rules:\n - #{duplicates.join("\n - ")}) unless duplicates.empty?
55
+ end
56
+
57
+ def validate_used(all, used)
58
+ unused = all - used - %w[configuration]
59
+ return if unused.empty?
60
+
61
+ $stderr.puts 'Warning: Unused rules:'
62
+ unused.each { |r| $stderr.puts " - #{r}" }
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,2 @@
1
+ require 'junoser/rule_tree/node'
2
+ require 'junoser/rule_tree/parser'
data/lib/junoser/ruler.rb CHANGED
@@ -43,7 +43,29 @@ module Junoser
43
43
  def process_reserved_element(str)
44
44
  str.gsub! /"\$\S+"/, 'arg'
45
45
 
46
- str.gsub! /"groups" \(\s*s\(\s*any\s*\)\s*\)/, 'a("groups", arg, configuration)'
46
+ str.gsub! /"groups" \(\s*s\(\s*any\s*\)\s*\)/, <<-EOS.strip
47
+ b(a("groups", arg),
48
+ c(
49
+ configuration,
50
+ "when" (
51
+ c(
52
+ "chassis" arg,
53
+ "member" arg,
54
+ "model" arg,
55
+ "node" arg,
56
+ "peers" arg,
57
+ "routing-engine" arg,
58
+ "time" (
59
+ c(
60
+ "to" arg,
61
+ arg
62
+ )
63
+ )
64
+ )
65
+ )
66
+ )
67
+ )
68
+ EOS
47
69
 
48
70
  str.gsub! '"equal-literal"', '"="'
49
71
  str.gsub! '"plus-literal"', '"+"'
@@ -224,10 +246,8 @@ module Junoser
224
246
  str.gsub! '"*"', 'arg'
225
247
 
226
248
  # Fix .xsd: "from-zone" arg is also required
227
- str.gsub!(/^(\s*)"policy" \(\s*s\(\s*arg,\s*"to-zone-name" arg,\s*c\(\s*"policy" \(\s*policy_type\s*\)\s*\)/) do
228
- format(['b(s("from-zone", arg, "to-zone", arg),',
229
- ' b("policy", policy_type',
230
- ], $1)
249
+ str.gsub!(/^ "policy" \(\s*s\(\s*arg,\s*"to-zone-name" arg,\s*(.*?)\s*\)\s*^ \),/m) do
250
+ format(['b(', ' s("from-zone", arg, "to-zone", arg),', " #$1", '),'], ' ')
231
251
  end
232
252
 
233
253
  # Fix .xsd: "members" accepts [ foo bar ]
@@ -271,6 +291,11 @@ module Junoser
271
291
  # Fix .xsd: support "set policy-options policy-statement xxx from policy [expression]"
272
292
  str.gsub!(/^rule\(:policy_algebra\) do(\s*)arg\.as\(:arg\)\send/) { "rule(:policy_algebra) do#{$1}any.as(:arg)\nend" }
273
293
 
294
+ # Fix .xsd: support "set interfaces xxx enable"
295
+ str.gsub!(/^(rule\(:interfaces_type\) do\s*[^\n]*\s*c\()(\s*)/m) do
296
+ %[#{$1}#{$2}"enable",#{$2}]
297
+ end
298
+
274
299
  str
275
300
  end
276
301
 
@@ -280,6 +305,8 @@ module Junoser
280
305
  str.empty? ? '' : offset + str
281
306
  when Array
282
307
  str.map { |s| s.empty? ? '' : offset + s.to_s }.join("\n")
308
+ else
309
+ ''
283
310
  end
284
311
  end
285
312
 
@@ -1,3 +1,3 @@
1
1
  module Junoser
2
- VERSION = "0.5.6"
2
+ VERSION = "0.7.0"
3
3
  end
@@ -0,0 +1,17 @@
1
+ module Junoser
2
+ module RuleTree
3
+ class Node
4
+ INDENT: String
5
+ @children: Array[Node]
6
+ @name: String
7
+
8
+ attr_reader children: Array[Node]
9
+ attr_reader name: String
10
+
11
+ def initialize: (String name) -> void
12
+
13
+ def <<: (Node child) -> void
14
+ def print: (Numeric level) -> void
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,21 @@
1
+ module Junoser
2
+ module RuleTree
3
+ class Parser
4
+ @_content: String
5
+ @content: String
6
+ @path: String
7
+ @nodes: Hash[String, Node]
8
+ @root: Node?
9
+
10
+ def initialize: (String content) -> void
11
+
12
+ def parse: -> void
13
+
14
+ private
15
+
16
+ def content: -> String
17
+ def validate_uniq: (Array[String] rules)-> void
18
+ def validate_used: (Array[String], Array[String])-> untyped
19
+ end
20
+ end
21
+ end
@@ -4,17 +4,19 @@
4
4
  module Junoser
5
5
  class Ruler
6
6
  OFFSET: String
7
- @rule: untyped
7
+ @rule: String
8
+
9
+ def initialize: (String input) -> void
8
10
 
9
- def initialize: (untyped input) -> void
10
11
  def to_rule: -> String
11
- def rule: -> untyped
12
+ def rule: -> String
12
13
 
13
14
  private
14
- def remove_comments: (untyped str) -> untyped
15
- def process_line: (untyped str) -> untyped
16
- def process_reserved_element: (untyped str) -> untyped
17
- def format: (Array[String?] | String str, ?String? offset) -> String?
15
+
16
+ def remove_comments: (String str) -> String
17
+ def process_line: (String str) -> String
18
+ def process_reserved_element: (String str) -> String
19
+ def format: (Array[String?] | String str, ?String? offset) -> String
18
20
  def rule_header: -> String
19
21
  def rule_footer: -> String
20
22
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: junoser
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.6
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shintaro Kojima
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-04-30 00:00:00.000000000 Z
11
+ date: 2024-12-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: parslet
@@ -89,6 +89,7 @@ executables:
89
89
  extensions: []
90
90
  extra_rdoc_files: []
91
91
  files:
92
+ - ".github/dependabot.yml"
92
93
  - ".github/workflows/test-linux.yaml"
93
94
  - ".gitignore"
94
95
  - ".pre-commit-config.yaml"
@@ -115,6 +116,9 @@ files:
115
116
  - lib/junoser/input.rb
116
117
  - lib/junoser/js_ruler.rb
117
118
  - lib/junoser/parser.rb
119
+ - lib/junoser/rule_tree.rb
120
+ - lib/junoser/rule_tree/node.rb
121
+ - lib/junoser/rule_tree/parser.rb
118
122
  - lib/junoser/ruler.rb
119
123
  - lib/junoser/squash.rb
120
124
  - lib/junoser/transformer.rb
@@ -131,6 +135,8 @@ files:
131
135
  - lib/junoser/xsd/simple_type.rb
132
136
  - lib/junoser/xsd/union.rb
133
137
  - lib/underscorable.rb
138
+ - sig/junoser/rule_tree/node.rbs
139
+ - sig/junoser/rule_tree/parser.rbs
134
140
  - sig/junoser/ruler.rbs
135
141
  homepage: https://github.com/codeout/junoser
136
142
  licenses: []
@@ -150,7 +156,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
150
156
  - !ruby/object:Gem::Version
151
157
  version: '0'
152
158
  requirements: []
153
- rubygems_version: 3.4.1
159
+ rubygems_version: 3.5.16
154
160
  signing_key:
155
161
  specification_version: 4
156
162
  summary: PEG parser for JUNOS configuration.