From 17e578cc68d5f13dc38bb406a5ee2f2e761d96fe Mon Sep 17 00:00:00 2001 From: Abhay Nikam Date: Sun, 19 May 2024 01:20:05 +0530 Subject: [PATCH] Refactor pronto gem installer --- lib/boring_generators/generator_helper.rb | 17 ++- .../boring/pronto/base_generator.rb | 69 ++++----- .../gitlab_ci/install/install_generator.rb | 132 +++++++++--------- 3 files changed, 102 insertions(+), 116 deletions(-) diff --git a/lib/boring_generators/generator_helper.rb b/lib/boring_generators/generator_helper.rb index 1a69497c..0d7cdb41 100644 --- a/lib/boring_generators/generator_helper.rb +++ b/lib/boring_generators/generator_helper.rb @@ -4,16 +4,27 @@ module GeneratorHelper 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 diff --git a/lib/generators/boring/pronto/base_generator.rb b/lib/generators/boring/pronto/base_generator.rb index 8ec5e556..d70569a1 100644 --- a/lib/generators/boring/pronto/base_generator.rb +++ b/lib/generators/boring/pronto/base_generator.rb @@ -7,62 +7,41 @@ 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: [] + 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_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 - + 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 - check_and_install_gem "pronto-brakeman", require: false + run "bundle install" end end - def add_flay_extension - return if options[:extensions_to_skip].include?('flay') - - say "Adding extension for flay", :green + def pronto_brakemen_gem_content + return unless options[:skip_extensions].exclude?('brakeman') + return if gem_installed?('pronto-brakeman') - Bundler.with_unbundled_env do - check_and_install_gem "pronto-flay", require: false - end + "\tgem \"pronto-brakeman\", require: false" end - def add_reek_extension - return if options[:extensions_to_skip].include?('reek') + def pronto_flay_gem_content + return unless options[:skip_extensions].exclude?('flay') + return if gem_installed?('pronto-flay') - 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 + "\tgem \"pronto-flay\", require: false" end end end -end +end \ No newline at end of file diff --git a/lib/generators/boring/pronto/gitlab_ci/install/install_generator.rb b/lib/generators/boring/pronto/gitlab_ci/install/install_generator.rb index 126b3881..a2baca0c 100644 --- a/lib/generators/boring/pronto/gitlab_ci/install/install_generator.rb +++ b/lib/generators/boring/pronto/gitlab_ci/install/install_generator.rb @@ -18,92 +18,88 @@ 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 + add_pronto_configuration + add_lint_stage show_readme else - say "Creating .gitlab-ci.yml with Pronto configurations", - :yellow - - template ".gitlab-ci.yml", ".gitlab-ci.yml" + create_gitlab_ci_with_pronto end end private + def create_gitlab_ci_with_pronto + say "Creating .gitlab-ci.yml with Pronto configurations", :yellow + template ".gitlab-ci.yml", ".gitlab-ci.yml" + end - def add_configuration_to_existing_file - if gitlab_ci_file_content["pronto"] - say "Skipping Pronto configurations", - :yellow + def add_pronto_configuration + return if pronto_configuration_exists? - return + say "Adding Pronto configurations to .gitlab-ci.yml", :green + inject_into_file ".gitlab-ci.yml", pronto_ci_content, before: /\Z/ 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) || {} + def add_lint_stage + return if lint_stage_exists? - if gitlab_ci_file_content["stages"] && - gitlab_ci_file_content["stages"].include?("lint") - return + if stages_exists? + inject_into_file ".gitlab-ci.yml", optimize_indentation("\n- lint", 2).chomp, after: /stages:/ + else + inject_into_file ".gitlab-ci.yml", stages_configuration, before: /pronto:/ + end 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 + def show_readme + readme "README" + end - inject_into_file ".gitlab-ci.yml", - "#{stages_configuration}\n", - before: /pronto:/ + def pronto_configuration_exists? + gitlab_ci_file_content["pronto"] end - end - def show_readme - readme "README" - end + def lint_stage_exists? + gitlab_ci_file_content["stages"] && gitlab_ci_file_content["stages"].include?("lint") + end - def gitlab_ci_file_content - return @gitlab_ci_file_content if defined?(@gitlab_ci_file_content) + def stages_exists? + gitlab_ci_file_content["stages"] + end - @gitlab_ci_file_content = - YAML.safe_load(File.open(".gitlab-ci.yml"), aliases: true) || {} - end + def gitlab_ci_file_content + @gitlab_ci_file_content ||= YAML.safe_load(File.open(".gitlab-ci.yml"), aliases: true) || {} + end + + def pronto_ci_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 + end + + def stages_configuration + <<~RUBY + stages: + - lint + RUBY + end end end end -end +end \ No newline at end of file