lib/pdksync.rb in pdksync-0.3.0 vs lib/pdksync.rb in pdksync-0.4.0

- old
+ new

@@ -2,47 +2,60 @@ require 'git' require 'open3' require 'fileutils' require 'rake' require 'pdk' -require 'octokit' require 'pdksync/constants' +require 'pdksync/gitplatformclient' require 'json' require 'yaml' require 'colorize' require 'bundler' # @summary # This module set's out and controls the pdksync process -# @param [String] @access_token -# The token used to access github, must be exported locally. # @param [String] @namspace # The namespace of the repositories we are updating. # @param [String] @pdksync_dir # The local directory the repositories are to be copied to. # @param [String] @push_file_destination # The remote that the pull requests are to be made against. # @param [String] @create_pr_against # The branch the the pull requests are to be made against. # @param [String] @managed_modules # The file that the array of managed modules is to be retrieved from. +# @param [Symbol] @git_platform +# The Git hosting platform to use for pull requests +# @param [String] @git_base_uri +# The base URI for Git repository access, for example 'https://github.com' or +# 'ssh://git@repo.example.com:2222' +# @param [Hash] @git_platform_access_settings +# Hash of access settings required to access the configured Git hosting +# platform API. Must always contain the key :access_token set to the exported +# GITHUB_TOKEN or GITLAB_TOKEN. In case of Gitlab it also must contain the +# key :gitlab_api_endpoint with an appropriate value. module PdkSync include Constants - @access_token = Constants::ACCESS_TOKEN @namespace = Constants::NAMESPACE @pdksync_dir = Constants::PDKSYNC_DIR @push_file_destination = Constants::PUSH_FILE_DESTINATION @create_pr_against = Constants::CREATE_PR_AGAINST @managed_modules = Constants::MANAGED_MODULES @default_pdksync_label = Constants::PDKSYNC_LABEL + @git_platform = Constants::GIT_PLATFORM + @git_base_uri = Constants::GIT_BASE_URI + @git_platform_access_settings = { + access_token: Constants::ACCESS_TOKEN, + gitlab_api_endpoint: Constants::GITLAB_API_ENDPOINT + } def self.main(steps: [:clone], args: nil) create_filespace client = setup_client module_names = return_modules raise "No modules found in '#{@managed_modules}'" if module_names.nil? - validate_modules_exist(module_names) + validate_modules_exist(client, module_names) pr_list = [] # The current directory is saved for cleanup purposes main_path = Dir.pwd @@ -57,20 +70,21 @@ puts "Commit branch_name=#{args[:branch_name]} commit_message=#{args[:commit_message]}" end # validation push_and_create_pr if steps.include?(:push_and_create_pr) raise 'Needs a pr_title' if args.nil? || args[:pr_title].nil? - puts "PR title =#{args[:pr_title]}" + puts "PR title =#{args[:additional_title]} #{args[:pr_title]}" end # validation clean_branches if steps.include?(:clean_branches) raise 'Needs a branch_name, and the branch name contains the string pdksync' if args.nil? || args[:branch_name].nil? || !args[:branch_name].include?('pdksync') puts "Removing branch_name =#{args[:branch_name]}" end abort "No modules listed in #{@managed_modules}" if module_names.nil? module_names.each do |module_name| + module_args = args.clone Dir.chdir(main_path) unless Dir.pwd == main_path print "#{module_name}, " repo_name = "#{@namespace}/#{module_name}" output_path = "#{@pdksync_dir}/#{module_name}" if steps.include?(:clone) @@ -96,50 +110,50 @@ next unless exit_status.zero? end if steps.include?(:run_a_command) Dir.chdir(main_path) unless Dir.pwd == main_path print 'run command, ' - exit_status = run_command(output_path, args) + exit_status = run_command(output_path, module_args) next unless exit_status.zero? end if steps.include?(:pdk_update) Dir.chdir(main_path) unless Dir.pwd == main_path next unless pdk_update(output_path).zero? if steps.include?(:use_pdk_ref) ref = return_template_ref - pr_title = args[:additional_title] ? "#{args[:additional_title]} - pdksync_#{ref}" : "pdksync_#{ref}" - args = { branch_name: "pdksync_#{ref}", - commit_message: "pdksync_#{ref}", - pr_title: pr_title, - pdksync_label: @default_pdksync_label } + pr_title = module_args[:additional_title] ? "#{module_args[:additional_title]} - pdksync_#{ref}" : "pdksync_#{ref}" + module_args = module_args.merge(branch_name: "pdksync_#{ref}", + commit_message: pr_title, + pr_title: pr_title, + pdksync_label: @default_pdksync_label) end print 'pdk update, ' end if steps.include?(:create_commit) Dir.chdir(main_path) unless Dir.pwd == main_path git_instance = Git.open(output_path) - create_commit(git_instance, args[:branch_name], args[:commit_message]) + create_commit(git_instance, module_args[:branch_name], module_args[:commit_message]) print 'commit created, ' end if steps.include?(:push_and_create_pr) Dir.chdir(main_path) unless Dir.pwd == main_path git_instance = Git.open(output_path) push_staged_files(git_instance, git_instance.current_branch, repo_name) print 'push, ' pdk_version = return_pdk_version("#{output_path}/metadata.json") # If a label is supplied, verify that it is available in the repo - label = args[:pdksync_label] ? args[:pdksync_label] : args[:label] + label = module_args[:pdksync_label] ? module_args[:pdksync_label] : module_args[:label] label_valid = (label.is_a?(String) && !label.to_str.empty?) ? check_for_label(client, repo_name, label) : nil # Exit current iteration if an error occured retrieving a label if label_valid == false raise 'Ensure label is valid' end # Create the PR and add link to pr list - pr = create_pr(client, repo_name, git_instance.current_branch, pdk_version, args[:pr_title]) + pr = create_pr(client, repo_name, git_instance.current_branch, pdk_version, module_args[:pr_title]) if pr.nil? break end pr_list.push(pr.html_url) @@ -151,11 +165,11 @@ print "added label '#{label}' " end end if steps.include?(:clean_branches) Dir.chdir(main_path) unless Dir.pwd == main_path - delete_branch(client, repo_name, args[:branch_name]) + delete_branch(client, repo_name, module_args[:branch_name]) print 'branch deleted, ' end puts 'done.'.green end return if pr_list.size.zero? @@ -171,18 +185,16 @@ FileUtils.mkdir @pdksync_dir unless Dir.exist?(@pdksync_dir) end # @summary # This method when called will create and return an octokit client with access to the upstream git repositories. - # @return [Octokit::Client] client - # The octokit client that has been created. + # @return [PdkSync::GitPlatformClient] client + # The Git platform client that has been created. def self.setup_client - client = Octokit::Client.new(access_token: @access_token.to_s) - client.user.login - client - rescue ArgumentError, Octokit::Unauthorized - raise "Access Token not set up correctly - Use export 'GITHUB_TOKEN=<put your token here>' to set it." + PdkSync::GitPlatformClient.new(@git_platform, @git_platform_access_settings) + rescue StandardError => error + raise "Git platform access not set up correctly: #{error}" end # @summary # This method when called will access a file set by the global variable '@managed_modules' and retrieve the information within as an array. # @return [Array] @@ -191,18 +203,23 @@ raise "File '#{@managed_modules}' is empty/does not exist" if File.size?(@managed_modules).nil? YAML.safe_load(File.open(@managed_modules)) end # @summary - # This method when called will parse an array of module names and verify whether they are valid GitHub repo names + # This method when called will parse an array of module names and verify + # whether they are valid repo or project names on the configured Git + # hosting platform. + # @param [PdkSync::GitPlatformClient] client + # The Git platform client used to get a repository. # @param [Array] module_names - # String array of the names of GitHub repos - def self.validate_modules_exist(module_names) + # String array of the names of Git platform repos + def self.validate_modules_exist(client, module_names) invalid_names = [] + raise "Error reading in modules. Check syntax of '#{@managed_modules}'." unless !module_names.nil? && module_names.is_a?(Array) module_names.each do |module_name| # If module name is invalid, push it to invalid names array - unless Octokit.repository?("#{@namespace}/#{module_name}") + unless client.repository?("#{@namespace}/#{module_name}") invalid_names.push(module_name) next end end # Raise error if any invalid matches were found @@ -248,11 +265,11 @@ # @param [String] output_path # The location the repository is to be cloned to. # @return [Git::Base] # A git object representing the local repository. def self.clone_directory(namespace, module_name, output_path) - Git.clone("https://github.com/#{namespace}/#{module_name}.git", output_path.to_s) # is returned + Git.clone("#{@git_base_uri}/#{namespace}/#{module_name}.git", output_path.to_s) # is returned rescue Git::GitExecuteError => error puts "(FAILURE) Cloning #{module_name} has failed. #{error}".red end # @summary @@ -350,11 +367,11 @@ # @param [Git::Base] git_repo # A git object representing the local repository against which the commit is to be made. # @param [String] template_ref # The unique template_ref that is used as part of the commit name. # @param [String] commit_message - # If sepecified it will be the message for the commit. + # If specified it will be the message for the commit. def self.commit_staged_files(git_repo, template_ref, commit_message = nil) message = if commit_message.nil? "pdksync_#{template_ref}" else commit_message @@ -376,12 +393,12 @@ puts "(FAILURE) Pushing to #{@push_file_destination} for #{repo_name} has failed. #{error}".red end # @summary # This method when called will create a pr on the given repository that will create a pr to merge the given commit into the master with the pdk version as an identifier. - # @param [Octokit::Client] client - # The octokit client used to gain access to and manipulate the repository. + # @param [PdkSync::GitPlatformClient] client + # The Git platform client used to gain access to and manipulate the repository. # @param [String] repo_name # The name of the repository on which the commit is to be made. # @param [String] template_ref # The unique reference that that represents the template the update has ran against. # @param [String] pdk_version @@ -405,12 +422,12 @@ puts "(FAILURE) PR creation for #{repo_name} has failed. #{error}".red end # @summary # This method when called will check on the given repository for the existence of the supplied label - # @param [Octokit::Client] client - # The octokit client used to gain access to and manipulate the repository. + # @param [PdkSync::GitPlatformClient] client + # The Git platform client used to gain access to and manipulate the repository. # @param [String] repo_name # The name of the repository on which the commit is to be made. # @param [String] label # The label to check for. # @return [Boolean] @@ -435,12 +452,12 @@ return false end # @summary # This method when called will add a given label to a given repository - # @param [Octokit::Client] client - # The octokit client used to gain access to and manipulate the repository. + # @param [PdkSync::GitPlatformClient] client + # The Git Platform client used to gain access to and manipulate the repository. # @param [String] repo_name # The name of the repository on which the commit is to be made. # @param [Integer] issue_number # The id of the issue (i.e. pull request) to add the label to. # @param [String] label @@ -452,11 +469,11 @@ return false end # @summary # This method when called will delete any preexisting branch on the given repository that matches the given name. - # @param [Octokit::Client] client - # The octokit client used to gain access to and manipulate the repository. + # @param [PdkSync::GitPlatformClient] client + # The Git platform client used to gain access to and manipulate the repository. # @param [String] repo_name # The name of the repository from which the branch is to be deleted. # @param [String] branch_name # The name of the branch that is to be deleted. def self.delete_branch(client, repo_name, branch_name)