lutaml-uml 0.2.5 → 0.2.10

Sign up to get free protection for your applications and to get access to all the features.
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