Fix formatting.
This commit is contained in:
parent
3fe7cb2a7e
commit
43dfe81f66
17 changed files with 1085 additions and 854 deletions
5
.flake8
Normal file
5
.flake8
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
[flake8]
|
||||||
|
extend-ignore = E203, E266, E501, W293, W291
|
||||||
|
max-line-length = 88
|
||||||
|
max-complexity = 18
|
||||||
|
select = B,C,E,F,W,T4,B9
|
|
@ -21,11 +21,10 @@ import stat
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
|
||||||
DEFAULT_PYTHON = 'python3'
|
DEFAULT_PYTHON = "python3"
|
||||||
|
|
||||||
|
|
||||||
class DetailedFailure(Exception):
|
class DetailedFailure(Exception):
|
||||||
|
|
||||||
def __init__(self, retcode, argv, error):
|
def __init__(self, retcode, argv, error):
|
||||||
self.retcode = retcode
|
self.retcode = retcode
|
||||||
self.argv = argv
|
self.argv = argv
|
||||||
|
@ -35,19 +34,19 @@ class DetailedFailure(Exception):
|
||||||
def shebang_binary(p):
|
def shebang_binary(p):
|
||||||
if not (os.stat(p).st_mode & stat.S_IEXEC):
|
if not (os.stat(p).st_mode & stat.S_IEXEC):
|
||||||
return None
|
return None
|
||||||
with open(p, 'rb') as f:
|
with open(p, "rb") as f:
|
||||||
firstline = f.readline()
|
firstline = f.readline()
|
||||||
if not firstline.startswith(b'#!'):
|
if not firstline.startswith(b"#!"):
|
||||||
return None
|
return None
|
||||||
args = firstline[2:].split(b' ')
|
args = firstline[2:].split(b" ")
|
||||||
if args[0] in (b'/usr/bin/env', b'env'):
|
if args[0] in (b"/usr/bin/env", b"env"):
|
||||||
return os.path.basename(args[1].decode()).strip()
|
return os.path.basename(args[1].decode()).strip()
|
||||||
return os.path.basename(args[0].decode()).strip()
|
return os.path.basename(args[0].decode()).strip()
|
||||||
|
|
||||||
|
|
||||||
def note(m):
|
def note(m):
|
||||||
sys.stdout.write('%s\n' % m)
|
sys.stdout.write("%s\n" % m)
|
||||||
|
|
||||||
|
|
||||||
def warning(m):
|
def warning(m):
|
||||||
sys.stderr.write('WARNING: %s\n' % m)
|
sys.stderr.write("WARNING: %s\n" % m)
|
||||||
|
|
|
@ -28,40 +28,44 @@ from .test import run_test
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'subcommand', type=str,
|
"subcommand", type=str, choices=["dist", "build", "clean", "test", "install"]
|
||||||
choices=['dist', 'build', 'clean', 'test', 'install'])
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--directory', '-d', type=str, help='Directory for project.',
|
"--directory", "-d", type=str, help="Directory for project.", default="."
|
||||||
default='.')
|
)
|
||||||
|
parser.add_argument("--schroot", type=str, help="schroot to run in.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--schroot', type=str, help='schroot to run in.')
|
"--resolve",
|
||||||
parser.add_argument(
|
choices=["explain", "apt", "native"],
|
||||||
'--resolve', choices=['explain', 'apt', 'native'],
|
help="What to do about missing dependencies",
|
||||||
help='What to do about missing dependencies')
|
)
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
if args.schroot:
|
if args.schroot:
|
||||||
from .session.schroot import SchrootSession
|
from .session.schroot import SchrootSession
|
||||||
|
|
||||||
session = SchrootSession(args.schroot)
|
session = SchrootSession(args.schroot)
|
||||||
else:
|
else:
|
||||||
from .session.plain import PlainSession
|
from .session.plain import PlainSession
|
||||||
|
|
||||||
session = PlainSession()
|
session = PlainSession()
|
||||||
with session:
|
with session:
|
||||||
os.chdir(args.directory)
|
os.chdir(args.directory)
|
||||||
try:
|
try:
|
||||||
if args.subcommand == 'dist':
|
if args.subcommand == "dist":
|
||||||
run_dist(session)
|
run_dist(session)
|
||||||
if args.subcommand == 'build':
|
if args.subcommand == "build":
|
||||||
run_build(session)
|
run_build(session)
|
||||||
if args.subcommand == 'clean':
|
if args.subcommand == "clean":
|
||||||
run_clean(session)
|
run_clean(session)
|
||||||
if args.subcommand == 'install':
|
if args.subcommand == "install":
|
||||||
run_install(session)
|
run_install(session)
|
||||||
if args.subcommand == 'test':
|
if args.subcommand == "test":
|
||||||
run_test(session)
|
run_test(session)
|
||||||
except NoBuildToolsFound:
|
except NoBuildToolsFound:
|
||||||
note('No build tools found.')
|
note("No build tools found.")
|
||||||
return 1
|
return 1
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,6 @@ from .session import Session, run_with_tee
|
||||||
|
|
||||||
|
|
||||||
class UnidentifiedError(Exception):
|
class UnidentifiedError(Exception):
|
||||||
|
|
||||||
def __init__(self, retcode, argv, lines, secondary=None):
|
def __init__(self, retcode, argv, lines, secondary=None):
|
||||||
self.retcode = retcode
|
self.retcode = retcode
|
||||||
self.argv = argv
|
self.argv = argv
|
||||||
|
@ -40,17 +39,16 @@ class UnidentifiedError(Exception):
|
||||||
|
|
||||||
def run_apt(session: Session, args: List[str]) -> None:
|
def run_apt(session: Session, args: List[str]) -> None:
|
||||||
"""Run apt."""
|
"""Run apt."""
|
||||||
args = ['apt', '-y'] + args
|
args = ["apt", "-y"] + args
|
||||||
retcode, lines = run_with_tee(session, args, cwd='/', user='root')
|
retcode, lines = run_with_tee(session, args, cwd="/", user="root")
|
||||||
if retcode == 0:
|
if retcode == 0:
|
||||||
return
|
return
|
||||||
offset, line, error = find_apt_get_failure(lines)
|
offset, line, error = find_apt_get_failure(lines)
|
||||||
if error is not None:
|
if error is not None:
|
||||||
raise DetailedFailure(retcode, args, error)
|
raise DetailedFailure(retcode, args, error)
|
||||||
if line is not None:
|
if line is not None:
|
||||||
raise UnidentifiedError(
|
raise UnidentifiedError(retcode, args, lines, secondary=(offset, line))
|
||||||
retcode, args, lines, secondary=(offset, line))
|
while lines and lines[-1] == "":
|
||||||
while lines and lines[-1] == '':
|
|
||||||
lines.pop(-1)
|
lines.pop(-1)
|
||||||
raise UnidentifiedError(retcode, args, lines)
|
raise UnidentifiedError(retcode, args, lines)
|
||||||
|
|
||||||
|
@ -63,23 +61,23 @@ class AptManager(object):
|
||||||
self.session = session
|
self.session = session
|
||||||
|
|
||||||
def missing(self, packages):
|
def missing(self, packages):
|
||||||
root = getattr(self.session, 'location', '/')
|
root = getattr(self.session, "location", "/")
|
||||||
status_path = os.path.join(root, 'var/lib/dpkg/status')
|
status_path = os.path.join(root, "var/lib/dpkg/status")
|
||||||
missing = set(packages)
|
missing = set(packages)
|
||||||
with apt_pkg.TagFile(status_path) as tagf:
|
with apt_pkg.TagFile(status_path) as tagf:
|
||||||
while missing:
|
while missing:
|
||||||
tagf.step()
|
tagf.step()
|
||||||
if not tagf.section:
|
if not tagf.section:
|
||||||
break
|
break
|
||||||
if tagf.section['Package'] in missing:
|
if tagf.section["Package"] in missing:
|
||||||
if tagf.section['Status'] == 'install ok installed':
|
if tagf.section["Status"] == "install ok installed":
|
||||||
missing.remove(tagf.section['Package'])
|
missing.remove(tagf.section["Package"])
|
||||||
return list(missing)
|
return list(missing)
|
||||||
|
|
||||||
def install(self, packages: List[str]) -> None:
|
def install(self, packages: List[str]) -> None:
|
||||||
packages = self.missing(packages)
|
packages = self.missing(packages)
|
||||||
if packages:
|
if packages:
|
||||||
run_apt(self.session, ['install'] + packages)
|
run_apt(self.session, ["install"] + packages)
|
||||||
|
|
||||||
def satisfy(self, deps: List[str]) -> None:
|
def satisfy(self, deps: List[str]) -> None:
|
||||||
run_apt(self.session, ['satisfy'] + deps)
|
run_apt(self.session, ["satisfy"] + deps)
|
||||||
|
|
|
@ -52,22 +52,21 @@ class BuildSystem(object):
|
||||||
|
|
||||||
|
|
||||||
class Pear(BuildSystem):
|
class Pear(BuildSystem):
|
||||||
|
|
||||||
def setup(self):
|
def setup(self):
|
||||||
apt = AptManager(self.session)
|
apt = AptManager(self.session)
|
||||||
apt.install(['php-pear'])
|
apt.install(["php-pear"])
|
||||||
|
|
||||||
def dist(self):
|
def dist(self):
|
||||||
self.setup()
|
self.setup()
|
||||||
run_with_build_fixer(self.session, ['pear', 'package'])
|
run_with_build_fixer(self.session, ["pear", "package"])
|
||||||
|
|
||||||
def test(self):
|
def test(self):
|
||||||
self.setup()
|
self.setup()
|
||||||
run_with_build_fixer(self.session, ['pear', 'run-tests'])
|
run_with_build_fixer(self.session, ["pear", "run-tests"])
|
||||||
|
|
||||||
def build(self):
|
def build(self):
|
||||||
self.setup()
|
self.setup()
|
||||||
run_with_build_fixer(self.session, ['pear', 'build'])
|
run_with_build_fixer(self.session, ["pear", "build"])
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
self.setup()
|
self.setup()
|
||||||
|
@ -75,242 +74,251 @@ class Pear(BuildSystem):
|
||||||
|
|
||||||
def install(self):
|
def install(self):
|
||||||
self.setup()
|
self.setup()
|
||||||
run_with_build_fixer(self.session, ['pear', 'install'])
|
run_with_build_fixer(self.session, ["pear", "install"])
|
||||||
|
|
||||||
|
|
||||||
class SetupPy(BuildSystem):
|
class SetupPy(BuildSystem):
|
||||||
|
|
||||||
def setup(self):
|
def setup(self):
|
||||||
apt = AptManager(self.session)
|
apt = AptManager(self.session)
|
||||||
apt.install(['python3', 'python3-pip'])
|
apt.install(["python3", "python3-pip"])
|
||||||
with open('setup.py', 'r') as f:
|
with open("setup.py", "r") as f:
|
||||||
setup_py_contents = f.read()
|
setup_py_contents = f.read()
|
||||||
try:
|
try:
|
||||||
with open('setup.cfg', 'r') as f:
|
with open("setup.cfg", "r") as f:
|
||||||
setup_cfg_contents = f.read()
|
setup_cfg_contents = f.read()
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
setup_cfg_contents = ''
|
setup_cfg_contents = ""
|
||||||
if 'setuptools' in setup_py_contents:
|
if "setuptools" in setup_py_contents:
|
||||||
logging.info('Reference to setuptools found, installing.')
|
logging.info("Reference to setuptools found, installing.")
|
||||||
apt.install(['python3-setuptools'])
|
apt.install(["python3-setuptools"])
|
||||||
if ('setuptools_scm' in setup_py_contents or
|
if (
|
||||||
'setuptools_scm' in setup_cfg_contents):
|
"setuptools_scm" in setup_py_contents
|
||||||
logging.info('Reference to setuptools-scm found, installing.')
|
or "setuptools_scm" in setup_cfg_contents
|
||||||
apt.install(['python3-setuptools-scm', 'git', 'mercurial'])
|
):
|
||||||
|
logging.info("Reference to setuptools-scm found, installing.")
|
||||||
|
apt.install(["python3-setuptools-scm", "git", "mercurial"])
|
||||||
|
|
||||||
# TODO(jelmer): Install setup_requires
|
# TODO(jelmer): Install setup_requires
|
||||||
|
|
||||||
def test(self):
|
def test(self):
|
||||||
self.setup()
|
self.setup()
|
||||||
self._run_setup(['test'])
|
self._run_setup(["test"])
|
||||||
|
|
||||||
def dist(self):
|
def dist(self):
|
||||||
self.setup()
|
self.setup()
|
||||||
self._run_setup(['sdist'])
|
self._run_setup(["sdist"])
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
self.setup()
|
self.setup()
|
||||||
self._run_setup(['clean'])
|
self._run_setup(["clean"])
|
||||||
|
|
||||||
def install(self):
|
def install(self):
|
||||||
self.setup()
|
self.setup()
|
||||||
self._run_setup(['install'])
|
self._run_setup(["install"])
|
||||||
|
|
||||||
def _run_setup(self, args):
|
def _run_setup(self, args):
|
||||||
apt = AptManager(self.session)
|
apt = AptManager(self.session)
|
||||||
interpreter = shebang_binary('setup.py')
|
interpreter = shebang_binary("setup.py")
|
||||||
if interpreter is not None:
|
if interpreter is not None:
|
||||||
if interpreter == 'python3':
|
if interpreter == "python3":
|
||||||
apt.install(['python3'])
|
apt.install(["python3"])
|
||||||
elif interpreter == 'python2':
|
elif interpreter == "python2":
|
||||||
apt.install(['python2'])
|
apt.install(["python2"])
|
||||||
elif interpreter == 'python':
|
elif interpreter == "python":
|
||||||
apt.install(['python'])
|
apt.install(["python"])
|
||||||
else:
|
else:
|
||||||
raise ValueError('Unknown interpreter %r' % interpreter)
|
raise ValueError("Unknown interpreter %r" % interpreter)
|
||||||
apt.install(['python2', 'python3'])
|
apt.install(["python2", "python3"])
|
||||||
run_with_build_fixer(
|
run_with_build_fixer(self.session, ["./setup.py"] + args)
|
||||||
self.session, ['./setup.py'] + args)
|
|
||||||
else:
|
else:
|
||||||
# Just assume it's Python 3
|
# Just assume it's Python 3
|
||||||
apt.install(['python3'])
|
apt.install(["python3"])
|
||||||
run_with_build_fixer(
|
run_with_build_fixer(self.session, ["python3", "./setup.py"] + args)
|
||||||
self.session, ['python3', './setup.py'] + args)
|
|
||||||
|
|
||||||
|
|
||||||
class PyProject(BuildSystem):
|
class PyProject(BuildSystem):
|
||||||
|
|
||||||
def load_toml(self):
|
def load_toml(self):
|
||||||
import toml
|
import toml
|
||||||
with open('pyproject.toml', 'r') as pf:
|
|
||||||
|
with open("pyproject.toml", "r") as pf:
|
||||||
return toml.load(pf)
|
return toml.load(pf)
|
||||||
|
|
||||||
def dist(self):
|
def dist(self):
|
||||||
apt = AptManager(self.session)
|
apt = AptManager(self.session)
|
||||||
pyproject = self.load_toml()
|
pyproject = self.load_toml()
|
||||||
if 'poetry' in pyproject.get('tool', []):
|
if "poetry" in pyproject.get("tool", []):
|
||||||
logging.info(
|
logging.info(
|
||||||
'Found pyproject.toml with poetry section, '
|
"Found pyproject.toml with poetry section, " "assuming poetry project."
|
||||||
'assuming poetry project.')
|
)
|
||||||
apt.install(['python3-venv', 'python3-pip'])
|
apt.install(["python3-venv", "python3-pip"])
|
||||||
self.session.check_call(['pip3', 'install', 'poetry'], user='root')
|
self.session.check_call(["pip3", "install", "poetry"], user="root")
|
||||||
self.session.check_call(['poetry', 'build', '-f', 'sdist'])
|
self.session.check_call(["poetry", "build", "-f", "sdist"])
|
||||||
return
|
return
|
||||||
raise AssertionError('no supported section in pyproject.toml')
|
raise AssertionError("no supported section in pyproject.toml")
|
||||||
|
|
||||||
|
|
||||||
class SetupCfg(BuildSystem):
|
class SetupCfg(BuildSystem):
|
||||||
|
|
||||||
def setup(self):
|
def setup(self):
|
||||||
apt = AptManager(self.session)
|
apt = AptManager(self.session)
|
||||||
apt.install(['python3-pep517', 'python3-pip'])
|
apt.install(["python3-pep517", "python3-pip"])
|
||||||
|
|
||||||
def dist(self):
|
def dist(self):
|
||||||
self.session.check_call(['python3', '-m', 'pep517.build', '-s', '.'])
|
self.session.check_call(["python3", "-m", "pep517.build", "-s", "."])
|
||||||
|
|
||||||
|
|
||||||
class NpmPackage(BuildSystem):
|
class NpmPackage(BuildSystem):
|
||||||
|
|
||||||
def setup(self):
|
def setup(self):
|
||||||
apt = AptManager(self.session)
|
apt = AptManager(self.session)
|
||||||
apt.install(['npm'])
|
apt.install(["npm"])
|
||||||
|
|
||||||
def dist(self):
|
def dist(self):
|
||||||
self.setup()
|
self.setup()
|
||||||
run_with_build_fixer(self.session, ['npm', 'pack'])
|
run_with_build_fixer(self.session, ["npm", "pack"])
|
||||||
|
|
||||||
|
|
||||||
class Waf(BuildSystem):
|
class Waf(BuildSystem):
|
||||||
|
|
||||||
def setup(self):
|
def setup(self):
|
||||||
apt = AptManager(self.session)
|
apt = AptManager(self.session)
|
||||||
apt.install(['python3'])
|
apt.install(["python3"])
|
||||||
|
|
||||||
def dist(self):
|
def dist(self):
|
||||||
self.setup()
|
self.setup()
|
||||||
run_with_build_fixer(self.session, ['./waf', 'dist'])
|
run_with_build_fixer(self.session, ["./waf", "dist"])
|
||||||
|
|
||||||
|
|
||||||
class Gem(BuildSystem):
|
class Gem(BuildSystem):
|
||||||
|
|
||||||
def setup(self):
|
def setup(self):
|
||||||
apt = AptManager(self.session)
|
apt = AptManager(self.session)
|
||||||
apt.install(['gem2deb'])
|
apt.install(["gem2deb"])
|
||||||
|
|
||||||
def dist(self):
|
def dist(self):
|
||||||
self.setup()
|
self.setup()
|
||||||
gemfiles = [entry.name for entry in self.session.scandir('.')
|
gemfiles = [
|
||||||
if entry.name.endswith('.gem')]
|
entry.name
|
||||||
|
for entry in self.session.scandir(".")
|
||||||
|
if entry.name.endswith(".gem")
|
||||||
|
]
|
||||||
if len(gemfiles) > 1:
|
if len(gemfiles) > 1:
|
||||||
logging.warning('More than one gemfile. Trying the first?')
|
logging.warning("More than one gemfile. Trying the first?")
|
||||||
run_with_build_fixer(self.session, ['gem2tgz', gemfiles[0]])
|
run_with_build_fixer(self.session, ["gem2tgz", gemfiles[0]])
|
||||||
|
|
||||||
|
|
||||||
class DistInkt(BuildSystem):
|
class DistInkt(BuildSystem):
|
||||||
|
|
||||||
def setup(self):
|
def setup(self):
|
||||||
apt = AptManager(self.session)
|
apt = AptManager(self.session)
|
||||||
apt.install(['libdist-inkt-perl'])
|
apt.install(["libdist-inkt-perl"])
|
||||||
|
|
||||||
def dist(self):
|
def dist(self):
|
||||||
self.setup()
|
self.setup()
|
||||||
apt = AptManager(self.session)
|
apt = AptManager(self.session)
|
||||||
with open('dist.ini', 'rb') as f:
|
with open("dist.ini", "rb") as f:
|
||||||
for line in f:
|
for line in f:
|
||||||
if not line.startswith(b';;'):
|
if not line.startswith(b";;"):
|
||||||
continue
|
continue
|
||||||
try:
|
try:
|
||||||
(key, value) = line[2:].split(b'=', 1)
|
(key, value) = line[2:].split(b"=", 1)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
continue
|
continue
|
||||||
if (key.strip() == b'class' and
|
if key.strip() == b"class" and value.strip().startswith(b"'Dist::Inkt"):
|
||||||
value.strip().startswith(b"'Dist::Inkt")):
|
|
||||||
logging.info(
|
logging.info(
|
||||||
'Found Dist::Inkt section in dist.ini, '
|
"Found Dist::Inkt section in dist.ini, " "assuming distinkt."
|
||||||
'assuming distinkt.')
|
)
|
||||||
# TODO(jelmer): install via apt if possible
|
# TODO(jelmer): install via apt if possible
|
||||||
self.session.check_call(
|
self.session.check_call(
|
||||||
['cpan', 'install', value.decode().strip("'")],
|
["cpan", "install", value.decode().strip("'")], user="root"
|
||||||
user='root')
|
)
|
||||||
run_with_build_fixer(self.session, ['distinkt-dist'])
|
run_with_build_fixer(self.session, ["distinkt-dist"])
|
||||||
return
|
return
|
||||||
# Default to invoking Dist::Zilla
|
# Default to invoking Dist::Zilla
|
||||||
logging.info('Found dist.ini, assuming dist-zilla.')
|
logging.info("Found dist.ini, assuming dist-zilla.")
|
||||||
apt.install(['libdist-zilla-perl'])
|
apt.install(["libdist-zilla-perl"])
|
||||||
run_with_build_fixer(self.session, ['dzil', 'build', '--in', '..'])
|
run_with_build_fixer(self.session, ["dzil", "build", "--in", ".."])
|
||||||
|
|
||||||
|
|
||||||
class Make(BuildSystem):
|
class Make(BuildSystem):
|
||||||
|
|
||||||
def setup(self):
|
def setup(self):
|
||||||
apt = AptManager(self.session)
|
apt = AptManager(self.session)
|
||||||
if self.session.exists('Makefile.PL') and not self.session.exists('Makefile'):
|
if self.session.exists("Makefile.PL") and not self.session.exists("Makefile"):
|
||||||
apt.install(['perl'])
|
apt.install(["perl"])
|
||||||
run_with_build_fixer(self.session, ['perl', 'Makefile.PL'])
|
run_with_build_fixer(self.session, ["perl", "Makefile.PL"])
|
||||||
|
|
||||||
if not self.session.exists('Makefile') and not self.session.exists('configure'):
|
if not self.session.exists("Makefile") and not self.session.exists("configure"):
|
||||||
if self.session.exists('autogen.sh'):
|
if self.session.exists("autogen.sh"):
|
||||||
if shebang_binary('autogen.sh') is None:
|
if shebang_binary("autogen.sh") is None:
|
||||||
run_with_build_fixer(
|
run_with_build_fixer(self.session, ["/bin/sh", "./autogen.sh"])
|
||||||
self.session, ['/bin/sh', './autogen.sh'])
|
|
||||||
try:
|
try:
|
||||||
run_with_build_fixer(
|
run_with_build_fixer(self.session, ["./autogen.sh"])
|
||||||
self.session, ['./autogen.sh'])
|
|
||||||
except UnidentifiedError as e:
|
except UnidentifiedError as e:
|
||||||
if ("Gnulib not yet bootstrapped; "
|
if (
|
||||||
"run ./bootstrap instead.\n" in e.lines):
|
"Gnulib not yet bootstrapped; "
|
||||||
|
"run ./bootstrap instead.\n" in e.lines
|
||||||
|
):
|
||||||
run_with_build_fixer(self.session, ["./bootstrap"])
|
run_with_build_fixer(self.session, ["./bootstrap"])
|
||||||
run_with_build_fixer(self.session, ['./autogen.sh'])
|
run_with_build_fixer(self.session, ["./autogen.sh"])
|
||||||
else:
|
else:
|
||||||
raise
|
raise
|
||||||
|
|
||||||
elif (self.session.exists('configure.ac') or
|
elif self.session.exists("configure.ac") or self.session.exists(
|
||||||
self.session.exists('configure.in')):
|
"configure.in"
|
||||||
apt.install([
|
):
|
||||||
'autoconf', 'automake', 'gettext', 'libtool',
|
apt.install(
|
||||||
'gnu-standards'])
|
["autoconf", "automake", "gettext", "libtool", "gnu-standards"]
|
||||||
run_with_build_fixer(self.session, ['autoreconf', '-i'])
|
)
|
||||||
|
run_with_build_fixer(self.session, ["autoreconf", "-i"])
|
||||||
|
|
||||||
if not self.session.exists('Makefile') and self.session.exists('configure'):
|
if not self.session.exists("Makefile") and self.session.exists("configure"):
|
||||||
self.session.check_call(['./configure'])
|
self.session.check_call(["./configure"])
|
||||||
|
|
||||||
def dist(self):
|
def dist(self):
|
||||||
self.setup()
|
self.setup()
|
||||||
apt = AptManager(self.session)
|
apt = AptManager(self.session)
|
||||||
apt.install(['make'])
|
apt.install(["make"])
|
||||||
try:
|
try:
|
||||||
run_with_build_fixer(self.session, ['make', 'dist'])
|
run_with_build_fixer(self.session, ["make", "dist"])
|
||||||
except UnidentifiedError as e:
|
except UnidentifiedError as e:
|
||||||
if ("make: *** No rule to make target 'dist'. Stop.\n"
|
if "make: *** No rule to make target 'dist'. Stop.\n" in e.lines:
|
||||||
in e.lines):
|
|
||||||
pass
|
pass
|
||||||
elif ("make[1]: *** No rule to make target 'dist'. Stop.\n"
|
elif "make[1]: *** No rule to make target 'dist'. Stop.\n" in e.lines:
|
||||||
in e.lines):
|
|
||||||
pass
|
pass
|
||||||
elif ("Reconfigure the source tree "
|
elif (
|
||||||
|
"Reconfigure the source tree "
|
||||||
"(via './config' or 'perl Configure'), please.\n"
|
"(via './config' or 'perl Configure'), please.\n"
|
||||||
) in e.lines:
|
) in e.lines:
|
||||||
run_with_build_fixer(self.session, ['./config'])
|
run_with_build_fixer(self.session, ["./config"])
|
||||||
run_with_build_fixer(self.session, ['make', 'dist'])
|
run_with_build_fixer(self.session, ["make", "dist"])
|
||||||
elif (
|
elif (
|
||||||
"Please try running 'make manifest' and then run "
|
"Please try running 'make manifest' and then run "
|
||||||
"'make dist' again.\n" in e.lines):
|
"'make dist' again.\n" in e.lines
|
||||||
run_with_build_fixer(self.session, ['make', 'manifest'])
|
):
|
||||||
run_with_build_fixer(self.session, ['make', 'dist'])
|
run_with_build_fixer(self.session, ["make", "manifest"])
|
||||||
|
run_with_build_fixer(self.session, ["make", "dist"])
|
||||||
elif "Please run ./configure first\n" in e.lines:
|
elif "Please run ./configure first\n" in e.lines:
|
||||||
run_with_build_fixer(self.session, ['./configure'])
|
run_with_build_fixer(self.session, ["./configure"])
|
||||||
run_with_build_fixer(self.session, ['make', 'dist'])
|
run_with_build_fixer(self.session, ["make", "dist"])
|
||||||
elif any([re.match(
|
elif any(
|
||||||
r'Makefile:[0-9]+: \*\*\* Missing \'Make.inc\' '
|
[
|
||||||
r'Run \'./configure \[options\]\' and retry. Stop.\n',
|
re.match(
|
||||||
line) for line in e.lines]):
|
r"Makefile:[0-9]+: \*\*\* Missing \'Make.inc\' "
|
||||||
run_with_build_fixer(self.session, ['./configure'])
|
r"Run \'./configure \[options\]\' and retry. Stop.\n",
|
||||||
run_with_build_fixer(self.session, ['make', 'dist'])
|
line,
|
||||||
elif any([re.match(
|
)
|
||||||
r'Problem opening MANIFEST: No such file or directory '
|
for line in e.lines
|
||||||
r'at .* line [0-9]+\.', line) for line in e.lines]):
|
]
|
||||||
run_with_build_fixer(self.session, ['make', 'manifest'])
|
):
|
||||||
run_with_build_fixer(self.session, ['make', 'dist'])
|
run_with_build_fixer(self.session, ["./configure"])
|
||||||
|
run_with_build_fixer(self.session, ["make", "dist"])
|
||||||
|
elif any(
|
||||||
|
[
|
||||||
|
re.match(
|
||||||
|
r"Problem opening MANIFEST: No such file or directory "
|
||||||
|
r"at .* line [0-9]+\.",
|
||||||
|
line,
|
||||||
|
)
|
||||||
|
for line in e.lines
|
||||||
|
]
|
||||||
|
):
|
||||||
|
run_with_build_fixer(self.session, ["make", "manifest"])
|
||||||
|
run_with_build_fixer(self.session, ["make", "dist"])
|
||||||
else:
|
else:
|
||||||
raise
|
raise
|
||||||
else:
|
else:
|
||||||
|
@ -319,40 +327,49 @@ class Make(BuildSystem):
|
||||||
|
|
||||||
def detect_buildsystems(session):
|
def detect_buildsystems(session):
|
||||||
"""Detect build systems."""
|
"""Detect build systems."""
|
||||||
if session.exists('package.xml'):
|
if session.exists("package.xml"):
|
||||||
logging.info('Found package.xml, assuming pear package.')
|
logging.info("Found package.xml, assuming pear package.")
|
||||||
yield Pear(session)
|
yield Pear(session)
|
||||||
|
|
||||||
if session.exists('setup.py'):
|
if session.exists("setup.py"):
|
||||||
logging.info('Found setup.py, assuming python project.')
|
logging.info("Found setup.py, assuming python project.")
|
||||||
yield SetupPy(session)
|
yield SetupPy(session)
|
||||||
|
|
||||||
if session.exists('pyproject.toml'):
|
if session.exists("pyproject.toml"):
|
||||||
logging.info('Found pyproject.toml, assuming python project.')
|
logging.info("Found pyproject.toml, assuming python project.")
|
||||||
yield PyProject(session)
|
yield PyProject(session)
|
||||||
|
|
||||||
if session.exists('setup.cfg'):
|
if session.exists("setup.cfg"):
|
||||||
logging.info('Found setup.cfg, assuming python project.')
|
logging.info("Found setup.cfg, assuming python project.")
|
||||||
yield SetupCfg(session)
|
yield SetupCfg(session)
|
||||||
|
|
||||||
if session.exists('package.json'):
|
if session.exists("package.json"):
|
||||||
logging.info('Found package.json, assuming node package.')
|
logging.info("Found package.json, assuming node package.")
|
||||||
yield NpmPackage(session)
|
yield NpmPackage(session)
|
||||||
|
|
||||||
if session.exists('waf'):
|
if session.exists("waf"):
|
||||||
logging.info('Found waf, assuming waf package.')
|
logging.info("Found waf, assuming waf package.")
|
||||||
yield Waf(session)
|
yield Waf(session)
|
||||||
|
|
||||||
gemfiles = [
|
gemfiles = [
|
||||||
entry.name for entry in session.scandir('.')
|
entry.name for entry in session.scandir(".") if entry.name.endswith(".gem")
|
||||||
if entry.name.endswith('.gem')]
|
]
|
||||||
if gemfiles:
|
if gemfiles:
|
||||||
yield Gem(session)
|
yield Gem(session)
|
||||||
|
|
||||||
if session.exists('dist.ini') and not session.exists('Makefile.PL'):
|
if session.exists("dist.ini") and not session.exists("Makefile.PL"):
|
||||||
yield DistInkt(session)
|
yield DistInkt(session)
|
||||||
|
|
||||||
if any([session.exists(p) for p in [
|
if any(
|
||||||
'Makefile', 'Makefile.PL', 'autogen.sh', 'configure.ac',
|
[
|
||||||
'configure.in']]):
|
session.exists(p)
|
||||||
|
for p in [
|
||||||
|
"Makefile",
|
||||||
|
"Makefile.PL",
|
||||||
|
"autogen.sh",
|
||||||
|
"configure.ac",
|
||||||
|
"configure.in",
|
||||||
|
]
|
||||||
|
]
|
||||||
|
):
|
||||||
yield Make(session)
|
yield Make(session)
|
||||||
|
|
|
@ -23,21 +23,18 @@ from ..session import Session
|
||||||
|
|
||||||
# TODO(jelmer): move this to debian/
|
# TODO(jelmer): move this to debian/
|
||||||
def satisfy_build_deps(session: Session, tree):
|
def satisfy_build_deps(session: Session, tree):
|
||||||
source = Deb822(tree.get_file('debian/control'))
|
source = Deb822(tree.get_file("debian/control"))
|
||||||
deps = []
|
deps = []
|
||||||
for name in ['Build-Depends', 'Build-Depends-Indep', 'Build-Depends-Arch']:
|
for name in ["Build-Depends", "Build-Depends-Indep", "Build-Depends-Arch"]:
|
||||||
try:
|
try:
|
||||||
deps.append(source[name].strip().strip(','))
|
deps.append(source[name].strip().strip(","))
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
for name in ['Build-Conflicts', 'Build-Conflicts-Indep',
|
for name in ["Build-Conflicts", "Build-Conflicts-Indep", "Build-Conflicts-Arch"]:
|
||||||
'Build-Conflicts-Arch']:
|
|
||||||
try:
|
try:
|
||||||
deps.append('Conflicts: ' + source[name])
|
deps.append("Conflicts: " + source[name])
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
deps = [
|
deps = [dep.strip().strip(",") for dep in deps]
|
||||||
dep.strip().strip(',')
|
|
||||||
for dep in deps]
|
|
||||||
apt = AptManager(session)
|
apt = AptManager(session)
|
||||||
apt.satisfy(deps)
|
apt.satisfy(deps)
|
||||||
|
|
|
@ -16,11 +16,11 @@
|
||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
'changes_filename',
|
"changes_filename",
|
||||||
'get_build_architecture',
|
"get_build_architecture",
|
||||||
'add_dummy_changelog_entry',
|
"add_dummy_changelog_entry",
|
||||||
'build',
|
"build",
|
||||||
'SbuildFailure',
|
"SbuildFailure",
|
||||||
]
|
]
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
@ -62,16 +62,24 @@ def changes_filename(package, version, arch):
|
||||||
|
|
||||||
def get_build_architecture():
|
def get_build_architecture():
|
||||||
try:
|
try:
|
||||||
return subprocess.check_output(
|
return (
|
||||||
['dpkg-architecture', '-qDEB_BUILD_ARCH']).strip().decode()
|
subprocess.check_output(["dpkg-architecture", "-qDEB_BUILD_ARCH"])
|
||||||
|
.strip()
|
||||||
|
.decode()
|
||||||
|
)
|
||||||
except subprocess.CalledProcessError as e:
|
except subprocess.CalledProcessError as e:
|
||||||
raise Exception(
|
raise Exception("Could not find the build architecture: %s" % e)
|
||||||
"Could not find the build architecture: %s" % e)
|
|
||||||
|
|
||||||
|
|
||||||
def add_dummy_changelog_entry(
|
def add_dummy_changelog_entry(
|
||||||
tree: MutableTree, subpath: str, suffix: str, suite: str,
|
tree: MutableTree,
|
||||||
message: str, timestamp=None, maintainer=None):
|
subpath: str,
|
||||||
|
suffix: str,
|
||||||
|
suite: str,
|
||||||
|
message: str,
|
||||||
|
timestamp=None,
|
||||||
|
maintainer=None,
|
||||||
|
):
|
||||||
"""Add a dummy changelog entry to a package.
|
"""Add a dummy changelog entry to a package.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
@ -80,87 +88,111 @@ def add_dummy_changelog_entry(
|
||||||
suite: Debian suite
|
suite: Debian suite
|
||||||
message: Changelog message
|
message: Changelog message
|
||||||
"""
|
"""
|
||||||
def add_suffix(v, suffix):
|
|
||||||
m = re.fullmatch('(.*)(' + re.escape(suffix) + ')([0-9]+)', v,)
|
|
||||||
if m:
|
|
||||||
return (m.group(1) + m.group(2) + '%d' % (int(m.group(3)) + 1))
|
|
||||||
else:
|
|
||||||
return v + suffix + '1'
|
|
||||||
|
|
||||||
path = os.path.join(subpath, 'debian', 'changelog')
|
def add_suffix(v, suffix):
|
||||||
|
m = re.fullmatch(
|
||||||
|
"(.*)(" + re.escape(suffix) + ")([0-9]+)",
|
||||||
|
v,
|
||||||
|
)
|
||||||
|
if m:
|
||||||
|
return m.group(1) + m.group(2) + "%d" % (int(m.group(3)) + 1)
|
||||||
|
else:
|
||||||
|
return v + suffix + "1"
|
||||||
|
|
||||||
|
path = os.path.join(subpath, "debian", "changelog")
|
||||||
if maintainer is None:
|
if maintainer is None:
|
||||||
maintainer = get_maintainer()
|
maintainer = get_maintainer()
|
||||||
if timestamp is None:
|
if timestamp is None:
|
||||||
timestamp = datetime.now()
|
timestamp = datetime.now()
|
||||||
with tree.get_file(path) as f:
|
with tree.get_file(path) as f:
|
||||||
cl = Changelog()
|
cl = Changelog()
|
||||||
cl.parse_changelog(
|
cl.parse_changelog(f, max_blocks=None, allow_empty_author=True, strict=False)
|
||||||
f, max_blocks=None, allow_empty_author=True, strict=False)
|
|
||||||
version = cl[0].version
|
version = cl[0].version
|
||||||
if version.debian_revision:
|
if version.debian_revision:
|
||||||
version.debian_revision = add_suffix(
|
version.debian_revision = add_suffix(version.debian_revision, suffix)
|
||||||
version.debian_revision, suffix)
|
|
||||||
else:
|
else:
|
||||||
version.upstream_version = add_suffix(
|
version.upstream_version = add_suffix(version.upstream_version, suffix)
|
||||||
version.upstream_version, suffix)
|
|
||||||
cl.new_block(
|
cl.new_block(
|
||||||
package=cl[0].package,
|
package=cl[0].package,
|
||||||
version=version,
|
version=version,
|
||||||
urgency='low',
|
urgency="low",
|
||||||
distributions=suite,
|
distributions=suite,
|
||||||
author='%s <%s>' % maintainer,
|
author="%s <%s>" % maintainer,
|
||||||
date=format_datetime(timestamp),
|
date=format_datetime(timestamp),
|
||||||
changes=['', ' * ' + message, ''])
|
changes=["", " * " + message, ""],
|
||||||
|
)
|
||||||
cl_str = cl._format(allow_missing_author=True)
|
cl_str = cl._format(allow_missing_author=True)
|
||||||
tree.put_file_bytes_non_atomic(path, cl_str.encode(cl._encoding))
|
tree.put_file_bytes_non_atomic(path, cl_str.encode(cl._encoding))
|
||||||
|
|
||||||
|
|
||||||
def get_latest_changelog_version(local_tree, subpath=''):
|
def get_latest_changelog_version(local_tree, subpath=""):
|
||||||
path = osutils.pathjoin(subpath, 'debian/changelog')
|
path = osutils.pathjoin(subpath, "debian/changelog")
|
||||||
with local_tree.get_file(path) as f:
|
with local_tree.get_file(path) as f:
|
||||||
cl = Changelog(f, max_blocks=1)
|
cl = Changelog(f, max_blocks=1)
|
||||||
return cl.package, cl.version
|
return cl.package, cl.version
|
||||||
|
|
||||||
|
|
||||||
def build(local_tree, outf, build_command=DEFAULT_BUILDER, result_dir=None,
|
def build(
|
||||||
distribution=None, subpath='', source_date_epoch=None):
|
local_tree,
|
||||||
args = [sys.executable, '-m', 'breezy', 'builddeb',
|
outf,
|
||||||
'--guess-upstream-branch-url', '--builder=%s' % build_command]
|
build_command=DEFAULT_BUILDER,
|
||||||
|
result_dir=None,
|
||||||
|
distribution=None,
|
||||||
|
subpath="",
|
||||||
|
source_date_epoch=None,
|
||||||
|
):
|
||||||
|
args = [
|
||||||
|
sys.executable,
|
||||||
|
"-m",
|
||||||
|
"breezy",
|
||||||
|
"builddeb",
|
||||||
|
"--guess-upstream-branch-url",
|
||||||
|
"--builder=%s" % build_command,
|
||||||
|
]
|
||||||
if result_dir:
|
if result_dir:
|
||||||
args.append('--result-dir=%s' % result_dir)
|
args.append("--result-dir=%s" % result_dir)
|
||||||
outf.write('Running %r\n' % (build_command, ))
|
outf.write("Running %r\n" % (build_command,))
|
||||||
outf.flush()
|
outf.flush()
|
||||||
env = dict(os.environ.items())
|
env = dict(os.environ.items())
|
||||||
if distribution is not None:
|
if distribution is not None:
|
||||||
env['DISTRIBUTION'] = distribution
|
env["DISTRIBUTION"] = distribution
|
||||||
if source_date_epoch is not None:
|
if source_date_epoch is not None:
|
||||||
env['SOURCE_DATE_EPOCH'] = '%d' % source_date_epoch
|
env["SOURCE_DATE_EPOCH"] = "%d" % source_date_epoch
|
||||||
logging.info('Building debian packages, running %r.', build_command)
|
logging.info("Building debian packages, running %r.", build_command)
|
||||||
try:
|
try:
|
||||||
subprocess.check_call(
|
subprocess.check_call(
|
||||||
args, cwd=local_tree.abspath(subpath), stdout=outf, stderr=outf,
|
args, cwd=local_tree.abspath(subpath), stdout=outf, stderr=outf, env=env
|
||||||
env=env)
|
)
|
||||||
except subprocess.CalledProcessError:
|
except subprocess.CalledProcessError:
|
||||||
raise BuildFailedError()
|
raise BuildFailedError()
|
||||||
|
|
||||||
|
|
||||||
def build_once(
|
def build_once(
|
||||||
local_tree, build_suite, output_directory, build_command,
|
local_tree,
|
||||||
subpath='', source_date_epoch=None):
|
build_suite,
|
||||||
build_log_path = os.path.join(output_directory, 'build.log')
|
output_directory,
|
||||||
|
build_command,
|
||||||
|
subpath="",
|
||||||
|
source_date_epoch=None,
|
||||||
|
):
|
||||||
|
build_log_path = os.path.join(output_directory, "build.log")
|
||||||
try:
|
try:
|
||||||
with open(build_log_path, 'w') as f:
|
with open(build_log_path, "w") as f:
|
||||||
build(local_tree, outf=f, build_command=build_command,
|
build(
|
||||||
result_dir=output_directory, distribution=build_suite,
|
local_tree,
|
||||||
subpath=subpath, source_date_epoch=source_date_epoch)
|
outf=f,
|
||||||
|
build_command=build_command,
|
||||||
|
result_dir=output_directory,
|
||||||
|
distribution=build_suite,
|
||||||
|
subpath=subpath,
|
||||||
|
source_date_epoch=source_date_epoch,
|
||||||
|
)
|
||||||
except BuildFailedError:
|
except BuildFailedError:
|
||||||
with open(build_log_path, 'rb') as f:
|
with open(build_log_path, "rb") as f:
|
||||||
raise worker_failure_from_sbuild_log(f)
|
raise worker_failure_from_sbuild_log(f)
|
||||||
|
|
||||||
(cl_package, cl_version) = get_latest_changelog_version(
|
(cl_package, cl_version) = get_latest_changelog_version(local_tree, subpath)
|
||||||
local_tree, subpath)
|
changes_name = changes_filename(cl_package, cl_version, get_build_architecture())
|
||||||
changes_name = changes_filename(
|
|
||||||
cl_package, cl_version, get_build_architecture())
|
|
||||||
changes_path = os.path.join(output_directory, changes_name)
|
changes_path = os.path.join(output_directory, changes_name)
|
||||||
if not os.path.exists(changes_path):
|
if not os.path.exists(changes_path):
|
||||||
raise MissingChangesFile(changes_name)
|
raise MissingChangesFile(changes_name)
|
||||||
|
@ -168,13 +200,19 @@ def build_once(
|
||||||
|
|
||||||
|
|
||||||
def gbp_dch(path):
|
def gbp_dch(path):
|
||||||
subprocess.check_call(['gbp', 'dch'], cwd=path)
|
subprocess.check_call(["gbp", "dch"], cwd=path)
|
||||||
|
|
||||||
|
|
||||||
def attempt_build(
|
def attempt_build(
|
||||||
local_tree, suffix, build_suite, output_directory, build_command,
|
local_tree,
|
||||||
build_changelog_entry='Build for debian-janitor apt repository.',
|
suffix,
|
||||||
subpath='', source_date_epoch=None):
|
build_suite,
|
||||||
|
output_directory,
|
||||||
|
build_command,
|
||||||
|
build_changelog_entry="Build for debian-janitor apt repository.",
|
||||||
|
subpath="",
|
||||||
|
source_date_epoch=None,
|
||||||
|
):
|
||||||
"""Attempt a build, with a custom distribution set.
|
"""Attempt a build, with a custom distribution set.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
@ -189,8 +227,13 @@ def attempt_build(
|
||||||
Returns: Tuple with (changes_name, cl_version)
|
Returns: Tuple with (changes_name, cl_version)
|
||||||
"""
|
"""
|
||||||
add_dummy_changelog_entry(
|
add_dummy_changelog_entry(
|
||||||
local_tree, subpath, suffix, build_suite,
|
local_tree, subpath, suffix, build_suite, build_changelog_entry
|
||||||
build_changelog_entry)
|
)
|
||||||
return build_once(
|
return build_once(
|
||||||
local_tree, build_suite, output_directory, build_command, subpath,
|
local_tree,
|
||||||
source_date_epoch=source_date_epoch)
|
build_suite,
|
||||||
|
output_directory,
|
||||||
|
build_command,
|
||||||
|
subpath,
|
||||||
|
source_date_epoch=source_date_epoch,
|
||||||
|
)
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -31,10 +31,6 @@ from breezy.workingtree import WorkingTree
|
||||||
from . import DetailedFailure
|
from . import DetailedFailure
|
||||||
from .buildsystem import detect_buildsystems, NoBuildToolsFound
|
from .buildsystem import detect_buildsystems, NoBuildToolsFound
|
||||||
from buildlog_consultant.common import (
|
from buildlog_consultant.common import (
|
||||||
find_build_failure_description,
|
|
||||||
Problem,
|
|
||||||
MissingPerlModule,
|
|
||||||
MissingCommand,
|
|
||||||
NoSpaceOnDevice,
|
NoSpaceOnDevice,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -78,7 +74,6 @@ def run_dist(session):
|
||||||
|
|
||||||
|
|
||||||
class DistCatcher(object):
|
class DistCatcher(object):
|
||||||
|
|
||||||
def __init__(self, directory):
|
def __init__(self, directory):
|
||||||
self.export_directory = directory
|
self.export_directory = directory
|
||||||
self.files = []
|
self.files = []
|
||||||
|
@ -94,7 +89,7 @@ class DistCatcher(object):
|
||||||
diff = set([n for n in diff_files if is_dist_file(n)])
|
diff = set([n for n in diff_files if is_dist_file(n)])
|
||||||
if len(diff) == 1:
|
if len(diff) == 1:
|
||||||
fn = diff.pop()
|
fn = diff.pop()
|
||||||
logging.info('Found tarball %s in package directory.', fn)
|
logging.info("Found tarball %s in package directory.", fn)
|
||||||
self.files.append(os.path.join(self.export_directory, fn))
|
self.files.append(os.path.join(self.export_directory, fn))
|
||||||
return fn
|
return fn
|
||||||
if "dist" in diff_files:
|
if "dist" in diff_files:
|
||||||
|
@ -103,13 +98,13 @@ class DistCatcher(object):
|
||||||
logging.info("Found tarball %s in dist directory.", entry.name)
|
logging.info("Found tarball %s in dist directory.", entry.name)
|
||||||
self.files.append(entry.path)
|
self.files.append(entry.path)
|
||||||
return entry.name
|
return entry.name
|
||||||
logging.info('No tarballs found in dist directory.')
|
logging.info("No tarballs found in dist directory.")
|
||||||
|
|
||||||
parent_directory = os.path.dirname(self.export_directory)
|
parent_directory = os.path.dirname(self.export_directory)
|
||||||
diff = set(os.listdir(parent_directory)) - set([subdir])
|
diff = set(os.listdir(parent_directory)) - set([subdir])
|
||||||
if len(diff) == 1:
|
if len(diff) == 1:
|
||||||
fn = diff.pop()
|
fn = diff.pop()
|
||||||
logging.info('Found tarball %s in parent directory.', fn)
|
logging.info("Found tarball %s in parent directory.", fn)
|
||||||
self.files.append(os.path.join(parent_directory, fn))
|
self.files.append(os.path.join(parent_directory, fn))
|
||||||
return fn
|
return fn
|
||||||
|
|
||||||
|
@ -119,25 +114,28 @@ class DistCatcher(object):
|
||||||
|
|
||||||
|
|
||||||
def create_dist_schroot(
|
def create_dist_schroot(
|
||||||
tree: Tree, target_dir: str,
|
tree: Tree,
|
||||||
chroot: str, packaging_tree: Optional[Tree] = None,
|
target_dir: str,
|
||||||
|
chroot: str,
|
||||||
|
packaging_tree: Optional[Tree] = None,
|
||||||
include_controldir: bool = True,
|
include_controldir: bool = True,
|
||||||
subdir: Optional[str] = None) -> str:
|
subdir: Optional[str] = None,
|
||||||
|
) -> str:
|
||||||
if subdir is None:
|
if subdir is None:
|
||||||
subdir = 'package'
|
subdir = "package"
|
||||||
with SchrootSession(chroot) as session:
|
with SchrootSession(chroot) as session:
|
||||||
if packaging_tree is not None:
|
if packaging_tree is not None:
|
||||||
from .debian import satisfy_build_deps
|
from .debian import satisfy_build_deps
|
||||||
|
|
||||||
satisfy_build_deps(session, packaging_tree)
|
satisfy_build_deps(session, packaging_tree)
|
||||||
build_dir = os.path.join(session.location, 'build')
|
build_dir = os.path.join(session.location, "build")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
directory = tempfile.mkdtemp(dir=build_dir)
|
directory = tempfile.mkdtemp(dir=build_dir)
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
if e.errno == errno.ENOSPC:
|
if e.errno == errno.ENOSPC:
|
||||||
raise DetailedFailure(
|
raise DetailedFailure(1, ["mkdtemp"], NoSpaceOnDevice())
|
||||||
1, ['mkdtemp'], NoSpaceOnDevice())
|
reldir = "/" + os.path.relpath(directory, session.location)
|
||||||
reldir = '/' + os.path.relpath(directory, session.location)
|
|
||||||
|
|
||||||
export_directory = os.path.join(directory, subdir)
|
export_directory = os.path.join(directory, subdir)
|
||||||
if not include_controldir:
|
if not include_controldir:
|
||||||
|
@ -158,11 +156,11 @@ def create_dist_schroot(
|
||||||
shutil.copy(path, target_dir)
|
shutil.copy(path, target_dir)
|
||||||
return os.path.join(target_dir, os.path.basename(path))
|
return os.path.join(target_dir, os.path.basename(path))
|
||||||
|
|
||||||
logging.info('No tarball created :(')
|
logging.info("No tarball created :(")
|
||||||
raise DistNoTarball()
|
raise DistNoTarball()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
import argparse
|
import argparse
|
||||||
import breezy.bzr # noqa: F401
|
import breezy.bzr # noqa: F401
|
||||||
import breezy.git # noqa: F401
|
import breezy.git # noqa: F401
|
||||||
|
@ -170,17 +168,24 @@ if __name__ == '__main__':
|
||||||
|
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--chroot', default='unstable-amd64-sbuild', type=str,
|
"--chroot",
|
||||||
help='Name of chroot to use')
|
default="unstable-amd64-sbuild",
|
||||||
|
type=str,
|
||||||
|
help="Name of chroot to use",
|
||||||
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'directory', default='.', type=str, nargs='?',
|
"directory",
|
||||||
help='Directory with upstream source.')
|
default=".",
|
||||||
|
type=str,
|
||||||
|
nargs="?",
|
||||||
|
help="Directory with upstream source.",
|
||||||
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--packaging-directory', type=str,
|
"--packaging-directory", type=str, help="Path to packaging directory."
|
||||||
help='Path to packaging directory.')
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--target-directory', type=str, default='..',
|
"--target-directory", type=str, default="..", help="Target directory"
|
||||||
help='Target directory')
|
)
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
logging.basicConfig(level=logging.INFO)
|
logging.basicConfig(level=logging.INFO)
|
||||||
|
@ -189,8 +194,8 @@ if __name__ == '__main__':
|
||||||
if args.packaging_directory:
|
if args.packaging_directory:
|
||||||
packaging_tree = WorkingTree.open(args.packaging_directory)
|
packaging_tree = WorkingTree.open(args.packaging_directory)
|
||||||
with packaging_tree.lock_read():
|
with packaging_tree.lock_read():
|
||||||
source = Deb822(packaging_tree.get_file('debian/control'))
|
source = Deb822(packaging_tree.get_file("debian/control"))
|
||||||
package = source['Source']
|
package = source["Source"]
|
||||||
subdir = package
|
subdir = package
|
||||||
else:
|
else:
|
||||||
packaging_tree = None
|
packaging_tree = None
|
||||||
|
@ -198,13 +203,15 @@ if __name__ == '__main__':
|
||||||
|
|
||||||
try:
|
try:
|
||||||
ret = create_dist_schroot(
|
ret = create_dist_schroot(
|
||||||
tree, subdir=subdir,
|
tree,
|
||||||
|
subdir=subdir,
|
||||||
target_dir=os.path.abspath(args.target_directory),
|
target_dir=os.path.abspath(args.target_directory),
|
||||||
packaging_tree=packaging_tree,
|
packaging_tree=packaging_tree,
|
||||||
chroot=args.chroot)
|
chroot=args.chroot,
|
||||||
|
)
|
||||||
except NoBuildToolsFound:
|
except NoBuildToolsFound:
|
||||||
logging.info('No build tools found, falling back to simple export.')
|
logging.info("No build tools found, falling back to simple export.")
|
||||||
export(tree, 'dist.tar.gz', 'tgz', None)
|
export(tree, "dist.tar.gz", "tgz", None)
|
||||||
else:
|
else:
|
||||||
print('Created %s' % ret)
|
print("Created %s" % ret)
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
|
@ -36,7 +36,6 @@ from .session import Session, run_with_tee
|
||||||
|
|
||||||
|
|
||||||
class SchrootDependencyContext(DependencyContext):
|
class SchrootDependencyContext(DependencyContext):
|
||||||
|
|
||||||
def __init__(self, session):
|
def __init__(self, session):
|
||||||
self.session = session
|
self.session = session
|
||||||
self.apt = AptManager(session)
|
self.apt = AptManager(session)
|
||||||
|
@ -50,13 +49,13 @@ class SchrootDependencyContext(DependencyContext):
|
||||||
def fix_perl_module_from_cpan(error, context):
|
def fix_perl_module_from_cpan(error, context):
|
||||||
# TODO(jelmer): Specify -T to skip tests?
|
# TODO(jelmer): Specify -T to skip tests?
|
||||||
context.session.check_call(
|
context.session.check_call(
|
||||||
['cpan', '-i', error.module], user='root',
|
["cpan", "-i", error.module], user="root", env={"PERL_MM_USE_DEFAULT": "1"}
|
||||||
env={'PERL_MM_USE_DEFAULT': '1'})
|
)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
NPM_COMMAND_PACKAGES = {
|
NPM_COMMAND_PACKAGES = {
|
||||||
'del-cli': 'del-cli',
|
"del-cli": "del-cli",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -66,19 +65,20 @@ def fix_npm_missing_command(error, context):
|
||||||
except KeyError:
|
except KeyError:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
context.session.check_call(['npm', '-g', 'install', package])
|
context.session.check_call(["npm", "-g", "install", package])
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
GENERIC_INSTALL_FIXERS: List[
|
GENERIC_INSTALL_FIXERS: List[
|
||||||
Tuple[Type[Problem], Callable[[Problem, DependencyContext], bool]]] = [
|
Tuple[Type[Problem], Callable[[Problem, DependencyContext], bool]]
|
||||||
|
] = [
|
||||||
(MissingPerlModule, fix_perl_module_from_cpan),
|
(MissingPerlModule, fix_perl_module_from_cpan),
|
||||||
(MissingCommand, fix_npm_missing_command),
|
(MissingCommand, fix_npm_missing_command),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
def run_with_build_fixer(session: Session, args: List[str]):
|
def run_with_build_fixer(session: Session, args: List[str]):
|
||||||
logging.info('Running %r', args)
|
logging.info("Running %r", args)
|
||||||
fixed_errors = []
|
fixed_errors = []
|
||||||
while True:
|
while True:
|
||||||
retcode, lines = run_with_tee(session, args)
|
retcode, lines = run_with_tee(session, args)
|
||||||
|
@ -86,23 +86,22 @@ def run_with_build_fixer(session: Session, args: List[str]):
|
||||||
return
|
return
|
||||||
offset, line, error = find_build_failure_description(lines)
|
offset, line, error = find_build_failure_description(lines)
|
||||||
if error is None:
|
if error is None:
|
||||||
logging.warning('Build failed with unidentified error. Giving up.')
|
logging.warning("Build failed with unidentified error. Giving up.")
|
||||||
if line is not None:
|
if line is not None:
|
||||||
raise UnidentifiedError(
|
raise UnidentifiedError(retcode, args, lines, secondary=(offset, line))
|
||||||
retcode, args, lines, secondary=(offset, line))
|
|
||||||
raise UnidentifiedError(retcode, args, lines)
|
raise UnidentifiedError(retcode, args, lines)
|
||||||
|
|
||||||
logging.info('Identified error: %r', error)
|
logging.info("Identified error: %r", error)
|
||||||
if error in fixed_errors:
|
if error in fixed_errors:
|
||||||
logging.warning(
|
logging.warning(
|
||||||
'Failed to resolve error %r, it persisted. Giving up.',
|
"Failed to resolve error %r, it persisted. Giving up.", error
|
||||||
error)
|
)
|
||||||
raise DetailedFailure(retcode, args, error)
|
raise DetailedFailure(retcode, args, error)
|
||||||
if not resolve_error(
|
if not resolve_error(
|
||||||
error, SchrootDependencyContext(session),
|
error,
|
||||||
fixers=(APT_FIXERS + GENERIC_INSTALL_FIXERS)):
|
SchrootDependencyContext(session),
|
||||||
logging.warning(
|
fixers=(APT_FIXERS + GENERIC_INSTALL_FIXERS),
|
||||||
'Failed to find resolution for error %r. Giving up.',
|
):
|
||||||
error)
|
logging.warning("Failed to find resolution for error %r. Giving up.", error)
|
||||||
raise DetailedFailure(retcode, args, error)
|
raise DetailedFailure(retcode, args, error)
|
||||||
fixed_errors.append(error)
|
fixed_errors.append(error)
|
||||||
|
|
|
@ -22,8 +22,7 @@ import subprocess
|
||||||
|
|
||||||
|
|
||||||
class Session(object):
|
class Session(object):
|
||||||
|
def __enter__(self) -> "Session":
|
||||||
def __enter__(self) -> 'Session':
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def __exit__(self, exc_type, exc_val, exc_tb):
|
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||||
|
@ -38,25 +37,30 @@ class Session(object):
|
||||||
|
|
||||||
def check_call(
|
def check_call(
|
||||||
self,
|
self,
|
||||||
argv: List[str], cwd: Optional[str] = None,
|
argv: List[str],
|
||||||
|
cwd: Optional[str] = None,
|
||||||
user: Optional[str] = None,
|
user: Optional[str] = None,
|
||||||
env: Optional[Dict[str, str]] = None):
|
env: Optional[Dict[str, str]] = None,
|
||||||
|
):
|
||||||
raise NotImplementedError(self.check_call)
|
raise NotImplementedError(self.check_call)
|
||||||
|
|
||||||
def check_output(
|
def check_output(
|
||||||
self,
|
self,
|
||||||
argv: List[str], cwd: Optional[str] = None,
|
argv: List[str],
|
||||||
|
cwd: Optional[str] = None,
|
||||||
user: Optional[str] = None,
|
user: Optional[str] = None,
|
||||||
env: Optional[Dict[str, str]] = None) -> bytes:
|
env: Optional[Dict[str, str]] = None,
|
||||||
|
) -> bytes:
|
||||||
raise NotImplementedError(self.check_output)
|
raise NotImplementedError(self.check_output)
|
||||||
|
|
||||||
def Popen(self, argv, cwd: Optional[str] = None,
|
def Popen(
|
||||||
user: Optional[str] = None, **kwargs):
|
self, argv, cwd: Optional[str] = None, user: Optional[str] = None, **kwargs
|
||||||
|
):
|
||||||
raise NotImplementedError(self.Popen)
|
raise NotImplementedError(self.Popen)
|
||||||
|
|
||||||
def call(
|
def call(
|
||||||
self, argv: List[str], cwd: Optional[str] = None,
|
self, argv: List[str], cwd: Optional[str] = None, user: Optional[str] = None
|
||||||
user: Optional[str] = None):
|
):
|
||||||
raise NotImplementedError(self.call)
|
raise NotImplementedError(self.call)
|
||||||
|
|
||||||
def create_home(self) -> None:
|
def create_home(self) -> None:
|
||||||
|
@ -76,12 +80,11 @@ class SessionSetupFailure(Exception):
|
||||||
|
|
||||||
|
|
||||||
def run_with_tee(session: Session, args: List[str], **kwargs):
|
def run_with_tee(session: Session, args: List[str], **kwargs):
|
||||||
p = session.Popen(
|
p = session.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, **kwargs)
|
||||||
args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, **kwargs)
|
|
||||||
contents = []
|
contents = []
|
||||||
while p.poll() is None:
|
while p.poll() is None:
|
||||||
line = p.stdout.readline()
|
line = p.stdout.readline()
|
||||||
sys.stdout.buffer.write(line)
|
sys.stdout.buffer.write(line)
|
||||||
sys.stdout.buffer.flush()
|
sys.stdout.buffer.flush()
|
||||||
contents.append(line.decode('utf-8', 'surrogateescape'))
|
contents.append(line.decode("utf-8", "surrogateescape"))
|
||||||
return p.returncode, contents
|
return p.returncode, contents
|
||||||
|
|
|
@ -25,7 +25,7 @@ import subprocess
|
||||||
class PlainSession(Session):
|
class PlainSession(Session):
|
||||||
"""Session ignoring user."""
|
"""Session ignoring user."""
|
||||||
|
|
||||||
location = '/'
|
location = "/"
|
||||||
|
|
||||||
def create_home(self):
|
def create_home(self):
|
||||||
pass
|
pass
|
||||||
|
@ -34,8 +34,7 @@ class PlainSession(Session):
|
||||||
return subprocess.check_call(args)
|
return subprocess.check_call(args)
|
||||||
|
|
||||||
def Popen(self, args, stdout=None, stderr=None, user=None, cwd=None):
|
def Popen(self, args, stdout=None, stderr=None, user=None, cwd=None):
|
||||||
return subprocess.Popen(
|
return subprocess.Popen(args, stdout=stdout, stderr=stderr, cwd=cwd)
|
||||||
args, stdout=stdout, stderr=stderr, cwd=cwd)
|
|
||||||
|
|
||||||
def exists(self, path):
|
def exists(self, path):
|
||||||
return os.path.exists(path)
|
return os.path.exists(path)
|
||||||
|
|
|
@ -34,24 +34,30 @@ class SchrootSession(Session):
|
||||||
|
|
||||||
def __init__(self, chroot: str):
|
def __init__(self, chroot: str):
|
||||||
if not isinstance(chroot, str):
|
if not isinstance(chroot, str):
|
||||||
raise TypeError('not a valid chroot: %r' % chroot)
|
raise TypeError("not a valid chroot: %r" % chroot)
|
||||||
self.chroot = chroot
|
self.chroot = chroot
|
||||||
self._location = None
|
self._location = None
|
||||||
self._cwd = None
|
self._cwd = None
|
||||||
|
|
||||||
def _get_location(self) -> str:
|
def _get_location(self) -> str:
|
||||||
return subprocess.check_output(
|
return (
|
||||||
['schroot', '--location', '-c', 'session:' + self.session_id
|
subprocess.check_output(
|
||||||
]).strip().decode()
|
["schroot", "--location", "-c", "session:" + self.session_id]
|
||||||
|
)
|
||||||
|
.strip()
|
||||||
|
.decode()
|
||||||
|
)
|
||||||
|
|
||||||
def _end_session(self) -> None:
|
def _end_session(self) -> None:
|
||||||
subprocess.check_output(
|
subprocess.check_output(["schroot", "-c", "session:" + self.session_id, "-e"])
|
||||||
['schroot', '-c', 'session:' + self.session_id, '-e'])
|
|
||||||
|
|
||||||
def __enter__(self) -> 'Session':
|
def __enter__(self) -> "Session":
|
||||||
try:
|
try:
|
||||||
self.session_id = subprocess.check_output(
|
self.session_id = (
|
||||||
['schroot', '-c', self.chroot, '-b']).strip().decode()
|
subprocess.check_output(["schroot", "-c", self.chroot, "-b"])
|
||||||
|
.strip()
|
||||||
|
.decode()
|
||||||
|
)
|
||||||
except subprocess.CalledProcessError:
|
except subprocess.CalledProcessError:
|
||||||
# TODO(jelmer): Capture stderr and forward in SessionSetupFailure
|
# TODO(jelmer): Capture stderr and forward in SessionSetupFailure
|
||||||
raise SessionSetupFailure()
|
raise SessionSetupFailure()
|
||||||
|
@ -70,30 +76,41 @@ class SchrootSession(Session):
|
||||||
self._location = self._get_location()
|
self._location = self._get_location()
|
||||||
return self._location
|
return self._location
|
||||||
|
|
||||||
def _run_argv(self, argv: List[str], cwd: Optional[str] = None,
|
def _run_argv(
|
||||||
|
self,
|
||||||
|
argv: List[str],
|
||||||
|
cwd: Optional[str] = None,
|
||||||
user: Optional[str] = None,
|
user: Optional[str] = None,
|
||||||
env: Optional[Dict[str, str]] = None):
|
env: Optional[Dict[str, str]] = None,
|
||||||
base_argv = ['schroot', '-r', '-c', 'session:' + self.session_id]
|
):
|
||||||
|
base_argv = ["schroot", "-r", "-c", "session:" + self.session_id]
|
||||||
if cwd is None:
|
if cwd is None:
|
||||||
cwd = self._cwd
|
cwd = self._cwd
|
||||||
if cwd is not None:
|
if cwd is not None:
|
||||||
base_argv.extend(['-d', cwd])
|
base_argv.extend(["-d", cwd])
|
||||||
if user is not None:
|
if user is not None:
|
||||||
base_argv.extend(['-u', user])
|
base_argv.extend(["-u", user])
|
||||||
if env:
|
if env:
|
||||||
argv = [
|
argv = [
|
||||||
'sh', '-c',
|
"sh",
|
||||||
' '.join(
|
"-c",
|
||||||
['%s=%s ' % (key, shlex.quote(value))
|
" ".join(
|
||||||
for (key, value) in env.items()] +
|
[
|
||||||
[shlex.quote(arg) for arg in argv])]
|
"%s=%s " % (key, shlex.quote(value))
|
||||||
return base_argv + ['--'] + argv
|
for (key, value) in env.items()
|
||||||
|
]
|
||||||
|
+ [shlex.quote(arg) for arg in argv]
|
||||||
|
),
|
||||||
|
]
|
||||||
|
return base_argv + ["--"] + argv
|
||||||
|
|
||||||
def check_call(
|
def check_call(
|
||||||
self,
|
self,
|
||||||
argv: List[str], cwd: Optional[str] = None,
|
argv: List[str],
|
||||||
|
cwd: Optional[str] = None,
|
||||||
user: Optional[str] = None,
|
user: Optional[str] = None,
|
||||||
env: Optional[Dict[str, str]] = None):
|
env: Optional[Dict[str, str]] = None,
|
||||||
|
):
|
||||||
try:
|
try:
|
||||||
subprocess.check_call(self._run_argv(argv, cwd, user, env=env))
|
subprocess.check_call(self._run_argv(argv, cwd, user, env=env))
|
||||||
except subprocess.CalledProcessError as e:
|
except subprocess.CalledProcessError as e:
|
||||||
|
@ -101,38 +118,42 @@ class SchrootSession(Session):
|
||||||
|
|
||||||
def check_output(
|
def check_output(
|
||||||
self,
|
self,
|
||||||
argv: List[str], cwd: Optional[str] = None,
|
argv: List[str],
|
||||||
|
cwd: Optional[str] = None,
|
||||||
user: Optional[str] = None,
|
user: Optional[str] = None,
|
||||||
env: Optional[Dict[str, str]] = None) -> bytes:
|
env: Optional[Dict[str, str]] = None,
|
||||||
|
) -> bytes:
|
||||||
try:
|
try:
|
||||||
return subprocess.check_output(
|
return subprocess.check_output(self._run_argv(argv, cwd, user, env=env))
|
||||||
self._run_argv(argv, cwd, user, env=env))
|
|
||||||
except subprocess.CalledProcessError as e:
|
except subprocess.CalledProcessError as e:
|
||||||
raise subprocess.CalledProcessError(e.returncode, argv)
|
raise subprocess.CalledProcessError(e.returncode, argv)
|
||||||
|
|
||||||
def Popen(self, argv, cwd: Optional[str] = None,
|
def Popen(
|
||||||
user: Optional[str] = None, **kwargs):
|
self, argv, cwd: Optional[str] = None, user: Optional[str] = None, **kwargs
|
||||||
|
):
|
||||||
return subprocess.Popen(self._run_argv(argv, cwd, user), **kwargs)
|
return subprocess.Popen(self._run_argv(argv, cwd, user), **kwargs)
|
||||||
|
|
||||||
def call(
|
def call(
|
||||||
self, argv: List[str], cwd: Optional[str] = None,
|
self, argv: List[str], cwd: Optional[str] = None, user: Optional[str] = None
|
||||||
user: Optional[str] = None):
|
):
|
||||||
return subprocess.call(self._run_argv(argv, cwd, user))
|
return subprocess.call(self._run_argv(argv, cwd, user))
|
||||||
|
|
||||||
def create_home(self) -> None:
|
def create_home(self) -> None:
|
||||||
"""Create the user's home directory."""
|
"""Create the user's home directory."""
|
||||||
home = self.check_output(
|
home = (
|
||||||
['sh', '-c', 'echo $HOME'], cwd='/').decode().rstrip('\n')
|
self.check_output(["sh", "-c", "echo $HOME"], cwd="/").decode().rstrip("\n")
|
||||||
user = self.check_output(
|
)
|
||||||
['sh', '-c', 'echo $LOGNAME'], cwd='/').decode().rstrip('\n')
|
user = (
|
||||||
logging.info('Creating directory %s', home)
|
self.check_output(["sh", "-c", "echo $LOGNAME"], cwd="/")
|
||||||
self.check_call(['mkdir', '-p', home], cwd='/', user='root')
|
.decode()
|
||||||
self.check_call(['chown', user, home], cwd='/', user='root')
|
.rstrip("\n")
|
||||||
|
)
|
||||||
|
logging.info("Creating directory %s", home)
|
||||||
|
self.check_call(["mkdir", "-p", home], cwd="/", user="root")
|
||||||
|
self.check_call(["chown", user, home], cwd="/", user="root")
|
||||||
|
|
||||||
def _fullpath(self, path: str) -> str:
|
def _fullpath(self, path: str) -> str:
|
||||||
return os.path.join(
|
return os.path.join(self.location, os.path.join(self._cwd, path).lstrip("/"))
|
||||||
self.location,
|
|
||||||
os.path.join(self._cwd, path).lstrip('/'))
|
|
||||||
|
|
||||||
def exists(self, path: str) -> bool:
|
def exists(self, path: str) -> bool:
|
||||||
fullpath = self._fullpath(path)
|
fullpath = self._fullpath(path)
|
||||||
|
|
|
@ -22,9 +22,9 @@ import unittest
|
||||||
|
|
||||||
def test_suite():
|
def test_suite():
|
||||||
names = [
|
names = [
|
||||||
'debian_build',
|
"debian_build",
|
||||||
'debian_fix_build',
|
"debian_fix_build",
|
||||||
]
|
]
|
||||||
module_names = ['ognibuild.tests.test_' + name for name in names]
|
module_names = ["ognibuild.tests.test_" + name for name in names]
|
||||||
loader = unittest.TestLoader()
|
loader = unittest.TestLoader()
|
||||||
return loader.loadTestsFromNames(module_names)
|
return loader.loadTestsFromNames(module_names)
|
||||||
|
|
|
@ -22,22 +22,35 @@ from breezy.tests import TestCaseWithTransport, TestCase
|
||||||
|
|
||||||
|
|
||||||
class AddDummyChangelogEntryTests(TestCaseWithTransport):
|
class AddDummyChangelogEntryTests(TestCaseWithTransport):
|
||||||
|
|
||||||
def test_simple(self):
|
def test_simple(self):
|
||||||
tree = self.make_branch_and_tree('.')
|
tree = self.make_branch_and_tree(".")
|
||||||
self.build_tree_contents([('debian/', ), ('debian/changelog', """\
|
self.build_tree_contents(
|
||||||
|
[
|
||||||
|
("debian/",),
|
||||||
|
(
|
||||||
|
"debian/changelog",
|
||||||
|
"""\
|
||||||
janitor (0.1-1) UNRELEASED; urgency=medium
|
janitor (0.1-1) UNRELEASED; urgency=medium
|
||||||
|
|
||||||
* Initial release. (Closes: #XXXXXX)
|
* Initial release. (Closes: #XXXXXX)
|
||||||
|
|
||||||
-- Jelmer Vernooij <jelmer@debian.org> Sat, 04 Apr 2020 14:12:13 +0000
|
-- Jelmer Vernooij <jelmer@debian.org> Sat, 04 Apr 2020 14:12:13 +0000
|
||||||
""")])
|
""",
|
||||||
tree.add(['debian', 'debian/changelog'])
|
),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
tree.add(["debian", "debian/changelog"])
|
||||||
add_dummy_changelog_entry(
|
add_dummy_changelog_entry(
|
||||||
tree, '', 'jan+some', 'some-fixes', 'Dummy build.',
|
tree,
|
||||||
|
"",
|
||||||
|
"jan+some",
|
||||||
|
"some-fixes",
|
||||||
|
"Dummy build.",
|
||||||
timestamp=datetime.datetime(2020, 9, 5, 12, 35, 4, 899654),
|
timestamp=datetime.datetime(2020, 9, 5, 12, 35, 4, 899654),
|
||||||
maintainer=("Jelmer Vernooij", "jelmer@debian.org"))
|
maintainer=("Jelmer Vernooij", "jelmer@debian.org"),
|
||||||
self.assertFileEqual("""\
|
)
|
||||||
|
self.assertFileEqual(
|
||||||
|
"""\
|
||||||
janitor (0.1-1jan+some1) some-fixes; urgency=low
|
janitor (0.1-1jan+some1) some-fixes; urgency=low
|
||||||
|
|
||||||
* Dummy build.
|
* Dummy build.
|
||||||
|
@ -49,23 +62,39 @@ janitor (0.1-1) UNRELEASED; urgency=medium
|
||||||
* Initial release. (Closes: #XXXXXX)
|
* Initial release. (Closes: #XXXXXX)
|
||||||
|
|
||||||
-- Jelmer Vernooij <jelmer@debian.org> Sat, 04 Apr 2020 14:12:13 +0000
|
-- Jelmer Vernooij <jelmer@debian.org> Sat, 04 Apr 2020 14:12:13 +0000
|
||||||
""", 'debian/changelog')
|
""",
|
||||||
|
"debian/changelog",
|
||||||
|
)
|
||||||
|
|
||||||
def test_native(self):
|
def test_native(self):
|
||||||
tree = self.make_branch_and_tree('.')
|
tree = self.make_branch_and_tree(".")
|
||||||
self.build_tree_contents([('debian/', ), ('debian/changelog', """\
|
self.build_tree_contents(
|
||||||
|
[
|
||||||
|
("debian/",),
|
||||||
|
(
|
||||||
|
"debian/changelog",
|
||||||
|
"""\
|
||||||
janitor (0.1) UNRELEASED; urgency=medium
|
janitor (0.1) UNRELEASED; urgency=medium
|
||||||
|
|
||||||
* Initial release. (Closes: #XXXXXX)
|
* Initial release. (Closes: #XXXXXX)
|
||||||
|
|
||||||
-- Jelmer Vernooij <jelmer@debian.org> Sat, 04 Apr 2020 14:12:13 +0000
|
-- Jelmer Vernooij <jelmer@debian.org> Sat, 04 Apr 2020 14:12:13 +0000
|
||||||
""")])
|
""",
|
||||||
tree.add(['debian', 'debian/changelog'])
|
),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
tree.add(["debian", "debian/changelog"])
|
||||||
add_dummy_changelog_entry(
|
add_dummy_changelog_entry(
|
||||||
tree, '', 'jan+some', 'some-fixes', 'Dummy build.',
|
tree,
|
||||||
|
"",
|
||||||
|
"jan+some",
|
||||||
|
"some-fixes",
|
||||||
|
"Dummy build.",
|
||||||
timestamp=datetime.datetime(2020, 9, 5, 12, 35, 4, 899654),
|
timestamp=datetime.datetime(2020, 9, 5, 12, 35, 4, 899654),
|
||||||
maintainer=("Jelmer Vernooij", "jelmer@debian.org"))
|
maintainer=("Jelmer Vernooij", "jelmer@debian.org"),
|
||||||
self.assertFileEqual("""\
|
)
|
||||||
|
self.assertFileEqual(
|
||||||
|
"""\
|
||||||
janitor (0.1jan+some1) some-fixes; urgency=low
|
janitor (0.1jan+some1) some-fixes; urgency=low
|
||||||
|
|
||||||
* Dummy build.
|
* Dummy build.
|
||||||
|
@ -77,23 +106,39 @@ janitor (0.1) UNRELEASED; urgency=medium
|
||||||
* Initial release. (Closes: #XXXXXX)
|
* Initial release. (Closes: #XXXXXX)
|
||||||
|
|
||||||
-- Jelmer Vernooij <jelmer@debian.org> Sat, 04 Apr 2020 14:12:13 +0000
|
-- Jelmer Vernooij <jelmer@debian.org> Sat, 04 Apr 2020 14:12:13 +0000
|
||||||
""", 'debian/changelog')
|
""",
|
||||||
|
"debian/changelog",
|
||||||
|
)
|
||||||
|
|
||||||
def test_exists(self):
|
def test_exists(self):
|
||||||
tree = self.make_branch_and_tree('.')
|
tree = self.make_branch_and_tree(".")
|
||||||
self.build_tree_contents([('debian/', ), ('debian/changelog', """\
|
self.build_tree_contents(
|
||||||
|
[
|
||||||
|
("debian/",),
|
||||||
|
(
|
||||||
|
"debian/changelog",
|
||||||
|
"""\
|
||||||
janitor (0.1-1jan+some1) UNRELEASED; urgency=medium
|
janitor (0.1-1jan+some1) UNRELEASED; urgency=medium
|
||||||
|
|
||||||
* Initial release. (Closes: #XXXXXX)
|
* Initial release. (Closes: #XXXXXX)
|
||||||
|
|
||||||
-- Jelmer Vernooij <jelmer@debian.org> Sat, 04 Apr 2020 14:12:13 +0000
|
-- Jelmer Vernooij <jelmer@debian.org> Sat, 04 Apr 2020 14:12:13 +0000
|
||||||
""")])
|
""",
|
||||||
tree.add(['debian', 'debian/changelog'])
|
),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
tree.add(["debian", "debian/changelog"])
|
||||||
add_dummy_changelog_entry(
|
add_dummy_changelog_entry(
|
||||||
tree, '', 'jan+some', 'some-fixes', 'Dummy build.',
|
tree,
|
||||||
|
"",
|
||||||
|
"jan+some",
|
||||||
|
"some-fixes",
|
||||||
|
"Dummy build.",
|
||||||
timestamp=datetime.datetime(2020, 9, 5, 12, 35, 4, 899654),
|
timestamp=datetime.datetime(2020, 9, 5, 12, 35, 4, 899654),
|
||||||
maintainer=("Jelmer Vernooij", "jelmer@debian.org"))
|
maintainer=("Jelmer Vernooij", "jelmer@debian.org"),
|
||||||
self.assertFileEqual("""\
|
)
|
||||||
|
self.assertFileEqual(
|
||||||
|
"""\
|
||||||
janitor (0.1-1jan+some2) some-fixes; urgency=low
|
janitor (0.1-1jan+some2) some-fixes; urgency=low
|
||||||
|
|
||||||
* Dummy build.
|
* Dummy build.
|
||||||
|
@ -111,6 +156,5 @@ janitor (0.1-1jan+some1) UNRELEASED; urgency=medium
|
||||||
|
|
||||||
|
|
||||||
class BuildArchitectureTests(TestCase):
|
class BuildArchitectureTests(TestCase):
|
||||||
|
|
||||||
def test_is_str(self):
|
def test_is_str(self):
|
||||||
self.assertIsInstance(get_build_architecture(), str)
|
self.assertIsInstance(get_build_architecture(), str)
|
||||||
|
|
|
@ -40,11 +40,15 @@ from breezy.tests import TestCaseWithTransport
|
||||||
|
|
||||||
|
|
||||||
class ResolveErrorTests(TestCaseWithTransport):
|
class ResolveErrorTests(TestCaseWithTransport):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(ResolveErrorTests, self).setUp()
|
super(ResolveErrorTests, self).setUp()
|
||||||
self.tree = self.make_branch_and_tree('.')
|
self.tree = self.make_branch_and_tree(".")
|
||||||
self.build_tree_contents([('debian/', ), ('debian/control', """\
|
self.build_tree_contents(
|
||||||
|
[
|
||||||
|
("debian/",),
|
||||||
|
(
|
||||||
|
"debian/control",
|
||||||
|
"""\
|
||||||
Source: blah
|
Source: blah
|
||||||
Build-Depends: libc6
|
Build-Depends: libc6
|
||||||
|
|
||||||
|
@ -52,16 +56,23 @@ Package: python-blah
|
||||||
Depends: ${python3:Depends}
|
Depends: ${python3:Depends}
|
||||||
Description: A python package
|
Description: A python package
|
||||||
Foo
|
Foo
|
||||||
"""), ('debian/changelog', """\
|
""",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"debian/changelog",
|
||||||
|
"""\
|
||||||
blah (0.1) UNRELEASED; urgency=medium
|
blah (0.1) UNRELEASED; urgency=medium
|
||||||
|
|
||||||
* Initial release. (Closes: #XXXXXX)
|
* Initial release. (Closes: #XXXXXX)
|
||||||
|
|
||||||
-- Jelmer Vernooij <jelmer@debian.org> Sat, 04 Apr 2020 14:12:13 +0000
|
-- Jelmer Vernooij <jelmer@debian.org> Sat, 04 Apr 2020 14:12:13 +0000
|
||||||
""")])
|
""",
|
||||||
self.tree.add(['debian', 'debian/control', 'debian/changelog'])
|
),
|
||||||
self.tree.commit('Initial commit')
|
]
|
||||||
self.overrideAttr(fix_build, 'search_apt_file', self._search_apt_file)
|
)
|
||||||
|
self.tree.add(["debian", "debian/control", "debian/changelog"])
|
||||||
|
self.tree.commit("Initial commit")
|
||||||
|
self.overrideAttr(fix_build, "search_apt_file", self._search_apt_file)
|
||||||
self._apt_files = {}
|
self._apt_files = {}
|
||||||
|
|
||||||
def _search_apt_file(self, path, regex=False):
|
def _search_apt_file(self, path, regex=False):
|
||||||
|
@ -73,129 +84,130 @@ blah (0.1) UNRELEASED; urgency=medium
|
||||||
if path == p:
|
if path == p:
|
||||||
yield pkg
|
yield pkg
|
||||||
|
|
||||||
def resolve(self, error, context=('build', )):
|
def resolve(self, error, context=("build",)):
|
||||||
context = BuildDependencyContext(
|
context = BuildDependencyContext(
|
||||||
self.tree, subpath='', committer='Janitor <janitor@jelmer.uk>',
|
self.tree,
|
||||||
update_changelog=True)
|
subpath="",
|
||||||
return resolve_error(
|
committer="Janitor <janitor@jelmer.uk>",
|
||||||
error, context, VERSIONED_PACKAGE_FIXERS + APT_FIXERS)
|
update_changelog=True,
|
||||||
|
)
|
||||||
|
return resolve_error(error, context, VERSIONED_PACKAGE_FIXERS + APT_FIXERS)
|
||||||
|
|
||||||
def get_build_deps(self):
|
def get_build_deps(self):
|
||||||
with open(self.tree.abspath('debian/control'), 'r') as f:
|
with open(self.tree.abspath("debian/control"), "r") as f:
|
||||||
return next(Deb822.iter_paragraphs(f)).get('Build-Depends', '')
|
return next(Deb822.iter_paragraphs(f)).get("Build-Depends", "")
|
||||||
|
|
||||||
def test_missing_command_unknown(self):
|
def test_missing_command_unknown(self):
|
||||||
self._apt_files = {}
|
self._apt_files = {}
|
||||||
self.assertFalse(self.resolve(
|
self.assertFalse(self.resolve(MissingCommand("acommandthatdoesnotexist")))
|
||||||
MissingCommand('acommandthatdoesnotexist')))
|
|
||||||
|
|
||||||
def test_missing_command_brz(self):
|
def test_missing_command_brz(self):
|
||||||
self._apt_files = {
|
self._apt_files = {
|
||||||
'/usr/bin/b': 'bash',
|
"/usr/bin/b": "bash",
|
||||||
'/usr/bin/brz': 'brz',
|
"/usr/bin/brz": "brz",
|
||||||
'/usr/bin/brzier': 'bash',
|
"/usr/bin/brzier": "bash",
|
||||||
}
|
}
|
||||||
self.assertTrue(self.resolve(MissingCommand('brz')))
|
self.assertTrue(self.resolve(MissingCommand("brz")))
|
||||||
self.assertEqual('libc6, brz', self.get_build_deps())
|
self.assertEqual("libc6, brz", self.get_build_deps())
|
||||||
rev = self.tree.branch.repository.get_revision(
|
rev = self.tree.branch.repository.get_revision(self.tree.branch.last_revision())
|
||||||
self.tree.branch.last_revision())
|
self.assertEqual("Add missing build dependency on brz.\n", rev.message)
|
||||||
self.assertEqual(
|
self.assertFalse(self.resolve(MissingCommand("brz")))
|
||||||
'Add missing build dependency on brz.\n',
|
self.assertEqual("libc6, brz", self.get_build_deps())
|
||||||
rev.message)
|
|
||||||
self.assertFalse(self.resolve(MissingCommand('brz')))
|
|
||||||
self.assertEqual('libc6, brz', self.get_build_deps())
|
|
||||||
|
|
||||||
def test_missing_command_ps(self):
|
def test_missing_command_ps(self):
|
||||||
self._apt_files = {
|
self._apt_files = {
|
||||||
'/bin/ps': 'procps',
|
"/bin/ps": "procps",
|
||||||
'/usr/bin/pscal': 'xcal',
|
"/usr/bin/pscal": "xcal",
|
||||||
}
|
}
|
||||||
self.assertTrue(self.resolve(MissingCommand('ps')))
|
self.assertTrue(self.resolve(MissingCommand("ps")))
|
||||||
self.assertEqual('libc6, procps', self.get_build_deps())
|
self.assertEqual("libc6, procps", self.get_build_deps())
|
||||||
|
|
||||||
def test_missing_ruby_file(self):
|
def test_missing_ruby_file(self):
|
||||||
self._apt_files = {
|
self._apt_files = {
|
||||||
'/usr/lib/ruby/vendor_ruby/rake/testtask.rb': 'rake',
|
"/usr/lib/ruby/vendor_ruby/rake/testtask.rb": "rake",
|
||||||
}
|
}
|
||||||
self.assertTrue(self.resolve(MissingRubyFile('rake/testtask')))
|
self.assertTrue(self.resolve(MissingRubyFile("rake/testtask")))
|
||||||
self.assertEqual('libc6, rake', self.get_build_deps())
|
self.assertEqual("libc6, rake", self.get_build_deps())
|
||||||
|
|
||||||
def test_missing_ruby_file_from_gem(self):
|
def test_missing_ruby_file_from_gem(self):
|
||||||
self._apt_files = {
|
self._apt_files = {
|
||||||
'/usr/share/rubygems-integration/all/gems/activesupport-'
|
"/usr/share/rubygems-integration/all/gems/activesupport-"
|
||||||
'5.2.3/lib/active_support/core_ext/string/strip.rb':
|
"5.2.3/lib/active_support/core_ext/string/strip.rb": "ruby-activesupport"
|
||||||
'ruby-activesupport'}
|
}
|
||||||
self.assertTrue(self.resolve(
|
self.assertTrue(
|
||||||
MissingRubyFile('active_support/core_ext/string/strip')))
|
self.resolve(MissingRubyFile("active_support/core_ext/string/strip"))
|
||||||
self.assertEqual('libc6, ruby-activesupport', self.get_build_deps())
|
)
|
||||||
|
self.assertEqual("libc6, ruby-activesupport", self.get_build_deps())
|
||||||
|
|
||||||
def test_missing_ruby_gem(self):
|
def test_missing_ruby_gem(self):
|
||||||
self._apt_files = {
|
self._apt_files = {
|
||||||
'/usr/share/rubygems-integration/all/specifications/'
|
"/usr/share/rubygems-integration/all/specifications/"
|
||||||
'bio-1.5.2.gemspec': 'ruby-bio',
|
"bio-1.5.2.gemspec": "ruby-bio",
|
||||||
'/usr/share/rubygems-integration/all/specifications/'
|
"/usr/share/rubygems-integration/all/specifications/"
|
||||||
'bio-2.0.2.gemspec': 'ruby-bio',
|
"bio-2.0.2.gemspec": "ruby-bio",
|
||||||
}
|
}
|
||||||
self.assertTrue(self.resolve(MissingRubyGem('bio', None)))
|
self.assertTrue(self.resolve(MissingRubyGem("bio", None)))
|
||||||
self.assertEqual('libc6, ruby-bio', self.get_build_deps())
|
self.assertEqual("libc6, ruby-bio", self.get_build_deps())
|
||||||
self.assertTrue(self.resolve(MissingRubyGem('bio', '2.0.3')))
|
self.assertTrue(self.resolve(MissingRubyGem("bio", "2.0.3")))
|
||||||
self.assertEqual('libc6, ruby-bio (>= 2.0.3)', self.get_build_deps())
|
self.assertEqual("libc6, ruby-bio (>= 2.0.3)", self.get_build_deps())
|
||||||
|
|
||||||
def test_missing_perl_module(self):
|
def test_missing_perl_module(self):
|
||||||
self._apt_files = {
|
self._apt_files = {"/usr/share/perl5/App/cpanminus/fatscript.pm": "cpanminus"}
|
||||||
'/usr/share/perl5/App/cpanminus/fatscript.pm': 'cpanminus'}
|
self.assertTrue(
|
||||||
self.assertTrue(self.resolve(MissingPerlModule(
|
self.resolve(
|
||||||
'App/cpanminus/fatscript.pm', 'App::cpanminus::fatscript', [
|
MissingPerlModule(
|
||||||
'/<<PKGBUILDDIR>>/blib/lib',
|
"App/cpanminus/fatscript.pm",
|
||||||
'/<<PKGBUILDDIR>>/blib/arch',
|
"App::cpanminus::fatscript",
|
||||||
'/etc/perl',
|
[
|
||||||
'/usr/local/lib/x86_64-linux-gnu/perl/5.30.0',
|
"/<<PKGBUILDDIR>>/blib/lib",
|
||||||
'/usr/local/share/perl/5.30.0',
|
"/<<PKGBUILDDIR>>/blib/arch",
|
||||||
'/usr/lib/x86_64-linux-gnu/perl5/5.30',
|
"/etc/perl",
|
||||||
'/usr/share/perl5',
|
"/usr/local/lib/x86_64-linux-gnu/perl/5.30.0",
|
||||||
'/usr/lib/x86_64-linux-gnu/perl/5.30',
|
"/usr/local/share/perl/5.30.0",
|
||||||
'/usr/share/perl/5.30',
|
"/usr/lib/x86_64-linux-gnu/perl5/5.30",
|
||||||
'/usr/local/lib/site_perl',
|
"/usr/share/perl5",
|
||||||
'/usr/lib/x86_64-linux-gnu/perl-base',
|
"/usr/lib/x86_64-linux-gnu/perl/5.30",
|
||||||
'.'])))
|
"/usr/share/perl/5.30",
|
||||||
self.assertEqual('libc6, cpanminus', self.get_build_deps())
|
"/usr/local/lib/site_perl",
|
||||||
|
"/usr/lib/x86_64-linux-gnu/perl-base",
|
||||||
|
".",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.assertEqual("libc6, cpanminus", self.get_build_deps())
|
||||||
|
|
||||||
def test_missing_pkg_config(self):
|
def test_missing_pkg_config(self):
|
||||||
self._apt_files = {
|
self._apt_files = {
|
||||||
'/usr/lib/x86_64-linux-gnu/pkgconfig/xcb-xfixes.pc':
|
"/usr/lib/x86_64-linux-gnu/pkgconfig/xcb-xfixes.pc": "libxcb-xfixes0-dev"
|
||||||
'libxcb-xfixes0-dev'}
|
}
|
||||||
self.assertTrue(self.resolve(MissingPkgConfig('xcb-xfixes')))
|
self.assertTrue(self.resolve(MissingPkgConfig("xcb-xfixes")))
|
||||||
self.assertEqual('libc6, libxcb-xfixes0-dev', self.get_build_deps())
|
self.assertEqual("libc6, libxcb-xfixes0-dev", self.get_build_deps())
|
||||||
|
|
||||||
def test_missing_pkg_config_versioned(self):
|
def test_missing_pkg_config_versioned(self):
|
||||||
self._apt_files = {
|
self._apt_files = {
|
||||||
'/usr/lib/x86_64-linux-gnu/pkgconfig/xcb-xfixes.pc':
|
"/usr/lib/x86_64-linux-gnu/pkgconfig/xcb-xfixes.pc": "libxcb-xfixes0-dev"
|
||||||
'libxcb-xfixes0-dev'}
|
}
|
||||||
self.assertTrue(self.resolve(MissingPkgConfig('xcb-xfixes', '1.0')))
|
self.assertTrue(self.resolve(MissingPkgConfig("xcb-xfixes", "1.0")))
|
||||||
self.assertEqual(
|
self.assertEqual("libc6, libxcb-xfixes0-dev (>= 1.0)", self.get_build_deps())
|
||||||
'libc6, libxcb-xfixes0-dev (>= 1.0)', self.get_build_deps())
|
|
||||||
|
|
||||||
def test_missing_python_module(self):
|
def test_missing_python_module(self):
|
||||||
self._apt_files = {
|
self._apt_files = {"/usr/lib/python3/dist-packages/m2r.py": "python3-m2r"}
|
||||||
'/usr/lib/python3/dist-packages/m2r.py': 'python3-m2r'
|
self.assertTrue(self.resolve(MissingPythonModule("m2r")))
|
||||||
}
|
self.assertEqual("libc6, python3-m2r", self.get_build_deps())
|
||||||
self.assertTrue(self.resolve(MissingPythonModule('m2r')))
|
|
||||||
self.assertEqual('libc6, python3-m2r', self.get_build_deps())
|
|
||||||
|
|
||||||
def test_missing_go_package(self):
|
def test_missing_go_package(self):
|
||||||
self._apt_files = {
|
self._apt_files = {
|
||||||
'/usr/share/gocode/src/github.com/chzyer/readline/utils_test.go':
|
"/usr/share/gocode/src/github.com/chzyer/readline/utils_test.go": "golang-github-chzyer-readline-dev",
|
||||||
'golang-github-chzyer-readline-dev',
|
|
||||||
}
|
}
|
||||||
self.assertTrue(self.resolve(
|
self.assertTrue(self.resolve(MissingGoPackage("github.com/chzyer/readline")))
|
||||||
MissingGoPackage('github.com/chzyer/readline')))
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
'libc6, golang-github-chzyer-readline-dev',
|
"libc6, golang-github-chzyer-readline-dev", self.get_build_deps()
|
||||||
self.get_build_deps())
|
)
|
||||||
|
|
||||||
def test_missing_vala_package(self):
|
def test_missing_vala_package(self):
|
||||||
self._apt_files = {
|
self._apt_files = {
|
||||||
'/usr/share/vala-0.48/vapi/posix.vapi': 'valac-0.48-vapi',
|
"/usr/share/vala-0.48/vapi/posix.vapi": "valac-0.48-vapi",
|
||||||
}
|
}
|
||||||
self.assertTrue(self.resolve(MissingValaPackage('posix')))
|
self.assertTrue(self.resolve(MissingValaPackage("posix")))
|
||||||
self.assertEqual('libc6, valac-0.48-vapi', self.get_build_deps())
|
self.assertEqual("libc6, valac-0.48-vapi", self.get_build_deps())
|
||||||
|
|
|
@ -30,11 +30,10 @@ from . import DetailedFailure
|
||||||
|
|
||||||
def export_vcs_tree(tree, directory):
|
def export_vcs_tree(tree, directory):
|
||||||
try:
|
try:
|
||||||
export(tree, directory, 'dir', None)
|
export(tree, directory, "dir", None)
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
if e.errno == errno.ENOSPC:
|
if e.errno == errno.ENOSPC:
|
||||||
raise DetailedFailure(
|
raise DetailedFailure(1, ["export"], NoSpaceOnDevice())
|
||||||
1, ['export'], NoSpaceOnDevice())
|
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
||||||
|
@ -44,12 +43,11 @@ def dupe_vcs_tree(tree, directory):
|
||||||
tree = tree.basis_tree()
|
tree = tree.basis_tree()
|
||||||
try:
|
try:
|
||||||
result = tree._repository.controldir.sprout(
|
result = tree._repository.controldir.sprout(
|
||||||
directory, create_tree_if_local=True,
|
directory, create_tree_if_local=True, revision_id=tree.get_revision_id()
|
||||||
revision_id=tree.get_revision_id())
|
)
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
if e.errno == errno.ENOSPC:
|
if e.errno == errno.ENOSPC:
|
||||||
raise DetailedFailure(
|
raise DetailedFailure(1, ["sprout"], NoSpaceOnDevice())
|
||||||
1, ['sprout'], NoSpaceOnDevice())
|
|
||||||
raise
|
raise
|
||||||
if not result.has_workingtree():
|
if not result.has_workingtree():
|
||||||
raise AssertionError
|
raise AssertionError
|
||||||
|
|
Loading…
Add table
Reference in a new issue