culturecode_stagehand 1.1.2 → 1.1.5
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/lib/stagehand/auditor/checklist_visualizer.rb +15 -9
- data/lib/stagehand/configuration.rb +8 -1
- data/lib/stagehand/connection_adapter_extensions.rb +17 -30
- data/lib/stagehand/production.rb +8 -3
- data/lib/stagehand/schema_extensions.rb +1 -1
- data/lib/stagehand/staging/checklist.rb +14 -1
- data/lib/stagehand/version.rb +1 -1
- data/lib/tasks/stagehand_tasks.rake +2 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b9684506c931ca15ad9c467e5d96fb359ede46c3d41624331b72b7efe0b7b850
|
|
4
|
+
data.tar.gz: 43f4509740eb53ace3293ad6bdbd718562e165adf282e1ca2114c5daebd5ee15
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5cca6f14c6f8c9194d400a5c21bb49f90758e2160a9ebac99b72621f8b64410f91429a5b6f3ba62db4faf92d7d50caf1caee66a4d5631ccf4ac196206677130c
|
|
7
|
+
data.tar.gz: 28f4439a34ed046edff565df691fd4d1fada3e227a52a9fc3d60fec9b245db8d0a0c4e50629ab86febc7e5d0171c270b7257ee4121b0b5517296f6fb152b4eb6
|
|
@@ -6,7 +6,7 @@ module Stagehand
|
|
|
6
6
|
def initialize(checklist, show_all_commits: false)
|
|
7
7
|
entries = checklist.affected_entries.select(&:commit_id)
|
|
8
8
|
|
|
9
|
-
@graph = GraphViz.new( :G, :type => :graph )
|
|
9
|
+
@graph = GraphViz.new( :G, :type => :graph )
|
|
10
10
|
@commits = Hash.new {|hash, commit_id| hash[commit_id] = Stagehand::Staging::CommitEntry.find(commit_id) }
|
|
11
11
|
nodes = Hash.new
|
|
12
12
|
edges = []
|
|
@@ -24,16 +24,22 @@ module Stagehand
|
|
|
24
24
|
|
|
25
25
|
# Create Subgraph nodes for commits with connections to other subjects
|
|
26
26
|
entries = edges.flatten.uniq unless show_all_commits
|
|
27
|
-
entries.group_by {|entry| commit_subject(entry) }.each do |
|
|
28
|
-
|
|
27
|
+
entries.group_by {|entry| commit_subject(entry) || entry.commit_id }.each do |group, entries|
|
|
28
|
+
subject = commit_subject(entries.first)
|
|
29
|
+
subgraph = create_subgraph(subject, @graph, id: group)
|
|
29
30
|
entries.each do |entry|
|
|
30
31
|
nodes[entry] = create_node(entry, subgraph)
|
|
31
32
|
end
|
|
32
33
|
end
|
|
33
34
|
|
|
35
|
+
# Create deduplicate edge data in case multiple entries for the same record were part of a single commit
|
|
36
|
+
edges = edges.map do |entry_a, entry_b|
|
|
37
|
+
[[nodes[entry_a], nodes[entry_b]], label: edge_label(entry_a, entry_b)]
|
|
38
|
+
end
|
|
39
|
+
|
|
34
40
|
# Create edges
|
|
35
|
-
edges.each do |
|
|
36
|
-
create_edge(
|
|
41
|
+
edges.uniq.each do |(node_a, node_b), options|
|
|
42
|
+
create_edge(node_a, node_b, options)
|
|
37
43
|
end
|
|
38
44
|
end
|
|
39
45
|
|
|
@@ -44,8 +50,8 @@ module Stagehand
|
|
|
44
50
|
|
|
45
51
|
private
|
|
46
52
|
|
|
47
|
-
def create_subgraph(subject, graph)
|
|
48
|
-
graph.add_graph("cluster_#{
|
|
53
|
+
def create_subgraph(subject, graph, id: subject)
|
|
54
|
+
graph.add_graph("cluster_#{id}", :label => subject, :style => :filled, :color => :lightgrey)
|
|
49
55
|
end
|
|
50
56
|
|
|
51
57
|
def create_edge(node_a, node_b, options = {})
|
|
@@ -65,7 +71,7 @@ module Stagehand
|
|
|
65
71
|
end
|
|
66
72
|
|
|
67
73
|
def same_subject?(entry_a, entry_b)
|
|
68
|
-
commit_subject(entry_a) == commit_subject(entry_b)
|
|
74
|
+
commit_subject(entry_a) == commit_subject(entry_b) && commit_subject(entry_a)
|
|
69
75
|
end
|
|
70
76
|
|
|
71
77
|
def commit_subject(entry)
|
|
@@ -77,7 +83,7 @@ module Stagehand
|
|
|
77
83
|
end
|
|
78
84
|
|
|
79
85
|
def pretty_key(entry)
|
|
80
|
-
"#{entry.table_name.classify} #{entry.record_id}"
|
|
86
|
+
"#{entry.table_name.classify} #{entry.record_id}" if entry.record_id && entry.table_name
|
|
81
87
|
end
|
|
82
88
|
end
|
|
83
89
|
end
|
|
@@ -9,7 +9,8 @@ module Stagehand
|
|
|
9
9
|
module Configuration
|
|
10
10
|
extend self
|
|
11
11
|
|
|
12
|
-
mattr_accessor :checklist_confirmation_filter, :checklist_association_filter, :checklist_relation_filter
|
|
12
|
+
mattr_accessor :checklist_confirmation_filter, :checklist_association_filter, :checklist_relation_filter, :ignored_columns
|
|
13
|
+
self.ignored_columns = HashWithIndifferentAccess.new
|
|
13
14
|
|
|
14
15
|
def staging_connection_name
|
|
15
16
|
Rails.env.to_sym
|
|
@@ -33,5 +34,11 @@ module Stagehand
|
|
|
33
34
|
def single_connection?
|
|
34
35
|
staging_connection_name == production_connection_name
|
|
35
36
|
end
|
|
37
|
+
|
|
38
|
+
# Columns not to copy to the production database
|
|
39
|
+
# e.g. table_name => [column, column, ...]
|
|
40
|
+
def self.ignored_columns=(hash)
|
|
41
|
+
super HashWithIndifferentAccess.new(hash)
|
|
42
|
+
end
|
|
36
43
|
end
|
|
37
44
|
end
|
|
@@ -1,15 +1,22 @@
|
|
|
1
1
|
module Stagehand
|
|
2
2
|
module Connection
|
|
3
|
-
def self.with_production_writes(
|
|
4
|
-
|
|
3
|
+
def self.with_production_writes(&block)
|
|
4
|
+
state = allow_unsynced_production_writes?
|
|
5
|
+
allow_unsynced_production_writes!(true)
|
|
6
|
+
return block.call
|
|
7
|
+
ensure
|
|
8
|
+
allow_unsynced_production_writes!(state)
|
|
5
9
|
end
|
|
6
10
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
base.set_callback :checkin, :before, :clear_readonly_state
|
|
11
|
-
end
|
|
11
|
+
def self.allow_unsynced_production_writes!(state = true)
|
|
12
|
+
Thread.current[:stagehand_allow_unsynced_production_writes] = state
|
|
13
|
+
end
|
|
12
14
|
|
|
15
|
+
def self.allow_unsynced_production_writes?
|
|
16
|
+
!!Thread.current[:stagehand_allow_unsynced_production_writes]
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
module AdapterExtensions
|
|
13
20
|
def exec_insert(*)
|
|
14
21
|
handle_readonly_writes!
|
|
15
22
|
super
|
|
@@ -25,34 +32,14 @@ module Stagehand
|
|
|
25
32
|
super
|
|
26
33
|
end
|
|
27
34
|
|
|
28
|
-
def allow_writes(&block)
|
|
29
|
-
state = readonly?
|
|
30
|
-
readonly!(false)
|
|
31
|
-
return block.call
|
|
32
|
-
ensure
|
|
33
|
-
readonly!(state)
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def readonly!(state = true)
|
|
37
|
-
@readonly = state
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
def readonly?
|
|
41
|
-
!!@readonly
|
|
42
|
-
end
|
|
43
|
-
|
|
44
35
|
private
|
|
45
36
|
|
|
46
|
-
def
|
|
47
|
-
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
def clear_readonly_state
|
|
51
|
-
readonly!(false)
|
|
37
|
+
def write_access?
|
|
38
|
+
Configuration.single_connection? || @config[:database] == Database.staging_database_name || Connection.allow_unsynced_production_writes?
|
|
52
39
|
end
|
|
53
40
|
|
|
54
41
|
def handle_readonly_writes!
|
|
55
|
-
if
|
|
42
|
+
if write_access?
|
|
56
43
|
return
|
|
57
44
|
elsif Configuration.allow_unsynced_production_writes?
|
|
58
45
|
Rails.logger.warn "Writing directly to #{@config[:database]} database using readonly connection"
|
data/lib/stagehand/production.rb
CHANGED
|
@@ -24,7 +24,7 @@ module Stagehand
|
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
def write(staging_record, attributes, table_name = nil)
|
|
27
|
-
Connection.with_production_writes
|
|
27
|
+
Connection.with_production_writes do
|
|
28
28
|
is_new = matching(staging_record, table_name).update_all(attributes).zero?
|
|
29
29
|
|
|
30
30
|
# Ensure we always return a record, even when updating instead of creating
|
|
@@ -37,7 +37,7 @@ module Stagehand
|
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
def delete(staging_record, table_name = nil)
|
|
40
|
-
Connection.with_production_writes
|
|
40
|
+
Connection.with_production_writes do
|
|
41
41
|
matching(staging_record, table_name).delete_all
|
|
42
42
|
end
|
|
43
43
|
end
|
|
@@ -78,7 +78,12 @@ module Stagehand
|
|
|
78
78
|
|
|
79
79
|
def staging_record_attributes(staging_record, table_name = nil)
|
|
80
80
|
table_name, id = Stagehand::Key.generate(staging_record, :table_name => table_name)
|
|
81
|
-
Stagehand::Staging::CommitEntry.connection.select_one("SELECT * FROM #{table_name} WHERE id = #{id}")
|
|
81
|
+
hash = Stagehand::Staging::CommitEntry.connection.select_one("SELECT * FROM #{table_name} WHERE id = #{id}")
|
|
82
|
+
hash&.except(*ignored_columns(table_name))
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def ignored_columns(table_name)
|
|
86
|
+
Array.wrap(Configuration.ignored_columns[table_name]).map(&:to_s)
|
|
82
87
|
end
|
|
83
88
|
|
|
84
89
|
# CLASSES
|
|
@@ -2,7 +2,7 @@ module Stagehand
|
|
|
2
2
|
module SchemaExtensions
|
|
3
3
|
def define(*)
|
|
4
4
|
# Allow production writes during Schema.define to allow Rails to write to ar_internal_metadata table
|
|
5
|
-
Stagehand::Connection.with_production_writes
|
|
5
|
+
Stagehand::Connection.with_production_writes { super }
|
|
6
6
|
end
|
|
7
7
|
end
|
|
8
8
|
end
|
|
@@ -89,7 +89,20 @@ module Stagehand
|
|
|
89
89
|
private
|
|
90
90
|
|
|
91
91
|
def self.associated_associations(klass)
|
|
92
|
-
cache("#{klass.name}_associated_associations")
|
|
92
|
+
cache("#{klass.name}_associated_associations") do
|
|
93
|
+
reflections = klass.reflect_on_all_associations(:belongs_to)
|
|
94
|
+
|
|
95
|
+
reflections.select! do |reflection|
|
|
96
|
+
begin
|
|
97
|
+
reflection.check_preloadable!
|
|
98
|
+
next true
|
|
99
|
+
rescue ArgumentError
|
|
100
|
+
next false
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
reflections.collect(&:name)
|
|
105
|
+
end
|
|
93
106
|
end
|
|
94
107
|
|
|
95
108
|
def self.stagehand_class?(klass)
|
data/lib/stagehand/version.rb
CHANGED
|
@@ -20,7 +20,7 @@ namespace :stagehand do
|
|
|
20
20
|
def rake_both_databases(task, stagehand_task = task.gsub(':','_'))
|
|
21
21
|
task(stagehand_task => :environment) do
|
|
22
22
|
Stagehand::Database.each do |connection_name|
|
|
23
|
-
Stagehand::Connection.with_production_writes
|
|
23
|
+
Stagehand::Connection.with_production_writes do
|
|
24
24
|
puts "#{connection_name}"
|
|
25
25
|
Rake::Task[task].reenable
|
|
26
26
|
Rake::Task[task].invoke
|
|
@@ -35,4 +35,5 @@ namespace :stagehand do
|
|
|
35
35
|
|
|
36
36
|
rake_both_databases('db:migrate')
|
|
37
37
|
rake_both_databases('db:rollback')
|
|
38
|
+
rake_both_databases('db:test:load_structure')
|
|
38
39
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: culturecode_stagehand
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.1.
|
|
4
|
+
version: 1.1.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Nicholas Jakobsen
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date:
|
|
12
|
+
date: 2020-06-29 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: rails
|