lib/pdksync.rb in pdksync-0.2.0 vs lib/pdksync.rb in pdksync-0.3.0
- old
+ new
@@ -7,10 +7,11 @@
require 'octokit'
require 'pdksync/constants'
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.
@@ -30,16 +31,20 @@
@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
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)
pr_list = []
+
# The current directory is saved for cleanup purposes
main_path = Dir.pwd
# validation run_a_command
if steps.include?(:run_a_command)
@@ -99,13 +104,15 @@
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: "pdksync_#{ref}" }
+ 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
@@ -117,13 +124,34 @@
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_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])
+ if pr.nil?
+ break
+ end
+
pr_list.push(pr.html_url)
print 'created pr, '
+
+ # If a valid label is supplied, add this to the PR
+ if label_valid == true
+ add_label(client, repo_name, pr.number, label)
+ 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])
print 'branch deleted, '
@@ -158,14 +186,32 @@
# @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]
# An array of different module names.
def self.return_modules
+ 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
+ # @param [Array] module_names
+ # String array of the names of GitHub repos
+ def self.validate_modules_exist(module_names)
+ invalid_names = []
+ module_names.each do |module_name|
+ # If module name is invalid, push it to invalid names array
+ unless Octokit.repository?("#{@namespace}/#{module_name}")
+ invalid_names.push(module_name)
+ next
+ end
+ end
+ # Raise error if any invalid matches were found
+ raise "Could not find the following repositories: #{invalid_names}" unless invalid_names.empty?
+ end
+
+ # @summary
# Try to use a fully installed pdk, otherwise fall back to the bundled pdk gem.
# @return String
# Path to the pdk executable
def self.return_pdk_path
full_path = '/opt/puppetlabs/pdk/bin/pdk'
@@ -216,12 +262,25 @@
# @param [String] command
# The command to be run.
# @return [Integer]
# The status code of the command run.
def self.run_command(output_path, command)
+ stdout = ''
+ stderr = ''
+ status = Process::Status
+
Dir.chdir(output_path) unless Dir.pwd == output_path
- stdout, stderr, status = Open3.capture3(command)
+
+ # Environment cleanup required due to Ruby subshells using current Bundler environment
+ if command =~ %r{^bundle}
+ Bundler.with_clean_env do
+ stdout, stderr, status = Open3.capture3(command)
+ end
+ else
+ stdout, stderr, status = Open3.capture3(command)
+ end
+
puts "\n#{stdout}\n".yellow
puts "(FAILURE) Unable to run command '#{command}': #{stderr}".red unless status.exitstatus.zero?
status.exitstatus
end
@@ -342,9 +401,56 @@
title,
message)
pr
rescue StandardError => error
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 [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]
+ # A boolean stating whether the label was found.
+ def self.check_for_label(client, repo_name, label)
+ # Get labels from repository
+ repo_labels = client.labels(repo_name)
+
+ # Look for label in the repository's labels
+ match = false
+ repo_labels.each do |repo_label|
+ if repo_label.name == label
+ match = true
+ break
+ end
+ end
+
+ # Raise error if a match was not found else return true
+ (match == false) ? (raise StandardError, "Label '#{label}' not found in #{repo_name}") : (return true)
+ rescue StandardError => error
+ puts "(FAILURE) Retrieving labels for #{repo_name} has failed. #{error}".red
+ 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 [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
+ # The label to add.
+ def self.add_label(client, repo_name, issue_number, label)
+ client.update_issue(repo_name, issue_number, labels: [label])
+ rescue StandardError => error
+ puts "(FAILURE) Adding label to #{repo_name} issue #{issue_number} has failed. #{error}".red
+ 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