rake_migrations_velocity 1.0.11

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: aaed9036fb33e17913e42665b7ccae84aaddfa24c46536cdc2bf18098c5ec9dd
4
+ data.tar.gz: 5d252854d591c8a315a567641e5daf8bb3ae213192cc013fdf730611473eb7e1
5
+ SHA512:
6
+ metadata.gz: 54f63adc8d5d62dc0f67ac3f3494d7393668c6e81c268a4425d7f4d565e6149f728fe032c0c3fd9a8df8ea675f08d1b0e501c25a44d18bbecd5dab145483e089
7
+ data.tar.gz: d0f47ba6d55e0c74787f4746fae54577702491b6f9e8606dfeac0fed46e0f7ddd86cf03a4d390aae4f54be421304223ee65a9fc62affdb46b27db18456699ccb
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2014 YOURNAME
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,116 @@
1
+ Rake Migrations
2
+ ===============
3
+
4
+ This gem helps you and your team members keep track of which rake tasks are yet to be run on a particular system. The logic is similar to that of how `rake db:migrate` is used.
5
+
6
+ For a more verbose explanation please refer to [this blog post](http://eyaleizenberg.blogspot.com/2014/08/how-to-keep-track-of-rails-rake-tasks.html).
7
+
8
+ ## Requirements
9
+ At the moment I have only tested this on Rails 5.X.X, 6.X.x and 7.X.X running postgresql on Mac OS X.
10
+ If you can help by testing this on different versions, databases and platforms, let me know.
11
+
12
+ ## Installation
13
+ First, add this this to your gemfile:
14
+ ```ruby
15
+ gem 'rake_migrations', git: 'https://github.com/Velocity-Engineering/rake-migrations.git'
16
+ ```
17
+
18
+ Then, run:
19
+ ```sh
20
+ bundle install
21
+
22
+
23
+ rails g rake_migrations:install
24
+
25
+ # Don't forget to migrate
26
+ rake db:migrate
27
+ ```
28
+
29
+ This will copy a db schema migration (`rake_migrations`) file and a helper rake task (`devops_rake_utils.rake`) in your `lib/tasks/` directory
30
+
31
+ Finally, add the following file in your `config/initializers` folder to provide the gem with database credentials via the `database.yml` file
32
+ ```ruby
33
+ # rake_migrations.rb
34
+ RakeMigrations.configure do |config|
35
+ config.database_name = 'neobank'
36
+ config.hostname = ENV['DATABASE_HOST']
37
+ config.username = ENV['DATABASE_USERNAME']
38
+ config.password = ENV['DATABASE_PASSWORD']
39
+ end
40
+ ```
41
+
42
+ ## Usage
43
+ Whenever somebody from your team wants to create a new run once task, simply generate it by running:
44
+
45
+ ```sh
46
+ rails g task <namespace> <task>
47
+ ```
48
+
49
+ For example:
50
+
51
+ ```sh
52
+ rails g task migrations_test testing_the_gem
53
+ ```
54
+
55
+ This will generate a file under `lib/tasks/rake_migrations` with a timestamp and six random character prefixed filename and the following content:
56
+
57
+ ```ruby
58
+ #
59
+
60
+ # Checklist:
61
+ # 1. Re-runnable on production?
62
+ # 2. Is there a chance emails will be sent?
63
+ # 3. puts ids & logs (progress log)
64
+ # 4. Should this be inside a Active Record Transaction block?
65
+ # 5. Are there any callbacks?
66
+ # 6. Performance issues?
67
+
68
+ namespace :migrations_test do
69
+ desc "TODO"
70
+ task testing_the_gem: [:environment] do
71
+
72
+ # DO NOT REMOVE THIS PART. MARKS THE RAKE AS COMPLETE IN THE DATABASE
73
+ RakeMigration.mark_complete(__FILE__)
74
+ end
75
+ end
76
+
77
+ ```
78
+
79
+ Simply insert your code above the "DO NOT REMOVE THIS PART" line. The checklist is there to help you and the person who is code-reviewing your code to think of problems that might occur from your rake task.
80
+
81
+ Afterwards, whenever we need to check whether pending rake tasks, we run the following helper rake task...
82
+
83
+ ```sh
84
+ rake devops_rake_utils:list_pending_rake_tasks
85
+ ```
86
+
87
+ ... which will give the following output in case some tasks aren't mapped to the `rake_migrations` database table
88
+
89
+ ```sh
90
+ You need to run the following rakes:
91
+ ------------------------------------
92
+ rake migrations_test:testing_the_gem
93
+ ```
94
+
95
+ You can run the rake task normally:
96
+
97
+ ```sh
98
+ rake migrations_test:testing_the_gem
99
+ ```
100
+
101
+ In case all of the rake files have been mapped across the `rake_migrations` table, you will receive the following message
102
+
103
+ ```sh
104
+ All rake files are mapped in the DB! No untracked rake tasks are present!
105
+ ```
106
+
107
+ ## Caveats
108
+ - In order to make sure the gem is serving the intended purpose, please make sure every rake file has just one namespace and one task only
109
+ - Adding support for multiple tasks beneath a single name space in a single rake file might a feature request we may consider in the future
110
+
111
+ ## Issues, suggestions and forks.
112
+ Feel free to open issues, send suggestions and fork this repository.
113
+
114
+ This gem was developed by [Eyal Eizenberg](http://eyaleizenberg.blogspot.com/2014/08/how-to-keep-track-of-rails-rake-tasks.html) and enhanced by [Mani Bhushan](https://github.com/manibhushan05/).
115
+
116
+ Thanks and Enjoy! :)
data/Rakefile ADDED
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+ begin
8
+ require 'rdoc/task'
9
+ rescue LoadError
10
+ require 'rdoc/rdoc'
11
+ require 'rake/rdoctask'
12
+ RDoc::Task = Rake::RDocTask
13
+ end
14
+
15
+ RDoc::Task.new(:rdoc) do |rdoc|
16
+ rdoc.rdoc_dir = 'rdoc'
17
+ rdoc.title = 'RakeMigrations'
18
+ rdoc.options << '--line-numbers'
19
+ rdoc.rdoc_files.include('README.rdoc')
20
+ rdoc.rdoc_files.include('lib/**/*.rb')
21
+ end
22
+
23
+
24
+
25
+
26
+ Bundler::GemHelper.install_tasks
27
+
28
+ require 'rake/testtask'
29
+
30
+ Rake::TestTask.new(:test) do |t|
31
+ t.libs << 'lib'
32
+ t.libs << 'test'
33
+ t.pattern = 'test/**/*_test.rb'
34
+ t.verbose = false
35
+ end
36
+
37
+
38
+ task :default => :test
@@ -0,0 +1,56 @@
1
+ require 'rails/generators'
2
+ require 'rails/generators/migration'
3
+ require 'rails/generators/active_record'
4
+
5
+ module RakeMigrations
6
+ class InstallGenerator < Rails::Generators::Base
7
+ include Rails::Generators::Migration
8
+ extend ActiveRecord::Generators::Migration
9
+ source_root File.expand_path('../templates', __FILE__)
10
+
11
+ def create_migration_file
12
+ copy_migration_template_based_on_rails_version
13
+
14
+ # copying the Devops task template
15
+ template("devops_rake_utils.rake", "lib/tasks/devops_rake_utils.rake")
16
+
17
+ end
18
+
19
+ def self.next_migration_number(dirname)
20
+ ActiveRecord::Generators::Base.next_migration_number dirname
21
+ end
22
+
23
+ def write_to_post_merge_hook
24
+ post_merge_file = ".git/hooks/post-merge"
25
+ what_to_write = <<-TEXT
26
+ #{!File.exists?(post_merge_file) ? '#!/bin/sh' : ''}
27
+ ruby ./config/rake_migrations_check.rb
28
+ TEXT
29
+
30
+ File.open(post_merge_file, 'a+') do |file|
31
+ file.write(what_to_write) unless file.read.match(/rake_migrations_check/)
32
+ end
33
+ `chmod 777 #{post_merge_file}`
34
+ end
35
+
36
+ private
37
+ def copy_migration_template_based_on_rails_version
38
+
39
+ host_rails_version = Rails.version
40
+ version_info = host_rails_version.split('.')
41
+
42
+ major_version = version_info.first
43
+ minor_version = version_info.second
44
+
45
+ if major_version.to_i <= 4
46
+ migration_template "migration_rails_on_and_before_v4.rb", "db/migrate/create_rake_migrations_table.rb"
47
+ else
48
+ @rails_major_minor_version = "[#{major_version}.#{minor_version}]"
49
+ migration_template "migration_rails_after_v4.rb", "db/migrate/create_rake_migrations_table.rb",
50
+ rails_major_minor_version: @rails_major_minor_version
51
+
52
+ end
53
+ end
54
+
55
+ end
56
+ end
@@ -0,0 +1,6 @@
1
+ namespace :devops_rake_utils do
2
+ desc "Lists out all the non migrated rake tasks for an application"
3
+ task list_pending_rake_tasks: [:environment] do
4
+ RakeMigrations.check
5
+ end
6
+ end
@@ -0,0 +1,16 @@
1
+ class CreateRakeMigrationsTable < ActiveRecord::Migration<%= @rails_major_minor_version %>
2
+ def self.up
3
+ create_table :rake_migrations do |t|
4
+ t.string :version
5
+ t.string :namespace
6
+ t.string :task_name
7
+ t.string :created_by
8
+ t.datetime :created_at
9
+ t.float :duration
10
+ end
11
+ end
12
+
13
+ def self.down
14
+ drop_table :rake_migrations
15
+ end
16
+ end
@@ -0,0 +1,11 @@
1
+ class CreateRakeMigrationsTable < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :rake_migrations, id: false do |t|
4
+ t.string :version
5
+ end
6
+ end
7
+
8
+ def self.down
9
+ drop_table :rake_migrations
10
+ end
11
+ end
@@ -0,0 +1,8 @@
1
+ Description:
2
+ This generator will create rake tasks with a time stamp and default messages.
3
+
4
+ Example:
5
+ rails generate task incidents convert_x_to_y
6
+
7
+ This will create:
8
+ lib/tasks/rake_migrations/[time_stamp]incidents.rake
@@ -0,0 +1,23 @@
1
+ =begin
2
+ Creates a rake task file sourced from the template and stores it in the following directory
3
+
4
+ `/lib/tasks/<namespace>`
5
+
6
+ under the file name YYYYMMDDHHMMSS_<random-six-char-str>_task_name.rake
7
+
8
+ eg.
9
+
10
+ lib/tasks/rake_migrations/migration_test/20190403165149_8e374a_first_test.rake
11
+
12
+ =end
13
+ class TaskGenerator < Rails::Generators::NamedBase
14
+ source_root File.expand_path('../templates', __FILE__)
15
+ argument :actions, type: :array, default: [], banner: "action action"
16
+
17
+ def create_task_files
18
+ time_stamp = Time.now.strftime("%Y%m%d%H%M%S")
19
+ random_char_str = SecureRandom.hex(3)
20
+ task_name = actions.first.present? ? actions.first : file_name
21
+ template 'task.rb', File.join("lib/tasks/rake_migrations/#{file_name}", "#{time_stamp}_#{random_char_str}_#{task_name}.rake")
22
+ end
23
+ end
@@ -0,0 +1,23 @@
1
+ # Checklist:
2
+ # - Should this be inside a Active Record Transaction block?
3
+ # - Do we need to notify specific stakeholders about the database changes?
4
+ # - Any callbacks, emails or notifications triggered?
5
+ # - Appropriate prints and progress logs?
6
+ # - Performance issues and manual garbage collection required?
7
+
8
+ namespace :<%= file_name %> do
9
+ <% actions.each do |action| -%>
10
+ desc "TODO"
11
+ task <%= action %>: [:environment] do
12
+ time = Benchmark.ms {
13
+ ActiveRecord::Base.transaction do
14
+ # ADD YOUR CODE HERE
15
+
16
+ end
17
+ }
18
+ # DO NOT REMOVE THIS PART. MARKS THE RAKE AS COMPLETE IN THE DATABASE
19
+ top_level_task = Rake.application.top_level_tasks[0]
20
+ RakeMigration.mark_complete(__FILE__, top_level_task.split(':')[0], top_level_task.split(':')[1], 'System', time)
21
+ end
22
+ <% end -%>
23
+ end
@@ -0,0 +1,25 @@
1
+ class RakeMigration < ::ActiveRecord::Base
2
+ def self.version_from_path(path)
3
+ path.split('/').last.split('_').first(2).join('_')
4
+ end
5
+
6
+ def self.findcreate_by_version(rake_id, namespace, task_name, created_by, duration)
7
+ find_or_create_by(
8
+ version: rake_id, namespace: namespace, task_name: task_name, created_by: created_by, duration: duration, created_at: Time.now.utc.in_time_zone('Asia/Kolkata'))
9
+ end
10
+
11
+ def self.mark_complete(file, namespace, task_name, created_by, duration)
12
+ rake_id = version_from_path(file)
13
+ if methods.include?(:find_or_create_by)
14
+ find_or_create_by(
15
+ version: rake_id, namespace: namespace, task_name: task_name, created_by: created_by, duration: duration, created_at: Time.now.utc.in_time_zone('Asia/Kolkata'))
16
+ else
17
+ findcreate_by_version(rake_id, namespace, task_name, created_by, duration)
18
+ end
19
+ end
20
+
21
+ def self.check_for_pending_tasks
22
+ RakeMigrations.check
23
+ end
24
+
25
+ end
@@ -0,0 +1,45 @@
1
+ module RakeMigrations
2
+ class Config
3
+ attr_accessor :database_name, :hostname, :username, :password
4
+
5
+ def initialize
6
+ @database_name = nil
7
+ @hostname = nil
8
+ @username = nil
9
+ @password = nil
10
+ end
11
+
12
+ def generate_database_client
13
+ validate_presence_of_required_connection_attributes
14
+ log_presence_of_optional_connection_attributes
15
+ connection_object_based_on_attributes
16
+ end
17
+
18
+ private
19
+
20
+ def validate_presence_of_required_connection_attributes
21
+ fail 'Database name should be provided!' unless @database_name
22
+ fail 'Host Name should be provided' unless @hostname
23
+ true
24
+ end
25
+
26
+ def log_presence_of_optional_connection_attributes
27
+ p 'Connecting to the database without username' unless @username
28
+ p 'Connecting to the database without password' unless @password
29
+ end
30
+
31
+ def connection_object_based_on_attributes
32
+ if @password.present? && @username.present?
33
+ client = Mysql2::Client.new(host: @hostname,
34
+ dbname: @database_name,
35
+ user: @username,
36
+ password: @password)
37
+ else
38
+ client = Mysql2::Client.new(host: @hostname,
39
+ dbname: @database_name)
40
+ end
41
+ client
42
+ end
43
+
44
+ end
45
+ end
@@ -0,0 +1,3 @@
1
+ module RakeMigrations
2
+ VERSION = "1.0.11"
3
+ end
@@ -0,0 +1,47 @@
1
+ require 'active_record'
2
+ require 'rake_migration'
3
+ require 'rake_migrations/config'
4
+
5
+ module RakeMigrations
6
+
7
+ def self.configure
8
+ yield @config = RakeMigrations::Config.new
9
+ end
10
+
11
+ def self.check
12
+ =begin
13
+ - list out all the filename present in /lib/tasks/rake_migrations/
14
+ - compares the uuid (ts + 6 char) with that present database attached to the application
15
+ - if the file prefix is not present in the `rake_migrations` table, prints out on the console
16
+ that the rake task is pending
17
+ =end
18
+ client = @config.generate_database_client
19
+
20
+ results = client.exec("select * from rake_migrations").map {|res| res["version"] }
21
+ rake_migrations_lib = "#{`pwd`.strip}/lib/tasks/rake_migrations"
22
+ list_of_files = Dir[ File.join(rake_migrations_lib, '**', '*') ].reject { |p| File.directory? p }
23
+
24
+ rake_files = list_of_files.sort.map do |file|
25
+ rake_id = RakeMigration.version_from_path(file)
26
+
27
+ if !results.include?(rake_id)
28
+ file = File.read(file)
29
+ namespace = file[/namespace :?([^: ,]*)/m, 1].strip
30
+ task = file[/task :?([^ :,]*)/m, 1]
31
+ "rake #{namespace}:#{task} # #{rake_id}"
32
+ end
33
+ end.compact
34
+
35
+ if !rake_files.empty?
36
+ puts "\n"
37
+ puts "You need to run the following rakes:"
38
+ puts "------------------------------------"
39
+ rake_files.each { |file| puts "\e[31m#{file}\e[0m" }
40
+ puts "\n"
41
+ else
42
+ puts "\e[32mAll rake files are mapped in the DB! No untracked rake tasks are present!\e[0m"
43
+ end
44
+
45
+ end
46
+
47
+ end
metadata ADDED
@@ -0,0 +1,71 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rake_migrations_velocity
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.11
5
+ platform: ruby
6
+ authors:
7
+ - Mani Bhushan
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-05-10 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: '3.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.2'
27
+ description: This gem creates a rake_migrations table and keeps track of rake tasks
28
+ similar to migrations.
29
+ email:
30
+ - manilnct@gmail.com
31
+ executables: []
32
+ extensions: []
33
+ extra_rdoc_files: []
34
+ files:
35
+ - MIT-LICENSE
36
+ - README.md
37
+ - Rakefile
38
+ - lib/rails/generators/rake_migrations/install_generator.rb
39
+ - lib/rails/generators/rake_migrations/templates/devops_rake_utils.rake
40
+ - lib/rails/generators/rake_migrations/templates/migration_rails_after_v4.rb
41
+ - lib/rails/generators/rake_migrations/templates/migration_rails_on_and_before_v4.rb
42
+ - lib/rails/generators/task/USAGE
43
+ - lib/rails/generators/task/task_generator.rb
44
+ - lib/rails/generators/task/templates/task.rb
45
+ - lib/rake_migration.rb
46
+ - lib/rake_migrations.rb
47
+ - lib/rake_migrations/config.rb
48
+ - lib/rake_migrations/version.rb
49
+ homepage: http://eyaleizenberg.blogspot.com/
50
+ licenses: []
51
+ metadata: {}
52
+ post_install_message:
53
+ rdoc_options: []
54
+ require_paths:
55
+ - lib
56
+ required_ruby_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ required_rubygems_version: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ requirements: []
67
+ rubygems_version: 3.4.12
68
+ signing_key:
69
+ specification_version: 4
70
+ summary: A gem to easily keep track of rake tasks
71
+ test_files: []