Skip to content

Commit

Permalink
Fix updating pins on crates which track Alire-generated files
Browse files Browse the repository at this point in the history
  • Loading branch information
Seb-MCaw committed Nov 5, 2024
1 parent 15addad commit 1469174
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 1 deletion.
8 changes: 7 additions & 1 deletion src/alire/alire-user_pins.adb
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ package body Alire.User_Pins is
Trace.Detail ("Checking out pin " & Utils.TTY.Name (Crate) & " at "
& TTY.URL (Destination));

-- If the fetch URL has been changed, fall back to checkout
-- If the fetch URL has been changed, do a fresh 'git clone'.
--
-- Note that VCSs.Git.Clone converts the URL to a git-friendly form
-- with VCSs.Repo, so this is what the output of 'git config' should
Expand All @@ -216,6 +216,12 @@ package body Alire.User_Pins is
return;
end if;

-- Discard any uncommitted changes (e.g. files in 'config/' which
-- Alire has automatically generated).
-- These can cause Update's 'git pull' command to fail.

VCSs.Git.Discard_Uncommitted (Repo => Destination).Assert;

-- Finally update. In case the branch has just been changed by the
-- user in the manifest, the following call will also take care of
-- it.
Expand Down
15 changes: 15 additions & 0 deletions src/alire/alire-vcss-git.adb
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,21 @@ package body Alire.VCSs.Git is
return Alire.Errors.Get (E);
end Commit_All;

-------------------------
-- Discard_Uncommitted --
-------------------------

function Discard_Uncommitted (Repo : Directory_Path) return Outcome
is
Guard : Directories.Guard (Directories.Enter (Repo)) with Unreferenced;
begin
Run_Git (Empty_Vector & "reset" & "-q" & "--hard" & "HEAD");
return Outcome_Success;
exception
when E : others =>
return Alire.Errors.Get (E);
end Discard_Uncommitted;

----------
-- Push --
----------
Expand Down
6 changes: 6 additions & 0 deletions src/alire/alire-vcss-git.ads
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,9 @@ package Alire.VCSs.Git is
-- Add and commit all changes in a given repo; commiter will be set to the
-- user email stored in our config.

function Discard_Uncommitted (Repo : Directory_Path) return Outcome;
-- Reset all uncommitted changes to tracked files

function Push (Repo : Directory_Path;
Remote : String;
Force : Boolean := False;
Expand Down Expand Up @@ -184,6 +187,9 @@ package Alire.VCSs.Git is
return Outcome;
-- Update and track Branch, if given.
--
-- Does not discard uncommitted changes, so will fail if there are local
-- changes which conflict with the update.
--
-- Raises Checked_Error when the repo has multiple remotes configured and
-- Branch is not the same as the current HEAD.

Expand Down
55 changes: 55 additions & 0 deletions testsuite/tests/pin/branch-update-dirty/test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
"""
Check updating a branch pin when 'config/*' files are tracked.
"""


import os
import subprocess

from drivers.alr import run_alr, alr_pin, init_local_crate
from drivers.asserts import assert_match, assert_in_file
from drivers.helpers import git_branch, git_commit_file, init_git_repo


# Create crate yyy, with git tracking the 'config/*' files
init_local_crate("yyy")
yyy_path = os.getcwd()
with open(".gitignore") as f:
gitignore_content = f.read()
gitignore_content = gitignore_content.replace("/config/\n", "")
with open(".gitignore", "w") as f:
f.write(gitignore_content)
init_git_repo(".")
default_branch = git_branch()
os.chdir("..")

# Create and build another crate, with yyy's default branch added as a pin
init_local_crate()
xxx_path = os.getcwd()
alr_pin("yyy", url=f"git+file:{yyy_path}", branch=default_branch)
run_alr("build")

# Verify that the cached copy of yyy has a dirty repo (due to changes to the
# 'config/*' files)
cached_yyy_path = os.path.join(xxx_path, "alire", "cache", "pins", "yyy")
os.chdir(cached_yyy_path)
p = subprocess.run(["git", "status"], capture_output=True)
p.check_returncode()
assert_match(r".*modified:\s*config/yyy_config\.gpr", p.stdout.decode())

# Add commits to yyy's default branch, including a change to a file in 'config/'
os.chdir(yyy_path)
git_commit_file(
"Change_config", "config/yyy_config.gpr", "This is a new addition\n", "a"
)
git_commit_file("Add_test_file", "test_file", "This is a new file\n")

# Check that the dirty repo doesn't prevent updating the pin
os.chdir(xxx_path)
run_alr("update")

# Check that the update was successful
assert_in_file(os.path.join(cached_yyy_path, "test_file"), "This is a new file")


print('SUCCESS')
3 changes: 3 additions & 0 deletions testsuite/tests/pin/branch-update-dirty/test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
driver: python-script
indexes:
compiler_only_index: {}

0 comments on commit 1469174

Please sign in to comment.