diff --git a/CHANGELOG.md b/CHANGELOG.md index fe3d6561c..a7036f100 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ _None_ ### New Features -_None_ +- Improve failure message when pinned commit cannot be found during `configure_update` [#410] ### Bug Fixes diff --git a/lib/fastlane/plugin/wpmreleasetoolkit/helper/configure_helper.rb b/lib/fastlane/plugin/wpmreleasetoolkit/helper/configure_helper.rb index 1d58bf4c1..5cce113df 100644 --- a/lib/fastlane/plugin/wpmreleasetoolkit/helper/configure_helper.rb +++ b/lib/fastlane/plugin/wpmreleasetoolkit/helper/configure_helper.rb @@ -3,6 +3,7 @@ require 'English' require 'fastlane_core/ui/ui' require 'fileutils' +require 'git' require_relative '../models/configuration' @@ -74,8 +75,10 @@ def self.update_configure_file_commit_hash(new_hash) ### Returns the currently checked out branch for the `~/.mobile-secrets` repository. ### NB: Returns nil if the repo is in a detached HEAD state. def self.repo_branch_name - result = `cd #{repository_path} && git rev-parse --abbrev-ref HEAD`.strip - result == 'HEAD' ? nil : result + git = Git.open(repository_path) + return nil if git.branches.select(&:current).empty? + + git.current_branch end ### Returns the most recent commit hash in the `~/.mobile-secrets` repository. @@ -102,11 +105,16 @@ def self.configure_file_is_behind_local end def self.configure_file_commits_behind_repo - # Get a sily number of revisions to ensure we don't miss any + # Get a large number of revisions to ensure we don't miss any result = `cd #{repository_path} && git --no-pager log -10000 --pretty=format:"%H" && echo` hashes = result.each_line.map(&:strip).reverse index_of_configure_hash = hashes.find_index(configure_file_commit_hash) + + UI.user_error!("Could not find Git commit #{configure_file_commit_hash} from `.configure` file in local secrets repository. Please verify your local copy is up to date with the remote.") if index_of_configure_hash.nil? + + # No need to check for this to be `nil` because it comes by reading the + # local `.mobile-secrets` repo itself. index_of_repo_commit_hash = hashes.find_index(repo_commit_hash) return 0 if index_of_configure_hash >= index_of_repo_commit_hash diff --git a/spec/configure_helper_spec.rb b/spec/configure_helper_spec.rb index 221e1a64a..d0e4a0318 100644 --- a/spec/configure_helper_spec.rb +++ b/spec/configure_helper_spec.rb @@ -1,8 +1,48 @@ # frozen_string_literal: true require 'spec_helper' +require 'tmpdir' describe Fastlane::Helper::ConfigureHelper do + let(:test_repo_path) { Dir.mktmpdir } + + def run_git_command(command:, repo_path: test_repo_path) + # Notice that this will break if the command contains arguments in quotes, + # e.g. `commit -m "Test commit"` will be split into `['commit', '-m', '"Test', 'commit"']` + # which is not a valid arguments list for Git. + # + # For the context of these tests, we can deal with this limitation. + system('git', '-C', repo_path, *command.split, %I[out err] => File::NULL) + end + + before do + allow(described_class).to receive(:repository_path).and_return(test_repo_path) + + run_git_command(command: 'init') + run_git_command(command: 'config user.email test@example.com') + run_git_command(command: 'config user.name Test User') + File.write(File.join(test_repo_path, 'test.txt'), 'test content') + run_git_command(command: 'add test.txt') + run_git_command(command: 'commit -m test') + end + + after do + FileUtils.remove_entry test_repo_path + end + + describe '.repo_branch_name' do + it 'returns the current branch name when on a branch' do + run_git_command(command: 'checkout -b feature-branch') + expect(described_class.repo_branch_name).to eq('feature-branch') + end + + it 'returns nil when in detached HEAD state' do + current_sha = `git -C #{test_repo_path} rev-parse HEAD`.strip + run_git_command(command: "checkout #{current_sha}") + expect(described_class.repo_branch_name).to be_nil + end + end + describe '#add_file' do let(:destination) { 'path/to/destination' }