archimate 2.0.2 → 2.0.3
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 +5 -5
- data/.travis.yml +1 -1
- data/Gemfile +1 -0
- data/README.md +10 -55
- data/Rakefile +19 -1
- data/archimate.gemspec +16 -14
- data/bin/archimate +12 -0
- data/lib/archimate/cli/archi.rb +38 -19
- data/lib/archimate/cli/cleanup.rb +41 -25
- data/lib/archimate/cli/duper.rb +0 -1
- data/lib/archimate/cli/mapper.rb +53 -40
- data/lib/archimate/cli/svger.rb +33 -4
- data/lib/archimate/core_refinements.rb +41 -0
- data/lib/archimate/data_model/bounds.rb +14 -4
- data/lib/archimate/data_model/comparison.rb +3 -27
- data/lib/archimate/data_model/connection.rb +26 -11
- data/lib/archimate/data_model/diagram.rb +17 -10
- data/lib/archimate/data_model/element.rb +21 -9
- data/lib/archimate/data_model/elements.rb +24 -18
- data/lib/archimate/data_model/lang_string.rb +34 -10
- data/lib/archimate/data_model/layer.rb +6 -0
- data/lib/archimate/data_model/location.rb +10 -13
- data/lib/archimate/data_model/model.rb +55 -43
- data/lib/archimate/data_model/organization.rb +21 -5
- data/lib/archimate/data_model/property.rb +0 -6
- data/lib/archimate/data_model/referenceable.rb +29 -3
- data/lib/archimate/data_model/referenceable_list.rb +34 -14
- data/lib/archimate/data_model/relationship.rb +29 -8
- data/lib/archimate/data_model/relationship_references.rb +115 -6
- data/lib/archimate/data_model/relationships.rb +15 -0
- data/lib/archimate/data_model/view_node.rb +20 -13
- data/lib/archimate/data_model/viewpoint.rb +13 -1
- data/lib/archimate/data_model/viewpoints.rb +416 -0
- data/lib/archimate/data_model.rb +7 -1
- data/lib/archimate/derived_relations.rb +2 -11
- data/lib/archimate/export/cypher.rb +6 -5
- data/lib/archimate/file_format.rb +1 -0
- data/lib/archimate/file_formats/archi_file_reader.rb +11 -1
- data/lib/archimate/file_formats/archi_file_writer.rb +15 -46
- data/lib/archimate/file_formats/archi_file_writer_4.rb +14 -0
- data/lib/archimate/file_formats/model_exchange_file_reader.rb +2 -1
- data/lib/archimate/file_formats/model_exchange_file_writer_21.rb +1 -0
- data/lib/archimate/file_formats/sax/archi/diagram.rb +53 -13
- data/lib/archimate/file_formats/sax/archi/location.rb +1 -3
- data/lib/archimate/file_formats/sax/model_exchange_file/diagram.rb +13 -2
- data/lib/archimate/file_formats/sax.rb +1 -0
- data/lib/archimate/file_formats/serializer/archi/archi_file_writer.rb +63 -0
- data/lib/archimate/file_formats/serializer/archi/archi_file_writer_3.rb +18 -0
- data/lib/archimate/file_formats/serializer/archi/archi_file_writer_4.rb +18 -0
- data/lib/archimate/file_formats/serializer/archi/bounds.rb +2 -2
- data/lib/archimate/file_formats/serializer/archi/connection.rb +24 -13
- data/lib/archimate/file_formats/serializer/archi/diagram.rb +3 -3
- data/lib/archimate/file_formats/serializer/archi/element.rb +2 -2
- data/lib/archimate/file_formats/serializer/archi/organization.rb +1 -1
- data/lib/archimate/file_formats/serializer/archi/property.rb +1 -1
- data/lib/archimate/file_formats/serializer/archi/relationship.rb +2 -2
- data/lib/archimate/file_formats/serializer/archi/view_node.rb +20 -22
- data/lib/archimate/file_formats/serializer/archi/viewpoint3.rb +43 -0
- data/lib/archimate/file_formats/serializer/archi/viewpoint4.rb +41 -0
- data/lib/archimate/file_formats/serializer/model_exchange_file/style.rb +3 -7
- data/lib/archimate/file_formats/serializer/model_exchange_file/v21/diagram.rb +3 -3
- data/lib/archimate/file_formats/serializer/model_exchange_file/v21/model.rb +9 -2
- data/lib/archimate/file_formats/serializer/model_exchange_file/v21/view_node.rb +1 -1
- data/lib/archimate/file_formats/serializer/model_exchange_file/v21/viewpoint.rb +23 -0
- data/lib/archimate/file_formats/serializer/model_exchange_file/v30/diagram.rb +3 -3
- data/lib/archimate/file_formats/serializer/model_exchange_file/v30/model.rb +5 -7
- data/lib/archimate/file_formats/serializer/model_exchange_file/v30/view_node.rb +3 -3
- data/lib/archimate/file_formats/serializer/writer.rb +0 -5
- data/lib/archimate/file_formats/serializer.rb +6 -2
- data/lib/archimate/lint/duplicate_entities.rb +5 -5
- data/lib/archimate/lint/linter.rb +4 -4
- data/lib/archimate/maybe_io.rb +3 -2
- data/lib/archimate/svg/archimate.css +19 -21
- data/lib/archimate/svg/connection.rb +1 -1
- data/lib/archimate/svg/diagram.rb +1 -6
- data/lib/archimate/svg/entity/application_component.rb +9 -3
- data/lib/archimate/svg/entity/constraint.rb +0 -1
- data/lib/archimate/svg/entity/contract.rb +9 -0
- data/lib/archimate/svg/entity/data_entity.rb +1 -1
- data/lib/archimate/svg/entity/device.rb +1 -1
- data/lib/archimate/svg/entity/event_entity.rb +24 -7
- data/lib/archimate/svg/entity/group.rb +23 -4
- data/lib/archimate/svg/entity/grouping.rb +37 -0
- data/lib/archimate/svg/entity/interface_entity.rb +1 -1
- data/lib/archimate/svg/entity/node.rb +1 -1
- data/lib/archimate/svg/entity/outcome.rb +0 -1
- data/lib/archimate/svg/entity/principle.rb +0 -1
- data/lib/archimate/svg/entity/process_entity.rb +1 -1
- data/lib/archimate/svg/entity/requirement.rb +0 -1
- data/lib/archimate/svg/entity/service_entity.rb +6 -13
- data/lib/archimate/svg/entity.rb +1 -0
- data/lib/archimate/svg/entity_factory.rb +9 -5
- data/lib/archimate/svg/path.rb +57 -46
- data/lib/archimate/svg/point.rb +4 -0
- data/lib/archimate/svg/segment.rb +30 -0
- data/lib/archimate/svg/svg_template.svg.erb +11 -3
- data/lib/archimate/svg/view_node.rb +22 -0
- data/lib/archimate/version.rb +1 -1
- data/lib/archimate.rb +3 -2
- metadata +54 -54
- data/exe/archidiff +0 -7
- data/exe/archidiff-summary +0 -7
- data/exe/archimerge +0 -7
- data/exe/fmtxml +0 -7
- data/lib/archimate/data_model/viewpoint_type.rb +0 -389
- data/lib/archimate/file_formats/serializer/archi/location.rb +0 -26
- data/lib/archimate/file_formats/serializer/archi/viewpoint_type.rb +0 -45
- data/lib/archimate/svg/child.rb +0 -29
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 24983cbe0a25eb6b4fdd4592faf9d424f3f6dab8a0a28495cfa0c79f81bf6f18
|
|
4
|
+
data.tar.gz: 91796ec52b8680a1449c8a9e424894e786191a82b2e96679ca767dee69ffa04a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6b3d2698127d1aad4f6f729ef1735322658670e8527ab0d7a746ca23c9c7d77669ccb9751d731a4efe431355bf376904237f3a85fd60edf260f252a411a1a6be
|
|
7
|
+
data.tar.gz: 530ce2ba4cb376a6120fcb2c80c7aab6f2eed57c02a6dff21825de3018079c3714e39fec69728bc6dd38bbc0e8433e87d9c9d9fd458c9a4914738af2ad1cb0c5
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
|
@@ -26,62 +26,17 @@ Or install it yourself as:
|
|
|
26
26
|
|
|
27
27
|
The example scripts are (some are planned):
|
|
28
28
|
|
|
29
|
-
command
|
|
30
|
-
|
|
31
|
-
`archimate
|
|
29
|
+
command | description
|
|
30
|
+
----------------------------- | -----------
|
|
31
|
+
`archimate clean ARCHIFILE` | Clean up unreferenced elements and relations
|
|
32
32
|
`archimate convert ARCHIFILE` | Convert the incoming file to the desired type
|
|
33
|
-
`archimate dedupe ARCHIFILE`
|
|
34
|
-
`archimate
|
|
35
|
-
`archimate
|
|
36
|
-
`archimate
|
|
37
|
-
`archimate
|
|
38
|
-
`archimate
|
|
39
|
-
|
|
40
|
-
### archidiff & archimerge
|
|
41
|
-
|
|
42
|
-
Archidiff is a set of tools to help with versioning an `.archimate` file from Archi in a version control system (like git). Eventually I want to provide diff and (3-way) merge tools that understand how *Archi* files are structured and avoid problems that happen when multiple people collaborate on a model.
|
|
43
|
-
|
|
44
|
-
To enable using these from the command line git, add these lines to your `~/.gitconfig` replacing `{PATH_TO_ARCHIDIFF}` with the path to the archidiff binaries.
|
|
45
|
-
|
|
46
|
-
```
|
|
47
|
-
[difftool "archidiff"]
|
|
48
|
-
cmd = {PATH_TO_ARCHIDIFF}/archidiff $LOCAL $REMOTE
|
|
49
|
-
|
|
50
|
-
[difftool "archidiff-summary"]
|
|
51
|
-
cmd = {PATH_TO_ARCHIDIFF}/archidiff-summary $LOCAL $REMOTE
|
|
52
|
-
|
|
53
|
-
[mergetool "archimerge"]
|
|
54
|
-
cmd = {PATH_TO_ARCHIDIFF}/archimerge $PWD/$BASE $PWD/$REMOTE $PWD/$LOCAL $PWD/$MERGED
|
|
55
|
-
trustExitCode = false
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
Then to use the tool for diffing you can do this:
|
|
59
|
-
|
|
60
|
-
```sh
|
|
61
|
-
git difftool --tool archidiff 833cbb7 HEAD -- path_to/my.archimate
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
or to see a summary of what changed between versions:
|
|
65
|
-
|
|
66
|
-
```sh
|
|
67
|
-
git difftool --tool archidiff-summary 833cbb7 HEAD -- path_to/my.archimate
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
Finally, if you have a merge conflict, you can use archimerge to help make the merge sane:
|
|
71
|
-
|
|
72
|
-
```sh
|
|
73
|
-
git mergetool --tool archimerge -- path_to/my.archimate
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
### fmtxml
|
|
77
|
-
|
|
78
|
-
Can be used as a `textconv` filter in .gitconfig to pre-format files for better diff use (for visual scanning). You'd set this up in your `$HOME/.gitconfig` file like this.
|
|
79
|
-
|
|
80
|
-
```
|
|
81
|
-
[diff "archimate"]
|
|
82
|
-
textconv = fmtxml
|
|
83
|
-
cachetextconv = true
|
|
84
|
-
```
|
|
33
|
+
`archimate dedupe ARCHIFILE` | de-duplicate elements in Archi file
|
|
34
|
+
`archimate dupes ARCHIFILE` | List (potential) duplicate elements in Archi file
|
|
35
|
+
`archimate help [COMMAND]` | Describe available commands or one specific command
|
|
36
|
+
`archimate lint ARCHIFILE` | Examine the ArchiMate file for potential problems
|
|
37
|
+
`archimate map ARCHIFILE` | Produce a map of diagram links to a diagram
|
|
38
|
+
`archimate stats ARCHIFILE` | Show some statistics about the model
|
|
39
|
+
`archimate svg -o OUTPUTDIR ARCHIFILE o, --output=OUTPUT` | Produce semantically meaningful SVG files from an Archi file
|
|
85
40
|
|
|
86
41
|
## Development
|
|
87
42
|
|
data/Rakefile
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
# frozen_string_literal:
|
|
1
|
+
# frozen_string_literal: false
|
|
2
|
+
|
|
2
3
|
require "bundler/gem_tasks"
|
|
3
4
|
require "rake/testtask"
|
|
4
5
|
require "yard"
|
|
@@ -9,6 +10,23 @@ Rake::TestTask.new(:test) do |t|
|
|
|
9
10
|
t.test_files = FileList['test/**/*_test.rb']
|
|
10
11
|
end
|
|
11
12
|
|
|
13
|
+
namespace :test do
|
|
14
|
+
desc "Run only integration tests."
|
|
15
|
+
Rake::TestTask.new(:integration) do |t|
|
|
16
|
+
t.libs << "test"
|
|
17
|
+
t.libs << "lib"
|
|
18
|
+
t.test_files = FileList['test/integration/**/*_test.rb']
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
desc "Run tests and report slowest tests."
|
|
22
|
+
Rake::TestTask.new(:profile) do |t|
|
|
23
|
+
t.libs << "test"
|
|
24
|
+
t.libs << "lib"
|
|
25
|
+
t.options = "--profile"
|
|
26
|
+
t.test_files = FileList['test/**/*_test.rb']
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
12
30
|
YARD::Rake::YardocTask.new do |t|
|
|
13
31
|
t.options += ['--title', "YARD #{YARD::VERSION} Documentation"]
|
|
14
32
|
end
|
data/archimate.gemspec
CHANGED
|
@@ -21,32 +21,34 @@ Gem::Specification.new do |spec|
|
|
|
21
21
|
spec.metadata["yard.run"] = "yri" # use "yard" to build full HTML docs.
|
|
22
22
|
spec.required_ruby_version = '>= 2.3.0'
|
|
23
23
|
|
|
24
|
-
spec.add_runtime_dependency "nokogiri", "~> 1.6"
|
|
25
|
-
spec.add_runtime_dependency "thor", "~> 0.19"
|
|
26
24
|
spec.add_runtime_dependency "highline", "~> 1.7"
|
|
27
|
-
spec.add_runtime_dependency "
|
|
25
|
+
spec.add_runtime_dependency "nokogiri", "~> 1.6"
|
|
28
26
|
spec.add_runtime_dependency "parallel", "~> 1.11"
|
|
29
27
|
spec.add_runtime_dependency "ruby-enum", "~> 0.7.1"
|
|
28
|
+
spec.add_runtime_dependency "ruby-progressbar", "~>1.8.1"
|
|
29
|
+
spec.add_runtime_dependency "thor", "~> 0.19"
|
|
30
30
|
|
|
31
|
+
spec.add_development_dependency "awesome_print"
|
|
31
32
|
spec.add_development_dependency "bundler"
|
|
32
|
-
spec.add_development_dependency "
|
|
33
|
+
spec.add_development_dependency "faker"
|
|
34
|
+
spec.add_development_dependency "kramdown"
|
|
33
35
|
spec.add_development_dependency "minitest"
|
|
34
|
-
spec.add_development_dependency "minitest-matchers"
|
|
35
36
|
spec.add_development_dependency "minitest-color"
|
|
37
|
+
spec.add_development_dependency "minitest-matchers"
|
|
36
38
|
spec.add_development_dependency "minitest-profile"
|
|
37
39
|
spec.add_development_dependency "pry"
|
|
38
|
-
spec.add_development_dependency "
|
|
40
|
+
spec.add_development_dependency "rake"
|
|
41
|
+
spec.add_development_dependency "rubocop"
|
|
42
|
+
spec.add_development_dependency "yard"
|
|
43
|
+
|
|
44
|
+
# TODO: These should be in an MRI block
|
|
39
45
|
spec.add_development_dependency "guard"
|
|
40
|
-
spec.add_development_dependency "guard-minitest"
|
|
41
46
|
spec.add_development_dependency "guard-bundler"
|
|
47
|
+
spec.add_development_dependency "guard-ctags-bundler"
|
|
48
|
+
spec.add_development_dependency "guard-minitest"
|
|
49
|
+
spec.add_development_dependency "pry-byebug"
|
|
50
|
+
spec.add_development_dependency "rsense"
|
|
42
51
|
spec.add_development_dependency "ruby-prof"
|
|
43
52
|
spec.add_development_dependency "simplecov"
|
|
44
53
|
spec.add_development_dependency "simplecov-json"
|
|
45
|
-
spec.add_development_dependency "kramdown"
|
|
46
|
-
spec.add_development_dependency "yard"
|
|
47
|
-
spec.add_development_dependency "guard-ctags-bundler"
|
|
48
|
-
spec.add_development_dependency "faker"
|
|
49
|
-
spec.add_development_dependency "rsense"
|
|
50
|
-
spec.add_development_dependency "awesome_print"
|
|
51
|
-
spec.add_development_dependency "rubocop"
|
|
52
54
|
end
|
data/bin/archimate
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
# frozen_string_literal: true
|
|
3
|
+
|
|
3
4
|
#
|
|
4
5
|
# This file was generated by Bundler.
|
|
5
6
|
#
|
|
@@ -11,6 +12,17 @@ require "pathname"
|
|
|
11
12
|
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
|
12
13
|
Pathname.new(__FILE__).realpath)
|
|
13
14
|
|
|
15
|
+
bundle_binstub = File.expand_path("../bundle", __FILE__)
|
|
16
|
+
|
|
17
|
+
if File.file?(bundle_binstub)
|
|
18
|
+
if File.read(bundle_binstub, 150) =~ /This file was generated by Bundler/
|
|
19
|
+
load(bundle_binstub)
|
|
20
|
+
else
|
|
21
|
+
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
|
22
|
+
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
14
26
|
require "rubygems"
|
|
15
27
|
require "bundler/setup"
|
|
16
28
|
|
data/lib/archimate/cli/archi.rb
CHANGED
|
@@ -48,7 +48,7 @@ module Archimate
|
|
|
48
48
|
).map
|
|
49
49
|
end
|
|
50
50
|
|
|
51
|
-
desc "svg -o OUTPUTDIR ARCHIFILE", "
|
|
51
|
+
desc "svg -o OUTPUTDIR ARCHIFILE", "Produce semantically meaningful SVG files from an Archi file"
|
|
52
52
|
option :output,
|
|
53
53
|
aliases: :o,
|
|
54
54
|
required: true,
|
|
@@ -58,39 +58,53 @@ module Archimate
|
|
|
58
58
|
type: :boolean,
|
|
59
59
|
default: false,
|
|
60
60
|
desc: "Don't provide interactive feedback"
|
|
61
|
+
option :name,
|
|
62
|
+
type: :boolean,
|
|
63
|
+
default: false,
|
|
64
|
+
desc: "Use diagram name for filename (default: diagram id)"
|
|
61
65
|
def svg(archifile)
|
|
62
66
|
Config.instance.interactive = !options.fetch("noninteractive", false)
|
|
63
67
|
Archimate::Cli::Svger.export_svgs(
|
|
64
68
|
archifile,
|
|
65
|
-
options.fetch("output", Dir.pwd)
|
|
69
|
+
options.fetch("output", Dir.pwd),
|
|
70
|
+
options["name"] ? :name : :id
|
|
66
71
|
)
|
|
67
72
|
end
|
|
68
73
|
|
|
69
74
|
desc "clean ARCHIFILE", "Clean up unreferenced elements and relations"
|
|
70
75
|
option :output,
|
|
71
76
|
aliases: :o,
|
|
72
|
-
desc: "Write output to
|
|
77
|
+
desc: "Write output to OUTPUT instead of replacing ARCHIFILE"
|
|
73
78
|
option :saveremoved,
|
|
74
79
|
aliases: :r,
|
|
75
|
-
desc: "Write removed elements into
|
|
80
|
+
desc: "Write removed elements into SAVEREMOVED"
|
|
76
81
|
option :noninteractive,
|
|
77
82
|
aliases: :n,
|
|
78
83
|
type: :boolean,
|
|
79
84
|
default: false,
|
|
80
85
|
desc: "Don't provide interactive feedback"
|
|
86
|
+
option :force,
|
|
87
|
+
aliases: :f,
|
|
88
|
+
type: :boolean,
|
|
89
|
+
default: false,
|
|
90
|
+
desc: "Force overwriting of existing output file"
|
|
81
91
|
def clean(archifile)
|
|
82
92
|
Config.instance.interactive = !options.fetch("noninteractive", false)
|
|
83
|
-
|
|
93
|
+
output_io = Cli.output_io(
|
|
94
|
+
options.fetch("output", archifile),
|
|
95
|
+
options.fetch("force", false)
|
|
96
|
+
)
|
|
84
97
|
Archimate::MaybeIO.new(options.fetch(:saveremoved, nil)) do |removed_element_io|
|
|
85
|
-
Archimate::Cli::Cleanup.new(Archimate.read(archifile),
|
|
98
|
+
Archimate::Cli::Cleanup.new(Archimate.read(archifile), output_io, removed_element_io).clean
|
|
86
99
|
end
|
|
100
|
+
output_io.close
|
|
87
101
|
end
|
|
88
102
|
|
|
89
103
|
desc "dupes ARCHIFILE", "List (potential) duplicate elements in Archi file"
|
|
90
104
|
def dupes(archifile)
|
|
91
105
|
Archimate::Cli::Duper.new(
|
|
92
|
-
|
|
93
|
-
|
|
106
|
+
Archimate.read(archifile),
|
|
107
|
+
$stdout
|
|
94
108
|
).list
|
|
95
109
|
end
|
|
96
110
|
|
|
@@ -115,27 +129,32 @@ module Archimate
|
|
|
115
129
|
desc: "Don't provide interactive feedback"
|
|
116
130
|
def dedupe(archifile)
|
|
117
131
|
Config.instance.interactive = !options.fetch("noninteractive", false)
|
|
132
|
+
output_io = Cli.output_io(
|
|
133
|
+
options.fetch("output", archifile),
|
|
134
|
+
options[:force]
|
|
135
|
+
)
|
|
118
136
|
Archimate::Cli::Duper.new(
|
|
119
137
|
Archimate.read(archifile),
|
|
120
|
-
|
|
121
|
-
options.fetch("output", archifile),
|
|
122
|
-
options[:force]
|
|
123
|
-
),
|
|
138
|
+
output_io,
|
|
124
139
|
options[:mergeall]
|
|
125
140
|
).merge
|
|
141
|
+
output_io.close
|
|
126
142
|
end
|
|
127
143
|
|
|
128
144
|
desc "convert ARCHIFILE", "Convert the incoming file to the desired type"
|
|
145
|
+
long_desc <<~CONVERT_DESC
|
|
146
|
+
Converts the input ArchiMate file into another format. Options are:
|
|
147
|
+
\x5 • 'archi' for Archi file format (http://archimatetool.com),
|
|
148
|
+
\x5 • 'meff2.1' for Open Group Model Exchange File Format for ArchiMate 2.1,
|
|
149
|
+
\x5 • 'nquads' for RDF 1.1 N-Quads format https://www.w3.org/TR/n-quads/,
|
|
150
|
+
\x5 • 'graphml' for GraphML,
|
|
151
|
+
\x5 • 'csv' for CSV files (one file per element/relationship type)
|
|
152
|
+
CONVERT_DESC
|
|
129
153
|
option :to,
|
|
130
154
|
aliases: :t,
|
|
131
155
|
default: Archimate::Cli::Convert::SUPPORTED_FORMATS.first,
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
"'archi' for Archi http://archimatetool.com/ file format " \
|
|
135
|
-
"'nquads' for RDF 1.1 N-Quads format https://www.w3.org/TR/n-quads/" \
|
|
136
|
-
"'graphml' for GraphML" \
|
|
137
|
-
"'csv' for CSV files (one file per element/relationship type",
|
|
138
|
-
enum: Archimate::Cli::Convert::SUPPORTED_FORMATS
|
|
156
|
+
enum: Archimate::Cli::Convert::SUPPORTED_FORMATS,
|
|
157
|
+
desc: "Output format to convert to"
|
|
139
158
|
option :output,
|
|
140
159
|
aliases: :o,
|
|
141
160
|
desc: "Write output to FILE instead of stdout."
|
|
@@ -1,52 +1,68 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
|
|
2
3
|
require "nokogiri"
|
|
3
4
|
|
|
4
5
|
#
|
|
5
6
|
# The point of this script is to identify elements that aren't a part of any
|
|
6
7
|
# relationship and not referenced on any diagrams.
|
|
7
|
-
|
|
8
8
|
module Archimate
|
|
9
9
|
module Cli
|
|
10
10
|
class Cleanup
|
|
11
11
|
attr_reader :model
|
|
12
12
|
|
|
13
|
-
def
|
|
14
|
-
cleaner = new(Archimate.read(input), output, options)
|
|
15
|
-
cleaner.clean
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def initialize(model, output, options)
|
|
13
|
+
def initialize(model, output, removed_items_io)
|
|
19
14
|
@model = model
|
|
20
15
|
@output = output
|
|
21
|
-
@
|
|
22
|
-
@trash = Nokogiri::XML::Document.new("<deleted></deleted>")
|
|
16
|
+
@removed_items_io = removed_items_io
|
|
23
17
|
@model_set = nil
|
|
24
|
-
@progressbar = ProgressIndicator.new(total:
|
|
18
|
+
@progressbar = ProgressIndicator.new(total: unreferenced_nodes.size, title: "Unreferenced Elements and Relationships")
|
|
19
|
+
@unref_set = []
|
|
25
20
|
end
|
|
26
21
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
22
|
+
# detects elements not referenced by a relationship or a diagram
|
|
23
|
+
def unreferenced_elements
|
|
24
|
+
model
|
|
25
|
+
.elements
|
|
26
|
+
.select { |el| el.references.none?(&ref_is_relationship_or_diagram) }
|
|
27
|
+
end
|
|
30
28
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
@progressbar.increment
|
|
36
|
-
end
|
|
29
|
+
def unreferenced_relationships
|
|
30
|
+
model
|
|
31
|
+
.relationships
|
|
32
|
+
.select { |rel| rel.references.none?(&ref_is_relationship_or_diagram) }
|
|
37
33
|
end
|
|
38
34
|
|
|
39
|
-
def
|
|
40
|
-
|
|
35
|
+
def unreferenced_nodes
|
|
36
|
+
unreferenced_relationships + unreferenced_elements
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def destroy_nodes(nodes)
|
|
40
|
+
nodes.each do |unreferenced_node|
|
|
41
|
+
unreferenced_node.destroy
|
|
42
|
+
@removed_items_io.write(Color.uncolor(unreferenced_node.to_s) + "\n")
|
|
43
|
+
@unref_set << unreferenced_node
|
|
44
|
+
@progressbar.increment
|
|
45
|
+
end
|
|
41
46
|
end
|
|
42
47
|
|
|
43
48
|
def clean
|
|
44
49
|
return unless model
|
|
45
50
|
|
|
46
|
-
|
|
47
|
-
puts "
|
|
48
|
-
|
|
49
|
-
|
|
51
|
+
rels = unreferenced_relationships
|
|
52
|
+
$stdout.puts "Unreferenced Relationships: #{rels.size}"
|
|
53
|
+
destroy_nodes rels
|
|
54
|
+
els = unreferenced_elements
|
|
55
|
+
$stdout.puts "Unreferenced Elements: #{els.size}"
|
|
56
|
+
destroy_nodes els
|
|
57
|
+
|
|
58
|
+
$stdout.puts "Found #{@unref_set.size} model items unreferenced by diagram or relationships"
|
|
59
|
+
Archimate::FileFormats::ArchiFileWriter.write(model, @output)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
private
|
|
63
|
+
|
|
64
|
+
def ref_is_relationship_or_diagram
|
|
65
|
+
->(ref) { ref.is_a?(DataModel::Relationship) || ref.is_a?(DataModel::Diagram) }
|
|
50
66
|
end
|
|
51
67
|
end
|
|
52
68
|
end
|
data/lib/archimate/cli/duper.rb
CHANGED
data/lib/archimate/cli/mapper.rb
CHANGED
|
@@ -13,34 +13,57 @@ module Archimate
|
|
|
13
13
|
@output = output_io
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
+
def map
|
|
17
|
+
widths = compute_column_widths(process_diagrams(model.diagrams), HEADERS)
|
|
18
|
+
adjusted_widths = widths.inject(COL_DIVIDER.size * (HEADERS.size - 1), &:+)
|
|
19
|
+
header_row(widths, HEADERS)
|
|
20
|
+
organization_paths = build_organization_hash(model.organizations)
|
|
21
|
+
organization_paths.keys.sort.each do |organization_name|
|
|
22
|
+
diagrams = organization_paths[organization_name].select { |i| i.is_a?(DataModel::Diagram) }
|
|
23
|
+
next if diagrams.empty?
|
|
24
|
+
@output.puts(Color.color(format("%-#{adjusted_widths}s", organization_name), %i[bold green on_light_black]))
|
|
25
|
+
output_diagrams(process_diagrams(diagrams), widths)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
@output.puts "\n#{model.diagrams.size} Diagrams"
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
16
33
|
def header_row(widths, headers)
|
|
17
|
-
titles =
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
34
|
+
titles = widths
|
|
35
|
+
.zip(headers)
|
|
36
|
+
.map(&header_cell_format)
|
|
37
|
+
.join(col_divider)
|
|
38
|
+
@output.puts titles
|
|
39
|
+
@output.puts header_border(widths)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def col_divider
|
|
43
|
+
Color.color(COL_DIVIDER, :light_black)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def header_border(widths)
|
|
47
|
+
Color.color(widths.map { |w| "-" * w }.join("-+-"), :light_black)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def header_cell_format
|
|
51
|
+
->((width, header)) { Color.color(format("%-#{width}s", header).capitalize, %i[bold blue]) }
|
|
21
52
|
end
|
|
22
53
|
|
|
23
54
|
def process_diagrams(diagrams)
|
|
24
|
-
diagrams.map
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
when "archimate:ArchimateDiagramModel"
|
|
31
|
-
DataModel::ViewpointType.values[(row[2] || 0).to_i].to_s
|
|
32
|
-
else
|
|
33
|
-
row[3]
|
|
34
|
-
end
|
|
35
|
-
row[0] = Color.color("#{row[0]}.png", :underline)
|
|
36
|
-
row
|
|
55
|
+
diagrams.map do |diagram|
|
|
56
|
+
[
|
|
57
|
+
"#{diagram.id}.png",
|
|
58
|
+
diagram.name.to_s,
|
|
59
|
+
diagram.viewpoint_description
|
|
60
|
+
]
|
|
37
61
|
end
|
|
38
62
|
end
|
|
39
63
|
|
|
40
64
|
def compute_column_widths(diagrams, headers)
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
diagram.slice(0, headers.size).each_with_index do |o, i|
|
|
65
|
+
diagrams.each_with_object(headers.map(&:size)) do |diagram, memo|
|
|
66
|
+
diagram.each_with_index do |o, i|
|
|
44
67
|
memo[i] = !o.nil? && Color.uncolor(o).size > memo[i] ? Color.uncolor(o).size : memo[i]
|
|
45
68
|
end
|
|
46
69
|
memo
|
|
@@ -49,33 +72,23 @@ module Archimate
|
|
|
49
72
|
|
|
50
73
|
def output_diagrams(diagrams, widths)
|
|
51
74
|
diagrams.sort_by { |a| a[1] }.each do |m|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
75
|
+
@output.puts(
|
|
76
|
+
widths
|
|
77
|
+
.zip(m)
|
|
78
|
+
.map { |(width, col)| format("%-#{width}s", col) }
|
|
79
|
+
.join(Color.color(COL_DIVIDER, :light_black))
|
|
80
|
+
)
|
|
55
81
|
end
|
|
56
82
|
end
|
|
57
83
|
|
|
58
84
|
def build_organization_hash(organizations, parent = "", hash = {})
|
|
59
|
-
organizations.each_with_object(hash) do |i, a|
|
|
85
|
+
organization_paths = organizations.each_with_object(hash) do |i, a|
|
|
60
86
|
organization_path = [parent, i.name].join("/")
|
|
61
|
-
a[organization_path] = i
|
|
87
|
+
a[organization_path] = i.items
|
|
62
88
|
build_organization_hash(i.organizations, organization_path, a)
|
|
63
89
|
end
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
def map
|
|
67
|
-
widths = compute_column_widths(process_diagrams(model.diagrams), HEADERS)
|
|
68
|
-
adjusted_widths = widths.inject(COL_DIVIDER.size * (HEADERS.size - 1), &:+)
|
|
69
|
-
header_row(widths, HEADERS)
|
|
70
|
-
organization_paths = build_organization_hash(model.organizations)
|
|
71
|
-
organization_paths.keys.sort.each do |organization_name|
|
|
72
|
-
diagrams = organization_paths[organization_name].items.map { |i| model.lookup(i) }.select { |i| i.is_a?(DataModel::Diagram) }
|
|
73
|
-
next if diagrams.empty?
|
|
74
|
-
@output.puts(Color.color(format("%-#{adjusted_widths}s", organization_name), %i[bold green on_light_black]))
|
|
75
|
-
output_diagrams(process_diagrams(diagrams), widths)
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
@output.puts "\n#{model.diagrams.size} Diagrams"
|
|
90
|
+
organization_paths = { "/" => model.diagrams } if organization_paths.empty?
|
|
91
|
+
organization_paths
|
|
79
92
|
end
|
|
80
93
|
end
|
|
81
94
|
end
|
data/lib/archimate/cli/svger.rb
CHANGED
|
@@ -2,21 +2,26 @@
|
|
|
2
2
|
|
|
3
3
|
module Archimate
|
|
4
4
|
module Cli
|
|
5
|
+
SVG_NAME_OPTION = [:id, :name] # TODO: add a way to export in folders with :folder_name]
|
|
6
|
+
|
|
5
7
|
# This class is used to export SVG diagrams as defined in the given model
|
|
6
8
|
class Svger
|
|
7
|
-
def self.export_svgs(archi_file, output_dir)
|
|
8
|
-
new(Archimate.read(archi_file).diagrams, output_dir).export_svgs
|
|
9
|
+
def self.export_svgs(archi_file, output_dir, name_option = :id)
|
|
10
|
+
new(Archimate.read(archi_file).diagrams, output_dir, name_option).export_svgs
|
|
9
11
|
end
|
|
10
12
|
|
|
11
|
-
def initialize(diagrams, output_dir)
|
|
13
|
+
def initialize(diagrams, output_dir, name_option = :id)
|
|
12
14
|
@diagrams = diagrams
|
|
13
15
|
@output_dir = output_dir
|
|
16
|
+
@name_option = name_option
|
|
17
|
+
@diagram_base_names = {}
|
|
14
18
|
end
|
|
15
19
|
|
|
16
20
|
def export_svgs
|
|
21
|
+
@diagram_base_names = {}
|
|
17
22
|
progress = ProgressIndicator.new(total: @diagrams.size, title: "Writing SVGs")
|
|
18
23
|
@diagrams.each do |diagram|
|
|
19
|
-
export(diagram)
|
|
24
|
+
export(diagram, filename_for(diagram, @name_option))
|
|
20
25
|
progress.increment
|
|
21
26
|
end
|
|
22
27
|
ensure
|
|
@@ -29,6 +34,30 @@ module Archimate
|
|
|
29
34
|
svg_file.write(Svg::Diagram.new(diagram).to_svg)
|
|
30
35
|
end
|
|
31
36
|
end
|
|
37
|
+
|
|
38
|
+
# TODO: in case of duplicate name in a model, we need to extend the filename with a numeric or something.
|
|
39
|
+
def filename_for(diagram, name_option)
|
|
40
|
+
base_name = diagram_base_name(diagram, name_option)
|
|
41
|
+
if @diagram_base_names.include?(base_name)
|
|
42
|
+
idx = 2
|
|
43
|
+
while @diagram_base_names.include?(base_name + " - #{idx}") do
|
|
44
|
+
idx += 1
|
|
45
|
+
end
|
|
46
|
+
base_name = base_name + " - #{idx}"
|
|
47
|
+
end
|
|
48
|
+
base_name
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def diagram_base_name(diagram, name_option)
|
|
52
|
+
case name_option
|
|
53
|
+
when :name
|
|
54
|
+
diagram.name
|
|
55
|
+
# when :folder_name
|
|
56
|
+
# diagram.name # TODO: add the path
|
|
57
|
+
else
|
|
58
|
+
diagram.id
|
|
59
|
+
end
|
|
60
|
+
end
|
|
32
61
|
end
|
|
33
62
|
|
|
34
63
|
def self.process_svg_filename(name)
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Archimate
|
|
4
|
+
module CoreRefinements
|
|
5
|
+
refine String do
|
|
6
|
+
# Converts a mixed case string to a snake case string
|
|
7
|
+
# @return String
|
|
8
|
+
def snake_case
|
|
9
|
+
gsub(/([A-Z])/, '_\1').downcase.sub(/^_/, "")
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def to_method_name(suffix = nil)
|
|
13
|
+
[tr(' ', '_'), suffix]
|
|
14
|
+
.compact
|
|
15
|
+
.join("_")
|
|
16
|
+
.to_sym
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# A helper that makes it easier to compare a string to a DataModel::LangString
|
|
20
|
+
# @param [String, DataModel::LangString] other string to compare
|
|
21
|
+
# @returns [Boolean]
|
|
22
|
+
def ==(other)
|
|
23
|
+
super(other.to_s)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
refine Range do
|
|
28
|
+
# Returns midpoint of overlap between numeric ranges or nil if there
|
|
29
|
+
# is no overlap
|
|
30
|
+
# @param r [Range] a numeric range
|
|
31
|
+
# @return [Numeric] if the ranges overlap, the midpoint of the overlap
|
|
32
|
+
# @return [Nil] if the ranges do not overlap
|
|
33
|
+
def overlap_midpoint(r)
|
|
34
|
+
begin_max = [self, r].map(&:begin).max
|
|
35
|
+
end_min = [self, r].map(&:end).min
|
|
36
|
+
return nil if begin_max > end_min
|
|
37
|
+
(begin_max + end_min) / 2.0
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|