Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
uoy-faculty-rake / lib / faculty / rake / base_update.rb
Size: Mime:
# frozen_string_literal: true

require 'rake/tasklib'
require_relative 'helpers'

module Faculty
  module Rake
    # Functions for updating a sinatra app with the latest changes from sinatra-base
    class BaseUpdate < ::Rake::TaskLib
      include Helpers

      def initialize(remote, base_update_branch = nil)
        super()
        @remote = remote
        @base_update_branch = base_update_branch || `git branch --show-current`.strip

        base_update_task(base_update_branch)
      end

      private

      def base_branch_exists_in_remote
        system 'git show-ref --verify --quiet refs/remotes/origin/base'
      end

      def base_update_branch_exists?
        system "git show-ref --verify --quiet refs/heads/#{@base_update_branch}"
      end

      def base_update_task(base_update_branch)
        desc "Merge in changes from #{remote_repository_name}"
        task :base_update do
          check_origin_base_exists
          check_local_update_branch if base_update_branch
          update_origin_base
          merge_base_branch
          push_to_remote if base_update_branch
        end
      end

      def check_local_update_branch
        # Delete the local update branch if it already exists.
        # This will fail if it is not merged.
        system "git branch -d #{@base_update_branch}" if base_update_branch_exists?
      end

      def check_origin_base_exists
        puts bold 'Checking origin/base exists...'
        system 'git fetch origin'
        abort bold 'origin/base does not exist and must be set up first' unless base_branch_exists_in_remote
      end

      def merge_base_branch
        puts bold "Merging the base branch into #{@base_update_branch}"
        system 'git fetch origin'
        system "git checkout -b #{@base_update_branch}"
        system 'git merge origin/base --no-commit'
        conflicted_files = `git ls-files -u`.strip
        unless conflicted_files.empty?
          puts bold 'Solve any merge conflicts with your preferred method, and then hit enter:'
          $stdin.gets
        end
        system "git commit --message=\"Merge updates from #{remote_repository_name}\""
      end

      def push_to_remote
        system "git push -u origin #{@base_update_branch}"
      end

      def remote_repository_name
        repository_name_from_remote @remote
      end

      def update_origin_base
        puts bold("Merging changes from #{remote_repository_name} into the base branch...")
        remote_repo = `git config --get remote.origin.url`.strip
        tmp_dir = `mktemp -d -t base-merge-XXXXX`.strip
        system "git clone #{remote_repo} #{tmp_dir}"
        update_origin_base_in_tmp_dir tmp_dir
      ensure
        system "rm -rf #{tmp_dir}"
      end

      def update_origin_base_in_tmp_dir(tmp_dir) # rubocop:disable Metrics/MethodLength
        Dir.chdir tmp_dir do
          system 'git checkout -b base origin/base'
          system "git remote add baserepo #{@remote}"
          system 'git fetch baserepo'
          system 'git checkout baserepo/main'
          system 'git reset base'
          system 'git add .'
          last_hash = `git rev-parse --short baserepo/main`.strip
          system "git commit --message='Updates from #{remote_repository_name} at #{last_hash}'"
          system 'git checkout -B base'
          system 'git push --quiet origin base'
        end
      end
    end
  end
end