alibuild 1.17.14__tar.gz → 1.17.15__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {alibuild-1.17.14 → alibuild-1.17.15}/PKG-INFO +1 -1
- {alibuild-1.17.14 → alibuild-1.17.15}/alibuild.egg-info/PKG-INFO +1 -1
- {alibuild-1.17.14 → alibuild-1.17.15}/alibuild_helpers/_version.py +2 -2
- {alibuild-1.17.14 → alibuild-1.17.15}/alibuild_helpers/utilities.py +43 -10
- {alibuild-1.17.14 → alibuild-1.17.15}/codecov.yml +3 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/docs/docs/reference.md +4 -1
- {alibuild-1.17.14 → alibuild-1.17.15}/tests/test_deps.py +8 -5
- {alibuild-1.17.14 → alibuild-1.17.15}/tests/test_doctor.py +40 -36
- {alibuild-1.17.14 → alibuild-1.17.15}/tests/test_init.py +14 -10
- {alibuild-1.17.14 → alibuild-1.17.15}/tests/test_packagelist.py +62 -41
- {alibuild-1.17.14 → alibuild-1.17.15}/tests/test_utilities.py +91 -8
- {alibuild-1.17.14 → alibuild-1.17.15}/.flake8 +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/.github/workflows/documentation.yml +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/.github/workflows/pr-check.yml +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/.github/workflows/release.yml +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/.gitignore +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/.pylintrc +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/ANALYTICS.md +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/DESIGN.md +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/LICENSE.md +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/MANIFEST.in +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/PACKAGING.md +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/README.rst +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/alfaBuild +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/aliBuild +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/aliDeps +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/aliDoctor +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/alibuild.egg-info/SOURCES.txt +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/alibuild.egg-info/dependency_links.txt +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/alibuild.egg-info/requires.txt +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/alibuild.egg-info/top_level.txt +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/alibuild_helpers/__init__.py +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/alibuild_helpers/analytics.py +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/alibuild_helpers/args.py +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/alibuild_helpers/build.py +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/alibuild_helpers/build_template.sh +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/alibuild_helpers/clean.py +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/alibuild_helpers/cmd.py +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/alibuild_helpers/deps.py +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/alibuild_helpers/doctor.py +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/alibuild_helpers/git.py +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/alibuild_helpers/init.py +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/alibuild_helpers/log.py +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/alibuild_helpers/scm.py +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/alibuild_helpers/sl.py +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/alibuild_helpers/sync.py +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/alibuild_helpers/templating_plugin.py +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/alibuild_helpers/workarea.py +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/alienv +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/debian/changelog +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/debian/compat +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/debian/control +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/debian/copyright +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/debian/files +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/debian/rules +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/docs/README.md +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/docs/SUPPORT +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/docs/docs/alice_logo.png +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/docs/docs/deps.png +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/docs/docs/index.md +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/docs/docs/quick.md +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/docs/docs/stylesheets/extra.css +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/docs/docs/troubleshooting.md +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/docs/docs/user.md +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/docs/mkdocs.yml +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/pb +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/pyproject.toml +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/requirements.txt +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/setup.cfg +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/setup.py +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/templates/alibuild_to_please.jnj +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/tests/test_analytics.py +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/tests/test_args.py +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/tests/test_build.py +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/tests/test_clean.py +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/tests/test_cmd.py +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/tests/test_git.py +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/tests/test_hashing.py +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/tests/test_log.py +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/tests/test_parseRecipe.py +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/tests/test_sync.py +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/tests/test_workarea.py +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/tests/testdist/broken1.sh +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/tests/testdist/broken2.sh +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/tests/testdist/broken3.sh +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/tests/testdist/broken4.sh +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/tests/testdist/broken5.sh +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/tests/testdist/broken6.sh +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/tests/testdist/broken7.sh +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/tests/testdist/clobber-initdotsh.sh +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/tests/testdist/defaults-o2.sh +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/tests/testdist/delete-etc.sh +0 -0
- {alibuild-1.17.14 → alibuild-1.17.15}/tox.ini +0 -0
|
@@ -12,6 +12,7 @@ import platform
|
|
|
12
12
|
from datetime import datetime
|
|
13
13
|
from collections import OrderedDict
|
|
14
14
|
from shlex import quote
|
|
15
|
+
from typing import Optional
|
|
15
16
|
|
|
16
17
|
from alibuild_helpers.cmd import getoutput
|
|
17
18
|
from alibuild_helpers.git import git
|
|
@@ -261,21 +262,29 @@ def detectArch():
|
|
|
261
262
|
except:
|
|
262
263
|
return doDetectArch(hasOsRelease, osReleaseLines, ["unknown", "", ""], "", "")
|
|
263
264
|
|
|
264
|
-
def
|
|
265
|
+
def filterByArchitectureDefaults(arch, defaults, requires):
|
|
265
266
|
for r in requires:
|
|
266
267
|
require, matcher = ":" in r and r.split(":", 1) or (r, ".*")
|
|
268
|
+
if matcher.startswith("defaults="):
|
|
269
|
+
wanted = matcher[len("defaults="):]
|
|
270
|
+
if re.match(wanted, defaults):
|
|
271
|
+
yield require
|
|
267
272
|
if re.match(matcher, arch):
|
|
268
273
|
yield require
|
|
269
274
|
|
|
270
|
-
def
|
|
275
|
+
def disabledByArchitectureDefaults(arch, defaults, requires):
|
|
271
276
|
for r in requires:
|
|
272
277
|
require, matcher = ":" in r and r.split(":", 1) or (r, ".*")
|
|
273
|
-
if
|
|
278
|
+
if matcher.startswith("defaults="):
|
|
279
|
+
wanted = matcher[len("defaults="):]
|
|
280
|
+
if not re.match(wanted, defaults):
|
|
281
|
+
yield require
|
|
282
|
+
elif not re.match(matcher, arch):
|
|
274
283
|
yield require
|
|
275
284
|
|
|
276
285
|
def readDefaults(configDir, defaults, error, architecture):
|
|
277
|
-
defaultsFilename =
|
|
278
|
-
if not
|
|
286
|
+
defaultsFilename = resolveDefaultsFilename(defaults, configDir)
|
|
287
|
+
if not defaultsFilename:
|
|
279
288
|
error("Default `%s' does not exists. Viable options:\n%s" %
|
|
280
289
|
(defaults or "<no defaults specified>",
|
|
281
290
|
"\n".join("- " + basename(x).replace("defaults-", "").replace(".sh", "")
|
|
@@ -297,7 +306,7 @@ def readDefaults(configDir, defaults, error, architecture):
|
|
|
297
306
|
defaultsBody += "\n# Architecture defaults\n" + archBody
|
|
298
307
|
return (defaultsMeta, defaultsBody)
|
|
299
308
|
|
|
300
|
-
|
|
309
|
+
|
|
301
310
|
def getRecipeReader(url, dist=None):
|
|
302
311
|
m = re.search(r'^dist:(.*)@([^@]+)$', url)
|
|
303
312
|
if m and dist:
|
|
@@ -398,9 +407,30 @@ def parseDefaults(disable, defaultsGetter, log):
|
|
|
398
407
|
overrides[f] = dict(**(v or {}))
|
|
399
408
|
return (None, overrides, taps)
|
|
400
409
|
|
|
410
|
+
def checkForFilename(taps: dict, pkg: str, d: str):
|
|
411
|
+
return taps.get(pkg, join(d, f"{pkg}.sh"))
|
|
412
|
+
|
|
413
|
+
def getPkgDirs(configDir):
|
|
414
|
+
configPath = os.environ.get("BITS_PATH", "").rstrip(":") + ":"
|
|
415
|
+
pkgDirs = [join(configDir, d) for d in configPath.lstrip(":").split(":")]
|
|
416
|
+
return pkgDirs
|
|
417
|
+
|
|
418
|
+
def resolveFilename(taps: dict, pkg: str, configDir: str):
|
|
419
|
+
for d in getPkgDirs(configDir):
|
|
420
|
+
filename = checkForFilename(taps, pkg, d)
|
|
421
|
+
if os.path.exists(filename):
|
|
422
|
+
return (filename, os.path.abspath(d))
|
|
423
|
+
return (None, None)
|
|
424
|
+
|
|
425
|
+
def resolveDefaultsFilename(defaults, configDir) -> Optional[str]:
|
|
426
|
+
for d in getPkgDirs(configDir):
|
|
427
|
+
filename = join(d, f"defaults-{defaults}.sh")
|
|
428
|
+
if os.path.exists(filename):
|
|
429
|
+
return filename
|
|
430
|
+
|
|
401
431
|
def getPackageList(packages, specs, configDir, preferSystem, noSystem,
|
|
402
432
|
architecture, disable, defaults, performPreferCheck, performRequirementCheck,
|
|
403
|
-
performValidateDefaults, overrides, taps, log, force_rebuild=()):
|
|
433
|
+
performValidateDefaults, overrides, taps: dict, log, force_rebuild=()):
|
|
404
434
|
systemPackages = set()
|
|
405
435
|
ownPackages = set()
|
|
406
436
|
failedRequirements = set()
|
|
@@ -421,7 +451,9 @@ def getPackageList(packages, specs, configDir, preferSystem, noSystem,
|
|
|
421
451
|
# "defaults-release" for this to work, since the defaults are a dependency
|
|
422
452
|
# and all dependencies' names go into a package's hash.
|
|
423
453
|
pkg_filename = ("defaults-" + defaults) if p == "defaults-release" else p.lower()
|
|
424
|
-
|
|
454
|
+
|
|
455
|
+
filename, pkgdir = resolveFilename(taps, pkg_filename, configDir)
|
|
456
|
+
|
|
425
457
|
err, spec, recipe = parseRecipe(getRecipeReader(filename, configDir))
|
|
426
458
|
dieOnError(err, err)
|
|
427
459
|
# Unless there was an error, both spec and recipe should be valid.
|
|
@@ -430,6 +462,7 @@ def getPackageList(packages, specs, configDir, preferSystem, noSystem,
|
|
|
430
462
|
assert(recipe is not None)
|
|
431
463
|
dieOnError(spec["package"].lower() != pkg_filename,
|
|
432
464
|
"%s.sh has different package field: %s" % (p, spec["package"]))
|
|
465
|
+
spec["pkgdir"] = pkgdir
|
|
433
466
|
|
|
434
467
|
if p == "defaults-release":
|
|
435
468
|
# Re-rewrite the defaults' name to "defaults-release". Everything auto-
|
|
@@ -543,10 +576,10 @@ def getPackageList(packages, specs, configDir, preferSystem, noSystem,
|
|
|
543
576
|
validDefaults = None # no valid default works for all current packages
|
|
544
577
|
|
|
545
578
|
# For the moment we treat build_requires just as requires.
|
|
546
|
-
fn = lambda what:
|
|
579
|
+
fn = lambda what: disabledByArchitectureDefaults(architecture, defaults, spec.get(what, []))
|
|
547
580
|
spec["disabled"] += [x for x in fn("requires")]
|
|
548
581
|
spec["disabled"] += [x for x in fn("build_requires")]
|
|
549
|
-
fn = lambda what:
|
|
582
|
+
fn = lambda what: filterByArchitectureDefaults(architecture, defaults, spec.get(what, []))
|
|
550
583
|
spec["requires"] = [x for x in fn("requires") if not x in disable]
|
|
551
584
|
spec["build_requires"] = [x for x in fn("build_requires") if not x in disable]
|
|
552
585
|
if spec["package"] != "defaults-release":
|
|
@@ -130,7 +130,10 @@ The following entries are optional in the header:
|
|
|
130
130
|
|
|
131
131
|
The specified dependencies will be built before building the given package.
|
|
132
132
|
You can specify platform-specific dependencies by appending `:<regexp>` to
|
|
133
|
-
the dependency name.
|
|
133
|
+
the dependency name. Similarly, you can specify build default specific dependencies
|
|
134
|
+
by appending `:defaults=<regex>`.
|
|
135
|
+
|
|
136
|
+
Such a regular expression will be matched against the
|
|
134
137
|
architecture provided via `--architecture`, and if it does not match, the
|
|
135
138
|
requirement will not be included. For instance:
|
|
136
139
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from unittest.mock import patch, MagicMock
|
|
2
2
|
from io import StringIO
|
|
3
|
+
import os.path
|
|
3
4
|
|
|
4
5
|
from alibuild_helpers.deps import doDeps
|
|
5
6
|
from argparse import Namespace
|
|
@@ -64,12 +65,14 @@ class DepsTestCase(unittest.TestCase):
|
|
|
64
65
|
outgraph="/tmp/outgraph.pdf",
|
|
65
66
|
package="AliRoot",
|
|
66
67
|
defaults="release")
|
|
68
|
+
def fake_exists(n):
|
|
69
|
+
return {"/alidist/aliroot.sh": True}
|
|
70
|
+
with patch.object(os.path, "exists", fake_exists):
|
|
71
|
+
doDeps(args, MagicMock())
|
|
67
72
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
args.outdot = None
|
|
72
|
-
doDeps(args, MagicMock())
|
|
73
|
+
# Same check without explicit intermediate dotfile
|
|
74
|
+
args.outdot = None
|
|
75
|
+
doDeps(args, MagicMock())
|
|
73
76
|
|
|
74
77
|
|
|
75
78
|
if __name__ == '__main__':
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from __future__ import print_function
|
|
2
2
|
from unittest.mock import patch, MagicMock
|
|
3
3
|
from io import StringIO
|
|
4
|
+
import os.path
|
|
4
5
|
|
|
5
6
|
from alibuild_helpers.doctor import doDoctor
|
|
6
7
|
from argparse import Namespace
|
|
@@ -84,42 +85,45 @@ class DoctorTestCase(unittest.TestCase):
|
|
|
84
85
|
disable=[],
|
|
85
86
|
defaults="release")
|
|
86
87
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
88
|
+
def fake_exists(n):
|
|
89
|
+
return {"/alidist/aliroot.sh": True}
|
|
90
|
+
with patch.object(os.path, "exists", fake_exists):
|
|
91
|
+
# What to call (longer names deprecated in Python 3.5+)
|
|
92
|
+
if not hasattr(self, "assertRegex"):
|
|
93
|
+
self.assertRegex = self.assertRegexpMatches
|
|
94
|
+
self.assertNotRegex = self.assertNotRegexpMatches
|
|
95
|
+
|
|
96
|
+
# Test: all should go OK (exit with 0)
|
|
97
|
+
out = resetOut()
|
|
98
|
+
with self.assertRaises(SystemExit) as cm:
|
|
99
|
+
args.packages=["Package1"]
|
|
100
|
+
doDoctor(args, MagicMock())
|
|
101
|
+
self.assertEqual(cm.exception.code, 0)
|
|
102
|
+
|
|
103
|
+
# Test: system dependency not found
|
|
104
|
+
out = resetOut()
|
|
105
|
+
with self.assertRaises(SystemExit) as cm:
|
|
106
|
+
args.packages=["SysDep"]
|
|
107
|
+
doDoctor(args, MagicMock())
|
|
108
|
+
self.assertEqual(cm.exception.code, 1)
|
|
109
|
+
|
|
110
|
+
# Test: invalid default
|
|
111
|
+
out = resetOut()
|
|
112
|
+
with self.assertRaises(SystemExit) as cm:
|
|
113
|
+
args.packages=["BreakDefaults"]
|
|
114
|
+
doDoctor(args, MagicMock())
|
|
115
|
+
self.assertEqual(cm.exception.code, 2)
|
|
116
|
+
self.assertRegex(out["error"].getvalue(), "- its_not_there")
|
|
117
|
+
|
|
118
|
+
# Test: common defaults
|
|
119
|
+
out = resetOut()
|
|
120
|
+
with self.assertRaises(SystemExit) as cm:
|
|
121
|
+
args.packages=["TestDef1"]
|
|
122
|
+
doDoctor(args, MagicMock())
|
|
123
|
+
self.assertEqual(cm.exception.code, 2)
|
|
124
|
+
self.assertRegex(out["banner"].getvalue(), "- common_default")
|
|
125
|
+
self.assertNotRegex(out["banner"].getvalue(), "- default1")
|
|
126
|
+
self.assertNotRegex(out["banner"].getvalue(), "- default2")
|
|
123
127
|
|
|
124
128
|
if __name__ == '__main__':
|
|
125
129
|
unittest.main()
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from argparse import Namespace
|
|
2
2
|
import os.path as path
|
|
3
|
+
import os.path
|
|
3
4
|
import unittest
|
|
4
5
|
from unittest.mock import call, patch # In Python 3, mock is built-in
|
|
5
6
|
from io import StringIO
|
|
@@ -82,17 +83,20 @@ class InitTestCase(unittest.TestCase):
|
|
|
82
83
|
fetchRepos = False,
|
|
83
84
|
architecture = "slc7_x86-64"
|
|
84
85
|
)
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
86
|
+
def fake_exists(n):
|
|
87
|
+
return {"/alidist/aliroot.sh": True}
|
|
88
|
+
with patch.object(os.path, "exists", fake_exists):
|
|
89
|
+
doInit(args)
|
|
90
|
+
self.assertEqual(mock_git.mock_calls, CLONE_EVERYTHING)
|
|
91
|
+
mock_path.exists.assert_has_calls([call('.'), call('/sw/MIRROR'), call('/alidist'), call('./AliRoot')])
|
|
88
92
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
93
|
+
# Force fetch repos
|
|
94
|
+
mock_git.reset_mock()
|
|
95
|
+
mock_path.reset_mock()
|
|
96
|
+
args.fetchRepos = True
|
|
97
|
+
doInit(args)
|
|
98
|
+
self.assertEqual(mock_git.mock_calls, CLONE_EVERYTHING)
|
|
99
|
+
mock_path.exists.assert_has_calls([call('.'), call('/sw/MIRROR'), call('/alidist'), call('./AliRoot')])
|
|
96
100
|
|
|
97
101
|
|
|
98
102
|
if __name__ == '__main__':
|
|
@@ -2,6 +2,8 @@ from __future__ import print_function
|
|
|
2
2
|
from textwrap import dedent
|
|
3
3
|
import unittest
|
|
4
4
|
from unittest import mock
|
|
5
|
+
from unittest.mock import patch
|
|
6
|
+
import os.path
|
|
5
7
|
|
|
6
8
|
from alibuild_helpers.cmd import getstatusoutput
|
|
7
9
|
from alibuild_helpers.utilities import getPackageList
|
|
@@ -71,7 +73,7 @@ RECIPES = {
|
|
|
71
73
|
|
|
72
74
|
|
|
73
75
|
class MockReader:
|
|
74
|
-
def __init__(self, url, dist=None):
|
|
76
|
+
def __init__(self, url: str, dist=None):
|
|
75
77
|
self._contents = RECIPES[url]
|
|
76
78
|
self.url = "mock://" + url
|
|
77
79
|
|
|
@@ -79,6 +81,7 @@ class MockReader:
|
|
|
79
81
|
return self._contents
|
|
80
82
|
|
|
81
83
|
|
|
84
|
+
|
|
82
85
|
def getPackageListWithDefaults(packages, force_rebuild=()):
|
|
83
86
|
specs = {} # getPackageList will mutate this
|
|
84
87
|
return_values = getPackageList(
|
|
@@ -115,11 +118,14 @@ class ReplacementTestCase(unittest.TestCase):
|
|
|
115
118
|
This is was the only available behaviour in previous aliBuild versions
|
|
116
119
|
and must be preserved for backward compatibility.
|
|
117
120
|
"""
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
121
|
+
def fake_exists(n):
|
|
122
|
+
return n in RECIPES.keys()
|
|
123
|
+
with patch.object(os.path, "exists", fake_exists):
|
|
124
|
+
specs, systemPkgs, ownPkgs, failedReqs, validDefaults = \
|
|
125
|
+
getPackageListWithDefaults(["disable"])
|
|
126
|
+
self.assertIn("disable", systemPkgs)
|
|
127
|
+
self.assertNotIn("disable", ownPkgs)
|
|
128
|
+
self.assertNotIn("disable", specs)
|
|
123
129
|
|
|
124
130
|
def test_replacement_given(self):
|
|
125
131
|
"""Check that specifying a replacement spec means it is used.
|
|
@@ -127,16 +133,19 @@ class ReplacementTestCase(unittest.TestCase):
|
|
|
127
133
|
This also checks that if no recipe is given, we report the package as
|
|
128
134
|
a system package to the user.
|
|
129
135
|
"""
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
136
|
+
def fake_exists(n):
|
|
137
|
+
return n in RECIPES.keys()
|
|
138
|
+
with patch.object(os.path, "exists", fake_exists):
|
|
139
|
+
specs, systemPkgs, ownPkgs, failedReqs, validDefaults = \
|
|
140
|
+
getPackageListWithDefaults(["with-replacement"])
|
|
141
|
+
self.assertIn("with-replacement", specs)
|
|
142
|
+
self.assertEqual(specs["with-replacement"]["env"]["SENTINEL_VAR"], "magic")
|
|
143
|
+
# Make sure nothing is run by default.
|
|
144
|
+
self.assertEqual(specs["with-replacement"]["recipe"], "")
|
|
145
|
+
# If the replacement spec has no recipe, report to the user that we're
|
|
146
|
+
# taking the package from the system.
|
|
147
|
+
self.assertIn("with-replacement", systemPkgs)
|
|
148
|
+
self.assertNotIn("with-replacement", ownPkgs)
|
|
140
149
|
|
|
141
150
|
def test_replacement_recipe_given(self):
|
|
142
151
|
"""Check that specifying a replacement recipe means it is used.
|
|
@@ -144,29 +153,35 @@ class ReplacementTestCase(unittest.TestCase):
|
|
|
144
153
|
Also check that we report to the user that a package will be compiled
|
|
145
154
|
when a replacement recipe is given.
|
|
146
155
|
"""
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
+
def fake_exists(n):
|
|
157
|
+
return n in RECIPES.keys()
|
|
158
|
+
with patch.object(os.path, "exists", fake_exists):
|
|
159
|
+
specs, systemPkgs, ownPkgs, failedReqs, validDefaults = \
|
|
160
|
+
getPackageListWithDefaults(["with-replacement-recipe"])
|
|
161
|
+
self.assertIn("with-replacement-recipe", specs)
|
|
162
|
+
self.assertIn("recipe", specs["with-replacement-recipe"])
|
|
163
|
+
self.assertEqual("true", specs["with-replacement-recipe"]["recipe"])
|
|
164
|
+
# If the replacement spec has a recipe, report to the user that we're
|
|
165
|
+
# compiling the package.
|
|
166
|
+
self.assertNotIn("with-replacement-recipe", systemPkgs)
|
|
167
|
+
self.assertIn("with-replacement-recipe", ownPkgs)
|
|
156
168
|
|
|
157
169
|
@mock.patch("alibuild_helpers.utilities.warning")
|
|
158
170
|
def test_missing_replacement_spec(self, mock_warning):
|
|
159
171
|
"""Check a warning is displayed when the replacement spec is not found."""
|
|
160
172
|
warning_msg = "falling back to building the package ourselves"
|
|
161
173
|
warning_exists = False
|
|
162
|
-
def
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
174
|
+
def fake_exists(n):
|
|
175
|
+
return n in RECIPES.keys()
|
|
176
|
+
with patch.object(os.path, "exists", fake_exists):
|
|
177
|
+
def side_effect(msg, *args, **kwargs):
|
|
178
|
+
nonlocal warning_exists
|
|
179
|
+
if warning_msg in str(msg):
|
|
180
|
+
warning_exists = True
|
|
181
|
+
mock_warning.side_effect = side_effect
|
|
182
|
+
specs, systemPkgs, ownPkgs, failedReqs, validDefaults = \
|
|
183
|
+
getPackageListWithDefaults(["missing-spec"])
|
|
184
|
+
self.assertTrue(warning_exists)
|
|
170
185
|
|
|
171
186
|
|
|
172
187
|
|
|
@@ -176,17 +191,23 @@ class ForceRebuildTestCase(unittest.TestCase):
|
|
|
176
191
|
|
|
177
192
|
def test_force_rebuild_recipe(self):
|
|
178
193
|
"""If the recipe specifies force_rebuild, it must be applied."""
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
194
|
+
def fake_exists(n):
|
|
195
|
+
return n in RECIPES.keys()
|
|
196
|
+
with patch.object(os.path, "exists", fake_exists):
|
|
197
|
+
specs, _, _, _, _ = getPackageListWithDefaults(["force-rebuild"])
|
|
198
|
+
self.assertTrue(specs["force-rebuild"]["force_rebuild"])
|
|
199
|
+
self.assertFalse(specs["defaults-release"]["force_rebuild"])
|
|
182
200
|
|
|
183
201
|
def test_force_rebuild_command_line(self):
|
|
184
202
|
"""The --force-rebuild option must take precedence, if given."""
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
)
|
|
188
|
-
|
|
189
|
-
|
|
203
|
+
def fake_exists(n):
|
|
204
|
+
return n in RECIPES.keys()
|
|
205
|
+
with patch.object(os.path, "exists", fake_exists):
|
|
206
|
+
specs, _, _, _, _ = getPackageListWithDefaults(
|
|
207
|
+
["force-rebuild"], force_rebuild=["defaults-release", "force-rebuild"],
|
|
208
|
+
)
|
|
209
|
+
self.assertTrue(specs["force-rebuild"]["force_rebuild"])
|
|
210
|
+
self.assertTrue(specs["defaults-release"]["force_rebuild"])
|
|
190
211
|
|
|
191
212
|
|
|
192
213
|
if __name__ == '__main__':
|
|
@@ -5,12 +5,13 @@ import unittest
|
|
|
5
5
|
# Assuming you are using the mock library to ... mock things
|
|
6
6
|
from unittest.mock import patch
|
|
7
7
|
|
|
8
|
-
from alibuild_helpers.utilities import doDetectArch,
|
|
8
|
+
from alibuild_helpers.utilities import doDetectArch, filterByArchitectureDefaults, disabledByArchitectureDefaults, getPkgDirs
|
|
9
9
|
from alibuild_helpers.utilities import Hasher
|
|
10
10
|
from alibuild_helpers.utilities import asList
|
|
11
11
|
from alibuild_helpers.utilities import prunePaths
|
|
12
12
|
from alibuild_helpers.utilities import resolve_version
|
|
13
13
|
from alibuild_helpers.utilities import topological_sort
|
|
14
|
+
from alibuild_helpers.utilities import resolveFilename, resolveDefaultsFilename
|
|
14
15
|
import os
|
|
15
16
|
import string
|
|
16
17
|
|
|
@@ -175,12 +176,24 @@ class TestUtilities(unittest.TestCase):
|
|
|
175
176
|
self.assertEqual(asList(None), [None])
|
|
176
177
|
|
|
177
178
|
def test_filterByArchitecture(self):
|
|
178
|
-
self.assertEqual(["AliRoot"], list(
|
|
179
|
-
self.assertEqual([], list(
|
|
180
|
-
self.assertEqual(["GCC"], list(
|
|
181
|
-
self.assertEqual(["AliRoot", "GCC"], list(
|
|
182
|
-
self.assertEqual(["GCC"], list(
|
|
183
|
-
self.assertEqual([], list(
|
|
179
|
+
self.assertEqual(["AliRoot"], list(filterByArchitectureDefaults("osx_x86-64", "ali", ["AliRoot"])))
|
|
180
|
+
self.assertEqual([], list(filterByArchitectureDefaults("osx_x86-64", "ali", ["AliRoot:(?!osx)"])))
|
|
181
|
+
self.assertEqual(["GCC"], list(filterByArchitectureDefaults("osx_x86-64", "ali", ["AliRoot:(?!osx)", "GCC"])))
|
|
182
|
+
self.assertEqual(["AliRoot", "GCC"], list(filterByArchitectureDefaults("osx_x86-64", "ali", ["AliRoot:(?!slc6)", "GCC"])))
|
|
183
|
+
self.assertEqual(["GCC"], list(filterByArchitectureDefaults("osx_x86-64", "ali", ["AliRoot:slc6", "GCC:osx"])))
|
|
184
|
+
self.assertEqual([], list(filterByArchitectureDefaults("osx_x86-64", "ali", [])))
|
|
185
|
+
self.assertEqual(["GCC"], list(filterByArchitectureDefaults("osx_x86-64", "ali", ["AliRoot:slc6", "GCC:defaults=ali"])))
|
|
186
|
+
self.assertEqual([], list(filterByArchitectureDefaults("osx_x86-64", "o2", ["AliRoot:slc6", "GCC:defaults=ali"])))
|
|
187
|
+
|
|
188
|
+
def test_disabledByArchitecture(self):
|
|
189
|
+
self.assertEqual([], list(disabledByArchitectureDefaults("osx_x86-64", "ali", ["AliRoot"])))
|
|
190
|
+
self.assertEqual(["AliRoot"], list(disabledByArchitectureDefaults("osx_x86-64", "ali", ["AliRoot:(?!osx)"])))
|
|
191
|
+
self.assertEqual(["AliRoot"], list(disabledByArchitectureDefaults("osx_x86-64", "ali", ["AliRoot:(?!osx)", "GCC"])))
|
|
192
|
+
self.assertEqual([], list(disabledByArchitectureDefaults("osx_x86-64", "ali", ["AliRoot:(?!slc6)", "GCC"])))
|
|
193
|
+
self.assertEqual(["AliRoot"], list(disabledByArchitectureDefaults("osx_x86-64", "ali", ["AliRoot:slc6", "GCC:osx"])))
|
|
194
|
+
self.assertEqual([], list(disabledByArchitectureDefaults("osx_x86-64", "ali", [])))
|
|
195
|
+
self.assertEqual(["AliRoot"], list(disabledByArchitectureDefaults("osx_x86-64", "ali", ["AliRoot:slc6", "GCC:defaults=ali"])))
|
|
196
|
+
self.assertEqual(["AliRoot", "GCC"], list(disabledByArchitectureDefaults("osx_x86-64", "o2", ["AliRoot:slc6", "GCC:defaults=ali"])))
|
|
184
197
|
|
|
185
198
|
def test_prunePaths(self):
|
|
186
199
|
fake_env = {
|
|
@@ -227,6 +240,77 @@ class TestUtilities(unittest.TestCase):
|
|
|
227
240
|
spec["version"] = "NO%(defaults_upper)s"
|
|
228
241
|
self.assertTrue(resolve_version(spec, "release", "stream/v1", "v1"), "NO")
|
|
229
242
|
|
|
243
|
+
def test_get_pkg_dirs(self):
|
|
244
|
+
self.assertEqual(getPkgDirs("alidist"), ["alidist/"])
|
|
245
|
+
with patch.object(os, "environ", {"BITS_PATH": ""}):
|
|
246
|
+
self.assertEqual(getPkgDirs("alidist"), ["alidist/"])
|
|
247
|
+
with patch.object(os, "environ", {"BITS_PATH": "/foo/bar"}):
|
|
248
|
+
self.assertEqual(getPkgDirs("alidist"), ["/foo/bar", "alidist/"])
|
|
249
|
+
with patch.object(os, "environ", {"BITS_PATH": "/foo/bar:"}):
|
|
250
|
+
self.assertEqual(getPkgDirs("alidist"), ["/foo/bar", "alidist/"])
|
|
251
|
+
with patch.object(os, "environ", {"BITS_PATH": "foo/bar:"}):
|
|
252
|
+
self.assertEqual(getPkgDirs("alidist"), ["alidist/foo/bar", "alidist/"])
|
|
253
|
+
with patch.object(os, "environ", {"BITS_PATH": "foo/bar:/bar"}):
|
|
254
|
+
self.assertEqual(getPkgDirs("alidist"), ["alidist/foo/bar", "/bar", "alidist/"])
|
|
255
|
+
|
|
256
|
+
def test_resolveDefaults(self):
|
|
257
|
+
def fake_exists(n):
|
|
258
|
+
return {"alidist/defaults-release.sh": True,
|
|
259
|
+
"/foo/defaults-o2.sh": True,
|
|
260
|
+
"/bar/defaults-o2.sh": True,
|
|
261
|
+
"alidist/bar/defaults-o2.sh": True
|
|
262
|
+
}.get(n, False)
|
|
263
|
+
|
|
264
|
+
with patch.object(os.path, "exists", fake_exists):
|
|
265
|
+
self.assertEqual(resolveDefaultsFilename("release", "alidist"), "alidist/defaults-release.sh")
|
|
266
|
+
self.assertEqual(resolveDefaultsFilename("release", "alidost"), None)
|
|
267
|
+
self.assertEqual(resolveDefaultsFilename("o2", "alidist"), None)
|
|
268
|
+
with patch.object(os.path, "exists", fake_exists), \
|
|
269
|
+
patch.object(os, "environ", {"BITS_PATH": "/foo"}):
|
|
270
|
+
self.assertEqual(resolveDefaultsFilename("release", "alidist"), "alidist/defaults-release.sh")
|
|
271
|
+
self.assertEqual(resolveDefaultsFilename("release", "alidost"), None)
|
|
272
|
+
self.assertEqual(resolveDefaultsFilename("o2", "alidist"), "/foo/defaults-o2.sh")
|
|
273
|
+
with patch.object(os.path, "exists", fake_exists), \
|
|
274
|
+
patch.object(os, "environ", {"BITS_PATH": "/bar:/foo"}):
|
|
275
|
+
self.assertEqual(resolveDefaultsFilename("release", "alidist"), "alidist/defaults-release.sh")
|
|
276
|
+
self.assertEqual(resolveDefaultsFilename("release", "alidost"), None)
|
|
277
|
+
self.assertEqual(resolveDefaultsFilename("o2", "alidist"), "/bar/defaults-o2.sh")
|
|
278
|
+
with patch.object(os.path, "exists", fake_exists), \
|
|
279
|
+
patch.object(os, "environ", {"BITS_PATH": "bar:/foo"}):
|
|
280
|
+
self.assertEqual(resolveDefaultsFilename("release", "alidist"), "alidist/defaults-release.sh")
|
|
281
|
+
self.assertEqual(resolveDefaultsFilename("release", "alidost"), None)
|
|
282
|
+
self.assertEqual(resolveDefaultsFilename("o2", "alidist"), "alidist/bar/defaults-o2.sh")
|
|
283
|
+
|
|
284
|
+
def test_resolveFilename(self):
|
|
285
|
+
def fake_exists(n):
|
|
286
|
+
return {
|
|
287
|
+
"alidist/defaults-release.sh": True,
|
|
288
|
+
"alidist/zlib.sh": True,
|
|
289
|
+
"/foo/defaults-o2.sh": True,
|
|
290
|
+
"/bar/defaults-o2.sh": True,
|
|
291
|
+
"alidist/bar/defaults-o2.sh": True,
|
|
292
|
+
"/bar/python.sh": True
|
|
293
|
+
}.get(n, False)
|
|
294
|
+
|
|
295
|
+
def fake_abspath(n):
|
|
296
|
+
return os.path.join("/fake/", n)
|
|
297
|
+
|
|
298
|
+
with patch.object(os.path, "exists", fake_exists), \
|
|
299
|
+
patch.object(os.path, "abspath", fake_abspath):
|
|
300
|
+
self.assertEqual(resolveFilename({}, "zlib", "alidist"), ("alidist/zlib.sh", "/fake/alidist/"))
|
|
301
|
+
|
|
302
|
+
with patch.object(os.path, "exists", fake_exists), \
|
|
303
|
+
patch.object(os.path, "abspath", fake_abspath), \
|
|
304
|
+
patch.object(os, "environ", {"BITS_PATH": "/foo"}):
|
|
305
|
+
self.assertEqual(resolveFilename({}, "zlib", "alidist"), ("alidist/zlib.sh", "/fake/alidist/"))
|
|
306
|
+
|
|
307
|
+
with patch.object(os.path, "exists", fake_exists), \
|
|
308
|
+
patch.object(os.path, "abspath", fake_abspath), \
|
|
309
|
+
patch.object(os, "environ", {"BITS_PATH": "/bar:/foo"}):
|
|
310
|
+
self.assertEqual(resolveFilename({}, "zlib", "alidist"), ("alidist/zlib.sh", "/fake/alidist/"))
|
|
311
|
+
self.assertEqual(resolveFilename({}, "zlib", "alidost"), (None, None))
|
|
312
|
+
self.assertEqual(resolveFilename({}, "python", "alidist"), ("/bar/python.sh", "/bar"))
|
|
313
|
+
|
|
230
314
|
|
|
231
315
|
class TestTopologicalSort(unittest.TestCase):
|
|
232
316
|
"""Check that various properties of topological sorting hold."""
|
|
@@ -260,6 +344,5 @@ class TestTopologicalSort(unittest.TestCase):
|
|
|
260
344
|
self.assertEqual(frozenset(specs.keys()),
|
|
261
345
|
frozenset(topological_sort(specs)))
|
|
262
346
|
|
|
263
|
-
|
|
264
347
|
if __name__ == '__main__':
|
|
265
348
|
unittest.main()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|