uml_architect 0.0.2 → 0.0.4
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/.gitignore +1 -0
- data/README.md +40 -2
- data/architect.gemspec +1 -0
- data/bin/architect +9 -8
- data/examples/class_with_details.yuml +1 -1
- data/examples/composition_and_aggregation.yuml +2 -0
- data/examples/dependancy.yuml +1 -0
- data/examples/inheritance.yuml +2 -0
- data/examples/notes.yuml +2 -1
- data/examples/{color_and_utf8.yuml → pending/color_and_utf8.yuml} +0 -0
- data/examples/{interface.yuml → pending/interface.yuml} +0 -0
- data/examples/{interface_inheritance.yuml → pending/interface_inheritance.yuml} +0 -0
- data/examples/{international_characters.yuml → pending/international_characters.yuml} +0 -0
- data/examples/{something_meaty.yuml → pending/something_meaty.yuml} +0 -0
- data/examples/simple_association.yuml +1 -1
- data/examples/{class.yuml → simple_class.yuml} +0 -0
- data/lib/architect.rb +1 -1
- data/lib/architect/association.rb +22 -8
- data/lib/architect/class.rb +2 -1
- data/lib/architect/diagram.rb +5 -4
- data/lib/architect/edge.rb +0 -1
- data/lib/architect/node.rb +0 -1
- data/lib/architect/note.rb +17 -0
- data/lib/architect/parser.rb +21 -9
- data/lib/architect/runner.rb +1 -0
- data/lib/architect/version.rb +1 -1
- data/spec/lib/association_spec.rb +9 -3
- data/spec/lib/diagram_spec.rb +8 -4
- data/spec/lib/note_spec.rb +12 -0
- data/spec/lib/parser_spec.rb +5 -0
- data/spec/lib/runner_spec.rb +2 -2
- metadata +27 -12
- data/examples/aggregation.yuml +0 -1
- data/examples/cardinality.yuml +0 -1
- data/examples/composition.yuml +0 -1
- data/examples/dependancies.yuml +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fcf588256acefa798a448fa32320d55ee3f05a55
|
4
|
+
data.tar.gz: c1e2454709dac2ab62e0b19e314c4116769829fa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4f9ebbe1d97f49c96afd4fad7daeaecaaae01aa2c21525ab05a52b17c1d039d064195cbd60cc0fe256a3bb2bafa52b929e6423b87ccf21f0668a703da08ee3cc
|
7
|
+
data.tar.gz: 508072ac21f5e4223c247b2fdd07aaf58e4ffeb6e2d97748b90d843011fc024f66c7112f2408292474dd7faa92b5d9d38da1c169738cbca2335246a16e33a6c7
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -9,9 +9,47 @@ Create UML Class diagrams using a [yUML](http://yuml.me/diagram/scruffy/class/sa
|
|
9
9
|
|
10
10
|
## Usage
|
11
11
|
|
12
|
-
$ architect file
|
12
|
+
$ architect [file ...]
|
13
13
|
|
14
|
-
|
14
|
+
This generates a output file with a svg extension with the same base name as the
|
15
|
+
input file.
|
16
|
+
|
17
|
+
## Examples
|
18
|
+
|
19
|
+
### Simple Class
|
20
|
+
[User]
|
21
|
+

|
22
|
+
|
23
|
+
### Class with methods and attributes
|
24
|
+
[User|+Firstname;+Lasname;-Password;|+Login();+Logout()]
|
25
|
+

|
26
|
+
|
27
|
+
### Simple Association
|
28
|
+
[User]-[Tweet]
|
29
|
+

|
30
|
+
|
31
|
+
### Inheritance
|
32
|
+
[Animal]^-[Cat]
|
33
|
+
[Animal]^-[Dog]
|
34
|
+

|
35
|
+
|
36
|
+
### Composition and Aggregation
|
37
|
+
[Car]++0..1-1[Carburetor]
|
38
|
+
[Pong]+0..1-0..*[Duck]
|
39
|
+

|
40
|
+
|
41
|
+
### Directional Association
|
42
|
+
[Order]-billing >[Address], [Order]-shipping >[Address]
|
43
|
+

|
44
|
+
|
45
|
+
### Dependency
|
46
|
+
[REST]uses-.->[HTTP]
|
47
|
+

|
48
|
+
|
49
|
+
### Notes
|
50
|
+
[note: this is a note]
|
51
|
+
[note: This is a note about user]-.-[User]
|
52
|
+

|
15
53
|
|
16
54
|
## Contributing
|
17
55
|
|
data/architect.gemspec
CHANGED
data/bin/architect
CHANGED
@@ -2,13 +2,14 @@
|
|
2
2
|
$: << "./lib"
|
3
3
|
require 'architect/runner'
|
4
4
|
|
5
|
-
if ARGV.count
|
6
|
-
puts "usage: architect file"
|
5
|
+
if ARGV.count == 0
|
6
|
+
puts "usage: architect [file ...]"
|
7
7
|
else
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
8
|
+
ARGV.each do |file|
|
9
|
+
if File.exists?(file)
|
10
|
+
Architect::Runner.new(file, 'svg')
|
11
|
+
else
|
12
|
+
puts file + ": file does not exist"
|
13
|
+
end
|
13
14
|
end
|
14
|
-
end
|
15
|
+
end
|
@@ -1 +1 @@
|
|
1
|
-
[User|+
|
1
|
+
[User|+Firstname;+Lasname;-Password;|+Login();+Logout()]
|
@@ -0,0 +1 @@
|
|
1
|
+
[Service]uses-.->[HTTP]
|
data/examples/inheritance.yuml
CHANGED
data/examples/notes.yuml
CHANGED
@@ -1 +1,2 @@
|
|
1
|
-
[
|
1
|
+
[note: this is a note]
|
2
|
+
[note: This is a note about user]-.-[User]
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -1 +1 @@
|
|
1
|
-
[
|
1
|
+
[User]-[Tweet]
|
File without changes
|
data/lib/architect.rb
CHANGED
@@ -3,16 +3,16 @@ require_relative 'edge'
|
|
3
3
|
|
4
4
|
module Architect
|
5
5
|
|
6
|
+
## Association between two classes
|
6
7
|
class Association < Edge
|
7
8
|
|
8
|
-
attr_accessor :attributes, :graph
|
9
|
-
|
10
9
|
TYPES = {
|
11
10
|
"<>" => "odiamond",
|
12
11
|
"+" => "odiamond",
|
13
12
|
"++" => "diamond",
|
14
13
|
"" => "none",
|
15
|
-
">" => "vee"
|
14
|
+
">" => "vee",
|
15
|
+
"^" => "empty"
|
16
16
|
}
|
17
17
|
|
18
18
|
def initialize(node1, node2, markup="->")
|
@@ -21,16 +21,20 @@ module Architect
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def parse_markup(markup)
|
24
|
-
matches = /(.*)
|
24
|
+
matches = /(.*)-\.-(.*)/.match(markup)
|
25
|
+
matches = /(.*)-(.*)/.match(markup) if matches == nil
|
25
26
|
left = matches[1]
|
26
27
|
right = matches[2]
|
28
|
+
style = get_linestyle(markup)
|
27
29
|
{arrowhead: get_arrow(right), arrowtail: get_arrow(left),
|
28
|
-
headlabel:
|
29
|
-
|
30
|
+
headlabel: " " + get_label(right) + " ",
|
31
|
+
taillabel: " " + get_label(left) + " ",
|
32
|
+
dir: "both", style: style}
|
30
33
|
end
|
31
34
|
|
35
|
+
# Return the type of arrow contained in the markup
|
32
36
|
def get_arrow(string)
|
33
|
-
tokens = /([
|
37
|
+
tokens = /([<>+\^]+)/.match(string)
|
34
38
|
if tokens == nil
|
35
39
|
return "none"
|
36
40
|
else
|
@@ -38,7 +42,8 @@ module Architect
|
|
38
42
|
end
|
39
43
|
end
|
40
44
|
|
41
|
-
|
45
|
+
# Remove the arrow to get label
|
46
|
+
def get_label(string)
|
42
47
|
return "" if string == nil
|
43
48
|
TYPES.keys.each do |arrow|
|
44
49
|
string = string.gsub(arrow, "")
|
@@ -46,6 +51,15 @@ module Architect
|
|
46
51
|
return string
|
47
52
|
end
|
48
53
|
|
54
|
+
def get_linestyle(string)
|
55
|
+
if /-\.-/.match(string) == nil
|
56
|
+
return "solid"
|
57
|
+
else
|
58
|
+
return "dashed"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# Add associations to Graphviz
|
49
63
|
def graph(g)
|
50
64
|
g.add_edges(@node1.graphnode, @node2.graphnode, @attributes)
|
51
65
|
end
|
data/lib/architect/class.rb
CHANGED
@@ -2,8 +2,8 @@ require_relative 'node'
|
|
2
2
|
|
3
3
|
module Architect
|
4
4
|
|
5
|
+
# Class in a class diagram
|
5
6
|
class Class < Architect::Node
|
6
|
-
|
7
7
|
attr_accessor :graphnode, :markup
|
8
8
|
|
9
9
|
def initialize(markup)
|
@@ -21,6 +21,7 @@ module Architect
|
|
21
21
|
return "{" + markup.gsub(";", "\\n") + "}"
|
22
22
|
end
|
23
23
|
|
24
|
+
# Add class to Graphviz
|
24
25
|
def graph(g)
|
25
26
|
@graphnode = g.add_nodes(@markup, @style)
|
26
27
|
end
|
data/lib/architect/diagram.rb
CHANGED
@@ -2,21 +2,22 @@ require 'graphviz'
|
|
2
2
|
require_relative 'parser'
|
3
3
|
|
4
4
|
module Architect
|
5
|
-
|
5
|
+
|
6
6
|
# Diagram is the base class for generating any diagram.
|
7
7
|
class Diagram
|
8
|
+
|
8
9
|
# Draw
|
9
10
|
# [diagram] string containing the markup of the diagram
|
10
|
-
def draw(diagram, output = "class_diagram.
|
11
|
+
def draw(diagram, output = "class_diagram.svg", ext = 'svg')
|
11
12
|
parser = Parser.new
|
12
13
|
elements = parser.parse(diagram)
|
13
14
|
graph = GraphViz.new("ClassDiagram", type: "digraph")
|
14
|
-
graph.node["fillcolor"] = "
|
15
|
+
graph.node["fillcolor"] = "lightgrey"
|
15
16
|
graph.node["style"] = "filled"
|
16
17
|
elements.each do |element|
|
17
18
|
element.graph(graph)
|
18
19
|
end
|
19
|
-
graph.output(ext.to_sym => output)
|
20
|
+
graph.output(ext.to_sym => output, nothugly: true)
|
20
21
|
end
|
21
22
|
|
22
23
|
end
|
data/lib/architect/edge.rb
CHANGED
data/lib/architect/node.rb
CHANGED
@@ -0,0 +1,17 @@
|
|
1
|
+
module Architect
|
2
|
+
|
3
|
+
# A note in a class diagram
|
4
|
+
class Note < Architect::Node
|
5
|
+
attr_accessor :graphnode
|
6
|
+
|
7
|
+
def initialize(markup)
|
8
|
+
matches = /note:(.+)/i.match(markup)
|
9
|
+
@markup = matches[1].strip
|
10
|
+
@style = {shape: "note", style: "filled", fillcolor: "lightgrey"}
|
11
|
+
end
|
12
|
+
|
13
|
+
def graph(g)
|
14
|
+
@graphnode = g.add_nodes(@markup, @style)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/architect/parser.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
require_relative 'class'
|
2
|
+
require_relative 'note'
|
2
3
|
require_relative 'association'
|
3
4
|
|
4
5
|
module Architect
|
5
|
-
|
6
|
+
|
6
7
|
# Parses yUML files
|
7
8
|
class Parser
|
8
9
|
|
@@ -36,18 +37,29 @@ module Architect
|
|
36
37
|
# [statement] String containing statement
|
37
38
|
# Returns a list of classes markup and association markup in the statement
|
38
39
|
def parse_statement(statement)
|
39
|
-
pattern = /\[(?<
|
40
|
+
pattern = /\[(?<node1>.+?)\](?<association>.+?)\[(?<node2>.+)\]/
|
40
41
|
tokens = pattern.match(statement)
|
41
42
|
if tokens
|
42
|
-
|
43
|
-
|
44
|
-
association = Association.new(
|
45
|
-
return [
|
43
|
+
node1 = get_node(tokens[:node1])
|
44
|
+
node2 = get_node(tokens[:node2])
|
45
|
+
association = Association.new(node1, node2, tokens[:association])
|
46
|
+
return [node1, node2, association]
|
46
47
|
else
|
47
|
-
tokens = /\[(?<
|
48
|
-
|
49
|
-
return [
|
48
|
+
tokens = /\[(?<node1>.*)\]/.match(statement)
|
49
|
+
node1 = get_node(tokens[:node1])
|
50
|
+
return [node1]
|
50
51
|
end
|
51
52
|
end
|
53
|
+
|
54
|
+
# [markup] string containing content inside square brackets
|
55
|
+
# Returns Note or Class
|
56
|
+
def get_node(markup)
|
57
|
+
if /^note/i.match(markup) != nil
|
58
|
+
return Note.new(markup)
|
59
|
+
else
|
60
|
+
return Class.new(markup)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
52
64
|
end
|
53
65
|
end
|
data/lib/architect/runner.rb
CHANGED
data/lib/architect/version.rb
CHANGED
@@ -10,12 +10,13 @@ describe Architect::Association do
|
|
10
10
|
end
|
11
11
|
|
12
12
|
it "parses simple association" do
|
13
|
-
@association.attributes
|
13
|
+
attributes = @association.instance_eval("@attributes")
|
14
|
+
attributes[:arrowhead].should == "none"
|
14
15
|
end
|
15
16
|
|
16
17
|
it "parses association markup" do
|
17
18
|
dot = {arrowhead: "vee", arrowtail: "odiamond",
|
18
|
-
headlabel: "n", taillabel: "1", dir: "both"}
|
19
|
+
headlabel: " n ", taillabel: " 1 ", dir: "both", style: "solid"}
|
19
20
|
@association.parse_markup("<>1-n>").should == dot
|
20
21
|
end
|
21
22
|
|
@@ -24,7 +25,12 @@ describe Architect::Association do
|
|
24
25
|
end
|
25
26
|
|
26
27
|
it "strips arrows from strings" do
|
27
|
-
@association.
|
28
|
+
@association.get_label(">1").should == "1"
|
29
|
+
end
|
30
|
+
|
31
|
+
it "can draw dashed and solid lines" do
|
32
|
+
@association.get_linestyle("-").should == "solid"
|
33
|
+
@association.get_linestyle("-.-").should == "dashed"
|
28
34
|
end
|
29
35
|
|
30
36
|
end
|
data/spec/lib/diagram_spec.rb
CHANGED
@@ -8,19 +8,23 @@ describe Architect::Diagram do
|
|
8
8
|
end
|
9
9
|
|
10
10
|
it "can draw a class" do
|
11
|
-
@diagram.send("draw", "[User]", "class.
|
11
|
+
@diagram.send("draw", "[User]", "class.svg")
|
12
12
|
end
|
13
13
|
|
14
14
|
it "can draw an association" do
|
15
|
-
@diagram.send("draw", "[User]-[Pet]", "association.
|
15
|
+
@diagram.send("draw", "[User]-[Pet]", "association.svg")
|
16
16
|
end
|
17
17
|
|
18
18
|
it "can draw a class with attributes and methods" do
|
19
|
-
@diagram.send("draw", "[User|name; age; height|login(); logout()]-[Pet]", "record.
|
19
|
+
@diagram.send("draw", "[User|name; age; height|login(); logout()]-[Pet]", "record.svg")
|
20
20
|
end
|
21
21
|
|
22
22
|
it "can draw a diagram with composition" do
|
23
|
-
@diagram.send("draw", "[Pond]<>0..1-0..*[Duck]", "composition.
|
23
|
+
@diagram.send("draw", "[Pond]<>0..1-0..*[Duck]", "composition.svg")
|
24
|
+
end
|
25
|
+
|
26
|
+
it "can draw a note" do
|
27
|
+
@diagram.send("draw", "[note: This is a note about user]-.-[User]\n[note: this is a note]", "note.svg")
|
24
28
|
end
|
25
29
|
|
26
30
|
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'note'
|
3
|
+
|
4
|
+
describe Architect::Note do
|
5
|
+
it "can create note from markup" do
|
6
|
+
note = Architect::Note.new("note: hello world")
|
7
|
+
g = double()
|
8
|
+
g.should_receive(:add_nodes).with("hello world", {style: "filled",
|
9
|
+
shape: "note", fillcolor: "lightgrey"})
|
10
|
+
note.graph(g)
|
11
|
+
end
|
12
|
+
end
|
data/spec/lib/parser_spec.rb
CHANGED
data/spec/lib/runner_spec.rb
CHANGED
@@ -7,12 +7,12 @@ describe Architect::Runner do
|
|
7
7
|
it "should draw from file" do
|
8
8
|
Architect::Diagram.any_instance.should_receive(:draw)
|
9
9
|
Kernel.stub_chain(:open, :read).and_return("[User]")
|
10
|
-
architect = Architect::Runner.new("tmp/example.yuml", 'png'
|
10
|
+
architect = Architect::Runner.new("tmp/example.yuml", 'png')
|
11
11
|
end
|
12
12
|
|
13
13
|
it "should be able to change extension" do
|
14
14
|
Kernel.stub_chain(:open, :read).and_return("[User]")
|
15
|
-
architect = Architect::Runner.new("test.yuml", "png"
|
15
|
+
architect = Architect::Runner.new("test.yuml", "png")
|
16
16
|
architect.send(:change_extension, "test.yuml", "png").should == "test.png"
|
17
17
|
end
|
18
18
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: uml_architect
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ibrahim Muhammad
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-10-
|
11
|
+
date: 2013-10-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ruby-graphviz
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - '>='
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: libxslt-ruby
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: listen
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -125,27 +139,26 @@ files:
|
|
125
139
|
- Rakefile
|
126
140
|
- architect.gemspec
|
127
141
|
- bin/architect
|
128
|
-
- examples/aggregation.yuml
|
129
|
-
- examples/cardinality.yuml
|
130
|
-
- examples/class.yuml
|
131
142
|
- examples/class_with_details.yuml
|
132
|
-
- examples/
|
133
|
-
- examples/
|
134
|
-
- examples/dependancies.yuml
|
143
|
+
- examples/composition_and_aggregation.yuml
|
144
|
+
- examples/dependancy.yuml
|
135
145
|
- examples/directional_association.yuml
|
136
146
|
- examples/inheritance.yuml
|
137
|
-
- examples/interface.yuml
|
138
|
-
- examples/interface_inheritance.yuml
|
139
|
-
- examples/international_characters.yuml
|
140
147
|
- examples/notes.yuml
|
148
|
+
- examples/pending/color_and_utf8.yuml
|
149
|
+
- examples/pending/interface.yuml
|
150
|
+
- examples/pending/interface_inheritance.yuml
|
151
|
+
- examples/pending/international_characters.yuml
|
152
|
+
- examples/pending/something_meaty.yuml
|
141
153
|
- examples/simple_association.yuml
|
142
|
-
- examples/
|
154
|
+
- examples/simple_class.yuml
|
143
155
|
- lib/architect.rb
|
144
156
|
- lib/architect/association.rb
|
145
157
|
- lib/architect/class.rb
|
146
158
|
- lib/architect/diagram.rb
|
147
159
|
- lib/architect/edge.rb
|
148
160
|
- lib/architect/node.rb
|
161
|
+
- lib/architect/note.rb
|
149
162
|
- lib/architect/parser.rb
|
150
163
|
- lib/architect/runner.rb
|
151
164
|
- lib/architect/version.rb
|
@@ -154,6 +167,7 @@ files:
|
|
154
167
|
- spec/lib/diagram_spec.rb
|
155
168
|
- spec/lib/edge_spec.rb
|
156
169
|
- spec/lib/node_spec.rb
|
170
|
+
- spec/lib/note_spec.rb
|
157
171
|
- spec/lib/parser_spec.rb
|
158
172
|
- spec/lib/runner_spec.rb
|
159
173
|
- spec/spec_helper.rb
|
@@ -187,6 +201,7 @@ test_files:
|
|
187
201
|
- spec/lib/diagram_spec.rb
|
188
202
|
- spec/lib/edge_spec.rb
|
189
203
|
- spec/lib/node_spec.rb
|
204
|
+
- spec/lib/note_spec.rb
|
190
205
|
- spec/lib/parser_spec.rb
|
191
206
|
- spec/lib/runner_spec.rb
|
192
207
|
- spec/spec_helper.rb
|
data/examples/aggregation.yuml
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
[Company]<>-1>[Location], [Location]+->[Point]
|
data/examples/cardinality.yuml
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
[Customer]1-0..*[Address]
|
data/examples/composition.yuml
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
[Company]++-1>[Location]
|
data/examples/dependancies.yuml
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
[HttpContext]uses -.->[Response]
|