migration_button 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6fde655a082da6097e895d3bb4e5fc938f67c9ea
4
+ data.tar.gz: 66066fcb42ebc7dd7701da9f2ec16af490b17419
5
+ SHA512:
6
+ metadata.gz: e41232f8e62017c54302f07ed3f03ab6e9a84bd8dac266c611aa387b8493b7a69e86ac017b4a4d2309b2064d68114f897ad15a00c1653a7737a1add2ef0aca04
7
+ data.tar.gz: f77ab4325ad4a24d187abb2406282826faa34a20cee543fd1a7e291dc62bdbe61e86f649d4675a3ed31069283e3712fc78d6e2c6e7629bf48e6f91d23a124191
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2018
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,44 @@
1
+ # MigrationButton
2
+
3
+ Rails engine for running migrations via browser.
4
+
5
+ ![MigrationButton](docs/screencast.gif)
6
+
7
+ ## Installation
8
+ Add this line to your application's Gemfile:
9
+
10
+ ```ruby
11
+ gem 'migration_button', github: 'asok/migration_button'
12
+ ```
13
+
14
+ And then execute:
15
+ ```bash
16
+ $ bundle
17
+ ```
18
+
19
+ Set `:migration_button` in `config/environments/development.rb` like so:
20
+ ```ruby
21
+ config.active_record.migration_error = :migration_button
22
+ ```
23
+
24
+ Now if there are pending migrations you will be presented with the page for running them. You can always visit this page under [http://localhost:3000/__migration_button](http://localhost:3000/__migration_button).
25
+
26
+ ## Contributing
27
+
28
+ Clone the repo.
29
+
30
+ Install the dependencies with:
31
+ ```bash
32
+ $ bundle
33
+ ```
34
+
35
+ Run the tests with:
36
+ ```bash
37
+ $ MIGRATION_BUTTON=1 bundle exec rails test test/*
38
+ ```
39
+
40
+ Develop -> commit -> make a pull request :sunglasses:
41
+
42
+
43
+ ## License
44
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,32 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'MigrationButton'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.md')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__)
18
+ load 'rails/tasks/engine.rake'
19
+
20
+ load 'rails/tasks/statistics.rake'
21
+
22
+ require 'bundler/gem_tasks'
23
+
24
+ require 'rake/testtask'
25
+
26
+ Rake::TestTask.new(:test) do |t|
27
+ t.libs << 'test'
28
+ t.pattern = 'test/**/*_test.rb'
29
+ t.verbose = false
30
+ end
31
+
32
+ task default: :test
@@ -0,0 +1,2 @@
1
+ //= link_directory ../javascripts/migration_button .js
2
+ //= link_directory ../stylesheets/migration_button .css
@@ -0,0 +1,14 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // compiled file. JavaScript code in this file should be added after the last require_* statement.
9
+ //
10
+ // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
11
+ // about supported directives.
12
+ //
13
+ //= require rails-ujs
14
+ //= require_tree .
@@ -0,0 +1,15 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
+ * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
10
+ * files in this directory. Styles in this file should be added after the last require_* statement.
11
+ * It is generally better to create a new file per style scope.
12
+ *
13
+ *= require_tree .
14
+ *= require_self
15
+ */
@@ -0,0 +1,5 @@
1
+ module MigrationButton
2
+ class ApplicationController < ActionController::Base
3
+ protect_from_forgery with: :exception
4
+ end
5
+ end
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ class MigrationButton::RunnerController < ActionController::Base
4
+ layout "migration_button/application"
5
+
6
+ skip_before_action :verify_authenticity_token if respond_to?(:verify_authenticity_token)
7
+
8
+ def index
9
+ @page = page
10
+ end
11
+
12
+ def migrate
13
+ @page = page { runner.migrate }
14
+
15
+ render :index
16
+ end
17
+
18
+ def up
19
+ @page = page { runner.run(:up, params[:version]) }
20
+
21
+ render :index
22
+ end
23
+
24
+ def down
25
+ @page = page { runner.run(:down, params[:version]) }
26
+
27
+ render :index
28
+ end
29
+
30
+ def self.runner
31
+ MigrationButton::Runner.new
32
+ end
33
+
34
+ def self.page(&blk)
35
+ output = blk&.call
36
+
37
+ Page.new(runner.migrations_status,
38
+ output,
39
+ MigrationButton::Middleware.last_request)
40
+ end
41
+
42
+ protected
43
+
44
+ def runner
45
+ @runner ||= self.class.runner
46
+ end
47
+
48
+ def page(&blk)
49
+ self.class.page(&blk)
50
+ end
51
+
52
+ class Page
53
+ attr_reader :migrations, :output, :last_request
54
+
55
+ def initialize(migrations_status, output, last_request)
56
+ @migrations = migrations_status.map do |(state, version, name)|
57
+ Migration.new(state, version, name)
58
+ end.sort_by(&:version).reverse
59
+
60
+ @output = output
61
+ @last_request = last_request
62
+ end
63
+
64
+ class Migration < Struct.new(:state, :version, :name)
65
+ NO_FILE = '********** NO FILE **********'
66
+
67
+ def runnable?
68
+ name != NO_FILE
69
+ end
70
+
71
+ def down?
72
+ state == "down"
73
+ end
74
+
75
+ def up?
76
+ !down?
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,4 @@
1
+ module MigrationButton
2
+ module ApplicationHelper
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module MigrationButton
2
+ class ApplicationJob < ActiveJob::Base
3
+ end
4
+ end
@@ -0,0 +1,6 @@
1
+ module MigrationButton
2
+ class ApplicationMailer < ActionMailer::Base
3
+ default from: 'from@example.com'
4
+ layout 'mailer'
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ module MigrationButton
2
+ class ApplicationRecord < ActiveRecord::Base
3
+ self.abstract_class = true
4
+ end
5
+ end
@@ -0,0 +1,140 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Migration button</title>
5
+ <%= csrf_meta_tags %>
6
+
7
+ <%= stylesheet_link_tag "migration_button/application", media: "all" %>
8
+ <%= javascript_include_tag "migration_button/application" %>
9
+
10
+ <style>
11
+ header.pending {
12
+ color: #F0F0F0;
13
+ background: #C52F24;
14
+ }
15
+
16
+ header.no-pending {
17
+ color: #F0F0F0;
18
+ background: #00bfff;
19
+ }
20
+
21
+ .heading {
22
+ padding: 0.01em 1.5em;
23
+ }
24
+
25
+ .flex-grid {
26
+ display: flex;
27
+ }
28
+
29
+ .col {
30
+ flex: 1;
31
+ }
32
+
33
+ .up-btn {
34
+ background: #F0F0F0;
35
+ color: #00bfff;
36
+ font-weight: 800;
37
+ padding:5px 15px;
38
+ border:0 none;
39
+ cursor:pointer;
40
+ -webkit-border-radius: 5px;
41
+ border-radius: 5px;
42
+ }
43
+
44
+ .down-btn {
45
+ background: #D9D9D9;
46
+ color: #C52F24;
47
+ font-weight: 800;
48
+ padding:5px 15px;
49
+ border:0 none;
50
+ cursor:pointer;
51
+ -webkit-border-radius: 5px;
52
+ border-radius: 5px;
53
+ }
54
+
55
+ .button-form {
56
+ display: inline;
57
+ }
58
+
59
+ .output_pane * {
60
+ margin: 0px;
61
+ padding: 0px;
62
+ }
63
+
64
+ .output_pane {
65
+ border: 1px solid #D9D9D9;
66
+ background: #ECECEC;
67
+ height: 100%;
68
+ }
69
+
70
+ .output_pane .toggle {
71
+ padding: 10px;
72
+ }
73
+
74
+ .output_pane .output {
75
+ font-size: 80%;
76
+ overflow: auto;
77
+ background-color: #FFF;
78
+ padding: 1em;
79
+ height: 100%;
80
+ }
81
+
82
+ #migrator-output {
83
+ height: 100%;
84
+ }
85
+
86
+ #migrations-table th {
87
+ padding: 1em 0;
88
+ }
89
+
90
+ #migrations-table thead {
91
+ background-color: #ddd;
92
+ }
93
+
94
+ #migrations-table {
95
+ border-collapse: collapse;
96
+ border-spacing: 0;
97
+ width: 100%;
98
+ }
99
+
100
+ #migrations-table tbody tr.status-row {
101
+ border-top: 1px solid #ddd;
102
+ }
103
+
104
+ #migrations-table tbody tr:nth-child(odd) {
105
+ background: #f2f2f2;
106
+ }
107
+
108
+ #migrations-table td.padded {
109
+ padding: 4px 30px;
110
+ }
111
+
112
+ #migrations-table tr.output-row td {
113
+ /* display: table; */
114
+ border: none;
115
+ }
116
+
117
+ #migrations-table tr.status-row td {
118
+ border: none;
119
+ }
120
+
121
+ #migrations-table .output_pane {
122
+ border: none;
123
+ background: #f2f2f2;
124
+ }
125
+ </style>
126
+
127
+ <script>
128
+ var toggle = function(id) {
129
+ var s = document.getElementById(id).style;
130
+ s.display = s.display == 'none' ? 'block' : 'none';
131
+ return false;
132
+ }
133
+ </script>
134
+ </head>
135
+ <body data-turbolinks="false">
136
+
137
+ <%= yield %>
138
+
139
+ </body>
140
+ </html>
@@ -0,0 +1,5 @@
1
+ <div>
2
+ <code><pre id="migrator-output-<%= params[:version] || 'all' %>"><%= output %></pre></code>
3
+
4
+ <% yield if block_given? %>
5
+ </div>
@@ -0,0 +1,9 @@
1
+ <div class="output_pane">
2
+ <div class="output">
3
+ <% if output.present? %>
4
+ <code><pre><%= output %></pre></code>
5
+ <% else %>
6
+ <i>No output</i>
7
+ <% end %>
8
+ </div>
9
+ </div>
@@ -0,0 +1,70 @@
1
+ <% if @page.migrations.any?(&:down?) %>
2
+ <header class="pending heading">
3
+ <h1>
4
+ <span>
5
+ There are pending migrations
6
+ </span>
7
+ </h1>
8
+ </header>
9
+ <% else %>
10
+ <header class="no-pending heading">
11
+ <h1>
12
+ There are no pending migrations
13
+ <% if @page.last_request %>
14
+ <%= button_to "Resume", @page.last_request.fullpath, method: @page.last_request.request_method.downcase.intern, form_class: "button-form", class: "up-btn", params: @page.last_request.params %>
15
+ <% end %>
16
+ </h1>
17
+ </header>
18
+ <% end %>
19
+
20
+ <header class="heading">
21
+ <h2>
22
+ Migrations status
23
+ </h2>
24
+ </header>
25
+
26
+ <div class="flex-grid">
27
+ <div class="col">
28
+ <table id="migrations-table">
29
+ <thead>
30
+ <th>State</th>
31
+ <th>Version</th>
32
+ <th>Name</th>
33
+ <th>
34
+ <% if @page.migrations.any?(&:down?) %>
35
+ <%= button_to "Migrate all", "#{MigrationButton.mount_path}/migrate", method: "post", form_class: "button-form", class: "up-btn" %>
36
+ <% end %>
37
+ </th>
38
+ </thead>
39
+ <tbody>
40
+ <% if @page.migrations.empty? %>
41
+ <tr><td class="padded" colspan="4">No migrations</td></tr>
42
+ <% else %>
43
+ <% @page.migrations.each do |migration| %>
44
+ <tr class="status-row">
45
+ <td class="padded"><%= migration.state %></td>
46
+ <td class="padded"><%= migration.version %></td>
47
+ <td class="padded"><%= migration.name %></td>
48
+ <td class="padded">
49
+ <% if migration.runnable? %>
50
+ <% if migration.down? %>
51
+ <%= button_to "Up", "#{MigrationButton.mount_path}/up/#{migration.version}", method: "post", form_class: "button-form", class: "up-btn" %>
52
+ <% else %>
53
+ <%= button_to "Down", "#{MigrationButton.mount_path}/down/#{migration.version}", method: "post", form_class: "button-form", class: "down-btn" %>
54
+ <% end %>
55
+ <% end %>
56
+ </td>
57
+ </tr>
58
+ <% end %>
59
+ <% end %>
60
+ </tbody>
61
+ </table>
62
+ </div>
63
+
64
+ <div class="col">
65
+
66
+ <div id="migrator-output" style="display: <%= @page.output.nil? ? 'none' : 'block' %>">
67
+ <%= render "output_pane", output: @page.output %>
68
+ </div>
69
+ </div>
70
+ </div>
@@ -0,0 +1,7 @@
1
+ <%= render layout: "output", locals: {output: @output} do %>
2
+ <% if MigrationButton::Middleware.last_request %>
3
+ <div id="resume-button">
4
+ <%= button_to(MigrationButton::Middleware.resume_button_label, "/migration_button/resume") %>
5
+ </div>
6
+ <% end %>
7
+ <% end %>
@@ -0,0 +1,5 @@
1
+ <%= render layout: "output", locals: {output: @output, version: 'all'} do %>
2
+ <% if MigrationButton::Middleware.last_request %>
3
+ document.getElementById("resume-button").innerHTML = "<%= escape_javascript button_to(MigrationButton::Middleware.resume_button_label, "/migration_button/resume") %>"
4
+ <% end %>
5
+ <% end %>
data/config/routes.rb ADDED
@@ -0,0 +1,7 @@
1
+ MigrationButton::Engine.routes.draw do
2
+ get "/" => "runner#index"
3
+ post "/migrate" => "runner#migrate"
4
+
5
+ post "/up/:version" => "runner#up"
6
+ post "/down/:version" => "runner#down"
7
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "migration_button/middleware"
4
+ require "migration_button/engine"
5
+ require "migration_button/runner"
6
+
7
+ module MigrationButton
8
+ mattr_accessor :mount_path
9
+ self.mount_path = "/__migration_button"
10
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'migration_button/initializer'
4
+
5
+ module MigrationButton
6
+ class Engine < ::Rails::Engine
7
+ isolate_namespace MigrationButton
8
+
9
+ mattr_accessor :_initializer
10
+ self._initializer = MigrationButton::Initializer.new
11
+
12
+ config.before_initialize do
13
+ # Config entry `config.active_record.migration_error` is deleted
14
+ # by active record's railtie initializer.
15
+ # So we have to read it in `before_initialize` block,
16
+ # but we need to insert the middleware during initialization.
17
+ if config.active_record.migration_error == :migration_button
18
+ _initializer.on!
19
+ end
20
+ end
21
+
22
+ initializer "migration_button.setup" do
23
+ _initializer.add_hook do # rubocop:disable Style/MultilineIfModifier
24
+ config.after_initialize do |app|
25
+ app.routes.prepend do
26
+ mount MigrationButton::Engine => MigrationButton.mount_path, internal: true
27
+ end
28
+ end
29
+ end if _initializer.on?
30
+
31
+ _initializer.run(self)
32
+
33
+ config.after_initialize do
34
+ MigrationButton::Engine._initializer = nil
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MigrationButton
4
+ class Initializer
5
+ def on!
6
+ if !Rails.env.development? && ENV['MIGRATION_BUTTON'].nil?
7
+ add_warn_hook
8
+ else
9
+ @on = true
10
+ add_insert_middleware_hook
11
+ end
12
+ end
13
+
14
+ def run(object)
15
+ hooks.each do |hook|
16
+ object.instance_exec(&hook)
17
+ end
18
+ end
19
+
20
+ def add_hook(&hook)
21
+ hooks << hook
22
+ end
23
+
24
+ def on?
25
+ !!@on
26
+ end
27
+
28
+ protected
29
+
30
+ def add_warn_hook
31
+ add_hook do
32
+ Rails.logger.warn(<<-ERR)
33
+ MigrationButton engine is considered to be dangeroues in other environments than 'development'.
34
+ To surpress this warning message remove line:
35
+ `config.active_record.migration_error = :migration_button`
36
+ from 'config/environments/#{Rails.env}.rb' file.
37
+ Or force using it by settting environment variable 'MIGRATION_BUTTON'.
38
+ ERR
39
+ end
40
+ end
41
+
42
+ def add_insert_middleware_hook
43
+ add_hook do
44
+ if defined?(::BetterErrors::Middleware) &&
45
+ defined?(::BetterErrors::Railtie) &&
46
+ ::BetterErrors::Railtie.use_better_errors?
47
+
48
+ Rails.application.middleware.insert_after ::BetterErrors::Middleware, MigrationButton::Middleware
49
+ else
50
+ config.app_middleware.insert_after ActionDispatch::Callbacks, MigrationButton::Middleware
51
+ end
52
+ end
53
+ end
54
+
55
+ def hooks
56
+ @hooks ||= Set.new
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MigrationButton
4
+ class Middleware < ActiveRecord::Migration::CheckPending
5
+ cattr_accessor :last_request
6
+
7
+ def call(env)
8
+ case env['PATH_INFO']
9
+ when /#{MigrationButton.mount_path}/,
10
+ %r(\A/{0,2}#{::Rails.application.config.assets.prefix})
11
+ @app.call env
12
+ else
13
+ protected_app_call(env) { super }
14
+ end
15
+ end
16
+
17
+ def protected_app_call(env)
18
+ yield.tap do
19
+ self.class.last_request = nil
20
+ end
21
+ rescue ActiveRecord::PendingMigrationError
22
+ self.class.last_request = Rack::Request.new(env)
23
+ migrations_status_response
24
+ end
25
+
26
+ def migrations_status_response
27
+ [
28
+ 500,
29
+ {'Content-Type' => 'text/html; charset=utf-8'},
30
+ [render_migrations_status]
31
+ ]
32
+ end
33
+
34
+ def render_migrations_status
35
+ MigrationButton::RunnerController
36
+ .render('index',
37
+ assigns: {
38
+ page: MigrationButton::RunnerController.page
39
+ })
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,91 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_record'
4
+
5
+ module MigrationButton
6
+ module RunnerHelper
7
+ protected
8
+
9
+ def capture_output
10
+ logger = ActiveRecord::Base.logger
11
+ ::ActiveRecord::Base.logger = nil
12
+ stdout = $stdout
13
+
14
+ $stdout = StringIO.new
15
+
16
+ yield
17
+
18
+ $stdout.string || ""
19
+ ensure
20
+ ::ActiveRecord::Base.logger = logger
21
+ $stdout = stdout
22
+ end
23
+
24
+ def migrations_paths
25
+ Rails.application.paths['db/migrate'].to_a
26
+ end
27
+ end
28
+
29
+ class Implementation
30
+ include RunnerHelper
31
+
32
+ def initialize
33
+ @migrator = ActiveRecord::MigrationContext.new(migrations_paths)
34
+ end
35
+
36
+ def migrations_status
37
+ @migrator.migrations_status
38
+ end
39
+
40
+ def migrate
41
+ capture_output do
42
+ @migrator.migrate
43
+ end
44
+ end
45
+
46
+ def rollback
47
+ capture_output do
48
+ @migrator.rollback
49
+ end
50
+ end
51
+
52
+ def run(direction, version)
53
+ capture_output do
54
+ @migrator.run(direction.intern, version.to_i)
55
+ end
56
+ end
57
+ end
58
+
59
+ class LegacyImplementation
60
+ include RunnerHelper
61
+
62
+ def migrations_status
63
+ ActiveRecord::Migrator.migrations_status(migrations_paths)
64
+ end
65
+
66
+ def migrate
67
+ capture_output do
68
+ ActiveRecord::Migrator.migrate(migrations_paths)
69
+ end
70
+ end
71
+
72
+ def rollback
73
+ capture_output do
74
+ ActiveRecord::Migrator.rollback(migrations_paths)
75
+ end
76
+ end
77
+
78
+ def run(direction, version)
79
+ capture_output do
80
+ ActiveRecord::Migrator.run(direction.intern, migrations_paths, version.to_i)
81
+ end
82
+ end
83
+ end
84
+
85
+ # rubocop:disable Naming/ConstantName
86
+ Runner = if Gem::Version.new(Rails.version) >= Gem::Version.new('5.2.1.1')
87
+ Implementation
88
+ else
89
+ LegacyImplementation
90
+ end
91
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MigrationButton
4
+ VERSION = '0.3.0'
5
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :migration_button do
3
+ # # Task goes here
4
+ # end
metadata ADDED
@@ -0,0 +1,169 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: migration_button
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.0
5
+ platform: ruby
6
+ authors:
7
+ - Adam Sokolnicki
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-01-05 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '5.1'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '5.1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: sqlite3
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: capybara
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: capybara-screenshot
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: selenium-webdriver
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: pry
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: puma
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ description: Rails engine that checks for pending migrations and presents an error
112
+ screen that allows you to manage your migrations.
113
+ email:
114
+ - adam.sokolnicki@gmail.com
115
+ executables: []
116
+ extensions: []
117
+ extra_rdoc_files: []
118
+ files:
119
+ - MIT-LICENSE
120
+ - README.md
121
+ - Rakefile
122
+ - app/assets/config/migration_button_manifest.js
123
+ - app/assets/javascripts/migration_button/application.js
124
+ - app/assets/stylesheets/migration_button/application.css
125
+ - app/controllers/migration_button/application_controller.rb
126
+ - app/controllers/migration_button/runner_controller.rb
127
+ - app/helpers/migration_button/application_helper.rb
128
+ - app/jobs/migration_button/application_job.rb
129
+ - app/mailers/migration_button/application_mailer.rb
130
+ - app/models/migration_button/application_record.rb
131
+ - app/views/layouts/migration_button/application.html.erb
132
+ - app/views/migration_button/runner/_output.html.erb
133
+ - app/views/migration_button/runner/_output_pane.html.erb
134
+ - app/views/migration_button/runner/index.html.erb
135
+ - app/views/migration_button/runner/migrate_all.html.erb
136
+ - app/views/migration_button/runner/migrate_all.js.erb
137
+ - config/routes.rb
138
+ - lib/migration_button.rb
139
+ - lib/migration_button/engine.rb
140
+ - lib/migration_button/initializer.rb
141
+ - lib/migration_button/middleware.rb
142
+ - lib/migration_button/runner.rb
143
+ - lib/migration_button/version.rb
144
+ - lib/tasks/migration_button_tasks.rake
145
+ homepage: https://github.com/asok/migration_button
146
+ licenses:
147
+ - MIT
148
+ metadata: {}
149
+ post_install_message:
150
+ rdoc_options: []
151
+ require_paths:
152
+ - lib
153
+ required_ruby_version: !ruby/object:Gem::Requirement
154
+ requirements:
155
+ - - ">="
156
+ - !ruby/object:Gem::Version
157
+ version: '0'
158
+ required_rubygems_version: !ruby/object:Gem::Requirement
159
+ requirements:
160
+ - - ">="
161
+ - !ruby/object:Gem::Version
162
+ version: '0'
163
+ requirements: []
164
+ rubyforge_project:
165
+ rubygems_version: 2.5.2.2
166
+ signing_key:
167
+ specification_version: 4
168
+ summary: Rails engine for running migrations via browser
169
+ test_files: []