lutaml 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/macos.yml +41 -0
- data/.github/workflows/ubuntu.yml +40 -0
- data/.github/workflows/windows.yml +48 -0
- data/Gemfile +0 -3
- data/README.adoc +72 -0
- data/exe/lutaml +22 -0
- data/lib/lutaml.rb +1 -3
- data/lib/lutaml/command_line.rb +261 -0
- data/lib/lutaml/express/lutaml_path/document_wrapper.rb +59 -0
- data/lib/lutaml/formatter.rb +19 -0
- data/lib/lutaml/formatter/base.rb +66 -0
- data/lib/lutaml/formatter/graphviz.rb +332 -0
- data/lib/lutaml/layout/engine.rb +15 -0
- data/lib/lutaml/layout/graph_viz_engine.rb +18 -0
- data/lib/lutaml/lutaml_path/document_wrapper.rb +25 -7
- data/lib/lutaml/parser.rb +53 -0
- data/lib/lutaml/uml/lutaml_path/document_wrapper.rb +15 -0
- data/lib/lutaml/version.rb +1 -1
- data/lutaml.gemspec +8 -6
- metadata +40 -12
- data/README.md +0 -40
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 84bb179e752bc157f0de4a59ea8cf88e9bd1fe4430726dcefcf63269d12c86fb
|
4
|
+
data.tar.gz: a5f8917e80a33814b9cc6a9e3556b335da72fe05fd73e4d54dc294d1c4b6a27f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 64b11704d20aff55c53cb6b1d857d346a6e9016b84b091581372c38b100a3d21d499685550e8d5a8b132e4cc7de5e8da37c3efd14ae325d119a207a76fc0feea
|
7
|
+
data.tar.gz: f9800bc7e40536370807a3e4a3429d60dfa1f2fd728054adf6c9a8e73ba813b20bad80e22c85323309089eb41e1455806381513c139de1a99cc804ebb37378f2
|
@@ -0,0 +1,41 @@
|
|
1
|
+
name: macos
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: [ master ]
|
6
|
+
pull_request:
|
7
|
+
paths-ignore:
|
8
|
+
- .github/workflows/ubuntu.yml
|
9
|
+
- .github/workflows/windows.yml
|
10
|
+
|
11
|
+
jobs:
|
12
|
+
test-macos:
|
13
|
+
name: Test on Ruby ${{ matrix.ruby }} macOS
|
14
|
+
runs-on: macos-latest
|
15
|
+
continue-on-error: ${{ matrix.experimental }}
|
16
|
+
strategy:
|
17
|
+
fail-fast: false
|
18
|
+
matrix:
|
19
|
+
ruby: [ '2.6', '2.5' ]
|
20
|
+
experimental: [false]
|
21
|
+
include:
|
22
|
+
- ruby: '2.7'
|
23
|
+
experimental: true
|
24
|
+
steps:
|
25
|
+
- uses: actions/checkout@master
|
26
|
+
- name: Install build tools
|
27
|
+
run: |
|
28
|
+
brew install automake libtool
|
29
|
+
- name: Use Ruby
|
30
|
+
uses: actions/setup-ruby@v1
|
31
|
+
with:
|
32
|
+
ruby-version: ${{ matrix.ruby }}
|
33
|
+
- name: Install Grpahviz macOS
|
34
|
+
run: brew install graphviz
|
35
|
+
- name: Update gems
|
36
|
+
run: |
|
37
|
+
sudo gem install bundler --force
|
38
|
+
bundle install --jobs 4 --retry 3
|
39
|
+
- name: Run specs
|
40
|
+
run: |
|
41
|
+
bundle exec rake
|
@@ -0,0 +1,40 @@
|
|
1
|
+
name: ubuntu
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: [ master ]
|
6
|
+
tags:
|
7
|
+
- '*'
|
8
|
+
pull_request:
|
9
|
+
paths-ignore:
|
10
|
+
- .github/workflows/macos.yml
|
11
|
+
- .github/workflows/windows.yml
|
12
|
+
|
13
|
+
jobs:
|
14
|
+
test-linux:
|
15
|
+
name: Test on Ruby ${{ matrix.ruby }} Ubuntu
|
16
|
+
runs-on: ubuntu-latest
|
17
|
+
continue-on-error: ${{ matrix.experimental }}
|
18
|
+
strategy:
|
19
|
+
fail-fast: false
|
20
|
+
matrix:
|
21
|
+
ruby: [ '2.6', '2.5' ]
|
22
|
+
experimental: [false]
|
23
|
+
include:
|
24
|
+
- ruby: '2.7'
|
25
|
+
experimental: true
|
26
|
+
steps:
|
27
|
+
- uses: actions/checkout@master
|
28
|
+
- name: Use Ruby
|
29
|
+
uses: actions/setup-ruby@v1
|
30
|
+
with:
|
31
|
+
ruby-version: ${{ matrix.ruby }}
|
32
|
+
- name: Install Grpahviz Ubuntu
|
33
|
+
run: sudo apt-get install graphviz
|
34
|
+
- name: Update gems
|
35
|
+
run: |
|
36
|
+
gem install bundler
|
37
|
+
bundle install --jobs 4 --retry 3
|
38
|
+
- name: Run specs
|
39
|
+
run: |
|
40
|
+
bundle exec rake
|
@@ -0,0 +1,48 @@
|
|
1
|
+
name: windows
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: [ master ]
|
6
|
+
pull_request:
|
7
|
+
paths-ignore:
|
8
|
+
- .github/workflows/macos.yml
|
9
|
+
- .github/workflows/ubuntu.yml
|
10
|
+
|
11
|
+
jobs:
|
12
|
+
test-windows:
|
13
|
+
name: Test on Ruby ${{ matrix.ruby }} Windows
|
14
|
+
runs-on: windows-latest
|
15
|
+
continue-on-error: ${{ matrix.experimental }}
|
16
|
+
strategy:
|
17
|
+
fail-fast: false
|
18
|
+
matrix:
|
19
|
+
ruby: [ '2.6', '2.5' ]
|
20
|
+
experimental: [false]
|
21
|
+
# Does not supported yet:
|
22
|
+
# Ruby (< 2.7.dev, >= 2.3), which is required by gem 'nokogiri (~> 1.10)', is not
|
23
|
+
# available in the local ruby installation
|
24
|
+
# include:
|
25
|
+
# - ruby: '2.7'
|
26
|
+
# experimental: true
|
27
|
+
steps:
|
28
|
+
- uses: actions/checkout@master
|
29
|
+
- name: Use Ruby
|
30
|
+
uses: actions/setup-ruby@v1
|
31
|
+
with:
|
32
|
+
ruby-version: ${{ matrix.ruby }}
|
33
|
+
- name: Install graphviz
|
34
|
+
uses: nick-invision/retry@v1
|
35
|
+
with:
|
36
|
+
polling_interval_seconds: 5
|
37
|
+
timeout_minutes: 5
|
38
|
+
max_attempts: 3
|
39
|
+
command: choco install --no-progress graphviz --version 2.38.0.20190211
|
40
|
+
- name: Update gems
|
41
|
+
shell: pwsh
|
42
|
+
run: |
|
43
|
+
gem install bundler
|
44
|
+
bundle config --local path vendor/bundle
|
45
|
+
bundle install --jobs 4 --retry 3
|
46
|
+
- name: Run specs
|
47
|
+
run: |
|
48
|
+
bundle exec rake
|
data/Gemfile
CHANGED
data/README.adoc
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
= Lutaml
|
2
|
+
|
3
|
+
== Functionality
|
4
|
+
|
5
|
+
Entry point for lutaml extensions.
|
6
|
+
|
7
|
+
=== Installation
|
8
|
+
|
9
|
+
With bundler:
|
10
|
+
|
11
|
+
[source,ruby]
|
12
|
+
----
|
13
|
+
# Gemfile
|
14
|
+
gem "lutaml"
|
15
|
+
----
|
16
|
+
|
17
|
+
Then in console:
|
18
|
+
|
19
|
+
[source,console]
|
20
|
+
----
|
21
|
+
$ bundle
|
22
|
+
----
|
23
|
+
|
24
|
+
With RubyGems:
|
25
|
+
|
26
|
+
[source,console]
|
27
|
+
----
|
28
|
+
$ gem install lutaml
|
29
|
+
----
|
30
|
+
|
31
|
+
=== Usage
|
32
|
+
|
33
|
+
== From ruby
|
34
|
+
|
35
|
+
In order to parse files supported by lutaml extensions, use Lutaml::Parser.parse method.
|
36
|
+
|
37
|
+
[source,ruby]
|
38
|
+
----
|
39
|
+
# example.exp is an EXPRESS repository file
|
40
|
+
Lutaml::Parser.parse(File.new("example.exp")) # will produce Lutaml::LutamlPath::DocumentWrapper object with serialized express repository
|
41
|
+
----
|
42
|
+
|
43
|
+
== With cli tool
|
44
|
+
|
45
|
+
There is a cli tool available for parsing lutaml/exp files(also yaml datastruct files are supported).
|
46
|
+
|
47
|
+
[source,bash]
|
48
|
+
----
|
49
|
+
# Will generate `test.dot` file in the current directory
|
50
|
+
$: lutaml -o . test.lutaml
|
51
|
+
|
52
|
+
# Will generate `test.png` file in the `assets` directory
|
53
|
+
$: lutaml -o assets -t png test.lutaml
|
54
|
+
----
|
55
|
+
|
56
|
+
For additional info refer to `lutaml --help output`
|
57
|
+
|
58
|
+
|
59
|
+
== Development
|
60
|
+
|
61
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
62
|
+
|
63
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
64
|
+
|
65
|
+
## Contributing
|
66
|
+
|
67
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/lutaml. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/lutaml/blob/master/CODE_OF_CONDUCT.md).
|
68
|
+
|
69
|
+
|
70
|
+
== Code of Conduct
|
71
|
+
|
72
|
+
Everyone interacting in the Lutaml::Uml project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/lutaml/blob/master/CODE_OF_CONDUCT.md).
|
data/exe/lutaml
ADDED
@@ -0,0 +1,22 @@
|
|
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"
|
20
|
+
require "lutaml/command_line"
|
21
|
+
|
22
|
+
Lutaml::CommandLine.run(ARGV.dup, STDOUT)
|
data/lib/lutaml.rb
CHANGED
@@ -0,0 +1,261 @@
|
|
1
|
+
require "optparse"
|
2
|
+
require "pathname"
|
3
|
+
require "lutaml/formatter"
|
4
|
+
require "lutaml/uml/has_attributes"
|
5
|
+
require "lutaml/uml/parsers/attribute"
|
6
|
+
require "lutaml/uml/parsers/dsl"
|
7
|
+
require "lutaml/uml/parsers/yaml"
|
8
|
+
|
9
|
+
module Lutaml
|
10
|
+
class CommandLine
|
11
|
+
class Error < StandardError; end
|
12
|
+
class FileError < Error; end
|
13
|
+
class NotSupportedInputFormat < Error; end
|
14
|
+
|
15
|
+
include ::Lutaml::Uml::HasAttributes
|
16
|
+
|
17
|
+
SUPPORTED_FORMATS = %w[yaml lutaml exp].freeze
|
18
|
+
DEFAULT_INPUT_FORMAT = "lutaml".freeze
|
19
|
+
|
20
|
+
def self.run(args, out_object, attributes = {})
|
21
|
+
new(attributes, out_object).run(args)
|
22
|
+
end
|
23
|
+
|
24
|
+
def initialize(attributes = {}, out_object = STDOUT)
|
25
|
+
@formatter = ::Lutaml::Formatter::Graphviz.new
|
26
|
+
@verbose = false
|
27
|
+
@option_parser = OptionParser.new
|
28
|
+
@out_object = out_object
|
29
|
+
|
30
|
+
setup_parser_options
|
31
|
+
|
32
|
+
# rubocop:disable Rails/ActiveRecordAliases
|
33
|
+
update_attributes(attributes)
|
34
|
+
# rubocop:enable Rails/ActiveRecordAliases
|
35
|
+
end
|
36
|
+
|
37
|
+
def output_path=(value)
|
38
|
+
@output_path = determine_output_path_value(value)
|
39
|
+
end
|
40
|
+
|
41
|
+
def determine_output_path_value(value)
|
42
|
+
unless value.nil? || @output_path = value.is_a?(Pathname)
|
43
|
+
return Pathname.new(value.to_s)
|
44
|
+
end
|
45
|
+
|
46
|
+
value
|
47
|
+
end
|
48
|
+
|
49
|
+
def paths=(values)
|
50
|
+
@paths = values.to_a.map { |path| Pathname.new(path) }
|
51
|
+
end
|
52
|
+
|
53
|
+
def formatter=(value)
|
54
|
+
value = value.to_s.strip.downcase.to_sym
|
55
|
+
value = Lutaml::Uml::Formatter.find_by(name: value)
|
56
|
+
raise Error, "Formatter not found: #{value}" if value.nil?
|
57
|
+
|
58
|
+
@formatter = value
|
59
|
+
end
|
60
|
+
|
61
|
+
def input_format=(value)
|
62
|
+
if value.nil?
|
63
|
+
@input_format = DEFAULT_INPUT_FORMAT
|
64
|
+
return
|
65
|
+
end
|
66
|
+
|
67
|
+
@input_format = SUPPORTED_FORMATS.detect { |n| n == value }
|
68
|
+
raise(NotSupportedInputFormat, value) if @input_format.nil?
|
69
|
+
end
|
70
|
+
|
71
|
+
def run(original_args)
|
72
|
+
args = original_args.dup
|
73
|
+
@option_parser.parse!(args) rescue nil
|
74
|
+
@paths = args
|
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_string|
|
84
|
+
input_path = Pathname.new(input_path_string)
|
85
|
+
unless input_path.exist?
|
86
|
+
raise FileError, "File does not exist: #{input_path}"
|
87
|
+
end
|
88
|
+
|
89
|
+
document = Lutaml::Parser
|
90
|
+
.parse_into_document(File.new(input_path), @input_format)
|
91
|
+
result = @formatter.format(document)
|
92
|
+
|
93
|
+
if @output_path
|
94
|
+
output_path = @output_path
|
95
|
+
if output_path.directory?
|
96
|
+
output_path = output_path.join(input_path
|
97
|
+
.basename(".*").to_s +
|
98
|
+
".#{@formatter.type}")
|
99
|
+
end
|
100
|
+
|
101
|
+
output_path.open("w+") { |file| file.write(result) }
|
102
|
+
else
|
103
|
+
@out_object.puts(result)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
protected
|
109
|
+
|
110
|
+
def text_bold(body = nil)
|
111
|
+
text_effect(1, body)
|
112
|
+
end
|
113
|
+
|
114
|
+
def text_italic(body = nil)
|
115
|
+
text_effect(3, body)
|
116
|
+
end
|
117
|
+
|
118
|
+
def text_bold_italic(body = nil)
|
119
|
+
text_bold(text_italic(body))
|
120
|
+
end
|
121
|
+
|
122
|
+
def text_underline(body = nil)
|
123
|
+
text_effect(4, body)
|
124
|
+
end
|
125
|
+
|
126
|
+
def text_effect(num, body = nil)
|
127
|
+
result = "\e[#{num}m"
|
128
|
+
result << "#{body}#{text_reset}" unless body.nil?
|
129
|
+
|
130
|
+
result
|
131
|
+
end
|
132
|
+
|
133
|
+
def text_reset
|
134
|
+
"\e[0m"
|
135
|
+
end
|
136
|
+
|
137
|
+
def setup_parser_options
|
138
|
+
@option_parser.banner = ""
|
139
|
+
format_desc = "The output formatter (Default: '#{@formatter.name}')"
|
140
|
+
@option_parser
|
141
|
+
.on("-f",
|
142
|
+
"--formatter VALUE",
|
143
|
+
format_desc) do |value|
|
144
|
+
@formatter = value
|
145
|
+
end
|
146
|
+
@option_parser
|
147
|
+
.on("-t", "--type VALUE", "The output format type") do |value|
|
148
|
+
@type = value
|
149
|
+
end
|
150
|
+
@option_parser
|
151
|
+
.on("-o", "--output VALUE", "The output path") do |value|
|
152
|
+
@output_path = Pathname.new(value)
|
153
|
+
end
|
154
|
+
@option_parser
|
155
|
+
.on("-i", "--input-format VALUE", "The input format") do |value|
|
156
|
+
@input_format = value
|
157
|
+
end
|
158
|
+
@option_parser
|
159
|
+
.on("-h", "--help", "Prints this help") do
|
160
|
+
print_help
|
161
|
+
exit
|
162
|
+
end
|
163
|
+
@option_parser.on("-g", "--graph VALUE") do |value|
|
164
|
+
Parsers::Attribute.parse(value).each do |key, attr_value|
|
165
|
+
@formatter.graph[key] = attr_value
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
@option_parser.on("-e", "--edge VALUE") do |value|
|
170
|
+
Parsers::Attribute.parse(value).each do |key, attr_value|
|
171
|
+
@formatter.edge[key] = attr_value
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
@option_parser.on("-n", "--node VALUE") do |value|
|
176
|
+
Parsers::Attribute.parse(value).each do |key, attr_value|
|
177
|
+
@formatter.node[key] = attr_value
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
@option_parser.on("-a", "--all VALUE") do |value|
|
182
|
+
Parsers::Attribute.parse(value).each do |key, attr_value|
|
183
|
+
@formatter.graph[key] = attr_value
|
184
|
+
@formatter.edge[key] = attr_value
|
185
|
+
@formatter.node[key] = attr_value
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
def print_help
|
191
|
+
@out_object.puts <<~HELP
|
192
|
+
#{text_bold('Usage:')} lutaml [options] PATHS
|
193
|
+
|
194
|
+
#{text_bold('Overview:')} Generate output from Supplied language files if supported
|
195
|
+
|
196
|
+
#{text_bold('Options:')}
|
197
|
+
#{@option_parser}
|
198
|
+
#{text_bold('Paths:')}
|
199
|
+
|
200
|
+
LUTAML can accept multiple paths for parsing for easier batch processing.
|
201
|
+
|
202
|
+
The location of the output by default is standard output.
|
203
|
+
|
204
|
+
The output can be directed to a path with #{text_bold_italic('--output')}, which can be a file or a directory.
|
205
|
+
If the output path is a directory, then the filename will be the same as the input filename,
|
206
|
+
with it's file extension substituted with the #{text_bold_italic('--type')}.
|
207
|
+
|
208
|
+
#{text_underline('Examples')}
|
209
|
+
|
210
|
+
`lutaml project.lutaml`
|
211
|
+
|
212
|
+
Produces DOT notation, sent to standard output
|
213
|
+
|
214
|
+
`lutaml -o . project.lutaml`
|
215
|
+
|
216
|
+
Produces DOT notation, written to #{text_italic('./project.dot')}
|
217
|
+
|
218
|
+
`lutaml -o ./diagram.dot project.lutaml`
|
219
|
+
|
220
|
+
Produces DOT notation, written to #{text_italic('./diagram.dot')}
|
221
|
+
|
222
|
+
`lutaml -o ./diagram.png project.lutaml`
|
223
|
+
|
224
|
+
Produces PNG image, written to #{text_italic('./diagram.png')}
|
225
|
+
|
226
|
+
`lutaml -t png -o . project.lutaml`
|
227
|
+
|
228
|
+
Produces PNG image, written to #{text_italic('./project.png')}
|
229
|
+
|
230
|
+
`lutaml -t png -o . project.lutaml core_ext.lutaml`
|
231
|
+
|
232
|
+
Produces PNG images, written to #{text_italic('./project.png')} and #{text_italic('./core_ext.png')}
|
233
|
+
|
234
|
+
#{text_bold('Inputs:')}
|
235
|
+
|
236
|
+
#{text_underline('Lutaml')}
|
237
|
+
|
238
|
+
Lutaml dsl syntax files, supports diagram generation(image or dot files) with Graphviz
|
239
|
+
|
240
|
+
#{text_bold('Formatters:')}
|
241
|
+
|
242
|
+
#{text_underline('Graphviz')}
|
243
|
+
|
244
|
+
Generates DOT notation and can use the DOT notation to generate any format Graphviz can produce.
|
245
|
+
|
246
|
+
The output format is based on #{text_bold_italic('--type')}, which by default is "dot".
|
247
|
+
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.
|
248
|
+
|
249
|
+
Valid types/extensions are: #{Lutaml::Formatter::Graphviz::VALID_TYPES.join(', ')}
|
250
|
+
|
251
|
+
#{text_bold('Options:')}
|
252
|
+
|
253
|
+
-g, --graph VALUE The graph attributes
|
254
|
+
-e, --edge VALUE The edge attributes
|
255
|
+
-n, --node VALUE The node attributes
|
256
|
+
-a, --all VALUE Set attributes for graph, edge, and node
|
257
|
+
|
258
|
+
HELP
|
259
|
+
end
|
260
|
+
end
|
261
|
+
end
|