You've already forked OpenUxAS-bootstrap
mirror of
https://github.com/AdaCore/OpenUxAS-bootstrap.git
synced 2026-02-12 13:07:23 -08:00
Make sure references to python in shebangs and in text specify python3 rather than simply python. This better supports convention of fresh machines.
218 lines
6.3 KiB
Python
218 lines
6.3 KiB
Python
#! /usr/bin/env python3
|
|
|
|
"""Script to configure OpenUxAS anod environment for development work."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from lib.anod.paths import REPO_DIR, SPEC_DIR
|
|
|
|
from e3.main import Main
|
|
|
|
from argparse import ArgumentParser, RawDescriptionHelpFormatter
|
|
import logging
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
import yaml
|
|
|
|
|
|
SPEC_DIR_NAME = "specs"
|
|
|
|
CONFIG_DIR_NAME = "config"
|
|
REPOSITORIES_FILENAME = "repositories.yaml"
|
|
REPOSITORIES_YAML_PATH = os.path.join(SPEC_DIR, CONFIG_DIR_NAME, REPOSITORIES_FILENAME)
|
|
|
|
DEFAULT_REPO_DIR = os.path.join(REPO_DIR, "develop")
|
|
|
|
DEFAULT_UXAS_DIR = os.path.join(DEFAULT_REPO_DIR, "OpenUxAS")
|
|
UXAS_YAML_KEY = "openuxas"
|
|
|
|
DEFAULT_LMCP_DIR = os.path.join(DEFAULT_REPO_DIR, "LmcpGen")
|
|
LMCP_YAML_KEY = "lmcpgen"
|
|
|
|
DEFAULT_AMASE_DIR = os.path.join(DEFAULT_REPO_DIR, "OpenAMASE")
|
|
AMASE_YAML_KEY = "amase"
|
|
|
|
VCS_YAML_KEY = "vcs"
|
|
VCS_YAML_VALUE = "external"
|
|
|
|
URL_YAML_KEY = "url"
|
|
|
|
REV_YAML_KEY = "revision"
|
|
REV_YAML_VALUE = "None"
|
|
|
|
DESCRIPTION = """
|
|
Check out OpenUxAS, LmcpGen, and/or OpenAMASE for development work. Configure
|
|
anod so that the checked out repositories will be used during the build.
|
|
|
|
For example, run:
|
|
|
|
./anod devel-setup uxas
|
|
|
|
to check out OpenUxAS for development. By default, the checkout will be in
|
|
`develop/OpenUxAS`.
|
|
|
|
This results in a "development" configuration for the anod build, rather than
|
|
the default "release" configuration.
|
|
|
|
In the "release" configuration, anod will always ensure that all repositories
|
|
are at the specified refspec of their remote, stashing any local changes as
|
|
needed. This ensures that the build is up-to-date with all remotes, and is
|
|
thus appropriate for a release build. This configuration is not, however,
|
|
appropriate for a development build, as local changes are always stashed before
|
|
the build.
|
|
|
|
In the "development" configuration, however, anod will not manage the
|
|
repositories that are checked out by this script; instead, it will use their
|
|
current state for the build.
|
|
"""
|
|
|
|
|
|
def update_yaml(yaml_filename: str, key: str, clone_dir: str) -> None:
|
|
"""Update the given yaml file for the specified component."""
|
|
with open(yaml_filename, "r") as yaml_file:
|
|
loaded_yaml = yaml.safe_load(yaml_file.read())
|
|
|
|
loaded_yaml[key][VCS_YAML_KEY] = VCS_YAML_VALUE
|
|
loaded_yaml[key][URL_YAML_KEY] = clone_dir
|
|
loaded_yaml[key][REV_YAML_KEY] = REV_YAML_VALUE
|
|
|
|
with open(yaml_filename, "w") as yaml_file:
|
|
yaml_file.write(yaml.dump(loaded_yaml))
|
|
|
|
|
|
def check_out(name: str, remote: str, refspec: str, clone_dir: str) -> None:
|
|
"""
|
|
Check out the given repository.
|
|
|
|
This is a deep (non-shallow) checkout, which differs from e3's typical
|
|
operation.
|
|
"""
|
|
if not os.path.exists(clone_dir):
|
|
logging.info(
|
|
"Checking out %s\n from %s %s\n to %s"
|
|
% (name, remote, refspec, clone_dir)
|
|
)
|
|
|
|
subprocess.run(["git", "clone", remote, clone_dir])
|
|
subprocess.run(["git", "checkout", refspec], cwd=clone_dir)
|
|
|
|
|
|
def configure_argparse_for_component(
|
|
ap: ArgumentParser,
|
|
key: str,
|
|
name: str,
|
|
default_dir: str,
|
|
default_remote: str,
|
|
default_refspec: str,
|
|
) -> None:
|
|
"""Add arguments to argparse for the given component."""
|
|
ap.add_argument(
|
|
"--%s-clone-dir" % key,
|
|
default=default_dir,
|
|
help=("absolute path where the %s repository has been " + "or should be cloned")
|
|
% name,
|
|
)
|
|
|
|
ap.add_argument(
|
|
"--%s-remote" % key,
|
|
default=default_remote,
|
|
help="the remote %s repository to clone" % name,
|
|
)
|
|
|
|
ap.add_argument(
|
|
"--%s-refspec" % key,
|
|
default=default_refspec,
|
|
help="the %s refspec to clone" % name,
|
|
)
|
|
|
|
|
|
def do_devel_setup(m: Main, set_prog: bool = True) -> int:
|
|
"""Execute the main functionality of the script."""
|
|
if set_prog:
|
|
m.argument_parser.prog = m.argument_parser.prog + " devel-setup"
|
|
|
|
m.argument_parser.formatter_class = RawDescriptionHelpFormatter
|
|
m.argument_parser.description = DESCRIPTION
|
|
|
|
if not os.path.exists(REPOSITORIES_YAML_PATH):
|
|
logging.error(
|
|
"Cannot find `repositories.yaml` under `specs/config`.\n"
|
|
+ "Are you running in the right location?",
|
|
file=sys.stderr,
|
|
)
|
|
exit(1)
|
|
|
|
with open(REPOSITORIES_YAML_PATH, "r") as yaml_file:
|
|
loaded_yaml = yaml.safe_load(yaml_file.read())
|
|
|
|
m.argument_parser.add_argument(
|
|
"component",
|
|
choices=["uxas", "lmcp", "amase"],
|
|
nargs="+",
|
|
help="the component to configure for development",
|
|
)
|
|
|
|
# Some defensiveness could be added here by wrapping in try-except to
|
|
# account for possible missing keys in the repositories.yaml
|
|
configure_argparse_for_component(
|
|
m.argument_parser,
|
|
"uxas",
|
|
"OpenUxAS",
|
|
DEFAULT_UXAS_DIR,
|
|
loaded_yaml[UXAS_YAML_KEY][URL_YAML_KEY],
|
|
loaded_yaml[UXAS_YAML_KEY][REV_YAML_KEY],
|
|
)
|
|
|
|
configure_argparse_for_component(
|
|
m.argument_parser,
|
|
"lmcp",
|
|
"LmcpGen",
|
|
DEFAULT_LMCP_DIR,
|
|
loaded_yaml[LMCP_YAML_KEY][URL_YAML_KEY],
|
|
loaded_yaml[LMCP_YAML_KEY][REV_YAML_KEY],
|
|
)
|
|
|
|
configure_argparse_for_component(
|
|
m.argument_parser,
|
|
"amase",
|
|
"OpenAMASE",
|
|
DEFAULT_AMASE_DIR,
|
|
loaded_yaml[AMASE_YAML_KEY][URL_YAML_KEY],
|
|
loaded_yaml[AMASE_YAML_KEY][REV_YAML_KEY],
|
|
)
|
|
|
|
args = m.argument_parser.parse_args()
|
|
|
|
try:
|
|
if "uxas" in args.component:
|
|
update_yaml(REPOSITORIES_YAML_PATH, UXAS_YAML_KEY, args.uxas_clone_dir)
|
|
check_out(
|
|
"OpenUxAS", args.uxas_remote, args.uxas_refspec, args.uxas_clone_dir
|
|
)
|
|
|
|
if "lmcp" in args.component:
|
|
update_yaml(REPOSITORIES_YAML_PATH, LMCP_YAML_KEY, args.lmcp_clone_dir)
|
|
check_out(
|
|
"LmcpGen", args.lmcp_remote, args.lmcp_refspec, args.lmcp_clone_dir
|
|
)
|
|
|
|
if "amase" in args.component:
|
|
update_yaml(REPOSITORIES_YAML_PATH, AMASE_YAML_KEY, args.amase_clone_dir)
|
|
check_out(
|
|
"OpenAMASE", args.amase_remote, args.amase_refspec, args.amase_clone_dir
|
|
)
|
|
|
|
return 0
|
|
|
|
except Exception as e:
|
|
print(e, file=sys.stderr)
|
|
print(" ", file=sys.stderr)
|
|
m.argument_parser.print_usage()
|
|
|
|
return 1
|
|
|
|
|
|
if __name__ == "__main__":
|
|
exit(do_devel_setup(Main(), set_prog=False))
|