lutaml-uml 0.2.8 → 0.2.9
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/.github/workflows/ubuntu.yml +1 -1
- data/README.adoc +9 -10
- data/bin/plantuml2lutaml +1 -0
- data/exe/lutaml-wsd2uml +59 -0
- data/exe/lutaml-yaml2uml +144 -0
- data/lib/lutaml/uml.rb +4 -2
- data/lib/lutaml/uml/parsers/dsl.rb +2 -1
- data/lib/lutaml/uml/version.rb +1 -1
- data/lutaml-uml.gemspec +1 -1
- data/spec/fixtures/dsl/diagram_data_types.lutaml +1 -1
- metadata +7 -7
- data/exe/lutaml-uml +0 -21
- data/lib/lutaml/uml/interface/base.rb +0 -28
- data/lib/lutaml/uml/interface/command_line.rb +0 -265
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7e25b300c9a636999a7861a78ea5c677d1c0c6767180a81f8b63cc6f9af2f8aa
|
4
|
+
data.tar.gz: b78902b23e27ec296913e2943c5fb966d17268f6c28e2b1c50409450e0310ed8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 287de7e6b28b6ff2c1dffab0db3a4503257c3b75c00409cd56184629875f3196e9a91dee7acb21a8cf1d1e484a59a9d5188836d33002599d8a4407da4a51f68c
|
7
|
+
data.tar.gz: 14f5782e4d85885c3fca50f486cf8107648fac50e50acdeb2d931dc6a68c4e0e8fe1c9b9927dfd4449a02186ea36a969d1591fd55712334dca72cb49d7fba103
|
data/README.adoc
CHANGED
@@ -8,20 +8,19 @@ Lutaml is a language for specifying UML class diagrams and a tool for converting
|
|
8
8
|
|
9
9
|
### RubyGems: `gem install lutaml-uml`
|
10
10
|
|
11
|
-
##
|
11
|
+
## Language
|
12
12
|
|
13
|
-
[
|
14
|
-
--
|
15
|
-
# Convert example.lutaml to example.png
|
16
|
-
$ lutaml-uml --type png --output . example.lutaml
|
13
|
+
See link:LUTAML.adoc[LUTAML.adoc]
|
17
14
|
|
18
|
-
|
19
|
-
$ lutaml-uml --help
|
20
|
-
--
|
15
|
+
## Usage
|
21
16
|
|
22
|
-
|
17
|
+
Converter executables are available:
|
18
|
+
|
19
|
+
* PlantUML WSD to LutaML UML: `lutaml-wsd2uml`
|
20
|
+
* LutaML YAML to LutaML UML: `lutaml-yaml2uml`
|
21
|
+
|
22
|
+
EXAMPLE: `lutaml-wsd2uml mn/metanorma-model-standoc/models/StandardDoc_Blocks_New.wsd`
|
23
23
|
|
24
|
-
See link:LUTAML.adoc[LUTAML.adoc]
|
25
24
|
|
26
25
|
## Development
|
27
26
|
|
data/bin/plantuml2lutaml
CHANGED
@@ -27,6 +27,7 @@ ASSOCIATION_MAPPINGS = {
|
|
27
27
|
in_comment_block = false
|
28
28
|
|
29
29
|
def transform_line(line)
|
30
|
+
line = line.gsub(/^\s*'/, '** ').gsub(/\|[\sa-zA-Z]+$/, '')
|
30
31
|
return sync_puts(line, 2) if ASSOCIATION_MAPPINGS.keys.none? { |key| line =~ key }
|
31
32
|
|
32
33
|
owner_type, member_type = ASSOCIATION_MAPPINGS.detect { |(key, _value)| line =~ key }.last.split(",")
|
data/exe/lutaml-wsd2uml
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
#
|
5
|
+
# Script to convert plantuml files into LutaML syntax
|
6
|
+
# Usage: bin/plantuml2lutaml /path/to/plantuml.wsd
|
7
|
+
|
8
|
+
file_path = ARGV[0]
|
9
|
+
FILE_NAME = File.basename(file_path, ".wsd")
|
10
|
+
wsd_file = File.new(ARGV[0])
|
11
|
+
|
12
|
+
def sync_puts(line, level = 0)
|
13
|
+
$stdout.puts("#{''.rjust(level)}#{line}")
|
14
|
+
$stdout.flush
|
15
|
+
end
|
16
|
+
|
17
|
+
SKIPPED_LINES_REGEXP = /^(@startuml|'\*{7}|note|@enduml|\!|'\/)/
|
18
|
+
COMMENT_START = /\/'/
|
19
|
+
COMMENT_END = /'\//
|
20
|
+
ASSOCIATION_MAPPINGS = {
|
21
|
+
/-\|>/ => ",inheritance",
|
22
|
+
/<\|-/ => "inheritance,",
|
23
|
+
/->/ => ",direct",
|
24
|
+
/<-/ => "direct,",
|
25
|
+
}.freeze
|
26
|
+
|
27
|
+
in_comment_block = false
|
28
|
+
|
29
|
+
def transform_line(line)
|
30
|
+
line = line.gsub(/^\s*'/, '** ').gsub(/\|[\sa-zA-Z]+$/, '')
|
31
|
+
return sync_puts(line, 2) if ASSOCIATION_MAPPINGS.keys.none? { |key| line =~ key }
|
32
|
+
|
33
|
+
owner_type, member_type = ASSOCIATION_MAPPINGS.detect { |(key, _value)| line =~ key }.last.split(",")
|
34
|
+
blocks = line.split(" ")
|
35
|
+
owner = blocks.first
|
36
|
+
member = blocks.last
|
37
|
+
sync_puts("association {", 2)
|
38
|
+
sync_puts("owner #{owner}", 4)
|
39
|
+
sync_puts("member #{member}", 4)
|
40
|
+
sync_puts("owner_type #{owner_type}", 4) if !owner_type.to_s.empty?
|
41
|
+
sync_puts("member_type #{member_type}", 4) if !member_type.to_s.empty?
|
42
|
+
sync_puts("}", 2)
|
43
|
+
end
|
44
|
+
|
45
|
+
sync_puts("diagram #{FILE_NAME} {")
|
46
|
+
wsd_file.readlines.each do |line|
|
47
|
+
if line.match?(COMMENT_START)
|
48
|
+
in_comment_block = true
|
49
|
+
end
|
50
|
+
|
51
|
+
if line.match?(COMMENT_END)
|
52
|
+
in_comment_block = false
|
53
|
+
end
|
54
|
+
|
55
|
+
next if in_comment_block || line =~ SKIPPED_LINES_REGEXP
|
56
|
+
|
57
|
+
transform_line(line)
|
58
|
+
end
|
59
|
+
sync_puts("}")
|
data/exe/lutaml-yaml2uml
ADDED
@@ -0,0 +1,144 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
#
|
5
|
+
# Script to convert datamodel yaml files into LutaML syntax
|
6
|
+
# Usage: bin/yaml2lutaml /path/to/datamodel/view/file.yml
|
7
|
+
|
8
|
+
require "yaml"
|
9
|
+
|
10
|
+
view_yaml = YAML.safe_load(File.read(ARGV[0]))
|
11
|
+
models_path = File.expand_path("../../models", ARGV[0])
|
12
|
+
|
13
|
+
def sync_puts(line, level = 0)
|
14
|
+
$stdout.puts("#{''.rjust(level)}#{line}")
|
15
|
+
$stdout.flush
|
16
|
+
end
|
17
|
+
|
18
|
+
encountered_relations = Hash.new { |h, key| h[key] = [] }
|
19
|
+
# relations:
|
20
|
+
# - target: AttributeProfile
|
21
|
+
# relationship:
|
22
|
+
# source:
|
23
|
+
# type: aggregation
|
24
|
+
# attribute:
|
25
|
+
# addressClassProfile:
|
26
|
+
# target:
|
27
|
+
# type: direct
|
28
|
+
# attribute:
|
29
|
+
# attributeProfile:
|
30
|
+
# cardinality:
|
31
|
+
# min: 0
|
32
|
+
# max: '*'
|
33
|
+
def process_association(owner, values, encountered_relations)
|
34
|
+
target_name = values["target"]
|
35
|
+
return if encountered_relations[owner].include?(target_name)
|
36
|
+
|
37
|
+
encountered_relations[owner].push(target_name)
|
38
|
+
sync_puts("association {", 2)
|
39
|
+
|
40
|
+
relationship_block = values["relationship"] || {}
|
41
|
+
|
42
|
+
if relationship_block["source"] && relationship_block["source"]["type"]
|
43
|
+
source = relationship_block["source"]
|
44
|
+
sync_puts("owner_type #{source['type']}", 4)
|
45
|
+
if source["attribute"]
|
46
|
+
source_attribute_name = source["attribute"].keys.first
|
47
|
+
owner += "##{source_attribute_name}"
|
48
|
+
if source["attribute"][source_attribute_name] && source["attribute"][source_attribute_name]["cardinality"]
|
49
|
+
cardinality = source["attribute"][source_attribute_name]["cardinality"]
|
50
|
+
owner += " [#{cardinality['min']}..#{cardinality['max']}]"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
sync_puts("owner #{owner}", 4)
|
55
|
+
|
56
|
+
member = target_name
|
57
|
+
if relationship_block["target"]
|
58
|
+
target = relationship_block["target"]
|
59
|
+
type = target["type"] || "direct"
|
60
|
+
sync_puts("member_type #{type}", 4)
|
61
|
+
if target["attribute"]
|
62
|
+
target_attribute_name = target["attribute"].keys.first
|
63
|
+
member += "##{target_attribute_name}"
|
64
|
+
if target["attribute"][target_attribute_name] && target["attribute"][target_attribute_name]["cardinality"]
|
65
|
+
cardinality = target["attribute"][target_attribute_name]["cardinality"]
|
66
|
+
member += " [#{cardinality['min']}..#{cardinality['max']}]"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
else
|
70
|
+
sync_puts("member_type direct", 4)
|
71
|
+
end
|
72
|
+
sync_puts("member #{member}", 4)
|
73
|
+
|
74
|
+
sync_puts("}", 2)
|
75
|
+
end
|
76
|
+
sync_puts("diagram #{File.basename(ARGV[0], 'yml')[0..-2]} {")
|
77
|
+
sync_puts("title '#{view_yaml['title']}'", 2)
|
78
|
+
sync_puts("caption '#{view_yaml['caption']}'", 2)
|
79
|
+
|
80
|
+
# Class associations notations
|
81
|
+
view_yaml["relations"]&.each do |values|
|
82
|
+
process_association(values["source"], values, encountered_relations)
|
83
|
+
end
|
84
|
+
|
85
|
+
view_yaml["imports"].keys.each do |entry|
|
86
|
+
import = YAML.safe_load(File.read(File.join(models_path, "#{entry}.yml")))
|
87
|
+
import_name = import["name"] || File.basename(entry)
|
88
|
+
# Class notation
|
89
|
+
sync_puts("#{import['modelType']} #{import_name} {", 2)
|
90
|
+
if import["definition"]
|
91
|
+
definition = <<~TEXT
|
92
|
+
definition {
|
93
|
+
#{import['definition']}
|
94
|
+
}
|
95
|
+
TEXT
|
96
|
+
sync_puts(definition, 4)
|
97
|
+
end
|
98
|
+
import["values"]&.each_pair do |key, values|
|
99
|
+
result_string = key
|
100
|
+
if values["definition"]
|
101
|
+
result_string += <<~TEXT
|
102
|
+
{
|
103
|
+
definition {
|
104
|
+
#{values['definition']}
|
105
|
+
}
|
106
|
+
}
|
107
|
+
TEXT
|
108
|
+
end
|
109
|
+
sync_puts(result_string, 4)
|
110
|
+
end
|
111
|
+
import["attributes"]&.each_pair do |key, values|
|
112
|
+
definition = values["definition"]
|
113
|
+
cardinality = if values["cardinality"]
|
114
|
+
cardinality_val = values["cardinality"]
|
115
|
+
"[#{cardinality_val['min']}..#{cardinality_val['max']}]"
|
116
|
+
else
|
117
|
+
""
|
118
|
+
end
|
119
|
+
result_string = "+#{key}"
|
120
|
+
if values["type"]
|
121
|
+
result_string += ": #{values['type']}"
|
122
|
+
end
|
123
|
+
if cardinality
|
124
|
+
result_string += " #{cardinality}"
|
125
|
+
end
|
126
|
+
if definition
|
127
|
+
result_string += <<~TEXT
|
128
|
+
{
|
129
|
+
definition
|
130
|
+
#{definition}
|
131
|
+
end definition
|
132
|
+
}
|
133
|
+
TEXT
|
134
|
+
end
|
135
|
+
sync_puts(result_string, 4)
|
136
|
+
end
|
137
|
+
sync_puts("}", 2)
|
138
|
+
|
139
|
+
# Associations notations
|
140
|
+
import["relations"]&.each do |values|
|
141
|
+
process_association(import_name, values, encountered_relations)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
sync_puts("}")
|
data/lib/lutaml/uml.rb
CHANGED
@@ -1,11 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "lutaml/uml/version"
|
4
|
-
require "lutaml/uml/
|
4
|
+
require "lutaml/uml/parsers/dsl"
|
5
|
+
require "lutaml/uml/parsers/yaml"
|
6
|
+
require "lutaml/uml/parsers/attribute"
|
7
|
+
require "lutaml/uml/formatter"
|
5
8
|
|
6
9
|
module Lutaml
|
7
10
|
module Uml
|
8
11
|
class Error < StandardError; end
|
9
|
-
# Your code goes here...
|
10
12
|
end
|
11
13
|
end
|
@@ -63,7 +63,7 @@ module Lutaml
|
|
63
63
|
rule(:spaces) { match("\s").repeat(1) }
|
64
64
|
rule(:spaces?) { spaces.maybe }
|
65
65
|
rule(:whitespace) do
|
66
|
-
(match("\s") | match("\r?\n") | match("\r") | str(";")).repeat(1)
|
66
|
+
(match("\s") | match(" ") | match("\r?\n") | match("\r") | str(";")).repeat(1)
|
67
67
|
end
|
68
68
|
rule(:whitespace?) { whitespace.maybe }
|
69
69
|
rule(:name) { match["a-zA-Z0-9 _-"].repeat(1) }
|
@@ -322,6 +322,7 @@ module Lutaml
|
|
322
322
|
match['"\''].maybe >>
|
323
323
|
class_name.as(:name) >>
|
324
324
|
match['"\''].maybe >>
|
325
|
+
attribute_keyword? >>
|
325
326
|
enum_body?
|
326
327
|
end
|
327
328
|
|
data/lib/lutaml/uml/version.rb
CHANGED
data/lutaml-uml.gemspec
CHANGED
@@ -22,7 +22,7 @@ Gem::Specification.new do |spec|
|
|
22
22
|
|
23
23
|
spec.bindir = "exe"
|
24
24
|
spec.require_paths = ["lib"]
|
25
|
-
spec.executables = %w[lutaml-
|
25
|
+
spec.executables = %w[lutaml-wsd2uml lutaml-yaml2uml]
|
26
26
|
|
27
27
|
spec.add_runtime_dependency "hashie", "~> 4.1.0"
|
28
28
|
spec.add_runtime_dependency "parslet", "~> 1.7.1"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lutaml-uml
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ribose Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-03-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: hashie
|
@@ -168,7 +168,8 @@ description: UML model module for LutaML.
|
|
168
168
|
email:
|
169
169
|
- open.source@ribose.com'
|
170
170
|
executables:
|
171
|
-
- lutaml-
|
171
|
+
- lutaml-wsd2uml
|
172
|
+
- lutaml-yaml2uml
|
172
173
|
extensions: []
|
173
174
|
extra_rdoc_files: []
|
174
175
|
files:
|
@@ -188,7 +189,8 @@ files:
|
|
188
189
|
- bin/plantuml2lutaml
|
189
190
|
- bin/setup
|
190
191
|
- bin/yaml2lutaml
|
191
|
-
- exe/lutaml-
|
192
|
+
- exe/lutaml-wsd2uml
|
193
|
+
- exe/lutaml-yaml2uml
|
192
194
|
- lib/lutaml/layout/engine.rb
|
193
195
|
- lib/lutaml/layout/graph_viz_engine.rb
|
194
196
|
- lib/lutaml/uml.rb
|
@@ -214,8 +216,6 @@ files:
|
|
214
216
|
- lib/lutaml/uml/has_attributes.rb
|
215
217
|
- lib/lutaml/uml/has_members.rb
|
216
218
|
- lib/lutaml/uml/instance.rb
|
217
|
-
- lib/lutaml/uml/interface/base.rb
|
218
|
-
- lib/lutaml/uml/interface/command_line.rb
|
219
219
|
- lib/lutaml/uml/model.rb
|
220
220
|
- lib/lutaml/uml/node/base.rb
|
221
221
|
- lib/lutaml/uml/node/class_node.rb
|
@@ -319,7 +319,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
319
319
|
- !ruby/object:Gem::Version
|
320
320
|
version: '0'
|
321
321
|
requirements: []
|
322
|
-
rubygems_version: 3.0.
|
322
|
+
rubygems_version: 3.0.3
|
323
323
|
signing_key:
|
324
324
|
specification_version: 4
|
325
325
|
summary: UML model module for LutaML.
|
data/exe/lutaml-uml
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# encoding: UTF-8
|
3
|
-
# frozen_string_literal: true
|
4
|
-
|
5
|
-
# resolve bin path, ignoring symlinks
|
6
|
-
require "pathname"
|
7
|
-
bin_file = Pathname.new(__FILE__).realpath
|
8
|
-
|
9
|
-
# add self to libpath
|
10
|
-
$:.unshift File.expand_path("../../lib", bin_file)
|
11
|
-
|
12
|
-
# Fixes https://github.com/rubygems/rubygems/issues/1420
|
13
|
-
require "rubygems/specification"
|
14
|
-
|
15
|
-
class Gem::Specification
|
16
|
-
def this; self; end
|
17
|
-
end
|
18
|
-
|
19
|
-
require "lutaml/uml/interface/command_line"
|
20
|
-
|
21
|
-
Lutaml::Uml::Interface::CommandLine.run
|
@@ -1,28 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "optparse"
|
4
|
-
require "lutaml/uml/has_attributes"
|
5
|
-
|
6
|
-
module Lutaml
|
7
|
-
module Uml
|
8
|
-
module Interface
|
9
|
-
class Base
|
10
|
-
def self.run(attributes = {})
|
11
|
-
new(attributes).run
|
12
|
-
end
|
13
|
-
|
14
|
-
include HasAttributes
|
15
|
-
|
16
|
-
# rubocop:disable Rails/ActiveRecordAliases
|
17
|
-
def initialize(attributes = {})
|
18
|
-
update_attributes(attributes)
|
19
|
-
end
|
20
|
-
# rubocop:enable Rails/ActiveRecordAliases
|
21
|
-
|
22
|
-
def run
|
23
|
-
raise NotImplementedError
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
@@ -1,265 +0,0 @@
|
|
1
|
-
require "optparse"
|
2
|
-
require "pathname"
|
3
|
-
require "lutaml/uml/interface/base"
|
4
|
-
require "lutaml/uml/parsers/dsl"
|
5
|
-
require "lutaml/uml/parsers/yaml"
|
6
|
-
require "lutaml/uml/parsers/attribute"
|
7
|
-
require "lutaml/uml/formatter"
|
8
|
-
|
9
|
-
module Lutaml
|
10
|
-
module Uml
|
11
|
-
module Interface
|
12
|
-
class CommandLine < Base
|
13
|
-
class Error < StandardError; end
|
14
|
-
class FileError < Error; end
|
15
|
-
class NotSupportedInputFormat < Error; end
|
16
|
-
|
17
|
-
SUPPORTED_FORMATS = %w[yaml dsl].freeze
|
18
|
-
DEFAULT_INPUT_FORMAT = "dsl".freeze
|
19
|
-
|
20
|
-
def initialize(attributes = {})
|
21
|
-
@formatter = Formatter::Graphviz.new
|
22
|
-
@verbose = false
|
23
|
-
@option_parser = OptionParser.new
|
24
|
-
|
25
|
-
setup_parser_options
|
26
|
-
|
27
|
-
super
|
28
|
-
end
|
29
|
-
|
30
|
-
def output_path=(value)
|
31
|
-
@output_path = determine_output_path_value(value)
|
32
|
-
end
|
33
|
-
|
34
|
-
def determine_output_path_value(value)
|
35
|
-
unless value.nil? || @output_path = value.is_a?(Pathname)
|
36
|
-
return Pathname.new(value.to_s)
|
37
|
-
end
|
38
|
-
|
39
|
-
value
|
40
|
-
end
|
41
|
-
|
42
|
-
def paths=(values)
|
43
|
-
@paths = values.to_a.map { |path| Pathname.new(path) }
|
44
|
-
end
|
45
|
-
|
46
|
-
def formatter=(value)
|
47
|
-
value = value.to_s.strip.downcase.to_sym
|
48
|
-
value = Formatter.find_by(name: value)
|
49
|
-
raise Error, "Formatter not found: #{value}" if value.nil?
|
50
|
-
|
51
|
-
@formatter = value
|
52
|
-
end
|
53
|
-
|
54
|
-
def input_format=(value)
|
55
|
-
if value.nil?
|
56
|
-
@input_format = DEFAULT_INPUT_FORMAT
|
57
|
-
return
|
58
|
-
end
|
59
|
-
|
60
|
-
@input_format = SUPPORTED_FORMATS.detect { |n| n == value }
|
61
|
-
raise(NotSupportedInputFormat, value) if @input_format.nil?
|
62
|
-
end
|
63
|
-
|
64
|
-
def run
|
65
|
-
args = ARGV.dup # TODO: This is hacky
|
66
|
-
begin
|
67
|
-
@option_parser.parse!(args)
|
68
|
-
rescue StandardError
|
69
|
-
nil
|
70
|
-
end
|
71
|
-
setup_parser_formatter_options
|
72
|
-
@option_parser.parse!
|
73
|
-
|
74
|
-
self.paths = ARGV
|
75
|
-
@formatter.type = @type
|
76
|
-
|
77
|
-
if @output_path&.file? && @paths.length > 1
|
78
|
-
raise Error,
|
79
|
-
'Output path must be a directory \
|
80
|
-
if multiple input files are given'
|
81
|
-
end
|
82
|
-
|
83
|
-
@paths.each do |input_path|
|
84
|
-
unless input_path.exist?
|
85
|
-
raise FileError, "File does not exist: #{input_path}"
|
86
|
-
end
|
87
|
-
|
88
|
-
document = if @input_format == "yaml"
|
89
|
-
Parsers::Yaml.parse(input_path)
|
90
|
-
else
|
91
|
-
Parsers::Dsl.parse(File.new(input_path))
|
92
|
-
end
|
93
|
-
result = @formatter.format(document)
|
94
|
-
|
95
|
-
if @output_path
|
96
|
-
output_path = @output_path
|
97
|
-
if output_path.directory?
|
98
|
-
output_path = output_path.join(input_path
|
99
|
-
.basename(".*").to_s +
|
100
|
-
".#{@formatter.type}")
|
101
|
-
end
|
102
|
-
|
103
|
-
output_path.open("w+") { |file| file.write(result) }
|
104
|
-
else
|
105
|
-
puts result
|
106
|
-
end
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
protected
|
111
|
-
|
112
|
-
def text_bold(body = nil)
|
113
|
-
text_effect(1, body)
|
114
|
-
end
|
115
|
-
|
116
|
-
def text_italic(body = nil)
|
117
|
-
text_effect(3, body)
|
118
|
-
end
|
119
|
-
|
120
|
-
def text_bold_italic(body = nil)
|
121
|
-
text_bold(text_italic(body))
|
122
|
-
end
|
123
|
-
|
124
|
-
def text_underline(body = nil)
|
125
|
-
text_effect(4, body)
|
126
|
-
end
|
127
|
-
|
128
|
-
def text_effect(num, body = nil)
|
129
|
-
result = "\e[#{num}m"
|
130
|
-
result << "#{body}#{text_reset}" unless body.nil?
|
131
|
-
|
132
|
-
result
|
133
|
-
end
|
134
|
-
|
135
|
-
def text_reset
|
136
|
-
"\e[0m"
|
137
|
-
end
|
138
|
-
|
139
|
-
def setup_parser_options
|
140
|
-
@option_parser.banner = ""
|
141
|
-
format_desc = "The output formatter (Default: '#{@formatter.name}')"
|
142
|
-
@option_parser
|
143
|
-
.on("-f",
|
144
|
-
"--formatter VALUE",
|
145
|
-
format_desc) do |value|
|
146
|
-
self.formatter = value
|
147
|
-
end
|
148
|
-
@option_parser
|
149
|
-
.on("-t", "--type VALUE", "The output format type") do |value|
|
150
|
-
@type = value
|
151
|
-
end
|
152
|
-
@option_parser
|
153
|
-
.on("-o", "--output VALUE", "The output path") do |value|
|
154
|
-
self.output_path = value
|
155
|
-
end
|
156
|
-
@option_parser
|
157
|
-
.on("-i", "--input-format VALUE", "The input format") do |value|
|
158
|
-
self.input_format = value
|
159
|
-
end
|
160
|
-
@option_parser
|
161
|
-
.on("-h", "--help", "Prints this help") do
|
162
|
-
print_help
|
163
|
-
exit
|
164
|
-
end
|
165
|
-
end
|
166
|
-
|
167
|
-
def setup_parser_formatter_options
|
168
|
-
case @formatter.name
|
169
|
-
when :graphviz
|
170
|
-
@option_parser.on("-g", "--graph VALUE") do |value|
|
171
|
-
Parsers::Attribute.parse(value).each do |key, attr_value|
|
172
|
-
@formatter.graph[key] = attr_value
|
173
|
-
end
|
174
|
-
end
|
175
|
-
|
176
|
-
@option_parser.on("-e", "--edge VALUE") do |value|
|
177
|
-
Parsers::Attribute.parse(value).each do |key, attr_value|
|
178
|
-
@formatter.edge[key] = attr_value
|
179
|
-
end
|
180
|
-
end
|
181
|
-
|
182
|
-
@option_parser.on("-n", "--node VALUE") do |value|
|
183
|
-
Parsers::Attribute.parse(value).each do |key, attr_value|
|
184
|
-
@formatter.node[key] = attr_value
|
185
|
-
end
|
186
|
-
end
|
187
|
-
|
188
|
-
@option_parser.on("-a", "--all VALUE") do |value|
|
189
|
-
Parsers::Attribute.parse(value).each do |key, attr_value|
|
190
|
-
@formatter.graph[key] = attr_value
|
191
|
-
@formatter.edge[key] = attr_value
|
192
|
-
@formatter.node[key] = attr_value
|
193
|
-
end
|
194
|
-
end
|
195
|
-
end
|
196
|
-
end
|
197
|
-
|
198
|
-
def print_help
|
199
|
-
puts <<~HELP
|
200
|
-
#{text_bold('Usage:')} lutaml-uml [options] PATHS
|
201
|
-
|
202
|
-
#{text_bold('Overview:')} Generate output from UML Class Diagram language files
|
203
|
-
|
204
|
-
#{text_bold('Options:')}
|
205
|
-
#{@option_parser}
|
206
|
-
#{text_bold('Paths:')}
|
207
|
-
|
208
|
-
UCD can accept multiple paths for parsing for easier batch processing.
|
209
|
-
|
210
|
-
The location of the output by default is standard output.
|
211
|
-
|
212
|
-
The output can be directed to a path with #{text_bold_italic('--output')}, which can be a file or a directory.
|
213
|
-
If the output path is a directory, then the filename will be the same as the input filename,
|
214
|
-
with it's file extension substituted with the #{text_bold_italic('--type')}.
|
215
|
-
|
216
|
-
#{text_underline('Examples')}
|
217
|
-
|
218
|
-
`lutaml-uml project.lutaml`
|
219
|
-
|
220
|
-
Produces DOT notation, sent to standard output
|
221
|
-
|
222
|
-
`lutaml-uml -o . project.lutaml`
|
223
|
-
|
224
|
-
Produces DOT notation, written to #{text_italic('./project.dot')}
|
225
|
-
|
226
|
-
`lutaml-uml -o ./diagram.dot project.lutaml`
|
227
|
-
|
228
|
-
Produces DOT notation, written to #{text_italic('./diagram.dot')}
|
229
|
-
|
230
|
-
`lutaml-uml -o ./diagram.png project.lutaml`
|
231
|
-
|
232
|
-
Produces PNG image, written to #{text_italic('./diagram.png')}
|
233
|
-
|
234
|
-
`lutaml-uml -t png -o . project.lutaml`
|
235
|
-
|
236
|
-
Produces PNG image, written to #{text_italic('./project.png')}
|
237
|
-
|
238
|
-
`lutaml-uml -t png -o . project.lutaml-uml core_ext.lutaml`
|
239
|
-
|
240
|
-
Produces PNG images, written to #{text_italic('./project.png')} and #{text_italic('./core_ext.png')}
|
241
|
-
|
242
|
-
#{text_bold('Formatters:')}
|
243
|
-
|
244
|
-
#{text_underline('Graphviz')}
|
245
|
-
|
246
|
-
Generates DOT notation and can use the DOT notation to generate any format Graphviz can produce.
|
247
|
-
|
248
|
-
The output format is based on #{text_bold_italic('--type')}, which by default is "dot".
|
249
|
-
If #{text_bold_italic('--type')} is not given and #{text_bold_italic('--output')} is, the file extension of the #{text_bold_italic('--output')} path will be used.
|
250
|
-
|
251
|
-
Valid types/extensions are: #{Formatter::Graphviz::VALID_TYPES.join(', ')}
|
252
|
-
|
253
|
-
#{text_bold('Options:')}
|
254
|
-
|
255
|
-
-g, --graph VALUE The graph attributes
|
256
|
-
-e, --edge VALUE The edge attributes
|
257
|
-
-n, --node VALUE The node attributes
|
258
|
-
-a, --all VALUE Set attributes for graph, edge, and node
|
259
|
-
|
260
|
-
HELP
|
261
|
-
end
|
262
|
-
end
|
263
|
-
end
|
264
|
-
end
|
265
|
-
end
|