rails-erd 1.5.2 → 1.6.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 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.