Fix git-related commands not working in worktrees
If spack is checked out in a git worktree (see [1]), all git-related commands fail because the `spack_is_git_repo()`-check is not thorough enough. When developing in a feature-branch in a seperate worktree, this is annoying as all unittests regarding git-related spack commands fail, cluttering the test results with false-positives. [1]: https://git-scm.com/docs/git-worktree Change-Id: I94b573a2c0e058e9ccc169e7ee6561626fbb06fd
This commit is contained in:
parent
dea5d913db
commit
1cff717ca8
@ -9,6 +9,7 @@
|
||||
import re
|
||||
import sys
|
||||
import argparse
|
||||
import ruamel.yaml as yaml
|
||||
|
||||
import six
|
||||
|
||||
@ -16,7 +17,7 @@
|
||||
from llnl.util.lang import attr_setdefault, index_by
|
||||
from llnl.util.tty.colify import colify
|
||||
from llnl.util.tty.color import colorize
|
||||
from llnl.util.filesystem import working_dir
|
||||
from llnl.util.filesystem import join_path
|
||||
|
||||
import spack.config
|
||||
import spack.error
|
||||
@ -26,6 +27,7 @@
|
||||
import spack.store
|
||||
import spack.util.spack_json as sjson
|
||||
import spack.util.string
|
||||
from ruamel.yaml.error import MarkedYAMLError
|
||||
|
||||
|
||||
# cmd has a submodule called "list" so preserve the python list module
|
||||
@ -433,8 +435,23 @@ def format_list(specs):
|
||||
|
||||
def spack_is_git_repo():
|
||||
"""Ensure that this instance of Spack is a git clone."""
|
||||
with working_dir(spack.paths.prefix):
|
||||
return os.path.isdir('.git')
|
||||
return is_git_repo(spack.paths.prefix)
|
||||
|
||||
|
||||
def is_git_repo(path):
|
||||
dotgit_path = join_path(path, '.git')
|
||||
if os.path.isdir(dotgit_path):
|
||||
# we are in a regular git repo
|
||||
return True
|
||||
if os.path.isfile(dotgit_path):
|
||||
# we might be in a git worktree
|
||||
try:
|
||||
with open(dotgit_path, "rb") as f:
|
||||
dotgit_content = yaml.load(f)
|
||||
return os.path.isdir(dotgit_content.get("gitdir", dotgit_path))
|
||||
except MarkedYAMLError:
|
||||
pass
|
||||
return False
|
||||
|
||||
|
||||
class PythonNameError(spack.error.SpackError):
|
||||
|
67
lib/spack/spack/test/cmd/is_git_repo.py
Normal file
67
lib/spack/spack/test/cmd/is_git_repo.py
Normal file
@ -0,0 +1,67 @@
|
||||
# Copyright 2013-2020 Lawrence Livermore National Security, LLC and other
|
||||
# Spack Project Developers. See the top-level COPYRIGHT file for details.
|
||||
#
|
||||
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import spack
|
||||
import pytest
|
||||
|
||||
from llnl.util.filesystem import mkdirp
|
||||
|
||||
from spack.util.executable import which
|
||||
from spack.version import ver
|
||||
|
||||
|
||||
git = which("git")
|
||||
git_required_version = '2.17.0'
|
||||
|
||||
|
||||
def check_git_version():
|
||||
"""Check if git version is new enough for worktree functionality.
|
||||
Return True if requirements are met.
|
||||
|
||||
The latest required functionality is `worktree remove` which was only added
|
||||
in 2.17.0.
|
||||
|
||||
Refer:
|
||||
https://github.com/git/git/commit/cc73385cf6c5c229458775bc92e7dbbe24d11611
|
||||
"""
|
||||
git_version = ver(git('--version', output=str).lstrip('git version '))
|
||||
return git_version >= ver(git_required_version)
|
||||
|
||||
|
||||
pytestmark = pytest.mark.skipif(
|
||||
not git or not check_git_version(),
|
||||
reason="we need git to test if we are in a git repo"
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture(scope="function")
|
||||
def git_tmp_worktree(tmpdir):
|
||||
"""Create new worktree in a temporary folder and monkeypatch
|
||||
spack.paths.prefix to point to it.
|
||||
"""
|
||||
worktree_root = str(tmpdir.join("tmp_worktree"))
|
||||
mkdirp(worktree_root)
|
||||
|
||||
git("worktree", "add", "--detach", worktree_root, "HEAD")
|
||||
|
||||
yield worktree_root
|
||||
|
||||
git("worktree", "remove", "--force", worktree_root)
|
||||
|
||||
|
||||
def test_is_git_repo_in_worktree(git_tmp_worktree):
|
||||
"""Verify that spack.cmd.spack_is_git_repo() can identify a git repository
|
||||
in a worktree.
|
||||
"""
|
||||
assert spack.cmd.is_git_repo(git_tmp_worktree)
|
||||
|
||||
|
||||
def test_spack_is_git_repo_nongit(tmpdir, monkeypatch):
|
||||
"""Verify that spack.cmd.spack_is_git_repo() correctly returns False if we
|
||||
are in a non-git directory.
|
||||
"""
|
||||
assert not spack.cmd.is_git_repo(str(tmpdir))
|
Loading…
Reference in New Issue
Block a user