railroady 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +7 -0
- data/AUTHORS.rdoc +17 -0
- data/CHANGELOG.rdoc +110 -0
- data/LICENSE.rdoc +340 -0
- data/README.rdoc +169 -0
- data/Rakefile +47 -0
- data/VERSION.yml +5 -0
- data/bin/railroady +58 -0
- data/lib/railroady.rb +5 -0
- data/lib/railroady/aasm_diagram.rb +109 -0
- data/lib/railroady/app_diagram.rb +113 -0
- data/lib/railroady/controllers_diagram.rb +95 -0
- data/lib/railroady/diagram_graph.rb +130 -0
- data/lib/railroady/models_diagram.rb +146 -0
- data/lib/railroady/options_struct.rb +178 -0
- data/lib/railroady/railtie.rb +13 -0
- data/lib/railroady/version.rb +14 -0
- data/tasks/railroady.rake +62 -0
- metadata +92 -0
data/README.rdoc
ADDED
@@ -0,0 +1,169 @@
|
|
1
|
+
= RailRoady
|
2
|
+
|
3
|
+
RailRoady generates models and controllers diagrams in DOT language for a
|
4
|
+
Rails application.
|
5
|
+
|
6
|
+
This is a patched version based on the original v0.5.0.
|
7
|
+
|
8
|
+
I (Peter Hoeg) am not trying to hijack Javier's project, but since he hasn't released any
|
9
|
+
new versions since May '08, I figured I'd better put one out in order to make
|
10
|
+
railroad work with rails v2.3.
|
11
|
+
|
12
|
+
= Usage
|
13
|
+
|
14
|
+
Run RailRoady on the Rails application's root directory. You can redirect its
|
15
|
+
output to a .dot file or pipe it to the dot or neato utilities to produce a
|
16
|
+
graphic. Model diagrams are intended to be processed using dot and
|
17
|
+
controller diagrams are best processed using neato.
|
18
|
+
|
19
|
+
railroad [options] command
|
20
|
+
|
21
|
+
== Options
|
22
|
+
|
23
|
+
Common options:
|
24
|
+
-b, --brief Generate compact diagram
|
25
|
+
(no attributes nor methods)
|
26
|
+
-s, --specify file1[,fileN] Specify given files only for the diagram
|
27
|
+
(can take a glob pattern)
|
28
|
+
-e, --exclude file1[,fileN] Exclude given files
|
29
|
+
(can take a glob pattern)
|
30
|
+
-i, --inheritance Include inheritance relations
|
31
|
+
-l, --label Add a label with diagram information
|
32
|
+
(type, date, migration, version)
|
33
|
+
-o, --output FILE Write diagram to file FILE
|
34
|
+
-v, --verbose Enable verbose output
|
35
|
+
(produce messages to STDOUT)
|
36
|
+
|
37
|
+
Models diagram options:
|
38
|
+
-a, --all Include all models
|
39
|
+
(not only ActiveRecord::Base derived)
|
40
|
+
--hide-magic Hide magic field names
|
41
|
+
--hide-types Hide attributes type
|
42
|
+
-j, --join Concentrate edges
|
43
|
+
-m, --modules Include modules
|
44
|
+
-p, --plugins-models Include plugins models
|
45
|
+
-t, --transitive Include transitive associations
|
46
|
+
(through inheritance)
|
47
|
+
|
48
|
+
Controllers diagram options:
|
49
|
+
--hide-public Hide public methods
|
50
|
+
--hide-protected Hide protected methods
|
51
|
+
--hide-private Hide private methods
|
52
|
+
|
53
|
+
Other options:
|
54
|
+
-h, --help Show this message
|
55
|
+
--version Show version and copyright
|
56
|
+
|
57
|
+
== Commands
|
58
|
+
|
59
|
+
-M, --models Generate models diagram
|
60
|
+
-C, --controllers Generate controllers diagram
|
61
|
+
-A, --aasm Generate "acts as state machine" diagram
|
62
|
+
|
63
|
+
|
64
|
+
== Examples
|
65
|
+
|
66
|
+
railroad -o models.dot -M
|
67
|
+
Produces a models diagram to the file 'models.dot'
|
68
|
+
railroad -a -i -o full_models.dot -M
|
69
|
+
Models diagram with all classes showing inheritance relations
|
70
|
+
railroad -M | dot -Tsvg > models.svg
|
71
|
+
Model diagram in SVG format
|
72
|
+
railroad -C | neato -Tpng > controllers.png
|
73
|
+
Controller diagram in PNG format
|
74
|
+
railroad -h
|
75
|
+
Shows usage help
|
76
|
+
|
77
|
+
|
78
|
+
= Processing DOT files
|
79
|
+
|
80
|
+
To produce a PNG image from model diagram generated by RailRoady you can
|
81
|
+
issue the following command:
|
82
|
+
|
83
|
+
dot -Tpng models.dot > models.png
|
84
|
+
|
85
|
+
If you want to do the same with a controller diagram, use neato instead of
|
86
|
+
dot:
|
87
|
+
|
88
|
+
neato -Tpng controllers.dot > controllers.png
|
89
|
+
|
90
|
+
If you want to produce SVG (vectorial, scalable, editable) files, you can do
|
91
|
+
the following:
|
92
|
+
|
93
|
+
dot -Tsvg models.dot > models.svg
|
94
|
+
neato -Tsvg controllers.dot > controllers.svg
|
95
|
+
|
96
|
+
Important: There is a bug in Graphviz tools when generating SVG files that
|
97
|
+
cause a text overflow. You can solve this problem editing (with a text
|
98
|
+
editor, not a graphical SVG editor) the file and replacing around line 12
|
99
|
+
"font-size:14.00;" by "font-size:11.00;", or by issuing the following command
|
100
|
+
(see "man sed"):
|
101
|
+
|
102
|
+
sed -i 's/font-size:14.00/font-size:11.00/g' file.svg
|
103
|
+
|
104
|
+
Note: For viewing and editing SVG there is an excellent opensource tool
|
105
|
+
called Inkscape (similar to Adobe Illustrator. For DOT processing you can
|
106
|
+
also use Omnigraffle (on Mac OS X).
|
107
|
+
|
108
|
+
= RailRoady as a rake task
|
109
|
+
|
110
|
+
(Thanks to Thomas Ritz, http://www.galaxy-ritz.de ,for the code.)
|
111
|
+
|
112
|
+
In your Rails application, put the following rake tasks into 'lib/task/diagrams.rake':
|
113
|
+
|
114
|
+
namespace :doc do
|
115
|
+
namespace :diagram do
|
116
|
+
task :models do
|
117
|
+
sh "railroad -i -l -a -m -M | dot -Tsvg | sed 's/font-size:14.00/font-size:11.00/g' > doc/models.svg"
|
118
|
+
end
|
119
|
+
|
120
|
+
task :controllers do
|
121
|
+
sh "railroad -i -l -C | neato -Tsvg | sed 's/font-size:14.00/font-size:11.00/g' > doc/controllers.svg"
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
task :diagrams => %w(diagram:models diagram:controllers)
|
126
|
+
end
|
127
|
+
|
128
|
+
Then, 'rake doc:diagrams' produces 'doc/models.svg' and 'doc/controllers.svg'.
|
129
|
+
|
130
|
+
= Requirements
|
131
|
+
|
132
|
+
RailRoady has been tested with the following Ruby and Rails versions
|
133
|
+
|
134
|
+
== Ruby
|
135
|
+
* 1.8.5
|
136
|
+
* 1.8.7
|
137
|
+
|
138
|
+
== Rails
|
139
|
+
* 1.1.6 to 1.2.3
|
140
|
+
* 2.3.2 to 2.3.5
|
141
|
+
|
142
|
+
There are no additional requirements (nevertheless, all your Rails application
|
143
|
+
requirements must be installed).
|
144
|
+
|
145
|
+
In order to view/export the DOT diagrams, you'll need the processing tools
|
146
|
+
from Graphviz.
|
147
|
+
|
148
|
+
= Website and Project Home
|
149
|
+
|
150
|
+
http://railroad.rubyforge.org
|
151
|
+
|
152
|
+
= License
|
153
|
+
|
154
|
+
RailRoady is distributed under the terms of the GNU General Public License
|
155
|
+
as published by the Free Software Foundation; either version 2 of the
|
156
|
+
License, or (at your option) any later version.
|
157
|
+
|
158
|
+
See LICENSE for details.
|
159
|
+
|
160
|
+
== Copyright
|
161
|
+
|
162
|
+
Copyright (c) 2007-2008 Javier Smaldone
|
163
|
+
Copyright (c) 2009 Peter Hoeg
|
164
|
+
|
165
|
+
See LICENSE for details.
|
166
|
+
|
167
|
+
== Authors
|
168
|
+
|
169
|
+
See AUTHORS for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "railroady"
|
8
|
+
gem.executables = "railroady"
|
9
|
+
gem.email = ['conmotto@gmail.com', 'tcrawley@gmail.com', 'peter@hoeg.com', 'p.hoeg@northwind.sg', 'javier@smaldone.com.ar']
|
10
|
+
gem.homepage = "http://github.com/preston/railroady"
|
11
|
+
gem.authors = ["Preston Lee", "Tobias Crawley", "Peter Hoeg", "Javier Smaldone"]
|
12
|
+
gem.summary = "A DOT diagram generator for Ruby on Rail applications."
|
13
|
+
gem.description = gem.summary
|
14
|
+
gem.files = FileList["[A-Z]*", "{autotest,bin,lib,spec,tasks}/**/*", ".document"]
|
15
|
+
gem.extra_rdoc_files = FileList["*.rdoc"]
|
16
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
17
|
+
end
|
18
|
+
|
19
|
+
rescue LoadError
|
20
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
21
|
+
end
|
22
|
+
|
23
|
+
require 'rspec'
|
24
|
+
require 'rspec/core/rake_task'
|
25
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
26
|
+
# spec.libs << 'lib' << 'rspec'
|
27
|
+
spec.pattern = FileList['rspec/**/*_spec.rb']
|
28
|
+
end
|
29
|
+
|
30
|
+
RSpec::Core::RakeTask.new(:rcov) do |spec|
|
31
|
+
# spec.libs << 'lib' << 'rspec'
|
32
|
+
spec.pattern = 'rspec/**/*_spec.rb'
|
33
|
+
spec.rcov = true
|
34
|
+
end
|
35
|
+
|
36
|
+
task :default => :spec
|
37
|
+
|
38
|
+
require 'rake/rdoctask'
|
39
|
+
require 'railroady/version'
|
40
|
+
Rake::RDocTask.new do |rdoc|
|
41
|
+
rdoc.rdoc_dir = 'rdoc'
|
42
|
+
rdoc.title = "railroady #{RailRoady::VERSION::STRING}"
|
43
|
+
rdoc.rdoc_files.include('README*')
|
44
|
+
rdoc.rdoc_files.include('CHANGELOG*')
|
45
|
+
rdoc.rdoc_files.include('AUTHORS*')
|
46
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
47
|
+
end
|
data/VERSION.yml
ADDED
data/bin/railroady
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# RailRoady - RoR diagrams generator
|
4
|
+
# http://github.com/preston/railroady
|
5
|
+
#
|
6
|
+
# RailRoady generates models and controllers diagrams in DOT language
|
7
|
+
# for a Rails v3 application.
|
8
|
+
#
|
9
|
+
# Copyright 2007-2008 - Javier Smaldone (http://www.smaldone.com.ar)
|
10
|
+
#
|
11
|
+
# This program is free software; you can redistribute it and/or modify
|
12
|
+
# it under the terms of the GNU General Public License as published by
|
13
|
+
# the Free Software Foundation; either version 2 of the License, or
|
14
|
+
# (at your option) any later version.
|
15
|
+
#
|
16
|
+
# Modification 2010 by Preston Lee.
|
17
|
+
#
|
18
|
+
|
19
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
20
|
+
require 'railroady'
|
21
|
+
|
22
|
+
APP_NAME = "railroady"
|
23
|
+
APP_HUMAN_NAME = "RailRoady"
|
24
|
+
# APP_VERSION = [RailRoady::VERSION::MAJOR, RailRoady::VERSION::MINOR, RailRoady::VERSION::PATCH]
|
25
|
+
APP_VERSION = RailRoady::VERSION::STRING
|
26
|
+
COPYRIGHT = "Copyright (C) 2007-2008 Javier Smaldone, 2009 Peter Hoeg, 2010 Preston Lee"
|
27
|
+
|
28
|
+
options = OptionsStruct.new({:app_name => APP_NAME, :app_human_name => APP_HUMAN_NAME, :app_version =>APP_VERSION, :copyright =>COPYRIGHT})
|
29
|
+
|
30
|
+
options.parse ARGV
|
31
|
+
|
32
|
+
# puts "OPTS!!!"
|
33
|
+
# puts options
|
34
|
+
|
35
|
+
old_dir = Dir.pwd
|
36
|
+
|
37
|
+
Dir.chdir(options.root) if options.root != ''
|
38
|
+
|
39
|
+
if options.command == 'models'
|
40
|
+
diagram = ModelsDiagram.new options
|
41
|
+
elsif options.command == 'controllers'
|
42
|
+
diagram = ControllersDiagram.new options
|
43
|
+
elsif options.command == 'aasm'
|
44
|
+
diagram = AasmDiagram.new(options)
|
45
|
+
else
|
46
|
+
STDERR.print "#{APP_HUMAN_NAME} v#{RailRoady::VERSION::STRING}\n" +
|
47
|
+
"Error: You must supply a command\n" +
|
48
|
+
" (try #{APP_NAME} -h)\n\n"
|
49
|
+
exit 1
|
50
|
+
end
|
51
|
+
|
52
|
+
diagram.process
|
53
|
+
diagram.generate
|
54
|
+
|
55
|
+
Dir.chdir(old_dir)
|
56
|
+
|
57
|
+
diagram.print
|
58
|
+
|
data/lib/railroady.rb
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
# RailRoady - RoR diagrams generator
|
2
|
+
# http://railroad.rubyforge.org
|
3
|
+
#
|
4
|
+
# Copyright 2007-2008 - Javier Smaldone (http://www.smaldone.com.ar)
|
5
|
+
# See COPYING for more details
|
6
|
+
|
7
|
+
# AASM code provided by Ana Nelson (http://ananelson.com/)
|
8
|
+
|
9
|
+
require 'railroady/app_diagram'
|
10
|
+
|
11
|
+
# Diagram for Acts As State Machine
|
12
|
+
class AasmDiagram < AppDiagram
|
13
|
+
|
14
|
+
def initialize(options = OptionsStruct.new)
|
15
|
+
#options.exclude.map! {|e| e = "app/models/" + e}
|
16
|
+
super options
|
17
|
+
@graph.diagram_type = 'Models'
|
18
|
+
# Processed habtm associations
|
19
|
+
@habtm = []
|
20
|
+
end
|
21
|
+
|
22
|
+
# Process model files
|
23
|
+
def generate
|
24
|
+
STDERR.print "Generating AASM diagram\n" if @options.verbose
|
25
|
+
get_files.each do |f|
|
26
|
+
process_class extract_class_name(f).constantize
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def get_files(prefix ='')
|
31
|
+
files = !@options.specify.empty? ? Dir.glob(@options.specify) : Dir.glob(prefix << "app/models/**/*.rb")
|
32
|
+
files += Dir.glob("vendor/plugins/**/app/models/*.rb") if @options.plugins_models
|
33
|
+
files -= Dir.glob(@options.exclude)
|
34
|
+
files
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
# Load model classes
|
40
|
+
def load_classes
|
41
|
+
begin
|
42
|
+
disable_stdout
|
43
|
+
get_files.each {|m| require m }
|
44
|
+
enable_stdout
|
45
|
+
rescue LoadError
|
46
|
+
enable_stdout
|
47
|
+
print_error "model classes"
|
48
|
+
raise
|
49
|
+
end
|
50
|
+
end # load_classes
|
51
|
+
|
52
|
+
# Process a model class
|
53
|
+
def process_class(current_class)
|
54
|
+
|
55
|
+
STDERR.print "\tProcessing #{current_class}\n" if @options.verbose
|
56
|
+
|
57
|
+
# Only interested in acts_as_state_machine models.
|
58
|
+
process_acts_as_state_machine_class(current_class) if current_class.respond_to?(:states)
|
59
|
+
process_aasm_class(current_class) if current_class.respond_to?(:aasm_states)
|
60
|
+
end # process_class
|
61
|
+
|
62
|
+
def process_acts_as_state_machine_class(current_class)
|
63
|
+
node_attribs = []
|
64
|
+
node_type = 'aasm'
|
65
|
+
|
66
|
+
STDERR.print "\t\tprocessing as acts_as_state_machine\n" if @options.verbose
|
67
|
+
current_class.states.each do |state_name|
|
68
|
+
state = current_class.read_inheritable_attribute(:states)[state_name]
|
69
|
+
node_shape = (current_class.initial_state === state_name) ? ", peripheries = 2" : ""
|
70
|
+
node_attribs << "#{current_class.name.downcase}_#{state_name} [label=#{state_name} #{node_shape}];"
|
71
|
+
end
|
72
|
+
@graph.add_node [node_type, current_class.name, node_attribs]
|
73
|
+
|
74
|
+
current_class.read_inheritable_attribute(:transition_table).each do |event_name, event|
|
75
|
+
event.each do |transition|
|
76
|
+
@graph.add_edge [
|
77
|
+
'event',
|
78
|
+
current_class.name.downcase + "_" + transition.from.to_s,
|
79
|
+
current_class.name.downcase + "_" + transition.to.to_s,
|
80
|
+
event_name.to_s
|
81
|
+
]
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def process_aasm_class(current_class)
|
87
|
+
node_attribs = []
|
88
|
+
node_type = 'aasm'
|
89
|
+
|
90
|
+
STDERR.print "\t\tprocessing as aasm\n" if @options.verbose
|
91
|
+
current_class.aasm_states.each do |state|
|
92
|
+
node_shape = (current_class.aasm_initial_state === state.name) ? ", peripheries = 2" : ""
|
93
|
+
node_attribs << "#{current_class.name.downcase}_#{state.name} [label=#{state.name} #{node_shape}];"
|
94
|
+
end
|
95
|
+
@graph.add_node [node_type, current_class.name, node_attribs]
|
96
|
+
|
97
|
+
current_class.aasm_events.each do |event_name, event|
|
98
|
+
event.all_transitions.each do |transition|
|
99
|
+
@graph.add_edge [
|
100
|
+
'event',
|
101
|
+
current_class.name.downcase + "_" + transition.from.to_s,
|
102
|
+
current_class.name.downcase + "_" + transition.to.to_s,
|
103
|
+
event_name.to_s
|
104
|
+
]
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
end # class AasmDiagram
|
@@ -0,0 +1,113 @@
|
|
1
|
+
# RailRoady - RoR diagrams generator
|
2
|
+
# http://railroad.rubyforge.org
|
3
|
+
#
|
4
|
+
# Copyright 2007-2008 - Javier Smaldone (http://www.smaldone.com.ar)
|
5
|
+
# See COPYING for more details
|
6
|
+
|
7
|
+
require 'railroady/diagram_graph'
|
8
|
+
|
9
|
+
# camelize and constantize methods brought over from active_support
|
10
|
+
class String
|
11
|
+
def camelize(first_letter_in_uppercase = true)
|
12
|
+
if first_letter_in_uppercase
|
13
|
+
self.to_s.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
|
14
|
+
else
|
15
|
+
self.first + self.camelize[1..-1]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
def constantize
|
19
|
+
names = self.split('::')
|
20
|
+
names.shift if names.empty? || names.first.empty?
|
21
|
+
|
22
|
+
constant = Object
|
23
|
+
names.each do |name|
|
24
|
+
constant = constant.const_defined?(name) ? constant.const_get(name) : constant.const_missing(name)
|
25
|
+
end
|
26
|
+
constant
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Root class for RailRoady diagrams
|
31
|
+
class AppDiagram
|
32
|
+
|
33
|
+
def initialize(options = OptionsStruct.new)
|
34
|
+
@options = options
|
35
|
+
@graph = DiagramGraph.new
|
36
|
+
@graph.show_label = @options.label
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
# Print diagram
|
41
|
+
def print
|
42
|
+
if @options.output
|
43
|
+
old_stdout = STDOUT.dup
|
44
|
+
begin
|
45
|
+
STDOUT.reopen(@options.output)
|
46
|
+
rescue
|
47
|
+
STDERR.print "Error: Cannot write diagram to #{@options.output}\n\n"
|
48
|
+
exit 2
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
if @options.xmi
|
53
|
+
STDERR.print "Generating XMI diagram\n" if @options.verbose
|
54
|
+
STDOUT.print @graph.to_xmi
|
55
|
+
else
|
56
|
+
STDERR.print "Generating DOT graph\n" if @options.verbose
|
57
|
+
STDOUT.print @graph.to_dot
|
58
|
+
end
|
59
|
+
|
60
|
+
if @options.output
|
61
|
+
STDOUT.reopen(old_stdout)
|
62
|
+
end
|
63
|
+
end # print
|
64
|
+
|
65
|
+
def process
|
66
|
+
load_environment
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
# Load Rails application's environment
|
72
|
+
def load_environment
|
73
|
+
STDERR.print "Loading application environment\n" if @options.verbose
|
74
|
+
begin
|
75
|
+
disable_stdout
|
76
|
+
l = File.join(Dir.pwd.to_s, 'config/environment')
|
77
|
+
require l
|
78
|
+
enable_stdout
|
79
|
+
rescue LoadError
|
80
|
+
enable_stdout
|
81
|
+
print_error "application environment"
|
82
|
+
raise
|
83
|
+
end
|
84
|
+
STDERR.print "Loading application classes as we go\n" if @options.verbose
|
85
|
+
end
|
86
|
+
|
87
|
+
# Prevents Rails application from writing to STDOUT
|
88
|
+
def disable_stdout
|
89
|
+
@old_stdout = STDOUT.dup
|
90
|
+
STDOUT.reopen(::RUBY_PLATFORM =~ /mswin/ ? "NUL" : "/dev/null")
|
91
|
+
end
|
92
|
+
|
93
|
+
# Restore STDOUT
|
94
|
+
def enable_stdout
|
95
|
+
STDOUT.reopen(@old_stdout)
|
96
|
+
end
|
97
|
+
|
98
|
+
|
99
|
+
# Print error when loading Rails application
|
100
|
+
def print_error(type)
|
101
|
+
STDERR.print "Error loading #{type}.\n (Are you running " +
|
102
|
+
"#{@options.app_name} on the aplication's root directory?)\n\n"
|
103
|
+
end
|
104
|
+
|
105
|
+
# Extract class name from filename
|
106
|
+
def extract_class_name(filename)
|
107
|
+
#filename.split('/')[2..-1].join('/').split('.').first.camelize
|
108
|
+
# Fixed by patch from ticket #12742
|
109
|
+
# File.basename(filename).chomp(".rb").camelize
|
110
|
+
filename.split('/')[2..-1].collect { |i| i.camelize }.join('::').chomp(".rb")
|
111
|
+
end
|
112
|
+
|
113
|
+
end # class AppDiagram
|