actual_db_schema 0.7.5 → 0.7.6
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/CHANGELOG.md +5 -0
- data/Gemfile.lock +1 -1
- data/README.md +29 -0
- data/app/assets/javascripts/application.js +39 -0
- data/app/assets/stylesheets/styles.css +114 -0
- data/app/controllers/actual_db_schema/migrations_controller.rb +49 -0
- data/app/controllers/actual_db_schema/phantom_migrations_controller.rb +49 -0
- data/app/views/actual_db_schema/migrations/index.html.erb +70 -0
- data/app/views/actual_db_schema/migrations/show.html.erb +58 -0
- data/app/views/actual_db_schema/phantom_migrations/index.html.erb +67 -0
- data/app/views/actual_db_schema/phantom_migrations/show.html.erb +52 -0
- data/config/routes.rb +18 -0
- data/lib/actual_db_schema/commands/base.rb +6 -16
- data/lib/actual_db_schema/commands/list.rb +6 -15
- data/lib/actual_db_schema/commands/rollback.rb +2 -2
- data/lib/actual_db_schema/engine.rb +18 -0
- data/lib/actual_db_schema/migration.rb +119 -0
- data/lib/actual_db_schema/migration_context.rb +37 -0
- data/lib/actual_db_schema/patches/migration_context.rb +18 -12
- data/lib/actual_db_schema/version.rb +1 -1
- data/lib/actual_db_schema.rb +13 -12
- data/lib/tasks/db.rake +6 -6
- metadata +14 -3
- data/lib/railtie.rb +0 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a731a134ac425aed56e92b8c715812d17c9c1b3d519580281f7284dd05ae8d4a
|
4
|
+
data.tar.gz: e262bafa9ebc123fc702baa883fae55ac30a030d778ef9123f1f88cddb6b9192
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 03aecc678b4de3e808367715de4c7d193ebab7fb036fbba31b0d0da771637b165bc348ad08bce50dd6a5472701065e8888b9aecbed042a282627fa792260ba39
|
7
|
+
data.tar.gz: 81fa7c7b457be66ab587fa1062a61236fb5e578060b6565a2d26f1eaebd6817bdad09e6ec2b15ffbd8a5d489d84b42463fd02689bc8257a0e308f2cd6987e0ce
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
## [0.7.6] - 2024-07-22
|
2
|
+
- Added UI
|
3
|
+
- Added environment variable `ACTUAL_DB_SCHEMA_UI_ENABLED` to enable/disable the UI in specific environments
|
4
|
+
- Added configuration option `ActualDbSchema.config[:ui_enabled]` to enable/disable the UI in specific environments
|
5
|
+
|
1
6
|
## [0.7.5] - 2024-06-20
|
2
7
|
- Added db:rollback_migrations:manual task to manually rolls back phantom migrations one by one
|
3
8
|
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -62,6 +62,35 @@ The gem offers the following rake tasks that can be manually run according to yo
|
|
62
62
|
- `rails db:rollback_branches:manual` - run it to manually rolls back phantom migrations one by one.
|
63
63
|
- `rails db:phantom_migrations` - displays a list of phantom migrations.
|
64
64
|
|
65
|
+
## Accessing the UI
|
66
|
+
|
67
|
+
The UI for managing migrations is enabled automatically. To access the UI, simply navigate to the following URL in your web browser:
|
68
|
+
```
|
69
|
+
http://localhost:3000/rails/phantom_migrations
|
70
|
+
```
|
71
|
+
This page displays a list of phantom migrations for each database connection and provides options to view details and rollback them.
|
72
|
+
|
73
|
+
## UI options
|
74
|
+
|
75
|
+
By default, the UI is enabled in the development environment. If you prefer to enable the UI for another environment, you can do so in two ways:
|
76
|
+
|
77
|
+
### 1. Using Environment Variable
|
78
|
+
|
79
|
+
Set the environment variable `ACTUAL_DB_SCHEMA_UI_ENABLED` to `true`:
|
80
|
+
|
81
|
+
```sh
|
82
|
+
export ACTUAL_DB_SCHEMA_UI_ENABLED=true
|
83
|
+
```
|
84
|
+
|
85
|
+
### 2. Using Initializer
|
86
|
+
Add the following line to your initializer file (`config/initializers/actual_db_schema.rb`):
|
87
|
+
|
88
|
+
```ruby
|
89
|
+
ActualDbSchema.config[:ui_enabled] = true
|
90
|
+
```
|
91
|
+
|
92
|
+
> With this option, the UI can be disabled for all environments or be enabled in specific ones.
|
93
|
+
|
65
94
|
## Disabling Automatic Rollback
|
66
95
|
|
67
96
|
By default, the automatic rollback of migrations is enabled. If you prefer to perform manual rollbacks, you can disable the automatic rollback in two ways:
|
@@ -0,0 +1,39 @@
|
|
1
|
+
document.addEventListener('DOMContentLoaded', function () {
|
2
|
+
const migrationActions = document.querySelectorAll('.migration-action');
|
3
|
+
|
4
|
+
migrationActions.forEach(button => {
|
5
|
+
button.addEventListener('click', function (event) {
|
6
|
+
const originalText = button.value;
|
7
|
+
button.value = 'Loading...';
|
8
|
+
disableButtons();
|
9
|
+
|
10
|
+
fetch(event.target.form.action, { method: 'POST'})
|
11
|
+
.then(response => {
|
12
|
+
if (response.ok) {
|
13
|
+
window.location.reload();
|
14
|
+
} else {
|
15
|
+
throw new Error('Network response was not ok.');
|
16
|
+
}
|
17
|
+
})
|
18
|
+
.catch(error => {
|
19
|
+
console.error('There has been a problem with your fetch operation:', error);
|
20
|
+
enableButtons();
|
21
|
+
button.value = originalText;
|
22
|
+
});
|
23
|
+
|
24
|
+
event.preventDefault();
|
25
|
+
});
|
26
|
+
});
|
27
|
+
|
28
|
+
function disableButtons() {
|
29
|
+
migrationActions.forEach(button => {
|
30
|
+
button.disabled = true;
|
31
|
+
});
|
32
|
+
}
|
33
|
+
|
34
|
+
function enableButtons() {
|
35
|
+
migrationActions.forEach(button => {
|
36
|
+
button.disabled = false;
|
37
|
+
});
|
38
|
+
}
|
39
|
+
});
|
@@ -0,0 +1,114 @@
|
|
1
|
+
body {
|
2
|
+
margin: 8px;
|
3
|
+
background-color: #fff;
|
4
|
+
color: #333;
|
5
|
+
}
|
6
|
+
|
7
|
+
body, p, td {
|
8
|
+
font-family: helvetica, verdana, arial, sans-serif;
|
9
|
+
font-size: 13px;
|
10
|
+
line-height: 18px;
|
11
|
+
}
|
12
|
+
|
13
|
+
h2 {
|
14
|
+
padding-left: 10px;
|
15
|
+
}
|
16
|
+
|
17
|
+
table {
|
18
|
+
margin: 0;
|
19
|
+
border-collapse: collapse;
|
20
|
+
|
21
|
+
thead tr {
|
22
|
+
border-bottom: 2px solid #ddd;
|
23
|
+
}
|
24
|
+
|
25
|
+
tbody {
|
26
|
+
.migration-row.phantom {
|
27
|
+
background-color: #fff3f3;
|
28
|
+
}
|
29
|
+
|
30
|
+
.migration-row.normal {
|
31
|
+
background-color: #ffffff;
|
32
|
+
}
|
33
|
+
|
34
|
+
.migration-row:nth-child(odd).phantom {
|
35
|
+
background-color: #ffe6e6;
|
36
|
+
}
|
37
|
+
|
38
|
+
.migration-row:nth-child(odd).normal {
|
39
|
+
background-color: #f9f9f9;
|
40
|
+
}
|
41
|
+
}
|
42
|
+
|
43
|
+
td {
|
44
|
+
padding: 14px 30px;
|
45
|
+
}
|
46
|
+
}
|
47
|
+
|
48
|
+
.top-buttons {
|
49
|
+
margin: 8px;
|
50
|
+
display: flex;
|
51
|
+
align-items: center;
|
52
|
+
|
53
|
+
.top-button {
|
54
|
+
background-color: #ddd;
|
55
|
+
}
|
56
|
+
}
|
57
|
+
|
58
|
+
.button, .top-button {
|
59
|
+
font-weight: bold;
|
60
|
+
color: #000;
|
61
|
+
border: none;
|
62
|
+
padding: 5px 10px;
|
63
|
+
text-align: center;
|
64
|
+
text-decoration: none;
|
65
|
+
display: inline-block;
|
66
|
+
margin: 0 2px;
|
67
|
+
cursor: pointer;
|
68
|
+
border-radius: 4px;
|
69
|
+
transition: background-color 0.3s;
|
70
|
+
background: none;
|
71
|
+
}
|
72
|
+
|
73
|
+
.button:hover, .top-button:hover {
|
74
|
+
color: #fff;
|
75
|
+
background-color: #000;
|
76
|
+
}
|
77
|
+
|
78
|
+
.button:disabled, .button:hover:disabled {
|
79
|
+
background-color: transparent;
|
80
|
+
color: #666;
|
81
|
+
cursor: not-allowed;
|
82
|
+
}
|
83
|
+
|
84
|
+
.button-container {
|
85
|
+
display: flex;
|
86
|
+
}
|
87
|
+
|
88
|
+
pre {
|
89
|
+
background-color: #f7f7f7;
|
90
|
+
padding: 10px;
|
91
|
+
border: 1px solid #ddd;
|
92
|
+
}
|
93
|
+
|
94
|
+
.truncate-text {
|
95
|
+
max-width: 200px;
|
96
|
+
overflow: hidden;
|
97
|
+
text-overflow: ellipsis;
|
98
|
+
}
|
99
|
+
|
100
|
+
.flash {
|
101
|
+
padding: 10px;
|
102
|
+
margin-bottom: 10px;
|
103
|
+
border-radius: 5px;
|
104
|
+
}
|
105
|
+
|
106
|
+
.flash.notice {
|
107
|
+
background-color: #d4edda;
|
108
|
+
color: #155724;
|
109
|
+
}
|
110
|
+
|
111
|
+
.flash.alert {
|
112
|
+
background-color: #f8d7da;
|
113
|
+
color: #721c24;
|
114
|
+
}
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActualDbSchema
|
4
|
+
# Controller to display the list of migrations for each database connection.
|
5
|
+
class MigrationsController < ActionController::Base
|
6
|
+
protect_from_forgery with: :exception
|
7
|
+
skip_before_action :verify_authenticity_token
|
8
|
+
|
9
|
+
def index; end
|
10
|
+
|
11
|
+
def show
|
12
|
+
render file: "#{Rails.root}/public/404.html", layout: false, status: :not_found unless migration
|
13
|
+
end
|
14
|
+
|
15
|
+
def rollback
|
16
|
+
handle_rollback(params[:id], params[:database])
|
17
|
+
redirect_to migrations_path
|
18
|
+
end
|
19
|
+
|
20
|
+
def migrate
|
21
|
+
handle_migrate(params[:id], params[:database])
|
22
|
+
redirect_to migrations_path
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def handle_rollback(id, database)
|
28
|
+
ActualDbSchema::Migration.instance.rollback(id, database)
|
29
|
+
flash[:notice] = "Migration #{id} was successfully rolled back."
|
30
|
+
rescue StandardError => e
|
31
|
+
flash[:alert] = e.message
|
32
|
+
end
|
33
|
+
|
34
|
+
def handle_migrate(id, database)
|
35
|
+
ActualDbSchema::Migration.instance.migrate(id, database)
|
36
|
+
flash[:notice] = "Migration #{id} was successfully migrated."
|
37
|
+
rescue StandardError => e
|
38
|
+
flash[:alert] = e.message
|
39
|
+
end
|
40
|
+
|
41
|
+
helper_method def migrations
|
42
|
+
@migrations ||= ActualDbSchema::Migration.instance.all
|
43
|
+
end
|
44
|
+
|
45
|
+
helper_method def migration
|
46
|
+
@migration ||= ActualDbSchema::Migration.instance.find(params[:id], params[:database])
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActualDbSchema
|
4
|
+
# Controller to display the list of phantom migrations for each database connection.
|
5
|
+
class PhantomMigrationsController < ActionController::Base
|
6
|
+
protect_from_forgery with: :exception
|
7
|
+
skip_before_action :verify_authenticity_token
|
8
|
+
|
9
|
+
def index; end
|
10
|
+
|
11
|
+
def show
|
12
|
+
render file: "#{Rails.root}/public/404.html", layout: false, status: :not_found unless phantom_migration
|
13
|
+
end
|
14
|
+
|
15
|
+
def rollback
|
16
|
+
handle_rollback(params[:id], params[:database])
|
17
|
+
redirect_to phantom_migrations_path
|
18
|
+
end
|
19
|
+
|
20
|
+
def rollback_all
|
21
|
+
handle_rollback_all
|
22
|
+
redirect_to phantom_migrations_path
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def handle_rollback(id, database)
|
28
|
+
ActualDbSchema::Migration.instance.rollback(id, database)
|
29
|
+
flash[:notice] = "Migration #{id} was successfully rolled back."
|
30
|
+
rescue StandardError => e
|
31
|
+
flash[:alert] = e.message
|
32
|
+
end
|
33
|
+
|
34
|
+
def handle_rollback_all
|
35
|
+
ActualDbSchema::Migration.instance.rollback_all
|
36
|
+
flash[:notice] = "Migrations was successfully rolled back."
|
37
|
+
rescue StandardError => e
|
38
|
+
flash[:alert] = e.message
|
39
|
+
end
|
40
|
+
|
41
|
+
helper_method def phantom_migrations
|
42
|
+
@phantom_migrations ||= ActualDbSchema::Migration.instance.all_phantom
|
43
|
+
end
|
44
|
+
|
45
|
+
helper_method def phantom_migration
|
46
|
+
@phantom_migration ||= ActualDbSchema::Migration.instance.find(params[:id], params[:database])
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>Migrations</title>
|
5
|
+
<%= stylesheet_link_tag 'styles', media: 'all' %>
|
6
|
+
<%= javascript_include_tag 'application' %>
|
7
|
+
</head>
|
8
|
+
<body>
|
9
|
+
<div>
|
10
|
+
<% flash.each do |key, message| %>
|
11
|
+
<div class="flash <%= key %>"><%= message %></div>
|
12
|
+
<% end %>
|
13
|
+
<h2>Migrations</h2>
|
14
|
+
<p>
|
15
|
+
<span style="background-color: #ffe6e6; padding: 0 5px;">Red rows</span> represent phantom migrations.
|
16
|
+
</p>
|
17
|
+
<div class="top-buttons">
|
18
|
+
<%= link_to 'Phantom Migrations', phantom_migrations_path, class: "top-button" %>
|
19
|
+
</div>
|
20
|
+
<% if migrations.present? %>
|
21
|
+
<table>
|
22
|
+
<thead>
|
23
|
+
<tr>
|
24
|
+
<th>Status</th>
|
25
|
+
<th>Migration ID</th>
|
26
|
+
<th>Name</th>
|
27
|
+
<th>Branch</th>
|
28
|
+
<th>Database</th>
|
29
|
+
<th>Actions</th>
|
30
|
+
</tr>
|
31
|
+
</thead>
|
32
|
+
<tbody>
|
33
|
+
<% migrations.each do |migration| %>
|
34
|
+
<tr class="migration-row <%= migration[:phantom] ? 'phantom' : 'normal' %>">
|
35
|
+
<td><%= migration[:status] %></td>
|
36
|
+
<td><%= migration[:version] %></td>
|
37
|
+
<td>
|
38
|
+
<div class="truncate-text" title="<%= migration[:name] %>">
|
39
|
+
<%= migration[:name] %>
|
40
|
+
</div>
|
41
|
+
</td>
|
42
|
+
<td><%= migration[:branch] %></td>
|
43
|
+
<td><%= migration[:database] %></td>
|
44
|
+
<td>
|
45
|
+
<div class='button-container'>
|
46
|
+
<%= link_to '👁 Show',
|
47
|
+
migration_path(id: migration[:version], database: migration[:database]),
|
48
|
+
class: 'button' %>
|
49
|
+
<%= button_to '⎌ Rollback',
|
50
|
+
rollback_migration_path(id: migration[:version], database: migration[:database]),
|
51
|
+
method: :post,
|
52
|
+
class: 'button migration-action',
|
53
|
+
style: ('display: none;' if migration[:status] == "down") %>
|
54
|
+
<%= button_to '⬆ Migrate',
|
55
|
+
migrate_migration_path(id: migration[:version], database: migration[:database]),
|
56
|
+
method: :post,
|
57
|
+
class: 'button migration-action',
|
58
|
+
style: ('display: none;' if migration[:status] == "up" || migration[:phantom]) %>
|
59
|
+
</div>
|
60
|
+
</td>
|
61
|
+
</tr>
|
62
|
+
<% end %>
|
63
|
+
</tbody>
|
64
|
+
</table>
|
65
|
+
<% else %>
|
66
|
+
<p>No migrations found.</p>
|
67
|
+
<% end %>
|
68
|
+
</div>
|
69
|
+
</body>
|
70
|
+
</html>
|
@@ -0,0 +1,58 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>Migration Details</title>
|
5
|
+
<%= stylesheet_link_tag 'styles', media: 'all' %>
|
6
|
+
<%= javascript_include_tag 'application' %>
|
7
|
+
</head>
|
8
|
+
<body>
|
9
|
+
<div>
|
10
|
+
<% flash.each do |key, message| %>
|
11
|
+
<div class="flash <%= key %>"><%= message %></div>
|
12
|
+
<% end %>
|
13
|
+
<h2>Migration <%= migration[:name] %> Details</h2>
|
14
|
+
<table>
|
15
|
+
<tbody>
|
16
|
+
<tr>
|
17
|
+
<th>Status</th>
|
18
|
+
<td><%= migration[:status] %></td>
|
19
|
+
</tr>
|
20
|
+
<tr>
|
21
|
+
<th>Migration ID</th>
|
22
|
+
<td><%= migration[:version] %></td>
|
23
|
+
</tr>
|
24
|
+
<tr>
|
25
|
+
<th>Branch</th>
|
26
|
+
<td><%= migration[:branch] %></td>
|
27
|
+
</tr>
|
28
|
+
<tr>
|
29
|
+
<th>Database</th>
|
30
|
+
<td><%= migration[:database] %></td>
|
31
|
+
</tr>
|
32
|
+
<tr>
|
33
|
+
<th>Path</th>
|
34
|
+
<td><%= migration[:filename] %></td>
|
35
|
+
</tr>
|
36
|
+
</tbody>
|
37
|
+
</table>
|
38
|
+
|
39
|
+
<h3>Migration Code</h3>
|
40
|
+
<div>
|
41
|
+
<pre><%= File.read(migration[:filename]) %></pre>
|
42
|
+
</div>
|
43
|
+
<div class='button-container'>
|
44
|
+
<%= link_to '← Back', migrations_path, class: 'button' %>
|
45
|
+
<%= button_to '⎌ Rollback',
|
46
|
+
rollback_migration_path(id: migration[:version], database: migration[:database]),
|
47
|
+
method: :post,
|
48
|
+
class: 'button migration-action',
|
49
|
+
style: ('display: none;' if migration[:status] == "down") %>
|
50
|
+
<%= button_to '⬆ Migrate',
|
51
|
+
migrate_migration_path(id: migration[:version], database: migration[:database]),
|
52
|
+
method: :post,
|
53
|
+
class: 'button migration-action',
|
54
|
+
style: ('display: none;' if migration[:status] == "up" || migration[:phantom]) %>
|
55
|
+
</div>
|
56
|
+
</div>
|
57
|
+
</body>
|
58
|
+
</html>
|
@@ -0,0 +1,67 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>Phantom Migrations</title>
|
5
|
+
<%= stylesheet_link_tag 'styles', media: 'all' %>
|
6
|
+
<%= javascript_include_tag 'application' %>
|
7
|
+
</head>
|
8
|
+
<body>
|
9
|
+
<div>
|
10
|
+
<% flash.each do |key, message| %>
|
11
|
+
<div class="flash <%= key %>"><%= message %></div>
|
12
|
+
<% end %>
|
13
|
+
<h2>Phantom Migrations</h2>
|
14
|
+
<div class="top-buttons">
|
15
|
+
<%= link_to 'All Migrations', migrations_path, class: "top-button" %>
|
16
|
+
<% if phantom_migrations.present? %>
|
17
|
+
<%= button_to '⎌ Rollback all',
|
18
|
+
rollback_all_phantom_migrations_path,
|
19
|
+
method: :post,
|
20
|
+
class: 'button migration-action' %>
|
21
|
+
<% end %>
|
22
|
+
</div>
|
23
|
+
<% if phantom_migrations.present? %>
|
24
|
+
<table>
|
25
|
+
<thead>
|
26
|
+
<tr>
|
27
|
+
<th>Status</th>
|
28
|
+
<th>Migration ID</th>
|
29
|
+
<th>Name</th>
|
30
|
+
<th>Branch</th>
|
31
|
+
<th>Database</th>
|
32
|
+
<th>Actions</th>
|
33
|
+
</tr>
|
34
|
+
</thead>
|
35
|
+
<tbody>
|
36
|
+
<% phantom_migrations.each do |migration| %>
|
37
|
+
<tr class="migration-row phantom">
|
38
|
+
<td><%= migration[:status] %></td>
|
39
|
+
<td><%= migration[:version] %></td>
|
40
|
+
<td>
|
41
|
+
<div class="truncate-text" title="<%= migration[:name] %>">
|
42
|
+
<%= migration[:name] %>
|
43
|
+
</div>
|
44
|
+
</td>
|
45
|
+
<td><%= migration[:branch] %></td>
|
46
|
+
<td><%= migration[:database] %></td>
|
47
|
+
<td>
|
48
|
+
<div class='button-container'>
|
49
|
+
<%= link_to '👁 Show',
|
50
|
+
phantom_migration_path(id: migration[:version], database: migration[:database]),
|
51
|
+
class: 'button' %>
|
52
|
+
<%= button_to '⎌ Rollback',
|
53
|
+
rollback_phantom_migration_path(id: migration[:version], database: migration[:database]),
|
54
|
+
method: :post,
|
55
|
+
class: 'button migration-action' %>
|
56
|
+
</div>
|
57
|
+
</td>
|
58
|
+
</tr>
|
59
|
+
<% end %>
|
60
|
+
</tbody>
|
61
|
+
</table>
|
62
|
+
<% else %>
|
63
|
+
<p>No phantom migrations found.</p>
|
64
|
+
<% end %>
|
65
|
+
</div>
|
66
|
+
</body>
|
67
|
+
</html>
|
@@ -0,0 +1,52 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>Phantom Migration Details</title>
|
5
|
+
<%= stylesheet_link_tag 'styles', media: 'all' %>
|
6
|
+
<%= javascript_include_tag 'application' %>
|
7
|
+
</head>
|
8
|
+
<body>
|
9
|
+
<div>
|
10
|
+
<% flash.each do |key, message| %>
|
11
|
+
<div class="flash <%= key %>"><%= message %></div>
|
12
|
+
<% end %>
|
13
|
+
<h2>Phantom Migration <%= phantom_migration[:name] %> Details</h2>
|
14
|
+
<table>
|
15
|
+
<tbody>
|
16
|
+
<tr>
|
17
|
+
<th>Status</th>
|
18
|
+
<td><%= phantom_migration[:status] %></td>
|
19
|
+
</tr>
|
20
|
+
<tr>
|
21
|
+
<th>Migration ID</th>
|
22
|
+
<td><%= phantom_migration[:version] %></td>
|
23
|
+
</tr>
|
24
|
+
<tr>
|
25
|
+
<th>Branch</th>
|
26
|
+
<td><%= phantom_migration[:branch] %></td>
|
27
|
+
</tr>
|
28
|
+
<tr>
|
29
|
+
<th>Database</th>
|
30
|
+
<td><%= phantom_migration[:database] %></td>
|
31
|
+
</tr>
|
32
|
+
<tr>
|
33
|
+
<th>Path</th>
|
34
|
+
<td><%= phantom_migration[:filename] %></td>
|
35
|
+
</tr>
|
36
|
+
</tbody>
|
37
|
+
</table>
|
38
|
+
|
39
|
+
<h3>Migration Code</h3>
|
40
|
+
<div>
|
41
|
+
<pre><%= File.read(phantom_migration[:filename]) %></pre>
|
42
|
+
</div>
|
43
|
+
<div class='button-container'>
|
44
|
+
<%= link_to '← Back', phantom_migrations_path, class: 'button' %>
|
45
|
+
<%= button_to '⎌ Rollback',
|
46
|
+
rollback_phantom_migration_path(id: params[:id], database: params[:database]),
|
47
|
+
method: :post,
|
48
|
+
class: 'button migration-action' %>
|
49
|
+
</div>
|
50
|
+
</div>
|
51
|
+
</body>
|
52
|
+
</html>
|
data/config/routes.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
ActualDbSchema::Engine.routes.draw do
|
4
|
+
resources :migrations, only: %i[index show] do
|
5
|
+
member do
|
6
|
+
post :rollback
|
7
|
+
post :migrate
|
8
|
+
end
|
9
|
+
end
|
10
|
+
resources :phantom_migrations, only: %i[index show] do
|
11
|
+
member do
|
12
|
+
post :rollback
|
13
|
+
end
|
14
|
+
collection do
|
15
|
+
post :rollback_all
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -4,6 +4,12 @@ module ActualDbSchema
|
|
4
4
|
module Commands
|
5
5
|
# Base class for all commands
|
6
6
|
class Base
|
7
|
+
attr_reader :context
|
8
|
+
|
9
|
+
def initialize(context)
|
10
|
+
@context = context
|
11
|
+
end
|
12
|
+
|
7
13
|
def call
|
8
14
|
unless ActualDbSchema.config.fetch(:enabled, true)
|
9
15
|
raise "ActualDbSchema is disabled. Set ActualDbSchema.config[:enabled] = true to enable it."
|
@@ -17,22 +23,6 @@ module ActualDbSchema
|
|
17
23
|
def call_impl
|
18
24
|
raise NotImplementedError
|
19
25
|
end
|
20
|
-
|
21
|
-
def context
|
22
|
-
@context ||= fetch_migration_context.tap do |c|
|
23
|
-
c.extend(ActualDbSchema::Patches::MigrationContext)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
def fetch_migration_context
|
28
|
-
ar_version = Gem::Version.new(ActiveRecord::VERSION::STRING)
|
29
|
-
if ar_version >= Gem::Version.new("7.2.0") ||
|
30
|
-
(ar_version >= Gem::Version.new("7.1.0") && ar_version.prerelease?)
|
31
|
-
ActiveRecord::Base.connection_pool.migration_context
|
32
|
-
else
|
33
|
-
ActiveRecord::Base.connection.migration_context
|
34
|
-
end
|
35
|
-
end
|
36
26
|
end
|
37
27
|
end
|
38
28
|
end
|
@@ -12,27 +12,18 @@ module ActualDbSchema
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def indexed_phantom_migrations
|
15
|
-
@indexed_phantom_migrations ||= context.
|
15
|
+
@indexed_phantom_migrations ||= context.phantom_migrations.index_by { |m| m.version.to_s }
|
16
16
|
end
|
17
17
|
|
18
18
|
def preambule
|
19
19
|
puts "\nPhantom migrations\n\n"
|
20
20
|
puts "Below is a list of irrelevant migrations executed in unmerged branches."
|
21
21
|
puts "To bring your database schema up to date, the migrations marked as \"up\" should be rolled back."
|
22
|
-
|
23
|
-
puts "\ndatabase: #{database_path}\n\n"
|
22
|
+
puts "\ndatabase: #{ActualDbSchema.db_config[:database]}\n\n"
|
24
23
|
puts header.join(" ")
|
25
24
|
puts "-" * separator_width
|
26
25
|
end
|
27
26
|
|
28
|
-
def db_config
|
29
|
-
if ActiveRecord::Base.respond_to?(:connection_db_config)
|
30
|
-
ActiveRecord::Base.connection_db_config.configuration_hash
|
31
|
-
else
|
32
|
-
ActiveRecord::Base.connection_config
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
27
|
def separator_width
|
37
28
|
header.map(&:length).sum + (header.size - 1) * 2
|
38
29
|
end
|
@@ -66,14 +57,14 @@ module ActualDbSchema
|
|
66
57
|
].join(" ")
|
67
58
|
end
|
68
59
|
|
69
|
-
def branch_for(version)
|
70
|
-
metadata.fetch(version, {})[:branch] || "unknown"
|
71
|
-
end
|
72
|
-
|
73
60
|
def metadata
|
74
61
|
@metadata ||= ActualDbSchema::Store.instance.read
|
75
62
|
end
|
76
63
|
|
64
|
+
def branch_for(version)
|
65
|
+
metadata.fetch(version, {})[:branch] || "unknown"
|
66
|
+
end
|
67
|
+
|
77
68
|
def longest_branch_name
|
78
69
|
@longest_branch_name ||=
|
79
70
|
metadata.values.map { |v| v[:branch] }.compact.max_by(&:length) || "unknown"
|
@@ -4,9 +4,9 @@ module ActualDbSchema
|
|
4
4
|
module Commands
|
5
5
|
# Rolls back all phantom migrations
|
6
6
|
class Rollback < Base
|
7
|
-
def initialize(manual_mode: false)
|
7
|
+
def initialize(context, manual_mode: false)
|
8
8
|
@manual_mode = manual_mode || manual_mode_default?
|
9
|
-
super()
|
9
|
+
super(context)
|
10
10
|
end
|
11
11
|
|
12
12
|
private
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActualDbSchema
|
4
|
+
# It isolates the namespace to avoid conflicts with the main application.
|
5
|
+
class Engine < ::Rails::Engine
|
6
|
+
isolate_namespace ActualDbSchema
|
7
|
+
|
8
|
+
initializer "actual_db_schema.initialize" do |app|
|
9
|
+
if ActualDbSchema.config[:ui_enabled]
|
10
|
+
app.routes.append do
|
11
|
+
mount ActualDbSchema::Engine => "/rails"
|
12
|
+
end
|
13
|
+
|
14
|
+
app.config.assets.precompile += %w[styles.css application.js]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActualDbSchema
|
4
|
+
# The Migration class is responsible for managing and retrieving migration information
|
5
|
+
class Migration
|
6
|
+
include Singleton
|
7
|
+
|
8
|
+
Migration = Struct.new(:status, :version, :name, :branch, :database, :filename, :phantom, keyword_init: true)
|
9
|
+
|
10
|
+
def all_phantom
|
11
|
+
migrations = []
|
12
|
+
|
13
|
+
MigrationContext.instance.each do |context|
|
14
|
+
indexed_migrations = context.phantom_migrations.index_by { |m| m.version.to_s }
|
15
|
+
|
16
|
+
context.migrations_status.each do |status, version|
|
17
|
+
migration = indexed_migrations[version]
|
18
|
+
migrations << build_migration_struct(status, migration) if should_include?(status, migration)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
sort_migrations_desc(migrations)
|
23
|
+
end
|
24
|
+
|
25
|
+
def all
|
26
|
+
migrations = []
|
27
|
+
|
28
|
+
MigrationContext.instance.each do |context|
|
29
|
+
indexed_migrations = context.migrations.index_by { |m| m.version.to_s }
|
30
|
+
|
31
|
+
context.migrations_status.each do |status, version|
|
32
|
+
migration = indexed_migrations[version]
|
33
|
+
migrations << build_migration_struct(status, migration) if should_include?(status, migration)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
sort_migrations_desc(migrations)
|
38
|
+
end
|
39
|
+
|
40
|
+
def find(version, database)
|
41
|
+
MigrationContext.instance.each do |context|
|
42
|
+
next unless ActualDbSchema.db_config[:database] == database
|
43
|
+
|
44
|
+
migration = find_migration_in_context(context, version)
|
45
|
+
return migration if migration
|
46
|
+
end
|
47
|
+
nil
|
48
|
+
end
|
49
|
+
|
50
|
+
def rollback(version, database)
|
51
|
+
MigrationContext.instance.each do |context|
|
52
|
+
next unless ActualDbSchema.db_config[:database] == database
|
53
|
+
|
54
|
+
if context.migrations.detect { |m| m.version.to_s == version }
|
55
|
+
context.run(:down, version.to_i)
|
56
|
+
break
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def rollback_all
|
62
|
+
MigrationContext.instance.each(&:rollback_branches)
|
63
|
+
end
|
64
|
+
|
65
|
+
def migrate(version, database)
|
66
|
+
MigrationContext.instance.each do |context|
|
67
|
+
next unless ActualDbSchema.db_config[:database] == database
|
68
|
+
|
69
|
+
if context.migrations.detect { |m| m.version.to_s == version }
|
70
|
+
context.run(:up, version.to_i)
|
71
|
+
break
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
def build_migration_struct(status, migration)
|
79
|
+
Migration.new(
|
80
|
+
status: status,
|
81
|
+
version: migration.version.to_s,
|
82
|
+
name: migration.name,
|
83
|
+
branch: branch_for(migration.version),
|
84
|
+
database: ActualDbSchema.db_config[:database],
|
85
|
+
filename: migration.filename,
|
86
|
+
phantom: phantom?(migration)
|
87
|
+
)
|
88
|
+
end
|
89
|
+
|
90
|
+
def sort_migrations_desc(migrations)
|
91
|
+
migrations.sort_by { |migration| migration[:version].to_i }.reverse if migrations.any?
|
92
|
+
end
|
93
|
+
|
94
|
+
def phantom?(migration)
|
95
|
+
migration.filename.include?("/tmp/migrated")
|
96
|
+
end
|
97
|
+
|
98
|
+
def should_include?(status, migration)
|
99
|
+
migration && (status == "up" || !phantom?(migration))
|
100
|
+
end
|
101
|
+
|
102
|
+
def find_migration_in_context(context, version)
|
103
|
+
migration = context.migrations.detect { |m| m.version.to_s == version }
|
104
|
+
return unless migration
|
105
|
+
|
106
|
+
status = context.migrations_status.detect { |_s, v| v.to_s == version }&.first || "unknown"
|
107
|
+
build_migration_struct(status, migration)
|
108
|
+
end
|
109
|
+
|
110
|
+
def branch_for(version)
|
111
|
+
metadata.fetch(version.to_s, {})[:branch] || "unknown"
|
112
|
+
end
|
113
|
+
|
114
|
+
def metadata
|
115
|
+
@metadata ||= {}
|
116
|
+
@metadata[ActualDbSchema.db_config[:database]] ||= ActualDbSchema::Store.instance.read
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActualDbSchema
|
4
|
+
# The class manages connections to each database and provides the appropriate migration context for each connection.
|
5
|
+
class MigrationContext
|
6
|
+
include Singleton
|
7
|
+
|
8
|
+
def each
|
9
|
+
configs.each do |db_config|
|
10
|
+
establish_connection(db_config)
|
11
|
+
yield context
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def establish_connection(db_config)
|
18
|
+
config = db_config.respond_to?(:config) ? db_config.config : db_config
|
19
|
+
ActiveRecord::Base.establish_connection(config)
|
20
|
+
end
|
21
|
+
|
22
|
+
def configs
|
23
|
+
ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env)
|
24
|
+
end
|
25
|
+
|
26
|
+
def context
|
27
|
+
ar_version = Gem::Version.new(ActiveRecord::VERSION::STRING)
|
28
|
+
context = if ar_version >= Gem::Version.new("7.2.0") ||
|
29
|
+
(ar_version >= Gem::Version.new("7.1.0") && ar_version.prerelease?)
|
30
|
+
ActiveRecord::Base.connection_pool.migration_context
|
31
|
+
else
|
32
|
+
ActiveRecord::Base.connection.migration_context
|
33
|
+
end
|
34
|
+
context.extend(ActualDbSchema::Patches::MigrationContext)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -5,7 +5,7 @@ module ActualDbSchema
|
|
5
5
|
# Add new command to roll back the phantom migrations
|
6
6
|
module MigrationContext
|
7
7
|
def rollback_branches(manual_mode: false)
|
8
|
-
|
8
|
+
phantom_migrations.reverse_each do |migration|
|
9
9
|
next unless status_up?(migration)
|
10
10
|
|
11
11
|
show_info_for(migration) if manual_mode
|
@@ -15,6 +15,16 @@ module ActualDbSchema
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
+
def phantom_migrations
|
19
|
+
paths = Array(migrations_paths)
|
20
|
+
current_branch_files = Dir[*paths.flat_map { |path| "#{path}/**/[0-9]*_*.rb" }]
|
21
|
+
current_branch_file_names = current_branch_files.map { |f| ActualDbSchema.migration_filename(f) }
|
22
|
+
|
23
|
+
migrations.reject do |migration|
|
24
|
+
current_branch_file_names.include?(ActualDbSchema.migration_filename(migration.filename))
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
18
28
|
private
|
19
29
|
|
20
30
|
def down_migrator_for(migration)
|
@@ -31,9 +41,13 @@ module ActualDbSchema
|
|
31
41
|
paths = Array(migrations_paths)
|
32
42
|
current_branch_files = Dir[*paths.flat_map { |path| "#{path}/**/[0-9]*_*.rb" }]
|
33
43
|
other_branches_files = Dir["#{ActualDbSchema.migrated_folder}/**/[0-9]*_*.rb"]
|
44
|
+
current_branch_versions = current_branch_files.map { |file| file.match(/(\d+)_/)[1] }
|
45
|
+
filtered_other_branches_files = other_branches_files.reject do |file|
|
46
|
+
version = file.match(/(\d+)_/)[1]
|
47
|
+
current_branch_versions.include?(version)
|
48
|
+
end
|
34
49
|
|
35
|
-
|
36
|
-
other_branches_files.reject { |f| ActualDbSchema.migration_filename(f).in?(current_branch_file_names) }
|
50
|
+
current_branch_files + filtered_other_branches_files
|
37
51
|
end
|
38
52
|
|
39
53
|
def status_up?(migration)
|
@@ -52,7 +66,7 @@ module ActualDbSchema
|
|
52
66
|
puts "\n[ActualDbSchema] A phantom migration was found and is about to be rolled back."
|
53
67
|
puts "Please make a decision from the options below to proceed.\n\n"
|
54
68
|
puts "Branch: #{branch_for(migration.version.to_s)}"
|
55
|
-
puts "Database: #{db_config[:database]}"
|
69
|
+
puts "Database: #{ActualDbSchema.db_config[:database]}"
|
56
70
|
puts "Version: #{migration.version}\n\n"
|
57
71
|
puts File.read(migration.filename)
|
58
72
|
end
|
@@ -69,14 +83,6 @@ module ActualDbSchema
|
|
69
83
|
migrator.migrate
|
70
84
|
end
|
71
85
|
|
72
|
-
def db_config
|
73
|
-
@db_config ||= if ActiveRecord::Base.respond_to?(:connection_db_config)
|
74
|
-
ActiveRecord::Base.connection_db_config.configuration_hash
|
75
|
-
else
|
76
|
-
ActiveRecord::Base.connection_config
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
86
|
def branch_for(version)
|
81
87
|
metadata.fetch(version, {})[:branch] || "unknown"
|
82
88
|
end
|
data/lib/actual_db_schema.rb
CHANGED
@@ -1,10 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "actual_db_schema/engine"
|
3
4
|
require "active_record/migration"
|
4
5
|
require "csv"
|
5
6
|
require_relative "actual_db_schema/git"
|
6
7
|
require_relative "actual_db_schema/store"
|
7
8
|
require_relative "actual_db_schema/version"
|
9
|
+
require_relative "actual_db_schema/migration"
|
10
|
+
require_relative "actual_db_schema/migration_context"
|
8
11
|
require_relative "actual_db_schema/patches/migration_proxy"
|
9
12
|
require_relative "actual_db_schema/patches/migrator"
|
10
13
|
require_relative "actual_db_schema/patches/migration_context"
|
@@ -17,8 +20,6 @@ require_relative "actual_db_schema/commands/list"
|
|
17
20
|
module ActualDbSchema
|
18
21
|
raise NotImplementedError, "ActualDbSchema is only supported in Rails" unless defined?(Rails)
|
19
22
|
|
20
|
-
require "railtie"
|
21
|
-
|
22
23
|
class << self
|
23
24
|
attr_accessor :config, :failed
|
24
25
|
end
|
@@ -26,7 +27,8 @@ module ActualDbSchema
|
|
26
27
|
self.failed = []
|
27
28
|
self.config = {
|
28
29
|
enabled: Rails.env.development?,
|
29
|
-
auto_rollback_disabled: ENV["ACTUAL_DB_SCHEMA_AUTO_ROLLBACK_DISABLED"].present
|
30
|
+
auto_rollback_disabled: ENV["ACTUAL_DB_SCHEMA_AUTO_ROLLBACK_DISABLED"].present?,
|
31
|
+
ui_enabled: Rails.env.development? || ENV["ACTUAL_DB_SCHEMA_UI_ENABLED"].present?
|
30
32
|
}
|
31
33
|
|
32
34
|
def self.migrated_folder
|
@@ -58,17 +60,16 @@ module ActualDbSchema
|
|
58
60
|
end
|
59
61
|
end
|
60
62
|
|
61
|
-
def self.
|
62
|
-
|
63
|
+
def self.db_config
|
64
|
+
if ActiveRecord::Base.respond_to?(:connection_db_config)
|
65
|
+
ActiveRecord::Base.connection_db_config.configuration_hash
|
66
|
+
else
|
67
|
+
ActiveRecord::Base.connection_config
|
68
|
+
end
|
63
69
|
end
|
64
70
|
|
65
|
-
def self.
|
66
|
-
|
67
|
-
configs.each do |db_config|
|
68
|
-
config = db_config.respond_to?(:config) ? db_config.config : db_config
|
69
|
-
ActiveRecord::Base.establish_connection(config)
|
70
|
-
yield
|
71
|
-
end
|
71
|
+
def self.migration_filename(fullpath)
|
72
|
+
fullpath.split("/").last
|
72
73
|
end
|
73
74
|
end
|
74
75
|
|
data/lib/tasks/db.rake
CHANGED
@@ -4,8 +4,8 @@ namespace :db do
|
|
4
4
|
desc "Rollback migrations that were run inside not a merged branch."
|
5
5
|
task rollback_branches: :load_config do
|
6
6
|
ActualDbSchema.failed = []
|
7
|
-
ActualDbSchema.
|
8
|
-
ActualDbSchema::Commands::Rollback.new.call
|
7
|
+
ActualDbSchema::MigrationContext.instance.each do |context|
|
8
|
+
ActualDbSchema::Commands::Rollback.new(context).call
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
@@ -13,16 +13,16 @@ namespace :db do
|
|
13
13
|
desc "Manually rollback phantom migrations one by one"
|
14
14
|
task manual: :load_config do
|
15
15
|
ActualDbSchema.failed = []
|
16
|
-
ActualDbSchema.
|
17
|
-
ActualDbSchema::Commands::Rollback.new(manual_mode: true).call
|
16
|
+
ActualDbSchema::MigrationContext.instance.each do |context|
|
17
|
+
ActualDbSchema::Commands::Rollback.new(context, manual_mode: true).call
|
18
18
|
end
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
22
|
desc "List all phantom migrations - non-relevant migrations that were run inside not a merged branch."
|
23
23
|
task phantom_migrations: :load_config do
|
24
|
-
ActualDbSchema.
|
25
|
-
ActualDbSchema::Commands::List.new.call
|
24
|
+
ActualDbSchema::MigrationContext.instance.each do |context|
|
25
|
+
ActualDbSchema::Commands::List.new(context).call
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: actual_db_schema
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrei Kaleshka
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-07-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -127,6 +127,15 @@ files:
|
|
127
127
|
- README.md
|
128
128
|
- Rakefile
|
129
129
|
- actual_db_schema.gemspec
|
130
|
+
- app/assets/javascripts/application.js
|
131
|
+
- app/assets/stylesheets/styles.css
|
132
|
+
- app/controllers/actual_db_schema/migrations_controller.rb
|
133
|
+
- app/controllers/actual_db_schema/phantom_migrations_controller.rb
|
134
|
+
- app/views/actual_db_schema/migrations/index.html.erb
|
135
|
+
- app/views/actual_db_schema/migrations/show.html.erb
|
136
|
+
- app/views/actual_db_schema/phantom_migrations/index.html.erb
|
137
|
+
- app/views/actual_db_schema/phantom_migrations/show.html.erb
|
138
|
+
- config/routes.rb
|
130
139
|
- gemfiles/rails.6.0.gemfile
|
131
140
|
- gemfiles/rails.6.1.gemfile
|
132
141
|
- gemfiles/rails.7.0.gemfile
|
@@ -136,13 +145,15 @@ files:
|
|
136
145
|
- lib/actual_db_schema/commands/base.rb
|
137
146
|
- lib/actual_db_schema/commands/list.rb
|
138
147
|
- lib/actual_db_schema/commands/rollback.rb
|
148
|
+
- lib/actual_db_schema/engine.rb
|
139
149
|
- lib/actual_db_schema/git.rb
|
150
|
+
- lib/actual_db_schema/migration.rb
|
151
|
+
- lib/actual_db_schema/migration_context.rb
|
140
152
|
- lib/actual_db_schema/patches/migration_context.rb
|
141
153
|
- lib/actual_db_schema/patches/migration_proxy.rb
|
142
154
|
- lib/actual_db_schema/patches/migrator.rb
|
143
155
|
- lib/actual_db_schema/store.rb
|
144
156
|
- lib/actual_db_schema/version.rb
|
145
|
-
- lib/railtie.rb
|
146
157
|
- lib/tasks/db.rake
|
147
158
|
- sig/actual_db_schema.rbs
|
148
159
|
homepage: https://blog.widefix.com/actual-db-schema/
|
data/lib/railtie.rb
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "rails"
|
4
|
-
|
5
|
-
module ActualDbSchema
|
6
|
-
# Load the task into Rails app
|
7
|
-
class Railtie < Rails::Railtie
|
8
|
-
railtie_name :actual_db_schema
|
9
|
-
|
10
|
-
rake_tasks do
|
11
|
-
path = File.expand_path(__dir__)
|
12
|
-
Dir.glob("#{path}/tasks/**/*.rake").each { |f| load f }
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|