diff --git a/.github/workflows/pr-check.yml b/.github/workflows/pr-check.yml index a6d7c582..f934b2ef 100644 --- a/.github/workflows/pr-check.yml +++ b/.github/workflows/pr-check.yml @@ -82,7 +82,7 @@ jobs: - name: Install test dependencies run: | - brew install modules alisw/system-deps/o2-full-deps + brew install modules alisw/system-deps/o2-full-deps sapling python3 -m pip install --upgrade tox tox-gh-actions coverage - name: Run tests diff --git a/alibuild_helpers/build.py b/alibuild_helpers/build.py index 1a6a9b0c..fb407715 100644 --- a/alibuild_helpers/build.py +++ b/alibuild_helpers/build.py @@ -14,6 +14,7 @@ from alibuild_helpers.utilities import yamlDump from alibuild_helpers.utilities import resolve_tag, resolve_version from alibuild_helpers.git import git, clone_speedup_options, Git +from alibuild_helpers.sl import sapling, Sapling from alibuild_helpers.sync import (NoRemoteSync, HttpRemoteSync, S3RemoteSync, Boto3RemoteSync, RsyncRemoteSync) import yaml @@ -62,6 +63,10 @@ def update_git_repos(args, specs, buildOrder, develPkgs): def update_repo(package, git_prompt): specs[package]["scm"] = Git() + if package in develPkgs: + localCheckout = os.path.join(os.getcwd(), specs[package]["package"]) + if exists("%s/.sl" % localCheckout): + specs[package]["scm"] = Sapling() updateReferenceRepoSpec(args.referenceSources, package, specs[package], fetch=args.fetchRepos, usePartialClone=not args.docker, @@ -364,10 +369,20 @@ def doBuild(args, parser): if not exists(specDir): makedirs(specDir) - # By default Git is our SCM, so we find the commit hash of alidist - # using it. + # If the alidist workdir contains a .git directory, we use Git as SCM + # otherwise we use Sapling + scm = Git() - os.environ["ALIBUILD_ALIDIST_HASH"] = scm.checkedOutCommitName(directory=args.configDir) + try: + checkedOutCommitName = scm.checkedOutCommitName(directory=args.configDir) + except: + scm = Sapling() + try: + checkedOutCommitName = scm.checkedOutCommitName(directory=args.configDir) + except: + error("Cannot find SCM directory in %s.", args.configDir) + return 1 + os.environ["ALIBUILD_ALIDIST_HASH"] = checkedOutCommitName debug("Building for architecture %s", args.architecture) debug("Number of parallel builds: %d", args.jobs) diff --git a/alibuild_helpers/sl.py b/alibuild_helpers/sl.py new file mode 100644 index 00000000..ed07986a --- /dev/null +++ b/alibuild_helpers/sl.py @@ -0,0 +1,47 @@ +from shlex import quote # Python 3.3+ +from alibuild_helpers.cmd import getstatusoutput +from alibuild_helpers.log import debug +from alibuild_helpers.scm import SCM + +SL_COMMAND_TIMEOUT_SEC = 120 +"""How many seconds to let any sl command execute before being terminated.""" + +class Sapling(SCM): + name = "Sapling" + def checkedOutCommitName(self, directory): + return sapling(("whereami", ), directory) + def branchOrRef(self, directory): + # Format is [+] + identity = sapling(("identify", ), directory) + return identity.split(" ")[-1] + def exec(self, *args, **kwargs): + return sapling(*args, **kwargs) + def parseRefs(self, output): + return { + sl_ref: sl_hash for sl_ref, sep, sl_hash + in (line.partition("\t") for line in output.splitlines()) if sep + } + def listRefsCmd(self): + return ["bookmark", "--list", "--remote", "-R"] + def diffCmd(self, directory): + return "cd %s && sl diff && sl status" % directory + def checkUntracked(self, line): + return line.startswith("? ") + +def sapling(args, directory=".", check=True, prompt=True): + debug("Executing sl %s (in directory %s)", " ".join(args), directory) + # We can't use git --git-dir=%s/.git or git -C %s here as the former requires + # that the directory we're inspecting to be the root of a git directory, not + # just contained in one (and that breaks CI tests), and the latter isn't + # supported by the git version we have on slc6. + # Silence cd as shell configuration can cause the new directory to be echoed. + err, output = getstatusoutput("""\ + set -e +x + sl -R {directory} {args} + """.format( + directory=quote(directory), + args=" ".join(map(quote, args)), + ), timeout=SL_COMMAND_TIMEOUT_SEC) + if check and err != 0: + raise RuntimeError("Error {} from sl {}: {}".format(err, " ".join(args), output)) + return output if check else (err, output) diff --git a/tox.ini b/tox.ini index da3f14df..b7a436a0 100644 --- a/tox.ini +++ b/tox.ini @@ -40,6 +40,7 @@ allowlist_externals = git test touch + sl deps = py27: mock coverage @@ -109,6 +110,12 @@ commands = touch zlib/foo coverage run --source={toxinidir} -a {toxinidir}/aliBuild -a {env:ARCHITECTURE} --no-system --disable GCC-Toolchain build zlib coverage run --source={envsitepackagesdir} -a -m unittest discover {toxinidir}/tests + # On Darwin we also test sapling support + darwin: sl clone https://github.com/alisw/alidist alidist-sapling + darwin: coverage run --source={toxinidir} -a {toxinidir}/aliBuild -a {env:ARCHITECTURE} alidist-sapling --no-system --disable GCC-Toolchain build zlib + darwin: rm -fr zlib + darwin: sl clone https://github.com/alisw/zlib + darwin: coverage run --source={toxinidir} -a {toxinidir}/aliBuild -a {env:ARCHITECTURE} --no-system --disable GCC-Toolchain build zlib [coverage:run] branch = True