spec/integration/push_spec.rb in braid-1.1.3 vs spec/integration/push_spec.rb in braid-1.1.4

- old
+ new

@@ -1,12 +1,19 @@ require File.dirname(__FILE__) + '/integration_helper' +BRAID_PUSH_USES_SPARSE_CHECKOUT = git_require_version('2.27') + describe 'Pushing to a mirror' do - before do + # This code needs to run before the `around` hook in the required-filter test + # that sets up the virtual home directory inside TMP_PATH, but per-example + # `before` hooks always run after `around` hooks. So make this an `around` + # hook just to get it to run at the time we want. + around do |example| FileUtils.rm_rf(TMP_PATH) FileUtils.mkdir_p(TMP_PATH) + example.run end describe 'from a git repository' do before do @repository_dir = create_git_repo_from_fixture('shiny', :name => 'Some body', :email => 'somebody@example.com') @@ -164,11 +171,11 @@ in_dir(@vendor_repository_dir) do run_command('git config receive.denyCurrentBranch updateInstead') end FileUtils.cp_r(File.join(FIXTURE_PATH, 'skit1.1x') + '/layouts/layout.liquid', "#{@repository_dir}/skit-layout.liquid", - {preserve: true}) + preserve: true) in_dir(@repository_dir) do run_command('git add *') run_command('git commit -m "Make some changes to vendored files"') end end @@ -289,9 +296,107 @@ end end expect(braid_output).to match(/Braid: Mirror is not up to date. Stopping./) assert_no_diff("#{FIXTURE_PATH}/skit1.2/#{@file_name}", "#{TMP_PATH}/skit1/#{@file_name}") + end + end + end + + describe 'from a git repository with a required filter', :if => BRAID_PUSH_USES_SPARSE_CHECKOUT do + # This tests that a Git filter that is configured as "required" at the user + # account level but fails without additional repository-level configuration + # (which currently may be the case for Git LFS: + # https://github.com/cristibalan/braid/pull/98) does not interfere with + # pushing using a temporary repository. Braid achieves this by using an + # empty sparse checkout in the temporary repository to avoid triggering the + # filter. + + around do |example| + # In order to simulate configuring the filter at the user account level + # without modifying the user's real Git configuration, we have to + # temporarily change $HOME. Unfortunately, this may break other things + # that need the real $HOME. So far, the only problem we've seen is the + # Braid subprocess not finding Ruby gems, and setting $GEM_PATH seems to + # be a sufficient workaround. + orig_gem_path = run_command('gem environment gempath').strip + virtual_home = File.join(TMP_PATH, 'home') + FileUtils.mkdir_p(virtual_home) + Braid::Operations::with_modified_environment({ + 'HOME' => virtual_home, + # If the user has an $XDG_CONFIG_HOME-based configuration file, ensure + # that Git doesn't use it, to maintain consistency with not using the + # original ~/.gitconfig. TODO: Would it be better to `include` both + # files in case they have a setting that we actually need? + 'XDG_CONFIG_HOME' => nil, + 'GEM_PATH' => orig_gem_path + }) do + example.run + end + end + + before do + # create_git_repo_from_fixture('skit1_with_filter') would check out the + # working tree and trigger the broken filter before we have an opportunity + # to turn it off in the repository configuration. Avoiding this problem + # would take some extra code, so as a workaround, we just don't configure + # the filter until after that step. :/ + @vendor_repository_dir = create_git_repo_from_fixture('skit1_with_filter') + + # Avoid a warning emitted by because we use the old default default branch name + run_command('git config --global init.defaultBranch master') + + # Configure the broken filter globally. Here, `false` is the command that + # always exits 1. + run_command('git config --global filter.broken.clean false') + run_command('git config --global filter.broken.smudge false') + run_command('git config --global filter.broken.required true') + + # This won't trigger the filter because the .gitattributes file is only in + # the vendor repository. + @repository_dir = create_git_repo_from_fixture('shiny', :name => 'Some body', :email => 'somebody@example.com') + @file_name = 'layouts/layout.liquid' + + in_dir(@repository_dir) do + # Make the filter a no-op in the superproject repository. + run_command('git config filter.broken.clean cat') + run_command('git config filter.broken.smudge cat') + + run_command("#{BRAID_BIN} add #{@vendor_repository_dir} skit1") + end + + in_dir(@vendor_repository_dir) do + run_command('git config receive.denyCurrentBranch updateInstead') + end + + update_dir_from_fixture('shiny/skit1', 'skit1.1_with_filter') + in_dir(@repository_dir) do + run_command('git add *') + run_command('git commit -m "Make some changes to vendored files"') + end + end + + it 'should push changes successfully' do + braid_output = nil + commit_message = 'Make some changes' + in_dir(@repository_dir) do + with_editor_message(commit_message) do + braid_output = run_command("#{BRAID_BIN} push skit1") + end + end + expect(braid_output).to match(/Braid: Cloning mirror with local changes./) + expect(braid_output).to match(/Make some changes/) + expect(braid_output).to match(/Braid: Pushing changes to remote branch master./) + + assert_no_diff("#{FIXTURE_PATH}/skit1.1_with_filter/#{@file_name}", "#{@repository_dir}/skit1/#{@file_name}") + assert_no_diff("#{FIXTURE_PATH}/skit1.1_with_filter/#{@file_name}", "#{@vendor_repository_dir}/#{@file_name}") + + in_dir(@vendor_repository_dir) do + run_command('git checkout master 2>&1') + + assert_commit_subject(commit_message) + assert_commit_author('Some body') + assert_commit_email('somebody@example.com') end end end end