lutaml 0.10.13 → 0.10.14

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 (25) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +58 -18
  3. data/lib/lutaml/cli/interactive_shell/export_handler.rb +9 -7
  4. data/lib/lutaml/cli/interactive_shell/help_display.rb +39 -45
  5. data/lib/lutaml/cli/interactive_shell/navigation_commands.rb +36 -21
  6. data/lib/lutaml/cli/interactive_shell/query_commands.rb +63 -47
  7. data/lib/lutaml/cli/interactive_shell.rb +43 -25
  8. data/lib/lutaml/qea/factory/association_builder.rb +114 -125
  9. data/lib/lutaml/qea/factory/class_transformer.rb +67 -43
  10. data/lib/lutaml/qea/factory/enum_transformer.rb +22 -23
  11. data/lib/lutaml/qea/factory/generalization_builder.rb +146 -116
  12. data/lib/lutaml/qea/factory/stereotype_loader.rb +13 -7
  13. data/lib/lutaml/qea/lookup_indexes.rb +8 -1
  14. data/lib/lutaml/uml_repository/exporters/markdown/class_page_builder.rb +33 -25
  15. data/lib/lutaml/uml_repository/index_builders/association_index.rb +49 -47
  16. data/lib/lutaml/uml_repository/index_builders/class_index.rb +30 -23
  17. data/lib/lutaml/uml_repository/queries/class_query.rb +74 -48
  18. data/lib/lutaml/uml_repository/queries/inheritance_query.rb +42 -32
  19. data/lib/lutaml/uml_repository/static_site/data_transformer.rb +55 -35
  20. data/lib/lutaml/uml_repository/static_site/search_index_builder.rb +32 -19
  21. data/lib/lutaml/uml_repository/static_site/serializers/class_serializer.rb +27 -17
  22. data/lib/lutaml/uml_repository/static_site/serializers/inheritance_resolver.rb +92 -68
  23. data/lib/lutaml/uml_repository/static_site/serializers/package_tree_builder.rb +32 -23
  24. data/lib/lutaml/version.rb +1 -1
  25. metadata +1 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 66f287c7903f45ebce9fc0abdc3561ad6ef3df65fdb4b437a126685610756df7
4
- data.tar.gz: 8459a2ad63cf3e4071c7d56ec4ae105410d3044aad2f05810419d4dd90adf861
3
+ metadata.gz: 69670b20b9f7eeb39ebc7fc3fa638b7f2934d077e18319af972881c3ef0522b5
4
+ data.tar.gz: b77ad5274ea62236961489bfef7751d7f4ca98ddcc8e4daa5cff30469d00abd8
5
5
  SHA512:
6
- metadata.gz: d395f7c78511a601edef5eab6e96f5f896e46a135675767dfd031df36caaa6cfb34a3e5c834d96feed728760a59bd1fe2321ff2ce25490274d9d2693345eb2aa
7
- data.tar.gz: e0ab7f240736d995f948283a9668f578133a39443d95d1889178c7e8c97afb7872d581bc0d8b2d0b79db9c3587087448c82048bb2bce00ee28179b011c422597
6
+ metadata.gz: d75318da9968bee531f257272a490b574c7541a264ce54283f35bea1cd4cc24314d9766ab8da589a326ea06edb7ac953b43c4c2db3579cc55dee46f0bee22f25
7
+ data.tar.gz: 9ab593c061dfb0983ded7744859ddf3e7214dc8e64f5808dae4f54f779bab4a772b6c5af65eb5c69d1df887b2ae52837d69e872790656e9aa444cd0f91eb77e0
data/.rubocop_todo.yml CHANGED
@@ -1,32 +1,40 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2026-05-12 08:24:03 UTC using RuboCop version 1.86.1.
3
+ # on 2026-05-12 14:40:16 UTC using RuboCop version 1.86.1.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
7
7
  # versions of RuboCop, may require this file to be generated again.
8
8
 
9
- # Offense count: 1
9
+ # Offense count: 6
10
10
  # This cop supports safe autocorrection (--autocorrect).
11
11
  # Configuration parameters: EnforcedStyle, IndentationWidth.
12
12
  # SupportedStyles: with_first_argument, with_fixed_indentation
13
13
  Layout/ArgumentAlignment:
14
14
  Exclude:
15
- - 'spec/lutaml/xml/parsers/xsd_spec.rb'
15
+ - 'lib/lutaml/qea/factory/association_builder.rb'
16
+ - 'lib/lutaml/qea/factory/generalization_builder.rb'
17
+ - 'lib/lutaml/uml_repository/index_builders/class_index.rb'
18
+ - 'lib/lutaml/uml_repository/static_site/serializers/class_serializer.rb'
19
+ - 'lib/lutaml/uml_repository/static_site/serializers/inheritance_resolver.rb'
16
20
 
17
- # Offense count: 156
21
+ # Offense count: 158
18
22
  # This cop supports safe autocorrection (--autocorrect).
19
23
  # Configuration parameters: Max, AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, AllowRBSInlineAnnotation, AllowCopDirectives, AllowedPatterns, SplitStrings.
20
24
  # URISchemes: http, https
21
25
  Layout/LineLength:
22
26
  Enabled: false
23
27
 
24
- # Offense count: 1
28
+ # Offense count: 7
25
29
  # This cop supports safe autocorrection (--autocorrect).
26
30
  # Configuration parameters: AllowInHeredoc.
27
31
  Layout/TrailingWhitespace:
28
32
  Exclude:
29
- - 'spec/lutaml/xml/parsers/xsd_spec.rb'
33
+ - 'lib/lutaml/qea/factory/generalization_builder.rb'
34
+ - 'lib/lutaml/uml_repository/index_builders/class_index.rb'
35
+ - 'lib/lutaml/uml_repository/queries/inheritance_query.rb'
36
+ - 'lib/lutaml/uml_repository/static_site/serializers/class_serializer.rb'
37
+ - 'lib/lutaml/uml_repository/static_site/serializers/inheritance_resolver.rb'
30
38
 
31
39
  # Offense count: 1
32
40
  Lint/BinaryOperatorWithIdenticalOperands:
@@ -92,31 +100,41 @@ Lint/UselessConstantScoping:
92
100
  Exclude:
93
101
  - 'lib/lutaml/cli/interactive_shell.rb'
94
102
 
95
- # Offense count: 51
103
+ # Offense count: 33
96
104
  # Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes, Max.
97
105
  Metrics/AbcSize:
98
106
  Enabled: false
99
107
 
100
- # Offense count: 4
101
- # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns, inherit_mode.
102
- # AllowedMethods: refine
103
- Metrics/BlockLength:
104
- Max: 53
105
-
106
- # Offense count: 35
108
+ # Offense count: 23
107
109
  # Configuration parameters: AllowedMethods, AllowedPatterns, Max.
108
110
  Metrics/CyclomaticComplexity:
109
111
  Enabled: false
110
112
 
111
- # Offense count: 75
113
+ # Offense count: 63
112
114
  # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
113
115
  Metrics/MethodLength:
114
- Max: 62
116
+ Max: 21
117
+
118
+ # Offense count: 2
119
+ # Configuration parameters: CountKeywordArgs, MaxOptionalParameters.
120
+ Metrics/ParameterLists:
121
+ Max: 7
115
122
 
116
- # Offense count: 26
123
+ # Offense count: 12
117
124
  # Configuration parameters: AllowedMethods, AllowedPatterns, Max.
118
125
  Metrics/PerceivedComplexity:
119
- Enabled: false
126
+ Exclude:
127
+ - 'lib/lutaml/cli/interactive_shell/navigation_commands.rb'
128
+ - 'lib/lutaml/converter/xmi_to_uml.rb'
129
+ - 'lib/lutaml/qea/factory/association_builder.rb'
130
+ - 'lib/lutaml/qea/factory/ea_to_uml_factory.rb'
131
+ - 'lib/lutaml/qea/lookup_indexes.rb'
132
+ - 'lib/lutaml/uml_repository/index_builders/association_index.rb'
133
+ - 'lib/lutaml/uml_repository/repository/loader.rb'
134
+ - 'lib/lutaml/uml_repository/static_site/data_transformer.rb'
135
+ - 'lib/lutaml/uml_repository/static_site/serializers/class_serializer.rb'
136
+ - 'lib/lutaml/uml_repository/static_site/serializers/inheritance_resolver.rb'
137
+ - 'lib/lutaml/xmi/parsers/xmi_connector.rb'
120
138
 
121
139
  # Offense count: 3
122
140
  # Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames.
@@ -309,6 +327,12 @@ Style/EvalWithLocation:
309
327
  Exclude:
310
328
  - 'spec/lutaml/cli/uml/search_command_spec.rb'
311
329
 
330
+ # Offense count: 2
331
+ # This cop supports safe autocorrection (--autocorrect).
332
+ Style/MultilineIfModifier:
333
+ Exclude:
334
+ - 'lib/lutaml/uml_repository/index_builders/class_index.rb'
335
+
312
336
  # Offense count: 1
313
337
  # This cop supports unsafe autocorrection (--autocorrect-all).
314
338
  Style/PartitionInsteadOfDoubleSelect:
@@ -321,3 +345,19 @@ Style/SafeNavigationChainLength:
321
345
  Exclude:
322
346
  - 'lib/lutaml/qea/validation/attribute_validator.rb'
323
347
  - 'lib/lutaml/qea/validation/operation_validator.rb'
348
+
349
+ # Offense count: 8
350
+ # This cop supports safe autocorrection (--autocorrect).
351
+ # Configuration parameters: EnforcedStyle.
352
+ # SupportedStyles: single_quotes, double_quotes
353
+ Style/StringLiteralsInInterpolation:
354
+ Exclude:
355
+ - 'lib/lutaml/cli/interactive_shell/help_display.rb'
356
+
357
+ # Offense count: 1
358
+ # This cop supports safe autocorrection (--autocorrect).
359
+ # Configuration parameters: EnforcedStyle, AllowSafeAssignment.
360
+ # SupportedStyles: require_parentheses, require_no_parentheses, require_parentheses_when_complex
361
+ Style/TernaryParentheses:
362
+ Exclude:
363
+ - 'lib/lutaml/qea/factory/association_builder.rb'
@@ -6,6 +6,12 @@ module Lutaml
6
6
  module Cli
7
7
  class InteractiveShell
8
8
  class ExportHandler < CommandBase
9
+ EXPORT_FORMATS = {
10
+ "csv" => :export_csv,
11
+ "json" => :export_json,
12
+ "yaml" => :export_yaml,
13
+ }.freeze
14
+
9
15
  def cmd_export(args)
10
16
  if last_results.nil? || last_results.empty?
11
17
  puts OutputFormatter.warning("No results to export")
@@ -20,13 +26,9 @@ module Lutaml
20
26
  format = args[1].downcase
21
27
  file_path = args[2]
22
28
 
23
- case format
24
- when "csv"
25
- export_csv(file_path)
26
- when "json"
27
- export_json(file_path)
28
- when "yaml"
29
- export_yaml(file_path)
29
+ exporter = EXPORT_FORMATS[format]
30
+ if exporter
31
+ public_send(exporter, file_path)
30
32
  else
31
33
  puts OutputFormatter.error("Unsupported format: #{format}")
32
34
  end
@@ -8,18 +8,14 @@ module Lutaml
8
8
  class InteractiveShell
9
9
  class HelpDisplay < CommandBase
10
10
  def display_welcome
11
- puts OutputFormatter.colorize(
12
- "╔═══════════════════════════════════════╗", :cyan
13
- )
14
- puts OutputFormatter.colorize(
15
- "║ LutaML Interactive Shell (REPL) ║", :cyan
16
- )
17
- puts OutputFormatter.colorize(
18
- "╚═══════════════════════════════════════╝", :cyan
19
- )
20
- puts ""
21
- puts "Type 'help' for available commands, 'exit' to quit"
22
- puts ""
11
+ puts <<~WELCOME
12
+ #{OutputFormatter.colorize('╔═══════════════════════════════════════╗', :cyan)}
13
+ #{OutputFormatter.colorize('║ LutaML Interactive Shell (REPL) ║', :cyan)}
14
+ #{OutputFormatter.colorize('╚═══════════════════════════════════════╝', :cyan)}
15
+
16
+ Type 'help' for available commands, 'exit' to quit
17
+
18
+ WELCOME
23
19
 
24
20
  stats = repository.statistics
25
21
  puts "Repository loaded:"
@@ -65,43 +61,41 @@ module Lutaml
65
61
  end
66
62
 
67
63
  def display_general_help
68
- puts OutputFormatter.colorize("Available Commands:", :cyan)
69
- puts ""
64
+ puts <<~HELP
65
+ #{OutputFormatter.colorize('Available Commands:', :cyan)}
70
66
 
71
- puts OutputFormatter.colorize("Navigation:", :yellow)
72
- puts " cd PATH Change to package path"
73
- puts " pwd Print current path"
74
- puts " ls [PATH] List packages"
75
- puts " tree [PATH] Show package tree"
76
- puts " up Go to parent package"
77
- puts " root Go to ModelRoot"
78
- puts " back Go to previous location"
79
- puts ""
67
+ #{OutputFormatter.colorize('Navigation:', :yellow)}
68
+ cd PATH Change to package path
69
+ pwd Print current path
70
+ ls [PATH] List packages
71
+ tree [PATH] Show package tree
72
+ up Go to parent package
73
+ root Go to ModelRoot
74
+ back Go to previous location
80
75
 
81
- puts OutputFormatter.colorize("Query:", :yellow)
82
- puts " find CLASS Find class (fuzzy search)"
83
- puts " show class QNAME Show class details"
84
- puts " show package PATH Show package details"
85
- puts " show NUMBER Show numbered result"
86
- puts " search QUERY Full-text search"
87
- puts " ? QUERY Alias for search"
88
- puts ""
76
+ #{OutputFormatter.colorize('Query:', :yellow)}
77
+ find CLASS Find class (fuzzy search)
78
+ show class QNAME Show class details
79
+ show package PATH Show package details
80
+ show NUMBER Show numbered result
81
+ search QUERY Full-text search
82
+ ? QUERY Alias for search
89
83
 
90
- puts OutputFormatter.colorize("Bookmarks:", :yellow)
91
- puts " bookmark add NAME Bookmark current location"
92
- puts " bookmark list List bookmarks"
93
- puts " bookmark go NAME Jump to bookmark"
94
- puts " bookmark rm NAME Remove bookmark"
95
- puts " bm NAME Quick jump"
96
- puts ""
84
+ #{OutputFormatter.colorize('Bookmarks:', :yellow)}
85
+ bookmark add NAME Bookmark current location
86
+ bookmark list List bookmarks
87
+ bookmark go NAME Jump to bookmark
88
+ bookmark rm NAME Remove bookmark
89
+ bm NAME Quick jump
97
90
 
98
- puts OutputFormatter.colorize("Utilities:", :yellow)
99
- puts " help [COMMAND] Show help"
100
- puts " history Show command history"
101
- puts " clear Clear screen"
102
- puts " config Show configuration"
103
- puts " stats Show statistics"
104
- puts " exit, quit, q Exit shell"
91
+ #{OutputFormatter.colorize('Utilities:', :yellow)}
92
+ help [COMMAND] Show help
93
+ history Show command history
94
+ clear Clear screen
95
+ config Show configuration
96
+ stats Show statistics
97
+ exit, quit, q Exit shell
98
+ HELP
105
99
  end
106
100
 
107
101
  def display_command_help(command)
@@ -38,22 +38,13 @@ module Lutaml
38
38
  if packages.empty?
39
39
  puts OutputFormatter.warning("No packages found at #{path}")
40
40
  else
41
- packages.each do |pkg|
42
- icon = config[:icons] ? "#{EnhancedFormatter::ICONS[:package]} " : ""
43
- puts "#{icon}#{pkg.name}"
44
- end
45
- puts ""
46
- puts "Total: #{packages.size} package(s)"
41
+ display_packages(packages)
47
42
  end
48
43
  end
49
44
 
50
45
  def cmd_tree(args)
51
46
  path = args.empty? ? current_path : resolve_path(args[0])
52
-
53
- max_depth = nil
54
- args.each_with_index do |arg, i|
55
- max_depth = args[i + 1].to_i if arg == "-d" && args[i + 1]
56
- end
47
+ max_depth = extract_depth(args)
57
48
 
58
49
  tree_data = repository.package_tree(path, max_depth: max_depth)
59
50
 
@@ -62,11 +53,7 @@ module Lutaml
62
53
  return
63
54
  end
64
55
 
65
- if config[:icons]
66
- puts EnhancedFormatter.format_tree_with_icons(tree_data, config)
67
- else
68
- puts OutputFormatter.format_tree(tree_data)
69
- end
56
+ puts format_tree(tree_data)
70
57
  end
71
58
 
72
59
  def cmd_up(_args)
@@ -110,11 +97,7 @@ module Lutaml
110
97
  return "ModelRoot" if path == "/"
111
98
 
112
99
  if path.start_with?("../")
113
- parts = current_path.split("::")
114
- path.scan("../").each { parts.pop }
115
- remaining = path.gsub(/^(\.\.\/)+/, "")
116
- new_path = parts + remaining.split("/")
117
- new_path.join("::")
100
+ resolve_parent_path(path)
118
101
  elsif path.start_with?("./")
119
102
  "#{current_path}::#{path[2..]}"
120
103
  else
@@ -124,6 +107,38 @@ module Lutaml
124
107
 
125
108
  private
126
109
 
110
+ def display_packages(packages)
111
+ packages.each do |pkg|
112
+ icon = config[:icons] ? "#{EnhancedFormatter::ICONS[:package]} " : ""
113
+ puts "#{icon}#{pkg.name}"
114
+ end
115
+ puts ""
116
+ puts "Total: #{packages.size} package(s)"
117
+ end
118
+
119
+ def extract_depth(args)
120
+ args.each_with_index do |arg, i|
121
+ return args[i + 1].to_i if arg == "-d" && args[i + 1]
122
+ end
123
+ nil
124
+ end
125
+
126
+ def format_tree(tree_data)
127
+ if config[:icons]
128
+ EnhancedFormatter.format_tree_with_icons(tree_data, config)
129
+ else
130
+ OutputFormatter.format_tree(tree_data)
131
+ end
132
+ end
133
+
134
+ def resolve_parent_path(path)
135
+ parts = current_path.split("::")
136
+ path.scan("../").each { parts.pop }
137
+ remaining = path.gsub(/^(\.\.\/)+/, "")
138
+ new_path = parts + remaining.split("/")
139
+ new_path.join("::")
140
+ end
141
+
127
142
  def push_path_history
128
143
  return if path_history.last == current_path
129
144
 
@@ -19,16 +19,10 @@ module Lutaml
19
19
  if results[:class].empty?
20
20
  puts OutputFormatter.warning("No classes found matching '#{query}'")
21
21
  else
22
- self.last_results = results[:class]
23
-
24
22
  puts OutputFormatter.colorize(
25
- "Found #{last_results.size} class(es):", :cyan
23
+ "Found #{results[:class].size} class(es):", :cyan
26
24
  )
27
- last_results.each_with_index do |qname, i|
28
- puts " #{i + 1}. #{qname}"
29
- end
30
- puts ""
31
- puts "Use 'show NUMBER' to view details"
25
+ display_class_results(results[:class])
32
26
  end
33
27
  end
34
28
 
@@ -94,18 +88,7 @@ module Lutaml
94
88
  if config[:icons]
95
89
  puts EnhancedFormatter.format_class_details_enhanced(cls)
96
90
  else
97
- puts OutputFormatter.colorize("Class: #{qname}", :cyan)
98
- puts "=" * 50
99
- puts ""
100
- puts "Name: #{cls.name}"
101
-
102
- if cls.is_a?(Lutaml::Uml::Classifier) && cls.attributes && !cls.attributes.empty?
103
- puts ""
104
- puts OutputFormatter.colorize("Attributes:", :yellow)
105
- cls.attributes.each do |attr|
106
- puts " - #{attr.name}: #{attr.type}"
107
- end
108
- end
91
+ display_class_plain(cls, qname)
109
92
  end
110
93
  end
111
94
 
@@ -119,18 +102,7 @@ module Lutaml
119
102
  return
120
103
  end
121
104
 
122
- puts OutputFormatter.colorize("Package: #{path}", :cyan)
123
- puts "=" * 50
124
- puts ""
125
- puts "Name: #{pkg.name}"
126
- puts ""
127
-
128
- classes = repository.classes_in_package(path)
129
- puts OutputFormatter.colorize("Classes (#{classes.size}):", :yellow)
130
- classes.each do |cls|
131
- icon = config[:icons] ? "#{EnhancedFormatter::ICONS[:class]} " : ""
132
- puts " #{icon}#{cls.name}"
133
- end
105
+ display_package_contents(pkg, path)
134
106
  end
135
107
 
136
108
  def show_numbered_result(number)
@@ -159,26 +131,70 @@ module Lutaml
159
131
 
160
132
  case type
161
133
  when :class
162
- self.last_results = items
163
- items.each_with_index do |qname, i|
164
- icon = config[:icons] ? "#{EnhancedFormatter::ICONS[:class]} " : ""
165
- puts " #{i + 1}. #{icon}#{qname}"
166
- end
167
- puts ""
168
- puts "Use 'show NUMBER' to view details"
134
+ display_class_results(items)
169
135
  when :attribute
170
- items.each do |item|
171
- puts " - #{item[:class_name]}::#{item[:attribute_name]} : " \
172
- "#{item[:type]}"
173
- end
136
+ display_attribute_results(items)
174
137
  when :association
175
- items.each do |item|
176
- icon = config[:icons] ? "#{EnhancedFormatter::ICONS[:association]} " : ""
177
- puts " #{icon}#{item[:source]} → #{item[:target]}"
178
- end
138
+ display_association_results(items)
179
139
  end
180
140
  end
181
141
  end
142
+
143
+ private
144
+
145
+ def display_class_results(items)
146
+ self.last_results = items
147
+ items.each_with_index do |qname, i|
148
+ icon = config[:icons] ? "#{EnhancedFormatter::ICONS[:class]} " : ""
149
+ puts " #{i + 1}. #{icon}#{qname}"
150
+ end
151
+ puts ""
152
+ puts "Use 'show NUMBER' to view details"
153
+ end
154
+
155
+ def display_attribute_results(items)
156
+ items.each do |item|
157
+ puts " - #{item[:class_name]}::#{item[:attribute_name]} : " \
158
+ "#{item[:type]}"
159
+ end
160
+ end
161
+
162
+ def display_association_results(items)
163
+ items.each do |item|
164
+ icon = config[:icons] ? "#{EnhancedFormatter::ICONS[:association]} " : ""
165
+ puts " #{icon}#{item[:source]} → #{item[:target]}"
166
+ end
167
+ end
168
+
169
+ def display_class_plain(cls, qname)
170
+ puts OutputFormatter.colorize("Class: #{qname}", :cyan)
171
+ puts "=" * 50
172
+ puts ""
173
+ puts "Name: #{cls.name}"
174
+
175
+ return unless cls.is_a?(Lutaml::Uml::Classifier) && cls.attributes && !cls.attributes.empty?
176
+
177
+ puts ""
178
+ puts OutputFormatter.colorize("Attributes:", :yellow)
179
+ cls.attributes.each do |attr|
180
+ puts " - #{attr.name}: #{attr.type}"
181
+ end
182
+ end
183
+
184
+ def display_package_contents(pkg, path)
185
+ puts OutputFormatter.colorize("Package: #{path}", :cyan)
186
+ puts "=" * 50
187
+ puts ""
188
+ puts "Name: #{pkg.name}"
189
+ puts ""
190
+
191
+ classes = repository.classes_in_package(path)
192
+ puts OutputFormatter.colorize("Classes (#{classes.size}):", :yellow)
193
+ classes.each do |cls|
194
+ icon = config[:icons] ? "#{EnhancedFormatter::ICONS[:class]} " : ""
195
+ puts " #{icon}#{cls.name}"
196
+ end
197
+ end
182
198
  end
183
199
  end
184
200
  end
@@ -24,51 +24,68 @@ module Lutaml
24
24
  attr_accessor :current_path, :last_results
25
25
 
26
26
  def initialize(lur_path_or_repo, config: nil)
27
- @config = {
27
+ @config = default_config.merge(config || {})
28
+ @repository = load_repository(lur_path_or_repo)
29
+
30
+ @current_path = "ModelRoot"
31
+ @bookmarks = {}
32
+ @last_results = nil
33
+ @path_history = ["ModelRoot"]
34
+ @running = false
35
+
36
+ init_commands
37
+ setup_readline
38
+ load_history
39
+ end
40
+
41
+ def start
42
+ @running = true
43
+ @help.display_welcome
44
+
45
+ run_repl_loop
46
+
47
+ save_history
48
+ puts "\nGoodbye!"
49
+ end
50
+
51
+ private
52
+
53
+ def default_config
54
+ {
28
55
  color: true,
29
56
  icons: true,
30
57
  show_counts: true,
31
58
  page_size: 50,
32
- }.merge(config || {})
59
+ }
60
+ end
33
61
 
62
+ def load_repository(lur_path_or_repo)
34
63
  if lur_path_or_repo.is_a?(String)
35
64
  OutputFormatter.progress("Loading repository")
36
- @repository = Lutaml::UmlRepository::Repository.from_package(lur_path_or_repo)
65
+ repo = Lutaml::UmlRepository::Repository.from_package(lur_path_or_repo)
37
66
  OutputFormatter.progress_done
67
+ repo
38
68
  else
39
- @repository = lur_path_or_repo
69
+ lur_path_or_repo
40
70
  end
71
+ end
41
72
 
42
- @current_path = "ModelRoot"
43
- @bookmarks = {}
44
- @last_results = nil
45
- @path_history = ["ModelRoot"]
46
- @running = false
47
-
73
+ def init_commands
48
74
  @navigation = NavigationCommands.new(self)
49
75
  @query = QueryCommands.new(self)
50
76
  @bookmarks_cmd = BookmarkCommands.new(self)
51
77
  @export = ExportHandler.new(self)
52
78
  @help = HelpDisplay.new(self)
53
-
54
- setup_readline
55
- load_history
56
79
  end
57
80
 
58
- def start
59
- @running = true
60
- @help.display_welcome
61
-
81
+ def run_repl_loop
62
82
  while @running
63
83
  begin
64
84
  input = Readline.readline(prompt, true)
65
85
  break if input.nil?
66
86
  next if input.strip.empty?
67
87
 
68
- if Readline::HISTORY.length > 1 && Readline::HISTORY[-2] == input
69
- Readline::HISTORY.pop
70
- end
71
-
88
+ deduplicate_history(input)
72
89
  execute_command(input.strip)
73
90
  rescue Interrupt
74
91
  puts "\nUse 'exit' or 'quit' to exit the shell"
@@ -77,12 +94,13 @@ module Lutaml
77
94
  puts e.backtrace.first(3).join("\n") if ENV["DEBUG"]
78
95
  end
79
96
  end
80
-
81
- save_history
82
- puts "\nGoodbye!"
83
97
  end
84
98
 
85
- private
99
+ def deduplicate_history(input)
100
+ if Readline::HISTORY.length > 1 && Readline::HISTORY[-2] == input
101
+ Readline::HISTORY.pop
102
+ end
103
+ end
86
104
 
87
105
  COMMAND_DISPATCH = {
88
106
  # Navigation