cram fixes
This commit is contained in:
parent
bb50fa2c20
commit
60d40bd956
4 changed files with 64 additions and 27 deletions
0
projects/cram/src/python/cram/__init__.py
Normal file
0
projects/cram/src/python/cram/__init__.py
Normal file
|
@ -9,9 +9,10 @@ import re
|
||||||
import sys
|
import sys
|
||||||
from typing import NamedTuple
|
from typing import NamedTuple
|
||||||
|
|
||||||
|
from vfs import Vfs
|
||||||
|
|
||||||
import click
|
import click
|
||||||
from toposort import toposort_flatten
|
from toposort import toposort_flatten
|
||||||
from vfs import Vfs
|
|
||||||
|
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
@ -68,7 +69,7 @@ class PackageV0(NamedTuple):
|
||||||
|
|
||||||
return requires
|
return requires
|
||||||
|
|
||||||
def install(self, fs: Vfs, dest):
|
def install(self, fs: Vfs, dest: Path):
|
||||||
"""Install this package."""
|
"""Install this package."""
|
||||||
buildf = self.root / "BUILD"
|
buildf = self.root / "BUILD"
|
||||||
if buildf.exists():
|
if buildf.exists():
|
||||||
|
@ -89,6 +90,26 @@ class PackageV0(NamedTuple):
|
||||||
fs.exec(self.root, ["bash", str(postf)])
|
fs.exec(self.root, ["bash", str(postf)])
|
||||||
|
|
||||||
|
|
||||||
|
class ProfileV0(PackageV0):
|
||||||
|
def install(self, fs: Vfs, dest: Path):
|
||||||
|
"""Profiles differ from Packages in that they don't support literal files."""
|
||||||
|
buildf = self.root / "BUILD"
|
||||||
|
if buildf.exists():
|
||||||
|
fs.exec(self.root, ["bash", str(buildf)])
|
||||||
|
|
||||||
|
pref = self.root / "PRE_INSTALL"
|
||||||
|
if pref.exists():
|
||||||
|
fs.exec(self.root, ["bash", str(pref)])
|
||||||
|
|
||||||
|
installf = self.root / "INSTALL"
|
||||||
|
if installf.exists():
|
||||||
|
fs.exec(self.root, ["bash", str(installf)])
|
||||||
|
|
||||||
|
postf = self.root / "POST_INSTALL"
|
||||||
|
if postf.exists():
|
||||||
|
fs.exec(self.root, ["bash", str(postf)])
|
||||||
|
|
||||||
|
|
||||||
def load_config(root: Path) -> dict:
|
def load_config(root: Path) -> dict:
|
||||||
"""Load the configured packages."""
|
"""Load the configured packages."""
|
||||||
|
|
||||||
|
@ -109,8 +130,8 @@ def load_config(root: Path) -> dict:
|
||||||
p, str(p.relative_to(root))
|
p, str(p.relative_to(root))
|
||||||
)
|
)
|
||||||
|
|
||||||
# Register the metapackages themselves
|
# Register the metapackages themselves using the profile type
|
||||||
packages[str(mp_root.relative_to(root))] = PackageV0(
|
packages[str(mp_root.relative_to(root))] = ProfileV0(
|
||||||
mp_root, str(mp_root.relative_to(root)), True
|
mp_root, str(mp_root.relative_to(root)), True
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -206,13 +227,13 @@ def cli():
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
@cli.command("apply")
|
@cli.command()
|
||||||
@click.option("--execute/--dry-run", default=False)
|
@click.option("--execute/--dry-run", default=False)
|
||||||
@click.option("--optimize/--no-optimize", default=True)
|
|
||||||
@click.option("--state-file", default=".cram.log", type=Path)
|
@click.option("--state-file", default=".cram.log", type=Path)
|
||||||
|
@click.option("--optimize/--no-optimize", default=False)
|
||||||
@click.argument("confdir", type=Path)
|
@click.argument("confdir", type=Path)
|
||||||
@click.argument("destdir", type=Path)
|
@click.argument("destdir", type=Path)
|
||||||
def cmd_apply(confdir, destdir, state_file, execute, optimize):
|
def apply(confdir, destdir, state_file, execute, optimize):
|
||||||
"""The entry point of cram."""
|
"""The entry point of cram."""
|
||||||
|
|
||||||
# Resolve the two input paths to absolutes
|
# Resolve the two input paths to absolutes
|
||||||
|
@ -239,33 +260,47 @@ def cmd_apply(confdir, destdir, state_file, execute, optimize):
|
||||||
|
|
||||||
else:
|
else:
|
||||||
for e in executable_fs._log:
|
for e in executable_fs._log:
|
||||||
print("-", *e)
|
print("-", e)
|
||||||
|
|
||||||
|
|
||||||
@cli.command("show")
|
@cli.command()
|
||||||
@click.option("--state-file", default=".cram.log", type=Path)
|
@click.option("--state-file", default=".cram.log", type=Path)
|
||||||
@click.argument("confdir", type=Path)
|
@click.argument("confdir", type=Path)
|
||||||
def cmd_show(confdir, state_file):
|
def show(confdir, state_file):
|
||||||
"""List out the last `apply` state in the <confdir>/.cram.log or --state-file."""
|
"""List out the last `apply` state in the <confdir>/.cram.log or --state-file."""
|
||||||
root = confdir.resolve()
|
root = confdir.resolve()
|
||||||
|
|
||||||
if not state_file.is_absolute():
|
if not state_file.is_absolute():
|
||||||
state_file = root / state_file
|
state_file = root / state_file
|
||||||
|
|
||||||
fs = load_fs(state_file)
|
fs = load_fs(state_file)
|
||||||
|
|
||||||
for e in fs._log:
|
for e in fs._log:
|
||||||
print(*e)
|
print(*e)
|
||||||
|
|
||||||
|
|
||||||
@cli.command("list")
|
@cli.command()
|
||||||
@click.argument("confdir", type=Path)
|
@click.argument("confdir", type=Path)
|
||||||
def cmd_list(confdir):
|
@click.argument("list_packages", nargs=-1)
|
||||||
|
def list(confdir, list_packages):
|
||||||
"""List out packages, profiles, hosts and subpackages in the <confdir>."""
|
"""List out packages, profiles, hosts and subpackages in the <confdir>."""
|
||||||
packages = load_config(confdir)
|
packages = load_config(confdir)
|
||||||
|
|
||||||
|
if list_packages:
|
||||||
|
dest = Path("~/")
|
||||||
|
for pname in list_packages:
|
||||||
|
fs = Vfs()
|
||||||
|
p = packages[pname]
|
||||||
|
p.install(fs, dest)
|
||||||
|
print(f"{pname}: ({type(p).__name__})")
|
||||||
|
print("requires:")
|
||||||
|
for e in p.requires():
|
||||||
|
print(" -", e)
|
||||||
|
print("log:")
|
||||||
|
for e in fs._log:
|
||||||
|
print(" -", *e)
|
||||||
|
|
||||||
|
else:
|
||||||
for pname in sorted(packages.keys()):
|
for pname in sorted(packages.keys()):
|
||||||
p = packages[pname]
|
p = packages[pname]
|
||||||
print(f"{pname}:")
|
print(f"{pname}: ({type(p).__name__})")
|
||||||
for d in p.requires():
|
for d in p.requires():
|
||||||
print(f"- {d}")
|
print(f"- {d}")
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ The implementation.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
from shutil import rmtree
|
||||||
from subprocess import run
|
from subprocess import run
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,14 +16,11 @@ class Vfs(object):
|
||||||
def __init__(self, log=None):
|
def __init__(self, log=None):
|
||||||
self._log = log or []
|
self._log = log or []
|
||||||
|
|
||||||
def execute(self, execute=False):
|
def execute(self):
|
||||||
for e in self._log:
|
for e in self._log:
|
||||||
_log.debug(e)
|
_log.debug(e)
|
||||||
|
|
||||||
if not execute:
|
if e[0] == "exec":
|
||||||
continue
|
|
||||||
|
|
||||||
elif e[0] == "exec":
|
|
||||||
_, dir, cmd = e
|
_, dir, cmd = e
|
||||||
run(cmd, cwd=str(dir))
|
run(cmd, cwd=str(dir))
|
||||||
|
|
||||||
|
@ -36,6 +34,7 @@ class Vfs(object):
|
||||||
|
|
||||||
assert not dest.exists()
|
assert not dest.exists()
|
||||||
dest.symlink_to(src)
|
dest.symlink_to(src)
|
||||||
|
assert dest.exists()
|
||||||
|
|
||||||
elif e[0] == "copy":
|
elif e[0] == "copy":
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
@ -50,6 +49,9 @@ class Vfs(object):
|
||||||
|
|
||||||
elif e[0] == "unlink":
|
elif e[0] == "unlink":
|
||||||
_, dest = e
|
_, dest = e
|
||||||
|
if dest.is_dir():
|
||||||
|
rmtree(dest)
|
||||||
|
elif dest.is_file():
|
||||||
dest.unlink()
|
dest.unlink()
|
||||||
|
|
||||||
def _append(self, msg):
|
def _append(self, msg):
|
||||||
|
|
|
@ -6,7 +6,7 @@ multi_line_output = 3
|
||||||
lines_after_imports = 2
|
lines_after_imports = 2
|
||||||
default_section = THIRDPARTY
|
default_section = THIRDPARTY
|
||||||
known_localfolder = datalog
|
known_localfolder = datalog
|
||||||
sections = FUTURE,STDLIB,LOCALFOLDER,THIRDPARTY,
|
sections = STDLIB,LOCALFOLDER,FIRSTPARTY,THIRDPARTY
|
||||||
|
|
||||||
force_sort_within_sections = 1
|
force_sort_within_sections = 1
|
||||||
force_alphabetical_sort_within_sections = 1
|
force_alphabetical_sort_within_sections = 1
|
||||||
|
|
Loading…
Reference in a new issue