rails-erd 1.5.2 → 1.6.0

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
- SHA1:
3
- metadata.gz: 33b2df60c7db63f567ecf08e5e221d7e47dc0234
4
- data.tar.gz: 85fd38a21b0bb31cdbe1e19c20d0fbdd56e5d617
2
+ SHA256:
3
+ metadata.gz: 92187ba08cd1adaa824abac10a7b33b94d5c5659bbc2177e628fac853e28fa4c
4
+ data.tar.gz: cfde87f41307742ca046d9b6c899f9f71211c13e1a6294ef03aeea082b6a4d8e
5
5
  SHA512:
6
- metadata.gz: 0f10ee2e13c4d6e25c5bd3e4bc1e0df346a44f874e61f7f38ff0503639d046623a28bab1883cc49ff9fee1da3f5ecd1455a301b066eaa516c61ed04efe2fbe3b
7
- data.tar.gz: 6b4ddb644d1966ff5f5a3d34a016ea5668f5ddfcc3914eeb539f10760e7eda79ecc5fca593e84a141f23b420919aab783811e99c9d7ba76cc28110aeb86b365a
6
+ metadata.gz: df5946aeffa73955192e36dc3a6de6a66f824f6537af8cae9575f9b2f3e14ab5bef28464573b5615a9a12381cf74fe23bc332e5caa5e0774f6cccf42c8739e27
7
+ data.tar.gz: 34609d17ee199b9c39b92eb87885665d89b1db42a968a6f58cf2c508a8a42e9a4d4a1ac22ab3b2cd60b2ed57c119580211e4514102f5008fce38408dd8527382
data/README.md CHANGED
@@ -30,9 +30,9 @@ Getting started
30
30
 
31
31
  See the [installation instructions](https://voormedia.github.io/rails-erd/install.html) for a complete description of how to install Rails ERD. Here's a summary:
32
32
 
33
- * Install Graphviz 2.22+ ([how?](https://voormedia.github.io/rails-erd/install.html))
33
+ * Install Graphviz 2.22+ ([how?](https://voormedia.github.io/rails-erd/install.html)). On macOS with Homebrew run `brew install graphviz`.
34
34
 
35
- * Add <tt>gem "rails-erd"</tt> to your application's Gemfile
35
+ * Add <tt>gem 'rails-erd', group: :development</tt> to your application's Gemfile
36
36
 
37
37
  * Run <tt>bundle exec erd</tt>
38
38
 
@@ -69,8 +69,8 @@ splines: spline
69
69
  Auto generation
70
70
  ---------------
71
71
 
72
- * Run <tt>rails generate erd:install</tt>
73
- * Run <tt>rails db:migrate</tt>, then the diagram is generated
72
+ * Run <tt>bundle exec rails g erd:install</tt>
73
+ * Run <tt>bundle exec rails db:migrate</tt>, then the diagram is generated
74
74
 
75
75
  Learn more
76
76
  ----------
@@ -1,3 +1,4 @@
1
+ require "rails_erd"
1
2
  require "choice"
2
3
 
3
4
  Choice.options do
@@ -125,6 +126,12 @@ Choice.options do
125
126
  exit
126
127
  end
127
128
  end
129
+
130
+ option :config_file do
131
+ short "-c"
132
+ long "--config=FILENAME"
133
+ desc "Configuration file to use"
134
+ end
128
135
  end
129
136
 
130
137
  module RailsERD
@@ -143,6 +150,9 @@ module RailsERD
143
150
  opts[key.to_sym] = value
144
151
  end
145
152
  end
153
+ if options[:config_file] && options[:config_file] != ''
154
+ RailsERD.options = RailsERD.default_options.merge(Config.load(options[:config_file]))
155
+ end
146
156
  new(path, options).start
147
157
  end
148
158
  end
@@ -7,17 +7,21 @@ module RailsERD
7
7
 
8
8
  attr_reader :options
9
9
 
10
- def self.load
11
- new.load
10
+ def self.load(extra_config_file=nil)
11
+ new.load extra_config_file
12
12
  end
13
13
 
14
14
  def initialize
15
15
  @options = {}
16
16
  end
17
17
 
18
- def load
18
+ def load(extra_config_file=nil)
19
19
  load_file(USER_WIDE_CONFIG_FILE)
20
20
  load_file(CURRENT_CONFIG_FILE)
21
+ if extra_config_file
22
+ extra_config_path = File.expand_path(extra_config_file, Dir.pwd)
23
+ load_file(extra_config_path) if File.exist?(extra_config_path)
24
+ end
21
25
 
22
26
  @options
23
27
  end
@@ -125,7 +125,7 @@ module RailsERD
125
125
  def generate
126
126
  instance_eval(&callbacks[:setup])
127
127
  if options.only_recursion_depth.present?
128
- depth = options.only_recursion_depth.to_i
128
+ depth = options.only_recursion_depth.to_s.to_i
129
129
  options[:only].dup.each do |class_name|
130
130
  options[:only]+= recurse_into_relationships(@domain.entity_by_name(class_name), depth)
131
131
  end
@@ -177,7 +177,7 @@ module RailsERD
177
177
 
178
178
  def filtered_entities
179
179
  @domain.entities.reject { |entity|
180
- options.exclude.present? && entity.model && [options.exclude].flatten.map(&:to_sym).include?(entity.name.to_sym) or
180
+ options.exclude.present? && [options.exclude].flatten.map(&:to_sym).include?(entity.name.to_sym) or
181
181
  options[:only].present? && entity.model && ![options[:only]].flatten.map(&:to_sym).include?(entity.name.to_sym) or
182
182
  !options.inheritance && entity.specialized? or
183
183
  !options.polymorphism && entity.generalized? or
@@ -86,6 +86,11 @@ module RailsERD
86
86
  labeldistance: 1.8,
87
87
  }
88
88
 
89
+ # Default cluster attributes.
90
+ CLUSTER_ATTRIBUTES = {
91
+ margin: "10,10"
92
+ }
93
+
89
94
  module Simple
90
95
  def entity_style(entity, attributes)
91
96
  {}.tap do |options|
@@ -216,8 +221,10 @@ module RailsERD
216
221
  each_entity do |entity, attributes|
217
222
  if options[:cluster] && entity.namespace
218
223
  cluster_name = "cluster_#{entity.namespace}"
224
+ cluster_options = CLUSTER_ATTRIBUTES.merge(label: entity.namespace)
219
225
  cluster = graph.get_graph(cluster_name) ||
220
- graph.add_graph(cluster_name, label: entity.namespace)
226
+ graph.add_graph(cluster_name, cluster_options)
227
+
221
228
  draw_cluster_node cluster, entity.name, entity_options(entity, attributes)
222
229
  else
223
230
  draw_node entity.name, entity_options(entity, attributes)
@@ -303,7 +310,12 @@ module RailsERD
303
310
  end
304
311
 
305
312
  def read_template(type)
306
- ERB.new(File.read(File.expand_path("templates/#{NODE_LABEL_TEMPLATES[type]}", File.dirname(__FILE__))), nil, "<>")
313
+ template_text = File.read(File.expand_path("templates/#{NODE_LABEL_TEMPLATES[type]}", File.dirname(__FILE__)))
314
+ if ERB.instance_method(:initialize).parameters.assoc(:key) # Ruby 2.6+
315
+ ERB.new(template_text, trim_mode: "<>")
316
+ else
317
+ ERB.new(template_text, nil, "<>")
318
+ end
307
319
  end
308
320
  end
309
321
  end
@@ -140,8 +140,7 @@ module RailsERD
140
140
  association.check_validity!
141
141
 
142
142
  if association.options[:polymorphic]
143
- entity_name = association.class_name
144
- entity_by_name(entity_name) or raise "polymorphic interface #{entity_name} does not exist"
143
+ check_polymorphic_association_validity(association)
145
144
  else
146
145
  entity_name = association.klass.name # Raises NameError if the associated class cannot be found.
147
146
  entity_by_name(entity_name) or raise "model #{entity_name} exists, but is not included in domain"
@@ -150,6 +149,17 @@ module RailsERD
150
149
  warn "Ignoring invalid association #{association_description(association)} (#{e.message})"
151
150
  end
152
151
 
152
+ def check_polymorphic_association_validity(association)
153
+ entity_name = association.class_name
154
+ entity = entity_by_name(entity_name)
155
+
156
+ if entity || (entity && entity.generalized?)
157
+ return entity
158
+ else
159
+ raise("polymorphic interface #{entity_name} does not exist")
160
+ end
161
+ end
162
+
153
163
  def association_description(association)
154
164
  "#{association.name.inspect} on #{association.active_record}"
155
165
  end
@@ -93,7 +93,7 @@ module RailsERD
93
93
  end
94
94
 
95
95
  def namespace
96
- $1 if name.match /(.*)::.*/
96
+ $1 if name.match(/(.*)::.*/)
97
97
  end
98
98
 
99
99
  def to_s # @private :nodoc:
@@ -21,8 +21,7 @@ module RailsERD
21
21
  private
22
22
 
23
23
  def association_identity(association)
24
- identifier = association_identifier(association).to_s
25
- Set[identifier, association_owner(association), association_target(association)]
24
+ Set[association_owner(association), association_target(association)]
26
25
  end
27
26
 
28
27
  def association_identifier(association)
@@ -19,7 +19,13 @@ namespace :erd do
19
19
  when "true", "yes" then true
20
20
  when "false", "no" then false
21
21
  when /,/ then ENV[option].split(/\s*,\s*/)
22
- else ENV[option].to_sym
22
+ when /^\d+$/ then ENV[option].to_i
23
+ else
24
+ if option == 'only'
25
+ [ENV[option]]
26
+ else
27
+ ENV[option].to_sym
28
+ end
23
29
  end
24
30
  end
25
31
  end
@@ -1,4 +1,4 @@
1
1
  module RailsERD
2
- VERSION = "1.5.2"
2
+ VERSION = "1.6.0"
3
3
  BANNER = "RailsERD #{VERSION}"
4
4
  end
@@ -1,15 +1,12 @@
1
1
  require "rubygems"
2
2
  require "bundler/setup"
3
+ require 'pry'
4
+ require 'pry-nav'
3
5
 
4
6
  require "active_record"
5
7
 
6
- if ActiveSupport::VERSION::MAJOR >= 4
7
- require "minitest/autorun"
8
- require 'mocha/mini_test'
9
- else
10
- require "test/unit"
11
- require 'mocha/test_unit'
12
- end
8
+ require "minitest/autorun"
9
+ require 'mocha/minitest'
13
10
 
14
11
  require "rails_erd/domain"
15
12
 
@@ -75,6 +72,7 @@ class ActiveSupport::TestCase
75
72
  superklass = args.first.kind_of?(Class) ? args.shift : ActiveRecord::Base
76
73
  columns = args.first || {}
77
74
  klass = Object.const_set name.to_sym, Class.new(superklass)
75
+
78
76
  if superklass == ActiveRecord::Base || superklass.abstract_class?
79
77
  create_table Object.const_get(name.to_sym).table_name, columns, Object.const_get(name.to_sym).primary_key rescue nil
80
78
  end
@@ -196,10 +194,19 @@ class ActiveSupport::TestCase
196
194
  model.reset_column_information
197
195
  remove_fully_qualified_constant(model.name)
198
196
  end
197
+
199
198
  tables_and_views.each do |table|
200
199
  ActiveRecord::Base.connection.drop_table table
201
200
  end
202
- ActiveRecord::Base.direct_descendants.clear
201
+
202
+ if ActiveRecord.version >= Gem::Version.new("6.0.0.rc1")
203
+ cv = ActiveSupport::DescendantsTracker.class_variable_get(:@@direct_descendants)
204
+ cv.delete(ActiveRecord::Base)
205
+ ActiveSupport::DescendantsTracker.class_variable_set(:@@direct_descendants, cv)
206
+ else
207
+ ActiveRecord::Base.direct_descendants.clear
208
+ end
209
+
203
210
  ActiveSupport::Dependencies::Reference.clear!
204
211
  ActiveRecord::Base.clear_cache!
205
212
  end
@@ -61,6 +61,29 @@ class ConfigTest < ActiveSupport::TestCase
61
61
  assert_equal expected_hash, RailsERD::Config.load
62
62
  end
63
63
 
64
+ test "load_config_file should return a hash from the configured config file when a new config file is given as an argument" do
65
+ set_local_config_file_to("erdconfig.another_example")
66
+
67
+ expected_hash = {
68
+ attributes: [:content, :foreign_key, :inheritance, :false],
69
+ disconnected: true,
70
+ filename: "erd",
71
+ filetype: :pdf,
72
+ indirect: true,
73
+ inheritance: false,
74
+ markup: true,
75
+ notation: :simple,
76
+ orientation: "horizontal",
77
+ polymorphism: false,
78
+ warn: true,
79
+ title: "sample title",
80
+ exclude: [],
81
+ only: []
82
+ }
83
+
84
+ assert_equal expected_hash, RailsERD::Config.load("test/support_files/erdconfig.example")
85
+ end
86
+
64
87
  test "load_config_gile should return a hash from CURRENT_CONFIG_FILE overriding USER_WIDE_CONFIG_FILE when both of them exist." do
65
88
  set_user_config_file_to("erdconfig.example")
66
89
  set_local_config_file_to("erdconfig.another_example")
@@ -136,6 +136,15 @@ class DiagramTest < ActiveSupport::TestCase
136
136
  assert_equal [Book], retrieve_entities(:exclude => [:Author, :Editor]).map(&:model)
137
137
  end
138
138
 
139
+ test "generate should filter excluded polymorphic entities" do
140
+ create_model "Cannon"
141
+ create_model "Galleon" do
142
+ has_many :cannons, as: :defensible
143
+ end
144
+ assert_equal ["Cannon", "Galleon"], retrieve_entities(polymorphism: true, exclude: :Defensible).map(&:name)
145
+ end
146
+
147
+
139
148
  test "generate should include only specified entity" do
140
149
  create_model "Book"
141
150
  create_model "Author"
@@ -127,13 +127,21 @@ class DomainTest < ActiveSupport::TestCase
127
127
  end
128
128
 
129
129
  test "relationships should count relationship between same models with distinct foreign key seperately" do
130
- create_model "Foo", :bar => :references, :special_bar => :references do
131
- belongs_to :bar
132
- end
133
- create_model "Bar" do
134
- has_many :foos, :foreign_key => :special_bar_id
130
+ # TODO: Once we drop Rails 3.2 support, we _should_ be able to drop the
131
+ # :respond_to? check
132
+ #
133
+ if respond_to? :skip
134
+ skip("multiple edges between the same objects can cause segfaults in some versions of Graphviz")
135
+
136
+ create_model "Foo", :bar => :references, :special_bar => :references do
137
+ belongs_to :bar
138
+ end
139
+ create_model "Bar" do
140
+ has_many :foos, :foreign_key => :special_bar_id
141
+ end
142
+
143
+ assert_equal [Domain::Relationship] * 2, Domain.generate.relationships.collect(&:class)
135
144
  end
136
- assert_equal [Domain::Relationship] * 2, Domain.generate.relationships.collect(&:class)
137
145
  end
138
146
 
139
147
  test "relationships should use model name first in alphabet as source for many to many relationships" do
@@ -304,13 +304,21 @@ class GraphvizTest < ActiveSupport::TestCase
304
304
  end
305
305
 
306
306
  test "generate should create edge for each relationship" do
307
- create_model "Foo", :bar => :references do
308
- belongs_to :bar
309
- end
310
- create_model "Bar", :foo => :references do
311
- belongs_to :foo
307
+ # TODO: Once we drop Rails 3.2 support, we _should_ be able to drop the
308
+ # :respond_to? check
309
+ #
310
+ if respond_to? :skip
311
+ skip("multiple edges between the same objects can cause segfaults in some versions of Graphviz")
312
+
313
+ create_model "Foo", :bar => :references do
314
+ belongs_to :bar
315
+ end
316
+ create_model "Bar", :foo => :references do
317
+ belongs_to :foo
318
+ end
319
+
320
+ assert_equal [["m_Bar", "m_Foo"], ["m_Foo", "m_Bar"]], find_dot_node_pairs(diagram).sort
312
321
  end
313
- assert_equal [["m_Bar", "m_Foo"], ["m_Foo", "m_Bar"]], find_dot_node_pairs(diagram).sort
314
322
  end
315
323
 
316
324
  test "generate should create edge to polymorphic entity if polymorphism is true" do
@@ -173,4 +173,22 @@ Error occurred while loading application: FooBar (RuntimeError)
173
173
  Rake::Task["erd:options"].execute
174
174
  assert_equal %w[content timestamps], RailsERD.options.attributes
175
175
  end
176
+
177
+ test "options task should set known integer command line options when value is only digits" do
178
+ ENV["only_recursion_depth"] = "2"
179
+ Rake::Task["erd:options"].execute
180
+ assert_equal 2, RailsERD.options.only_recursion_depth
181
+ end
182
+
183
+ test "options task sets known command line options as symbols when not boolean or numeric" do
184
+ ENV["only_recursion_depth"] = "test"
185
+ Rake::Task["erd:options"].execute
186
+ assert_equal :test, RailsERD.options.only_recursion_depth
187
+ end
188
+
189
+ test "options task should set single parameter to only as array xxx" do
190
+ ENV["only"] = "model"
191
+ Rake::Task["erd:options"].execute
192
+ assert_equal ["model"], RailsERD.options.only
193
+ end
176
194
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails-erd
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.2
4
+ version: 1.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rolf Timmermans
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2017-05-24 00:00:00.000000000 Z
12
+ date: 2019-05-14 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord
@@ -17,28 +17,28 @@ dependencies:
17
17
  requirements:
18
18
  - - ">="
19
19
  - !ruby/object:Gem::Version
20
- version: '3.2'
20
+ version: '4.2'
21
21
  type: :runtime
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
25
  - - ">="
26
26
  - !ruby/object:Gem::Version
27
- version: '3.2'
27
+ version: '4.2'
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: activesupport
30
30
  requirement: !ruby/object:Gem::Requirement
31
31
  requirements:
32
32
  - - ">="
33
33
  - !ruby/object:Gem::Version
34
- version: '3.2'
34
+ version: '4.2'
35
35
  type: :runtime
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
39
  - - ">="
40
40
  - !ruby/object:Gem::Version
41
- version: '3.2'
41
+ version: '4.2'
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: ruby-graphviz
44
44
  requirement: !ruby/object:Gem::Requirement
@@ -67,6 +67,34 @@ dependencies:
67
67
  - - "~>"
68
68
  - !ruby/object:Gem::Version
69
69
  version: 0.2.0
70
+ - !ruby/object:Gem::Dependency
71
+ name: pry
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ - !ruby/object:Gem::Dependency
85
+ name: pry-nav
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
70
98
  description: Automatically generate an entity-relationship diagram (ERD) for your
71
99
  Rails models.
72
100
  email:
@@ -127,7 +155,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
127
155
  requirements:
128
156
  - - ">="
129
157
  - !ruby/object:Gem::Version
130
- version: 1.9.3
158
+ version: '2.2'
131
159
  required_rubygems_version: !ruby/object:Gem::Requirement
132
160
  requirements:
133
161
  - - ">="
@@ -135,7 +163,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
135
163
  version: '0'
136
164
  requirements: []
137
165
  rubyforge_project:
138
- rubygems_version: 2.6.10
166
+ rubygems_version: 2.7.9
139
167
  signing_key:
140
168
  specification_version: 4
141
169
  summary: Entity-relationship diagram for your Rails models.