template.rb 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. require "fileutils"
  2. require "shellwords"
  3. # Copied from: https://github.com/mattbrictson/rails-template
  4. # Add this template directory to source_paths so that Thor actions like
  5. # copy_file and template resolve against our source files. If this file was
  6. # invoked remotely via HTTP, that means the files are not present locally.
  7. # In that case, use `git clone` to download them to a local temporary dir.
  8. def add_template_repository_to_source_path
  9. if __FILE__ =~ %r{\Ahttps?://}
  10. require "tmpdir"
  11. source_paths.unshift(tempdir = Dir.mktmpdir("jumpstart-"))
  12. at_exit { FileUtils.remove_entry(tempdir) }
  13. git clone: [
  14. "--quiet",
  15. "https://github.com/excid3/jumpstart.git",
  16. tempdir
  17. ].map(&:shellescape).join(" ")
  18. if (branch = __FILE__[%r{jumpstart/(.+)/template.rb}, 1])
  19. Dir.chdir(tempdir) { git checkout: branch }
  20. end
  21. else
  22. source_paths.unshift(File.dirname(__FILE__))
  23. end
  24. end
  25. def add_gems
  26. gem 'administrate', '~> 0.10.0'
  27. gem 'bootstrap', '~> 4.1', '>= 4.1.1'
  28. gem 'data-confirm-modal', '~> 1.6', '>= 1.6.2'
  29. gem 'devise', '~> 4.4', '>= 4.4.3'
  30. gem 'devise-bootstrapped', github: 'excid3/devise-bootstrapped', branch: 'bootstrap4'
  31. gem 'devise_masquerade', '~> 0.6.2'
  32. gem 'font-awesome-sass', '~> 5.0', '>= 5.0.13'
  33. gem 'foreman', '~> 0.84.0'
  34. gem 'friendly_id', '~> 5.2', '>= 5.2.4'
  35. gem 'gravatar_image_tag', github: 'mdeering/gravatar_image_tag'
  36. gem 'jquery-rails', '~> 4.3.1'
  37. gem 'local_time', '~> 2.0', '>= 2.0.1'
  38. gem 'mini_magick', '~> 4.8'
  39. gem 'name_of_person', '~> 1.0'
  40. gem 'omniauth-facebook', '~> 5.0'
  41. gem 'omniauth-github', '~> 1.3'
  42. gem 'omniauth-twitter', '~> 1.4'
  43. gem 'sidekiq', '~> 5.1', '>= 5.1.3'
  44. gem 'sitemap_generator', '~> 6.0', '>= 6.0.1'
  45. gem 'webpacker', '~> 3.5', '>= 3.5.3'
  46. gem 'whenever', require: false
  47. end
  48. def set_application_name
  49. # Add Application Name to Config
  50. environment "config.application_name = Rails.application.class.parent_name"
  51. # Announce the user where he can change the application name in the future.
  52. puts "You can change application name inside: ./config/application.rb"
  53. end
  54. def add_users
  55. # Install Devise
  56. generate "devise:install"
  57. # Configure Devise
  58. environment "config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }",
  59. env: 'development'
  60. route "root to: 'home#index'"
  61. # Devise notices are installed via Bootstrap
  62. generate "devise:views:bootstrapped"
  63. # Create Devise User
  64. generate :devise, "User",
  65. "first_name",
  66. "last_name",
  67. "announcements_last_read_at:datetime",
  68. "admin:boolean"
  69. # Set admin default to false
  70. in_root do
  71. migration = Dir.glob("db/migrate/*").max_by{ |f| File.mtime(f) }
  72. gsub_file migration, /:admin/, ":admin, default: false"
  73. end
  74. requirement = Gem::Requirement.new("> 5.2")
  75. rails_version = Gem::Version.new(Rails::VERSION::STRING)
  76. if requirement.satisfied_by? rails_version
  77. gsub_file "config/initializers/devise.rb",
  78. / # config.secret_key = .+/,
  79. " config.secret_key = Rails.application.credentials.secret_key_base"
  80. end
  81. # Add Devise masqueradable to users
  82. inject_into_file("app/models/user.rb", "omniauthable, :masqueradable, :", after: "devise :")
  83. end
  84. def add_bootstrap
  85. # Remove Application CSS
  86. run "rm app/assets/stylesheets/application.css"
  87. # Add Bootstrap JS
  88. insert_into_file(
  89. "app/assets/javascripts/application.js",
  90. "\n//= require jquery\n//= require popper\n//= require bootstrap\n//= require data-confirm-modal\n//= require local-time",
  91. after: "//= require rails-ujs"
  92. )
  93. end
  94. def copy_templates
  95. directory "app", force: true
  96. directory "config", force: true
  97. directory "lib", force: true
  98. route "get '/terms', to: 'home#terms'"
  99. route "get '/privacy', to: 'home#privacy'"
  100. end
  101. def add_webpack
  102. rails_command 'webpacker:install'
  103. end
  104. def add_sidekiq
  105. environment "config.active_job.queue_adapter = :sidekiq"
  106. insert_into_file "config/routes.rb",
  107. "require 'sidekiq/web'\n\n",
  108. before: "Rails.application.routes.draw do"
  109. insert_into_file "config/routes.rb",
  110. " authenticate :user, lambda { |u| u.admin? } do\n mount Sidekiq::Web => '/sidekiq'\n end\n\n",
  111. after: "Rails.application.routes.draw do\n"
  112. end
  113. def add_foreman
  114. copy_file "Procfile"
  115. end
  116. def add_announcements
  117. generate "model Announcement published_at:datetime announcement_type name description:text"
  118. route "resources :announcements, only: [:index]"
  119. end
  120. def add_notifications
  121. generate "model Notification recipient_id:integer actor_id:integer read_at:datetime action:string notifiable_id:integer notifiable_type:string"
  122. route "resources :notifications, only: [:index]"
  123. end
  124. def add_administrate
  125. generate "administrate:install"
  126. gsub_file "app/dashboards/announcement_dashboard.rb",
  127. /announcement_type: Field::String/,
  128. "announcement_type: Field::Select.with_options(collection: Announcement::TYPES)"
  129. gsub_file "app/dashboards/user_dashboard.rb",
  130. /email: Field::String/,
  131. "email: Field::String,\n password: Field::String.with_options(searchable: false)"
  132. gsub_file "app/dashboards/user_dashboard.rb",
  133. /FORM_ATTRIBUTES = \[/,
  134. "FORM_ATTRIBUTES = [\n :password,"
  135. gsub_file "app/controllers/admin/application_controller.rb",
  136. /# TODO Add authentication logic here\./,
  137. "redirect_to '/', alert: 'Not authorized.' unless user_signed_in? && current_user.admin?"
  138. end
  139. def add_app_helpers_to_administrate
  140. environment do <<-RUBY
  141. # Expose our application's helpers to Administrate
  142. config.to_prepare do
  143. Administrate::ApplicationController.helper #{@app_name.camelize}::Application.helpers
  144. end
  145. RUBY
  146. end
  147. end
  148. def add_multiple_authentication
  149. insert_into_file "config/routes.rb",
  150. ', controllers: { omniauth_callbacks: "users/omniauth_callbacks" }',
  151. after: " devise_for :users"
  152. generate "model Service user:references provider uid access_token access_token_secret refresh_token expires_at:datetime auth:text"
  153. template = """
  154. if Rails.application.secrets.facebook_app_id.present? && Rails.application.secrets.facebook_app_secret.present?
  155. config.omniauth :facebook, Rails.application.secrets.facebook_app_id, Rails.application.secrets.facebook_app_secret, scope: 'email,user_posts'
  156. end
  157. if Rails.application.secrets.twitter_app_id.present? && Rails.application.secrets.twitter_app_secret.present?
  158. config.omniauth :twitter, Rails.application.secrets.twitter_app_id, Rails.application.secrets.twitter_app_secret
  159. end
  160. if Rails.application.secrets.github_app_id.present? && Rails.application.secrets.github_app_secret.present?
  161. config.omniauth :github, Rails.application.secrets.github_app_id, Rails.application.secrets.github_app_secret
  162. end
  163. """.strip
  164. insert_into_file "config/initializers/devise.rb", " " + template + "\n\n",
  165. before: " # ==> Warden configuration"
  166. end
  167. def add_whenever
  168. run "wheneverize ."
  169. end
  170. def add_friendly_id
  171. generate "friendly_id"
  172. insert_into_file(
  173. Dir["db/migrate/**/*friendly_id_slugs.rb"].first,
  174. "[5.2]",
  175. after: "ActiveRecord::Migration"
  176. )
  177. end
  178. def stop_spring
  179. run "spring stop"
  180. end
  181. def add_sitemap
  182. rails_command "sitemap:install"
  183. end
  184. # Main setup
  185. add_template_repository_to_source_path
  186. add_gems
  187. after_bundle do
  188. set_application_name
  189. stop_spring
  190. add_users
  191. add_bootstrap
  192. add_sidekiq
  193. add_foreman
  194. add_webpack
  195. add_announcements
  196. add_notifications
  197. add_multiple_authentication
  198. add_friendly_id
  199. copy_templates
  200. # Migrate
  201. rails_command "db:create"
  202. rails_command "db:migrate"
  203. # Migrations must be done before this
  204. add_administrate
  205. add_app_helpers_to_administrate
  206. add_whenever
  207. add_sitemap
  208. git :init
  209. git add: "."
  210. git commit: %Q{ -m 'Initial commit' }
  211. end