Skip to content

Commit

Permalink
Resolve conflicts with main
Browse files Browse the repository at this point in the history
  • Loading branch information
coolprobn committed May 30, 2024
2 parents 95c7ecf + c806c84 commit 6bbf5cb
Show file tree
Hide file tree
Showing 26 changed files with 1,179 additions and 9 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

## master (unreleased)
* Adds Sentry generator. ([@mausamp][])
* Adds Pronto Generator with Gitlab CI ([@coolprobn][])
* Adds Rack Mini Profiler generator. ([@mausamp][])
* Adds VCR generator. ([@TheZero0-ctrl][])
* Adds Pronto Generator with Gihub Action. ([@TheZero0-ctrl][])
* Adds Doorkeeper Generator with Devise. ([@TheZero0-ctrl][])

## 0.13.0 (March 26th, 2024)
* Adds Letter Opener generator. ([@coolprobn][])
Expand Down Expand Up @@ -86,3 +91,4 @@
[@coolprobn]: https://github.com/coolprobn
[@aadil]: https://github.com/AdilRT
[@mausamp]: https://github.com/mausamp
[@TheZero0-ctrl]: https://github.com/TheZero0-ctrl
4 changes: 2 additions & 2 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
boring_generators (0.12.0)
boring_generators (0.13.0)
railties

GEM
Expand Down Expand Up @@ -143,4 +143,4 @@ DEPENDENCIES
sqlite3 (~> 1.4)

BUNDLED WITH
2.1.4
2.2.33
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,11 @@ The boring generator introduces following generators:
- Install Rswag: `rails generate boring:rswag:install --rails_port=<rails_app_port> --authentication_type=<api_authentication_type> --skip_api_authentication=<skip_api_authentication> --api_authentication_options=<api_authentication_options> --enable_swagger_ui_authentication=<enable_swagger_ui_authentication>`
- Install Webmock: `rails generate boring:webmock:install --app_test_framework=<test_framework>`
- Install Sentry: `rails generate boring:sentry:install --use_env_variable --breadcrumbs_logger=<breadcrumbs_logger_options>`
- Install Pronto with Gitlab CI: `rails generate boring:pronto:gitlab_ci:install`
- Install Rack Mini Profiler: `rails generate boring:rack_mini_profiler:install`
- Install VCR: `rails generate boring:vcr:install --testing_framework=<testing_framework> --stubbing_libraries=<stubbing_libraries>`
- Install Pronto with Github Action: `rails generate boring:pronto:github_action:install`
- Install Doorkeeper with devise: `rails generate boring:devise:doorkeeper:install`

## Screencasts

Expand Down
38 changes: 38 additions & 0 deletions lib/boring_generators/generator_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
module BoringGenerators
module GeneratorHelper
include Rails::Generators::Actions

def app_ruby_version
with_ruby_string = `grep "^ruby.*$" Gemfile` || `cat .ruby-version`

# only keep 3.3.0
with_ruby_string.gsub(/[^\d\.]/, '').squish
end

def gem_installed?(gem_name)
gem_regex = /gem.*\b#{gem_name}\b.*/
File.read("Gemfile").match?(gem_regex)
end

def bundle_install
Bundler.with_unbundled_env do
run "bundle install"
end
end

def check_and_install_gem(*args)
gem_name, = args

gem_file_content_array = File.readlines("Gemfile")


gem_exists = gem_file_content_array.any? { |line| line.include?(gem_name) }

if gem_exists
say "#{gem_name} is already in the Gemfile, skipping it ...", :yellow
else
gem *args
end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module Boring
module ActiveStorage
module Azure
class InstallGenerator < Rails::Generators::Base
desc "Adds ActiveStorage Mircosoft Azure the application"
desc "Adds ActiveStorage Microsoft Azure the application"

class_option :skip_active_storage, type: :boolean, aliases: "-s",
desc: "Skips running ActiveStorage installer"
Expand Down
2 changes: 1 addition & 1 deletion lib/generators/boring/audit/install/install_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def add_bullet_gem
\n
\t# Patch-level verification for Bundler. https://github.com/rubysec/bundler-audit
\tgem "bundler-audit", require: false
\t# vulnerabity checker for Ruby itself. https://github.com/civisanalytics/ruby_audit
\t# vulnerability checker for Ruby itself. https://github.com/civisanalytics/ruby_audit
\tgem "ruby_audit", require: false
RUBY
insert_into_file "Gemfile", audit_gems_content, after: /group :development do/
Expand Down
190 changes: 190 additions & 0 deletions lib/generators/boring/devise/doorkeeper/install/install_generator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
# frozen_string_literal: true

require 'boring_generators/generator_helper'

module Boring
module Devise
module Doorkeeper
class InstallGenerator < Rails::Generators::Base
include BoringGenerators::GeneratorHelper

desc "Adds doorkeeper with devise to the application"

class_option :model_name, type: :string, aliases: "-m", default: "User",
desc: "Tell us the user model name which will be used for authentication. Defaults to User"
class_option :grant_flows, type: :array, aliases: "-gf", default: %w[authorization_code client_credentials],
enum: %w[authorization_code client_credentials password],
desc: "Tell us the grant flows you want to use separated by space. Defaults to authorization_code and client_credentials"
class_option :api_only, type: :boolean, aliases: "-a", default: false,
desc: "Tell us if you want to setup doorkeeper for API only application. Defaults to false"
class_option :skip_applications_routes, type: :boolean, aliases: "-sr", default: false,
desc: "Tell us if you want to skip adding doorkeeper routes to manage applications. Defaults to false"
class_option :use_refresh_token, type: :boolean, aliases: "-rt", default: false,
desc: "Keep user logged in with refresh tokens. Defaults to false"

def verify_presence_of_devise_gem
return if gem_installed?("devise")

say "We couldn't find devise gem. Please configure devise gem and rerun the generator. Consider running `rails generate boring:devise:install` to set up Devise.",
:red

abort
end

def verify_presence_of_devise_model
return if File.exist?("app/models/#{options[:model_name].underscore}.rb")

say "We couldn't find the #{options[:model_name]} model. Maybe there is a typo? Please provide the correct model name and run the generator again.",
:red

abort
end

def add_doorkeeper_gem
say "Adding doorkeeper gem", :green
check_and_install_gem("doorkeeper")
bundle_install
end

def run_doorkeeper_generators
say "Running doorkeeper generators", :green

Bundler.with_unbundled_env do
run "bundle exec rails generate doorkeeper:install"
run "bundle exec rails generate doorkeeper:migration"
end
end

def add_doorkeeper_related_association_to_model
model_name = options[:model_name].underscore
say "Adding doorkeeper related associations to the model file app/models/#{model_name}.rb",
:green
model_content = <<~RUBY
has_many :access_grants,
class_name: 'Doorkeeper::AccessGrant',
foreign_key: :resource_owner_id,
dependent: :delete_all # or :destroy if you need callbacks
has_many :access_tokens,
class_name: 'Doorkeeper::AccessToken',
foreign_key: :resource_owner_id,
dependent: :delete_all # or :destroy if you need callbacks
RUBY

inject_into_file "app/models/#{model_name}.rb",
optimize_indentation(model_content, 2),
after: "ApplicationRecord\n"
end

def update_doorkeeper_initializer
say "Updating doorkeeper initializer", :green

configure_resource_owner_authenticator if options[:grant_flows].include?("authorization_code")
configure_admin_authenticator unless options[:api_only] || options[:skip_applications_routes]
configure_resource_owner_from_credentials if options[:grant_flows].include?("password")

gsub_file "config/initializers/doorkeeper.rb",
/# grant_flows %w\[authorization_code client_credentials\]/,
"grant_flows %w[#{options[:grant_flows].uniq.join(' ')}]"

if options[:api_only]
gsub_file "config/initializers/doorkeeper.rb",
/# api_only/,
"api_only"
end

if options[:skip_applications_routes]
doorkeeper_routes_content = <<~RUBY
use_doorkeeper do
skip_controllers :applications, :authorized_applications
end
RUBY

gsub_file "config/routes.rb",
/.*use_doorkeeper/,
optimize_indentation(doorkeeper_routes_content, 2)
end

if options[:use_refresh_token]
uncomment_lines "config/initializers/doorkeeper.rb",
/use_refresh_token/
end
end

def update_doorkeeper_migration
say "Updating doorkeeper migration", :green
model_name = options[:model_name].underscore

uncomment_lines Dir["db/migrate/*_create_doorkeeper_tables.rb"].first,
/add_foreign_key :oauth/

gsub_file Dir["db/migrate/*_create_doorkeeper_tables.rb"].first,
/<model>/,
":#{model_name.pluralize}"

return unless (%w[password client_credentials] & options[:grant_flows]).any?

gsub_file Dir["db/migrate/*_create_doorkeeper_tables.rb"].first,
/t.text :redirect_uri, null: false/,
"t.text :redirect_uri"
end

def show_message
return if options[:api_only] || options[:skip_applications_routes]

model_name = options[:model_name].underscore
admin_authenticator_content = "current_#{model_name} || warden.authenticate!(scope: :#{model_name})"

say "\nWe've implemented `#{admin_authenticator_content}` in the admin_authenticator block of config/initializers/doorkeeper.rb to manage access to application routes. Please adjust it as necessary to suit your requirements.",
:yellow
end

private

def configure_resource_owner_authenticator
model_name = options[:model_name].underscore
resource_owner_authenticator_content = <<~RUBY
resource_owner_authenticator do
current_#{model_name} || warden.authenticate!(scope: :#{model_name})
end
RUBY

gsub_file "config/initializers/doorkeeper.rb",
/.*resource_owner_authenticator do\n(?:\s|.)*?end/,
optimize_indentation(resource_owner_authenticator_content, 2)
end

def configure_admin_authenticator
model_name = options[:model_name].underscore
gsub_file "config/initializers/doorkeeper.rb",
/(?:# admin_authenticator do\n*)((?:\s|.)*?)(?:# end)/,
"admin_authenticator do\n" + "\\1" + "end"

admin_authenticator_content = "current_#{model_name} || warden.authenticate!(scope: :#{model_name})"
inject_into_file "config/initializers/doorkeeper.rb",
optimize_indentation(admin_authenticator_content, 4),
after: /admin_authenticator do\n/,
force: true

end

def configure_resource_owner_from_credentials
model_name = options[:model_name].underscore
resource_owner_for_credentials_content = <<~RUBY
resource_owner_from_credentials do |routes|
#{model_name} = #{options[:model_name]}.find_for_database_authentication(email: params[:email])
if #{model_name}&.valid_for_authentication? { #{model_name}.valid_password?(params[:password]) } && #{model_name}&.active_for_authentication?
request.env['warden'].set_user(#{model_name}, scope: :#{model_name}, store: false)
#{model_name}
end
end
RUBY

inject_into_file "config/initializers/doorkeeper.rb",
optimize_indentation(resource_owner_for_credentials_content, 2),
after: /resource_owner_authenticator do\n(?:\s|.)*?end\n/
end
end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class InstallGenerator < Rails::Generators::Base
def add_factory_bot_gem
log :adding, "FactoryBot"
Bundler.with_unbundled_env do
run "bundle add factory_bot_rails --group='developement,test'"
run "bundle add factory_bot_rails --group='development,test'"
end
end

Expand Down
2 changes: 1 addition & 1 deletion lib/generators/boring/faker/install/install_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class InstallGenerator < Rails::Generators::Base
def add_faker_gem
log :adding, "faker"
Bundler.with_unbundled_env do
run "bundle add faker --group='developement,test'"
run "bundle add faker --group='development,test'"
end
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ class MissingDeviseConfigurationError < StandardError; end
desc "Adds Google OmniAuth to the application"
source_root File.expand_path("templates", __dir__)

def add_github_omniauth_gem
say "Adding GitHub OmniAuth gem", :green
def add_google_omniauth_gem
say "Adding Google OmniAuth gem", :green
Bundler.with_unbundled_env do
run "bundle add omniauth-google-oauth2"
end
Expand Down
47 changes: 47 additions & 0 deletions lib/generators/boring/pronto/base_generator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# frozen_string_literal: true

require 'boring_generators/generator_helper'

module Boring
module Pronto
class BaseGenerator < Rails::Generators::Base
desc "Adds Pronto gem with various extensions"

class_option :skip_extensions, type: :array, aliases: "-se",
desc: "List of extensions to skip. Available options: brakeman, flay, reek, rubocop",
enum: %w[brakeman flay reek rubocop],
default: []

include BoringGenerators::GeneratorHelper

def add_pronto_gems
say "Adding pronto gems", :green
pronto_gem_content = <<~RUBY
\n
\t# Pronto is a code linter runner that can be used with git and GitHub pull requests
\tgem "pronto"
#{pronto_brakemen_gem_content}
#{pronto_flay_gem_content}
RUBY
insert_into_file "Gemfile", pronto_gem_content
Bundler.with_unbundled_env do
run "bundle install"
end
end

def pronto_brakemen_gem_content
return unless options[:skip_extensions].exclude?('brakeman')
return if gem_installed?('pronto-brakeman')

"\tgem \"pronto-brakeman\", require: false"
end

def pronto_flay_gem_content
return unless options[:skip_extensions].exclude?('flay')
return if gem_installed?('pronto-flay')

"\tgem \"pronto-flay\", require: false"
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# frozen_string_literal: true

require "generators/boring/pronto/base_generator"
require "boring_generators/generator_helper"

module Boring
module Pronto
module GithubAction
class InstallGenerator < Boring::Pronto::BaseGenerator
desc "Adds Pronto configurations to Github Action"
source_root File.expand_path("templates", __dir__)

class_option :ruby_version, type: :string, aliases: "-rv"

include BoringGenerators::GeneratorHelper

def add_pronto_configuration_for_github_action
say "Adding Pronto configurations to .github/workflows/pronto.yml", :green

@ruby_version = options.ruby_version || app_ruby_version

template("pronto.yml", ".github/workflows/pronto.yml")
end
end
end
end
end
Loading

0 comments on commit 6bbf5cb

Please sign in to comment.