lutaml-uml 0.2.5 → 0.2.10

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4dd197690f8da12b6b7ba5055db64eeb862717769f78ef7acf3477ce0a32f377
4
- data.tar.gz: 400e3ead0e0d89f6a781a09a97967ed51d0d955015779334290829ed76d317da
3
+ metadata.gz: 2a4318a33ee0facc590ee478a533551314aa96290ff3f9beb2a8506518f107fb
4
+ data.tar.gz: 18164bb8e957223dc1f1fdeacd7603f61705482d3299de01edcd6c96bb1860a4
5
5
  SHA512:
6
- metadata.gz: bb4a6abf3136b6d1b4e207bd14d889e43ce2be9f9c4f036956702c0f9430c22baebaabd7d281f57feaa923b9ab9531a43be5d7d88276cce0fc8b856a222c807a
7
- data.tar.gz: 228355fdf7c6fcb51f5ec0958470d3e0f9ff6fc675f0a6029ecba4c22a597fdef6bdd4d9a2df76bb2d5e2141c5a4227bdd97c2269ec3e2628f9ef3eac8508b78
6
+ metadata.gz: fcb70562cec32586375a93e1a80a575bd6dc3b7150d2867046447af6461dec4af6e0c59ed179607dc03408e285c8cb6f1c627004f36118372027c8e9b9890bc2
7
+ data.tar.gz: 304d5c7326dbe2378a431c07cb50f0f21596a18dca6e0d694b2c7de26d1726a30e3932b3b2fd52f7f404a0a0453d7d7ec098b731f9460bab8eb24dd61939cbff
@@ -18,7 +18,7 @@ jobs:
18
18
  strategy:
19
19
  fail-fast: false
20
20
  matrix:
21
- ruby: [ '2.6', '2.5', '2.4' ]
21
+ ruby: [ '2.6', '2.5' ]
22
22
  experimental: [false]
23
23
  include:
24
24
  - ruby: '2.7'
data/LUTAML.adoc CHANGED
@@ -7,13 +7,18 @@
7
7
  [source,java]
8
8
  ----
9
9
  diagram MyView {
10
- import Relationship, Element
11
- render_option typed_as_associations
12
- file "my_view.png"
10
+ title "My diagram"
11
+ caption "My custom caption"
13
12
  fontname "Helvetica"
14
13
  }
15
14
  ----
16
15
 
16
+ where:
17
+
18
+ * `fontname` - optional, configuration option to use supplied font name
19
+ * `title` - optional, set custom title for diagram
20
+ * `caption` - optional, set custom caption for diagram
21
+
17
22
  == DataTypes
18
23
 
19
24
  Lutaml supports 3 types of data_types: `data_type`, `primitive` and `enum`. Example of data types declaration:
@@ -118,9 +123,9 @@ Full syntax:
118
123
 
119
124
  [source,java]
120
125
  ----
121
- definition
126
+ definition {
122
127
  inner text
123
- end definition
128
+ }
124
129
  ----
125
130
 
126
131
 
@@ -204,9 +209,9 @@ example:
204
209
  ----
205
210
  class Figure {
206
211
  + radius {
207
- definition
212
+ definition {
208
213
  Radius of the Figure
209
- end definition
214
+ }
210
215
  }
211
216
  }
212
217
  ----
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
- ## Executable
11
+ ## Language
12
12
 
13
- [source,sh]
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
- # Display detailed help message
19
- $ lutaml-uml --help
20
- --
15
+ ## Usage
21
16
 
22
- ## Language
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/bin/yaml2lutaml CHANGED
@@ -89,9 +89,9 @@ view_yaml["imports"].keys.each do |entry|
89
89
  sync_puts("#{import['modelType']} #{import_name} {", 2)
90
90
  if import["definition"]
91
91
  definition = <<~TEXT
92
- definition
92
+ definition {
93
93
  #{import['definition']}
94
- end definition
94
+ }
95
95
  TEXT
96
96
  sync_puts(definition, 4)
97
97
  end
@@ -100,9 +100,9 @@ view_yaml["imports"].keys.each do |entry|
100
100
  if values["definition"]
101
101
  result_string += <<~TEXT
102
102
  {
103
- definition
103
+ definition {
104
104
  #{values['definition']}
105
- end definition
105
+ }
106
106
  }
107
107
  TEXT
108
108
  end
@@ -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("}")
@@ -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/interface/command_line"
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
@@ -16,7 +16,6 @@ module Lutaml
16
16
 
17
17
  attr_reader :associations,
18
18
  :attributes,
19
- :definition,
20
19
  :members,
21
20
  :modifier
22
21
 
@@ -32,10 +31,6 @@ module Lutaml
32
31
  @modifier = value.to_s # TODO: Validate?
33
32
  end
34
33
 
35
- def definition=(value)
36
- @definition = value.to_s
37
- end
38
-
39
34
  def attributes=(value)
40
35
  @attributes = value.to_a.map do |attr|
41
36
  TopElementAttribute.new(attr)
@@ -27,10 +27,6 @@ module Lutaml
27
27
  end
28
28
  end
29
29
 
30
- def definition=(value)
31
- @definition = value.to_s
32
- end
33
-
34
30
  # TODO: reserved name, change
35
31
  def methods
36
32
  []
@@ -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) }
@@ -82,9 +82,9 @@ module Lutaml
82
82
  str(")")).maybe
83
83
  end
84
84
  rule(:cardinality_body_definition) do
85
- match['0-9\*'].as(:min) >>
85
+ match['0-9\*'].as('min') >>
86
86
  str("..").maybe >>
87
- match['0-9\*'].as(:max).maybe
87
+ match['0-9\*'].as('max').maybe
88
88
  end
89
89
  rule(:cardinality) do
90
90
  str("[") >>
@@ -117,7 +117,7 @@ module Lutaml
117
117
  attribute_keyword? >>
118
118
  spaces? >>
119
119
  match['"\''].maybe >>
120
- match['a-zA-Z0-9_\- '].repeat(1).as(:type) >>
120
+ match['a-zA-Z0-9_\- \/'].repeat(1).as(:type) >>
121
121
  match['"\''].maybe >>
122
122
  spaces?
123
123
  )
@@ -126,7 +126,7 @@ module Lutaml
126
126
  attribute_type.maybe
127
127
  end
128
128
 
129
- rule(:attribute_name) { name.as(:name) }
129
+ rule(:attribute_name) { match['a-zA-Z0-9_\- \/'].repeat(1).as(:name) }
130
130
  rule(:attribute_definition) do
131
131
  (visibility?.as(:visibility) >>
132
132
  match['"\''].maybe >>
@@ -291,9 +291,11 @@ module Lutaml
291
291
  spaces? >>
292
292
  str("definition") >>
293
293
  whitespace? >>
294
- (str("end definition").absent? >> any).repeat.as(:definition) >>
294
+ str("{") >>
295
+ whitespace? >>
296
+ (match("[\n\s]}").absent? >> any).repeat.as(:definition) >>
295
297
  whitespace? >>
296
- str("end definition")
298
+ str('}')
297
299
  end
298
300
 
299
301
  # -- Enum
@@ -320,6 +322,7 @@ module Lutaml
320
322
  match['"\''].maybe >>
321
323
  class_name.as(:name) >>
322
324
  match['"\''].maybe >>
325
+ attribute_keyword? >>
323
326
  enum_body?
324
327
  end
325
328
 
@@ -6,6 +6,7 @@ module Lutaml
6
6
  include HasAttributes
7
7
 
8
8
  attr_accessor :name,
9
+ :definition,
9
10
  :xmi_id,
10
11
  :xmi_uuid,
11
12
  :namespace,
@@ -42,6 +43,16 @@ module Lutaml
42
43
 
43
44
  the_name
44
45
  end
46
+
47
+ def definition=(value)
48
+ @definition = value
49
+ .to_s
50
+ .gsub(/\\}/, '}')
51
+ .gsub(/\\{/, '{')
52
+ .split("\n")
53
+ .map(&:strip)
54
+ .join("\n")
55
+ end
45
56
  end
46
57
  end
47
58
  end
@@ -21,6 +21,16 @@ module Lutaml
21
21
  update_attributes(attributes)
22
22
  end
23
23
  # rubocop:enable Rails/ActiveRecordAliases
24
+
25
+ def definition=(value)
26
+ @definition = value
27
+ .to_s
28
+ .gsub(/\\}/, '}')
29
+ .gsub(/\\{/, '{')
30
+ .split("\n")
31
+ .map(&:strip)
32
+ .join("\n")
33
+ end
24
34
  end
25
35
  end
26
36
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Lutaml
4
4
  module Uml
5
- VERSION = "0.2.5"
5
+ VERSION = "0.2.10"
6
6
  end
7
7
  end
data/lutaml-uml.gemspec CHANGED
@@ -22,9 +22,8 @@ Gem::Specification.new do |spec|
22
22
 
23
23
  spec.bindir = "exe"
24
24
  spec.require_paths = ["lib"]
25
- spec.executables = %w[lutaml-uml]
25
+ spec.executables = %w[lutaml-wsd2uml lutaml-yaml2uml]
26
26
 
27
- spec.add_runtime_dependency "activesupport", "~> 5.0"
28
27
  spec.add_runtime_dependency "hashie", "~> 4.1.0"
29
28
  spec.add_runtime_dependency "parslet", "~> 1.7.1"
30
29
  spec.add_runtime_dependency "ruby-graphviz", "~> 1.2"
@@ -15,5 +15,7 @@ diagram MyView {
15
15
  ~friendlyAttributeProfile: <<Type>> "CharacterString" [1..*]
16
16
  ~friendlyAttributeProfile1: <<Type>> "CharacterString"
17
17
  #protectedAttributeProfile: CharacterString
18
+ type/text: String
19
+ slashType: slash/type
18
20
  }
19
21
  }
@@ -3,7 +3,7 @@ diagram MyView {
3
3
 
4
4
  enum MyEnum {}
5
5
 
6
- enum AddressClassProfile {
6
+ enum AddressClassProfile <<my_keyword>> {
7
7
  +addressClassProfile: CharacterString
8
8
  }
9
9
 
@@ -2,19 +2,24 @@ diagram MyView {
2
2
  title "my diagram"
3
3
 
4
4
  class AddressClassProfile {
5
- definition
5
+ definition {
6
6
  this is multiline with `ascidoc`
7
7
  comments
8
8
  and list
9
- end definition
9
+ \{foo\} \{name\}
10
+ }
10
11
  +addressClassProfile: CharacterString [0..1]
11
12
  }
12
13
 
13
14
  class AttributeProfile {
14
15
  imlicistAttributeProfile: CharacterString [0..1] {
15
- definition this is attribute definition
16
- with multiply lines
17
- end definition
16
+ definition
17
+ {
18
+ this is attribute definition
19
+ with multiply lines
20
+ \{foo\} \{name\}
21
+ end definition
22
+ }
18
23
  }
19
24
  }
20
25
  }
@@ -68,7 +68,18 @@ RSpec.describe Lutaml::Uml::Parsers::Dsl do
68
68
  expect(by_name(classes, "AddressClassProfile")
69
69
  .attributes.length).to eq(1)
70
70
  expect(by_name(classes, "AttributeProfile")
71
- .attributes.length).to eq(7)
71
+ .attributes.length).to eq(9)
72
+ expect(by_name(classes, "AttributeProfile")
73
+ .attributes.map(&:name))
74
+ .to(eq(["imlicistAttributeProfile",
75
+ "attributeProfile",
76
+ "attributeProfile1",
77
+ "privateAttributeProfile",
78
+ "friendlyAttributeProfile",
79
+ "friendlyAttributeProfile1",
80
+ "protectedAttributeProfile",
81
+ "type/text",
82
+ "slashType"]))
72
83
  end
73
84
 
74
85
  it "creates the correct attributes with the correct visibility" do
@@ -121,7 +132,7 @@ RSpec.describe Lutaml::Uml::Parsers::Dsl do
121
132
  expect(association.member_end).to(eq("AttributeProfile"))
122
133
  expect(association.member_end_attribute_name)
123
134
  .to(eq("attributeProfile"))
124
- expect(association.member_end_cardinality).to(eq(min: "0", max: "*"))
135
+ expect(association.member_end_cardinality).to(eq("min" => "0", "max" => "*"))
125
136
  end
126
137
  end
127
138
 
@@ -254,10 +265,10 @@ RSpec.describe Lutaml::Uml::Parsers::Dsl do
254
265
  File.new(fixtures_path("dsl/diagram_definitions.lutaml"))
255
266
  end
256
267
  let(:class_definition) do
257
- "this is multiline with `ascidoc`\n comments\n and list"
268
+ "this is multiline with `ascidoc`\ncomments\nand list\n{foo} {name}"
258
269
  end
259
270
  let(:attribute_definition) do
260
- "this is attribute definition\n with multiply lines"
271
+ "this is attribute definition\nwith multiply lines\n{foo} {name}\nend definition"
261
272
  end
262
273
 
263
274
  it "create comments for document and classes" do
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lutaml-uml
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.5
4
+ version: 0.2.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-11-24 00:00:00.000000000 Z
11
+ date: 2021-03-17 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: activesupport
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: '5.0'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "~>"
25
- - !ruby/object:Gem::Version
26
- version: '5.0'
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: hashie
29
15
  requirement: !ruby/object:Gem::Requirement
@@ -182,7 +168,8 @@ description: UML model module for LutaML.
182
168
  email:
183
169
  - open.source@ribose.com'
184
170
  executables:
185
- - lutaml-uml
171
+ - lutaml-wsd2uml
172
+ - lutaml-yaml2uml
186
173
  extensions: []
187
174
  extra_rdoc_files: []
188
175
  files:
@@ -202,7 +189,8 @@ files:
202
189
  - bin/plantuml2lutaml
203
190
  - bin/setup
204
191
  - bin/yaml2lutaml
205
- - exe/lutaml-uml
192
+ - exe/lutaml-wsd2uml
193
+ - exe/lutaml-yaml2uml
206
194
  - lib/lutaml/layout/engine.rb
207
195
  - lib/lutaml/layout/graph_viz_engine.rb
208
196
  - lib/lutaml/uml.rb
@@ -228,8 +216,6 @@ files:
228
216
  - lib/lutaml/uml/has_attributes.rb
229
217
  - lib/lutaml/uml/has_members.rb
230
218
  - lib/lutaml/uml/instance.rb
231
- - lib/lutaml/uml/interface/base.rb
232
- - lib/lutaml/uml/interface/command_line.rb
233
219
  - lib/lutaml/uml/model.rb
234
220
  - lib/lutaml/uml/node/base.rb
235
221
  - lib/lutaml/uml/node/class_node.rb
@@ -333,7 +319,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
333
319
  - !ruby/object:Gem::Version
334
320
  version: '0'
335
321
  requirements: []
336
- rubygems_version: 3.0.6
322
+ rubygems_version: 3.0.3
337
323
  signing_key:
338
324
  specification_version: 4
339
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