post_pusher 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +60 -0
  3. data/Rakefile +15 -0
  4. data/db/migrate/20160620190743_create_post_push_status.rb +7 -0
  5. data/exe/post_push +6 -0
  6. data/lib/generators/post_push_invoke/post_push_invoke_generator.rb +35 -0
  7. data/lib/generators/post_push_invoke/templates/post_push_invoke.rake.erb +8 -0
  8. data/lib/generators/post_push_task/post_push_task_generator.rb +17 -0
  9. data/lib/generators/post_push_task/templates/post_push_task.rake.erb +32 -0
  10. data/lib/post_push_cli.rb +98 -0
  11. data/lib/post_pusher.rb +16 -0
  12. data/lib/post_pusher/engine.rb +13 -0
  13. data/lib/post_pusher/rake_task_runner.rb +44 -0
  14. data/lib/post_pusher/version.rb +4 -0
  15. data/test/dummy/README.rdoc +28 -0
  16. data/test/dummy/Rakefile +6 -0
  17. data/test/dummy/app/assets/javascripts/application.js +13 -0
  18. data/test/dummy/app/assets/stylesheets/application.css +15 -0
  19. data/test/dummy/app/controllers/application_controller.rb +5 -0
  20. data/test/dummy/app/helpers/application_helper.rb +2 -0
  21. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  22. data/test/dummy/bin/bundle +3 -0
  23. data/test/dummy/bin/rails +4 -0
  24. data/test/dummy/bin/rake +4 -0
  25. data/test/dummy/bin/setup +29 -0
  26. data/test/dummy/config.ru +4 -0
  27. data/test/dummy/config/application.rb +12 -0
  28. data/test/dummy/config/boot.rb +5 -0
  29. data/test/dummy/config/database.yml +7 -0
  30. data/test/dummy/config/environment.rb +5 -0
  31. data/test/dummy/config/environments/development.rb +41 -0
  32. data/test/dummy/config/environments/production.rb +79 -0
  33. data/test/dummy/config/environments/test.rb +42 -0
  34. data/test/dummy/config/initializers/assets.rb +11 -0
  35. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  36. data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
  37. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  38. data/test/dummy/config/initializers/inflections.rb +16 -0
  39. data/test/dummy/config/initializers/mime_types.rb +4 -0
  40. data/test/dummy/config/initializers/session_store.rb +3 -0
  41. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  42. data/test/dummy/config/locales/en.yml +23 -0
  43. data/test/dummy/config/routes.rb +1 -0
  44. data/test/dummy/config/secrets.yml +22 -0
  45. data/test/dummy/db/migrate/20150618161222_create_user.rb +6 -0
  46. data/test/dummy/db/migrate/20151229195418_create_soft_deletables.rb +8 -0
  47. data/test/dummy/db/schema.rb +34 -0
  48. data/test/dummy/lib/tasks/dummy_tasks.rake +31 -0
  49. data/test/dummy/public/404.html +67 -0
  50. data/test/dummy/public/422.html +67 -0
  51. data/test/dummy/public/500.html +66 -0
  52. data/test/dummy/public/favicon.ico +0 -0
  53. data/test/post_push_exe_test.rb +61 -0
  54. data/test/rake_task_runner_test.rb +32 -0
  55. data/test/test_helper.rb +31 -0
  56. metadata +224 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ab7826c0117965f5dcc7227dee0cb9ce28c658d3
4
+ data.tar.gz: c8c732f07cfd4f4a780a4bc235ae669e647b0aac
5
+ SHA512:
6
+ metadata.gz: 16040dcfbb6e034126c2829ebe694bef31ad5ba511400508892beeb05babc0d96416fb2b049ddda37c84a6e6e975c5d32ea64024caa110123bf87df5a975248e
7
+ data.tar.gz: 7b224d13fb05419433da875a532b9881220549dd0939330c56d8c5851f68be2238796bb30b79487e090d4f574343f35cd66aeac322c68931c33084734856e703
@@ -0,0 +1,60 @@
1
+ ## What Is PostPusher?
2
+
3
+ A sweet gem that makes post pushing way easier.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```
10
+ gem 'post_pusher'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ ```
16
+ $ bundle
17
+ ```
18
+
19
+ Or install it yourself with:
20
+
21
+ ```
22
+ gem install post_pusher
23
+ ```
24
+
25
+
26
+ ## Im a dev, how can I use PostPusher? Is it hard?
27
+
28
+ No way buddy; getting your post push task ready for a release using PostPusher is super easy.
29
+
30
+ Steps:
31
+ -rails g post_push_task task_name
32
+ -add your code into the new task
33
+ -commit
34
+
35
+ Running the tasks:
36
+ -bin/post_push work
37
+
38
+ ## How do I add this to my rails app?
39
+
40
+ -Add PostPusher to your gemfile
41
+ -bundle
42
+ -Run migrations (creates records table)
43
+ -bundle binstub post_pusher (this enables you to be able to run bin/post_push by putting the post_push file in your bin directory)
44
+ -Commit your changes
45
+
46
+ ## Running Tests
47
+
48
+ 1. Change to the gem's directory
49
+ 2. Run `bundle`
50
+ 3. Run `rake`
51
+
52
+ ## Release Process
53
+
54
+ Once pull request is merged to master, on latest master:
55
+
56
+ 1. Update CHANGELOG.md. Version: [ major (breaking change: non-backwards
57
+ compatible release) | minor (new features) | patch (bugfixes) ]
58
+ 2. Update version in lib/post\_pusher/version.rb
59
+ 3. Release by running `bundle exec rake release`
60
+
@@ -0,0 +1,15 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
5
+ load "rails/tasks/engine.rake"
6
+
7
+ import "#{Rails.root}/lib/tasks/dummy_tasks.rake" if Rails.env.test?
8
+
9
+ Rake::TestTask.new(:test) do |t|
10
+ t.libs << "test"
11
+ t.libs << "lib"
12
+ t.test_files = FileList["test/**/*_test.rb"]
13
+ end
14
+
15
+ task default: :test
@@ -0,0 +1,7 @@
1
+ class CreatePostPushStatus < (Rails::VERSION::MAJOR >= 5 ? ActiveRecord::Migration[4.2] : ActiveRecord::Migration)
2
+ def change
3
+ create_table :post_push_statuses do |t|
4
+ t.string :task_name, null: false, index: true
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative "../lib/post_pusher"
4
+ require_relative "../lib/post_push_cli"
5
+
6
+ PostPushCli.start ARGV
@@ -0,0 +1,35 @@
1
+ class PostPushInvokeGenerator < Rails::Generators::Base
2
+ source_root File.expand_path("../templates", __FILE__)
3
+
4
+ desc "Create a post push task that invokes another rake task"
5
+ argument :rake_task_name, type: :string
6
+ def create_post_push_invoke
7
+ check_task!
8
+ template "post_push_invoke.rake.erb", "lib/tasks/post_push/#{timestamp}_#{task_name}.rake"
9
+ end
10
+
11
+ private
12
+
13
+ def check_task!
14
+ Dir[File.join("lib/tasks/**/*.rake")].each do |f|
15
+ begin
16
+ load f
17
+ rescue LoadError, StandardError
18
+ nil
19
+ end
20
+ end
21
+
22
+ return if rake_task_name.start_with?("db:seed") # TODO: figure out where this is defined and load it
23
+ Rake::Task[rake_task_name] # raises an error if it's not present
24
+ end
25
+
26
+ def timestamp
27
+ # print out the dates/timestamps we see in migrations
28
+ # year month day hour minute second
29
+ DateTime.now.strftime("%Y%m%d%H%M%S")
30
+ end
31
+
32
+ def task_name
33
+ rake_task_name.tr ":", "_"
34
+ end
35
+ end
@@ -0,0 +1,8 @@
1
+ namespace :post_push do
2
+ namespace "<%= timestamp %>" do
3
+ desc 'Runs <%= task_name %>'
4
+ task '<%= task_name %>' => :environment do
5
+ Rake::Task['<%= rake_task_name %>'].invoke
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,17 @@
1
+ class PostPushTaskGenerator < Rails::Generators::Base
2
+ source_root File.expand_path("../templates", __FILE__)
3
+
4
+ desc "Create a post push task"
5
+ argument :task_name, type: :string
6
+ def create_post_push_task
7
+ template "post_push_task.rake.erb", "lib/tasks/post_push/#{timestamp}_#{task_name}.rake"
8
+ end
9
+
10
+ private
11
+
12
+ def timestamp
13
+ # print out the dates/timestamps we see in migrations
14
+ # year month day hour minute second
15
+ DateTime.now.strftime("%Y%m%d%H%M%S")
16
+ end
17
+ end
@@ -0,0 +1,32 @@
1
+ require 'progress_bar'
2
+ <%
3
+ full_name = "post_push:#{timestamp}:#{task_name}"
4
+ %>
5
+ # When writing your task, be sure to:
6
+ # * Print out useful information at startup and on completion
7
+ # * Use a progress bar if the task will take a while
8
+ # * Check Rails.env.development? or stage? and skip lengthy operations
9
+
10
+ namespace :post_push do
11
+ namespace "<%=timestamp%>" do
12
+ desc 'Describe the task here'
13
+ task '<%=task_name%>' => :environment do
14
+
15
+ puts "---------------------------------------------------------"
16
+ puts "Starting <%=full_name%> at #{DateTime.now}"
17
+
18
+ total_records = YourModel.count
19
+ next if total_records.zero?
20
+ progress_bar = ProgressBar.new(total_records)
21
+
22
+ YourModel.find_each do |model|
23
+ # YOUR CODE HERE
24
+
25
+ progress_bar.increment!
26
+ end
27
+
28
+ puts "Updated #{total_records} records."
29
+ puts "Completed <%=full_name%> at #{DateTime.now}"
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,98 @@
1
+ require "thor"
2
+ require_relative "../lib/post_pusher/rake_task_runner"
3
+
4
+ class PostPushCli < Thor
5
+ desc "work", "Run remaining post push tasks"
6
+ def work
7
+ load_rails_env!
8
+ succeeded = []
9
+ failed = []
10
+
11
+ runnable_tasks.each do |task|
12
+ puts "Running task #{task}..."
13
+ puts
14
+ job = RakeTaskRunner.exec(task)
15
+
16
+ if job.status
17
+ task_complete!(task)
18
+ succeeded << task
19
+ success_message "Successfully ran #{task}"
20
+ else
21
+ error_message "Error in: #{task}"
22
+ failed << task
23
+ end
24
+
25
+ puts "-" * 56
26
+ puts
27
+ end
28
+
29
+ success_message "#{succeeded.size} tasks succeeded"
30
+ error_message "Errors occured in #{failed.size} tasks:\n#{failed.join("\n")}" if failed.any?
31
+ end
32
+
33
+ desc "status", "List post push tasks and their status"
34
+ option :new, default: false, desc: "Only show unrun tasks", type: :boolean
35
+ option :done, default: false, desc: "Only show finished tasks", type: :boolean
36
+ def status
37
+ load_rails_env!
38
+
39
+ unless options[:new]
40
+ puts "Finished tasks:"
41
+ puts completed_tasks.join "\n"
42
+ end
43
+
44
+ puts unless options[:new] || options[:done]
45
+
46
+ unless options[:done]
47
+ puts "Pending tasks:"
48
+ puts runnable_tasks.join "\n"
49
+ end
50
+
51
+ puts
52
+ end
53
+
54
+ private
55
+
56
+ def runnable_tasks
57
+ post_push_tasks - completed_tasks
58
+ end
59
+
60
+ def connection
61
+ ActiveRecord::Base.connection
62
+ end
63
+
64
+ def completed_tasks
65
+ connection.select_values("SELECT task_name from post_push_statuses")
66
+ end
67
+
68
+ def task_complete!(task_name)
69
+ connection.execute("INSERT INTO post_push_statuses (task_name) VALUES ('#{task_name}')")
70
+ end
71
+
72
+ def post_push_tasks
73
+ rake_task_names.grep(/^post_push:/).sort
74
+ end
75
+
76
+ def rake_task_names
77
+ rake_tasks.map(&:name)
78
+ end
79
+
80
+ def rake_tasks
81
+ @rake_tasks ||= begin
82
+ Rails.application.load_tasks
83
+ Rake.application.tasks
84
+ end
85
+ end
86
+
87
+ def load_rails_env!
88
+ require(File.expand_path("config/environment", Dir.getwd)) unless Rails.application
89
+ end
90
+
91
+ def success_message(msg)
92
+ puts "\e[32m#{msg}\e[0m" # green
93
+ end
94
+
95
+ def error_message(msg)
96
+ puts "\e[31m#{msg}\e[0m" # red
97
+ end
98
+ end
@@ -0,0 +1,16 @@
1
+ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2
+ # STEP 1
3
+ # Load all dependent gems.
4
+
5
+ # require 'a_dependent_gem'
6
+ # require 'another_dependent_gem'
7
+ # require 'a_dependent_local_gem'
8
+ # ...
9
+
10
+ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
11
+ # STEP 2
12
+ # Load this gem's code.
13
+ require "rails"
14
+ require "rails/engine"
15
+
16
+ require "post_pusher/engine"
@@ -0,0 +1,13 @@
1
+ module PostPusher
2
+ class Engine < ::Rails::Engine
3
+ engine_name "post_pusher"
4
+
5
+ initializer :append_migrations do |app|
6
+ unless app.root.to_s.match root.to_s
7
+ config.paths["db/migrate"].expanded.each do |expanded_path|
8
+ app.config.paths["db/migrate"] << expanded_path
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,44 @@
1
+ require "pty"
2
+
3
+ class RakeTaskRunner
4
+ BUFSIZE = 160
5
+
6
+ def self.exec(task)
7
+ RakeTaskRunner.new(task).tap(&:work)
8
+ end
9
+
10
+ attr_reader :task_name, :status
11
+
12
+ def initialize(task_name)
13
+ @task_name = task_name
14
+ end
15
+
16
+ def work
17
+ @status = system(logging_rake_command)
18
+ end
19
+
20
+ private
21
+
22
+ def rake_command
23
+ "bundle exec rake #{task_name} RAILS_ENV=#{Rails.env}"
24
+ end
25
+
26
+ def logging_rake_command
27
+ # PIPESTATUS is a bash and zsh construct. It stashes the exit statuses
28
+ # of commands in a long pipe line like this one. $PIPESTATUS[0] is the
29
+ # first exit status. $PIPESTATUS[1] would give us the exit status from
30
+ # tee. So we're running rake, piping it into tee, and then making sure
31
+ # to exit with the exit status we care about.
32
+ "#{rake_command} 2>&1 | tee #{log_file_path} ; (exit ${PIPESTATUS[0]})"
33
+ end
34
+
35
+ def log_file_path
36
+ logs = File.join(Rails.root, "log", "post_push")
37
+ Dir.mkdir(logs) unless Dir.exist?(logs)
38
+ File.join(logs, "#{log_file_name}.log")
39
+ end
40
+
41
+ def log_file_name
42
+ task_name.split(":").drop(1).join("_")
43
+ end
44
+ end
@@ -0,0 +1,4 @@
1
+ module PostPusher
2
+ VERSION = "1.0.0".freeze
3
+ end
4
+
@@ -0,0 +1,28 @@
1
+ == README
2
+
3
+ This README would normally document whatever steps are necessary to get the
4
+ application up and running.
5
+
6
+ Things you may want to cover:
7
+
8
+ * Ruby version
9
+
10
+ * System dependencies
11
+
12
+ * Configuration
13
+
14
+ * Database creation
15
+
16
+ * Database initialization
17
+
18
+ * How to run the test suite
19
+
20
+ * Services (job queues, cache servers, search engines, etc.)
21
+
22
+ * Deployment instructions
23
+
24
+ * ...
25
+
26
+
27
+ Please feel free to use a different markup language if you do not plan to run
28
+ <tt>rake doc:app</tt>.
@@ -0,0 +1,6 @@
1
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
2
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
+
4
+ require File.expand_path("../config/application", __FILE__)
5
+
6
+ Rails.application.load_tasks
@@ -0,0 +1,13 @@
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.
9
+ //
10
+ // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
11
+ // about supported directives.
12
+ //
13
+ //= 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 styles
10
+ * defined in the other CSS/SCSS files in this directory. It is generally better to create a new
11
+ * file per style scope.
12
+ *
13
+ *= require_tree .
14
+ *= require_self
15
+ */