186 lines
6.2 KiB
Python
186 lines
6.2 KiB
Python
# Copyright (C) 2019-2020 Jelmer Vernooij <jelmer@jelmer.uk>
|
|
# encoding: utf-8
|
|
#
|
|
# This program is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; either version 2 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program; if not, write to the Free Software
|
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
import logging
|
|
import os
|
|
import sys
|
|
from . import UnidentifiedError
|
|
from .buildsystem import NoBuildToolsFound, detect_buildsystems
|
|
from .resolver import (
|
|
auto_resolver,
|
|
native_resolvers,
|
|
)
|
|
from .resolver.apt import AptResolver
|
|
|
|
|
|
def get_necessary_declared_requirements(resolver, requirements, stages):
|
|
missing = []
|
|
for stage, req in requirements:
|
|
if stage in stages:
|
|
missing.append(req)
|
|
return missing
|
|
|
|
|
|
def install_necessary_declared_requirements(resolver, buildsystem, stages):
|
|
missing = []
|
|
try:
|
|
declared_reqs = list(buildsystem.get_declared_dependencies())
|
|
except NotImplementedError:
|
|
logging.warning(
|
|
"Unable to determine declared dependencies from %s", buildsystem
|
|
)
|
|
else:
|
|
missing.extend(
|
|
get_necessary_declared_requirements(resolver, declared_reqs, stages)
|
|
)
|
|
resolver.install(missing)
|
|
|
|
|
|
# Types of dependencies:
|
|
# - core: necessary to do anything with the package
|
|
# - build: necessary to build the package
|
|
# - test: necessary to run the tests
|
|
# - dev: necessary for development (e.g. linters, yacc)
|
|
|
|
STAGE_MAP = {
|
|
"dist": [],
|
|
"info": [],
|
|
"install": ["core", "build"],
|
|
"test": ["test", "build", "core"],
|
|
"build": ["build", "core"],
|
|
"clean": [],
|
|
}
|
|
|
|
|
|
def determine_fixers(session, resolver):
|
|
from .buildlog import RequirementFixer
|
|
return [RequirementFixer(resolver)]
|
|
|
|
|
|
def main(): # noqa: C901
|
|
import argparse
|
|
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument(
|
|
"--directory", "-d", type=str, help="Directory for project.", default="."
|
|
)
|
|
parser.add_argument("--schroot", type=str, help="schroot to run in.")
|
|
parser.add_argument(
|
|
"--resolve",
|
|
choices=["apt", "native", "auto"],
|
|
default="auto",
|
|
help="What to do about missing dependencies",
|
|
)
|
|
parser.add_argument(
|
|
"--explain",
|
|
action="store_true",
|
|
help="Explain what needs to be done rather than making changes",
|
|
)
|
|
parser.add_argument(
|
|
"--ignore-declared-dependencies",
|
|
"--optimistic",
|
|
action="store_true",
|
|
help="Ignore declared dependencies, follow build errors only",
|
|
)
|
|
parser.add_argument("--verbose", action="store_true", help="Be verbose")
|
|
subparsers = parser.add_subparsers(dest="subcommand")
|
|
subparsers.add_parser("dist")
|
|
subparsers.add_parser("build")
|
|
subparsers.add_parser("clean")
|
|
subparsers.add_parser("test")
|
|
subparsers.add_parser("info")
|
|
install_parser = subparsers.add_parser("install")
|
|
install_parser.add_argument(
|
|
"--user", action="store_true", help="Install in local-user directories."
|
|
)
|
|
|
|
args = parser.parse_args()
|
|
if not args.subcommand:
|
|
parser.print_usage()
|
|
return 1
|
|
if args.verbose:
|
|
logging.basicConfig(level=logging.DEBUG, format="%(message)s")
|
|
else:
|
|
logging.basicConfig(level=logging.INFO, format="%(message)s")
|
|
if args.schroot:
|
|
from .session.schroot import SchrootSession
|
|
|
|
session = SchrootSession(args.schroot)
|
|
else:
|
|
from .session.plain import PlainSession
|
|
|
|
session = PlainSession()
|
|
with session:
|
|
if args.resolve == "apt":
|
|
resolver = AptResolver.from_session(session)
|
|
elif args.resolve == "native":
|
|
resolver = native_resolvers(session)
|
|
elif args.resolve == "auto":
|
|
resolver = auto_resolver(session)
|
|
logging.info("Using requirement resolver: %s", resolver)
|
|
os.chdir(args.directory)
|
|
try:
|
|
bss = list(detect_buildsystems(args.directory))
|
|
logging.info("Detected buildsystems: %r", bss)
|
|
if not args.ignore_declared_dependencies and not args.explain:
|
|
stages = STAGE_MAP[args.subcommand]
|
|
if stages:
|
|
logging.info("Checking that declared requirements are present")
|
|
for bs in bss:
|
|
install_necessary_declared_requirements(resolver, bs, stages)
|
|
fixers = determine_fixers(session, resolver)
|
|
if args.subcommand == "dist":
|
|
from .dist import run_dist
|
|
|
|
run_dist(
|
|
session=session, buildsystems=bss, resolver=resolver, fixers=fixers
|
|
)
|
|
if args.subcommand == "build":
|
|
from .build import run_build
|
|
|
|
run_build(session, buildsystems=bss, resolver=resolver, fixers=fixers)
|
|
if args.subcommand == "clean":
|
|
from .clean import run_clean
|
|
|
|
run_clean(session, buildsystems=bss, resolver=resolver, fixers=fixers)
|
|
if args.subcommand == "install":
|
|
from .install import run_install
|
|
|
|
run_install(
|
|
session,
|
|
buildsystems=bss,
|
|
resolver=resolver,
|
|
fixers=fixers,
|
|
user=args.user,
|
|
)
|
|
if args.subcommand == "test":
|
|
from .test import run_test
|
|
|
|
run_test(session, buildsystems=bss, resolver=resolver, fixers=fixers)
|
|
if args.subcommand == "info":
|
|
from .info import run_info
|
|
|
|
run_info(session, buildsystems=bss)
|
|
except UnidentifiedError:
|
|
return 1
|
|
except NoBuildToolsFound:
|
|
logging.info("No build tools found.")
|
|
return 1
|
|
return 0
|
|
|
|
|
|
sys.exit(main())
|