Skip to content

Commit

Permalink
Merge pull request #95 from TruemarkDev/generator-for-pronto-with-git…
Browse files Browse the repository at this point in the history
…lab-ci

Generator for Pronto with Gitlab CI
  • Loading branch information
abhaynikam authored May 18, 2024
2 parents 30ab42c + a7b4fdf commit 53bf096
Show file tree
Hide file tree
Showing 9 changed files with 423 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Changelog

## master (unreleased)
* Adds Pronto Generator with Gitlab CI ([@coolprobn][])
* Adds Rack Mini Profiler generator. ([@mausamp][])

## 0.13.0 (March 26th, 2024)
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ The boring generator introduces following generators:
- Install Whenever: `rails generate boring:whenever:install`
- 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 Pronto with Gitlab CI: `rails generate boring:pronto:gitlab_ci:install`
- Install Rack Mini Profiler: `rails generate boring:rack_mini_profiler:install`

## Screencasts
Expand Down
26 changes: 26 additions & 0 deletions lib/boring_generators/generator_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
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 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
68 changes: 68 additions & 0 deletions lib/generators/boring/pronto/base_generator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# 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 :extensions_to_skip,
type: :array,
aliases: "-se",
desc: "Skip one or list of extensions. Example usage `--extensions_to_skip=rubocop flay`",
enum: %w[brakeman flay reek rubocop],
default: []

include BoringGenerators::GeneratorHelper

def add_pronto_gem
say "Adding pronto gem", :green

Bundler.with_unbundled_env do
check_and_install_gem "pronto"
end
end

def add_brakeman_extension
return if options[:extensions_to_skip].include?('brakeman')

say "Adding extension for brakeman", :green

Bundler.with_unbundled_env do
check_and_install_gem "pronto-brakeman", require: false
end
end

def add_flay_extension
return if options[:extensions_to_skip].include?('flay')

say "Adding extension for flay", :green

Bundler.with_unbundled_env do
check_and_install_gem "pronto-flay", require: false
end
end

def add_reek_extension
return if options[:extensions_to_skip].include?('reek')

say "Adding extension for reek", :green

Bundler.with_unbundled_env do
check_and_install_gem "pronto-reek", require: false
end
end

def add_rubocop_extension
return if options[:extensions_to_skip].include?('rubocop')

say "Adding extension for rubocop", :green

Bundler.with_unbundled_env do
check_and_install_gem "pronto-rubocop", require: false
end
end
end
end
end
109 changes: 109 additions & 0 deletions lib/generators/boring/pronto/gitlab_ci/install/install_generator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# frozen_string_literal: true

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

module Boring
module Pronto
module GitlabCi
class InstallGenerator < Boring::Pronto::BaseGenerator
desc "Adds Pronto gem with various extensions and configures it for Gitlab CI"
source_root File.expand_path("templates", __dir__)

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

include BoringGenerators::GeneratorHelper

def add_configuration
@ruby_version = options.ruby_version || app_ruby_version

if File.exists?(".gitlab-ci.yml")
add_configuration_to_existing_file
add_lint_stage_to_existing_file
show_readme
else
say "Creating .gitlab-ci.yml with Pronto configurations",
:yellow

template ".gitlab-ci.yml", ".gitlab-ci.yml"
end
end

private

def add_configuration_to_existing_file
if gitlab_ci_file_content["pronto"]
say "Skipping Pronto configurations",
:yellow

return
end

say "Adding Pronto configurations to .gitlab-ci.yml", :green

ci_file_content = <<~RUBY
pronto:
image: ruby:#{@ruby_version}
stage: lint
only:
# run pronto on merge requests and when new changes are pushed to it
- merge_requests
variables:
PRONTO_GITLAB_API_PRIVATE_TOKEN: $PRONTO_ACCESS_TOKEN
before_script:
# Install cmake required for rugged gem (Pronto depends on it)
- apt-get update && apt-get install -y cmake
# use bundler version same as the one that bundled the Gemfile
- gem install bundler -v "$(grep -A 1 "BUNDLED WITH" Gemfile.lock | tail -n 1)" --no-document
- bundle install --jobs $(nproc)
script:
# Pronto fails with the error "revspec 'origin/{target_branch}' because Gitlab fetches changes with git depth set to 20 by default. You can remove this line if you update Gitlab CI setting to clone the full project.
- git fetch origin $CI_MERGE_REQUEST_TARGET_BRANCH_NAME
# Run pronto on branch of current merge request
- bundle exec pronto run -f gitlab_mr -c origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME
RUBY

inject_into_file ".gitlab-ci.yml",
"\n#{ci_file_content}\n",
before: /\Z/
end

def add_lint_stage_to_existing_file
ci_file_content =
YAML.safe_load(File.open(".gitlab-ci.yml"), aliases: true) || {}

if gitlab_ci_file_content["stages"] &&
gitlab_ci_file_content["stages"].include?("lint")
return
end

if ci_file_content["stages"]
inject_into_file ".gitlab-ci.yml",
optimize_indentation("\n- lint", 2).chomp,
after: /stages:/
else
stages_configuration = <<~RUBY
stages:
- lint
RUBY

inject_into_file ".gitlab-ci.yml",
"#{stages_configuration}\n",
before: /pronto:/
end
end

def show_readme
readme "README"
end

def gitlab_ci_file_content
return @gitlab_ci_file_content if defined?(@gitlab_ci_file_content)

@gitlab_ci_file_content =
YAML.safe_load(File.open(".gitlab-ci.yml"), aliases: true) || {}
end
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
stages:
- lint

pronto:
image: ruby:<%= @ruby_version %>
stage: lint
only:
# run pronto on merge requests and when new changes are pushed to it
- merge_requests
variables:
PRONTO_GITLAB_API_PRIVATE_TOKEN: $PRONTO_ACCESS_TOKEN
before_script:
# Install cmake required for rugged gem (Pronto depends on it)
- apt-get update && apt-get install -y cmake
# use bundler version same as the one that bundled the Gemfile
- gem install bundler -v "$(grep -A 1 "BUNDLED WITH" Gemfile.lock | tail -n 1)" --no-document
- bundle install --jobs $(nproc)
script:
# Pronto fails with the error "revspec 'origin/{target_branch}' because Gitlab fetches changes with git depth set to 20 by default. You can remove this line if you update Gitlab CI setting to clone the full project.
- git fetch origin $CI_MERGE_REQUEST_TARGET_BRANCH_NAME
# Run pronto on branch of current merge request
- bundle exec pronto run -f gitlab_mr -c origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

===============================================================================

❗️❗️
Pronto needs your Private Gitlab API token for posting comments in the merge request. It is configured as "PRONTO_ACCESS_TOKEN" inside .gitlab-ci.yml, don't forget to configure this variable in your Gitlab Project settings before pushing your new changes to git.

===============================================================================
92 changes: 92 additions & 0 deletions test/generators/pronto/base_generator_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# frozen_string_literal: true

require "test_helper"
require "generators/boring/pronto/base_generator"

class ProntoBaseGeneratorTest < Rails::Generators::TestCase
tests Boring::Pronto::BaseGenerator
setup :build_app
teardown :teardown_app

include GeneratorHelper
include ActiveSupport::Testing::Isolation

def destination_root
app_path
end

def test_should_install_pronto_with_all_extension_gems
Dir.chdir(app_path) do
quietly { run_generator }

assert_file "Gemfile" do |content|
assert_match("pronto", content)
assert_match("pronto-brakeman", content)
assert_match("pronto-flay", content)
assert_match("pronto-reek", content)
assert_match("pronto-rubocop", content)
end
end
end

def test_should_skip_brakeman_extension
Dir.chdir(app_path) do
quietly do
generator({}, ['--extensions_to_skip=brakeman']).add_brakeman_extension
end

assert_file "Gemfile" do |content|
refute_match("pronto-brakeman", content)
end
end
end

def test_should_skip_flay_extension
Dir.chdir(app_path) do
quietly do
generator({}, ['--extensions_to_skip=flay']).add_flay_extension
end

assert_file "Gemfile" do |content|
refute_match("pronto-flay", content)
end
end
end

def test_should_skip_reek_extension
Dir.chdir(app_path) do
quietly do
generator({}, ['--extensions_to_skip=reek']).add_reek_extension
end

assert_file "Gemfile" do |content|
refute_match("pronto-reek", content)
end
end
end

def test_should_skip_rubocop_extension
Dir.chdir(app_path) do
quietly do
generator({}, ['--extensions_to_skip=rubocop']).add_rubocop_extension
end

assert_file "Gemfile" do |content|
refute_match("pronto-rubocop", content)
end
end
end

def test_should_skip_multiple_extensions
Dir.chdir(app_path) do
quietly do
generator({}, ['--extensions_to_skip=reek', 'rubocop']).add_rubocop_extension
end

assert_file "Gemfile" do |content|
refute_match("pronto-reek", content)
refute_match("pronto-rubocop", content)
end
end
end
end
Loading

0 comments on commit 53bf096

Please sign in to comment.