Implement auto-migrate (aka fmt)

This commit is contained in:
Reid 'arrdem' McKenzie 2022-07-26 00:23:26 -06:00
parent 547396b76e
commit e718bae88e
3 changed files with 64 additions and 8 deletions

View file

@ -6,6 +6,7 @@ import os
from pathlib import Path
import pickle
from typing import List
import sys
from . import (
__author__,
@ -17,6 +18,7 @@ from .v0 import PackageV0, ProfileV0
from .v1 import PackageV1, ProfileV1
import click
import toml
from toposort import toposort_flatten
from vfs import Vfs
@ -294,12 +296,28 @@ def do_state(confdir, state_file):
print(*e)
@cli.command("migrate-to-toml")
@cli.command("fmt")
@click.argument("confdir", type=Path)
@click.argument("requirement", type=str)
def do_migrate(confdig, requirement):
def do_migrate(confdir, requirement):
"""Convert from the 0.0.0 config format to the 0.1.0 TOML format"""
root = confdir.resolve()
if not root.is_dir():
log.fatal(f"{confdir} does not exist!")
_exit(1)
packages = load_packages(root)
pkg = packages[requirement]
json = pkg.json()
for suffix in pkg.SPECIAL_FILES:
f = (root / requirement / suffix)
if f.exists():
f.unlink()
with open(root / requirement / "pkg.toml", "w") as fp:
toml.dump(json, fp)
if __name__ == "__main__" or 1:
logging.basicConfig(

View file

@ -52,6 +52,34 @@ class PackageV0(Package):
if postf.exists():
fs.exec(self.root, sh([str(postf)]))
def _read(self, p: Path):
if p.exists():
with open(p) as fp:
return fp.read()
else:
return None
def json(self):
buildt = self._read(self.root / "BUILD")
pret = self._read(self.root / "PRE_INSTALL")
installt = self._read(self.root / "INSTALL")
postt = self._read(self.root / "POST_INSTALL")
o = {"cram": {"version": 1}, "package": {"require": []}}
if buildt:
o["package"]["build"] = [{"run": buildt}]
if pret:
o["package"]["pre_install"] = [{"run": pret}]
if installt:
o["package"]["install"] = [{"run": installt}]
if postt:
o["package"]["install"] = [{"run": postt}]
o["package"]["require"] = [{"name": it} for it in sorted(self.requires())]
return o
class ProfileV0(PackageV0):
def requires(self):

View file

@ -39,8 +39,14 @@ class PackageV1(Package):
def requires(self):
"""Get the dependencies of this package."""
return self.config().get("package", {}).get("requires") or [
it["name"] for it in self.config().get("package", {}).get("require", [])
def _name(it):
if isinstance(it, str):
return it
elif isinstance(it, dict):
return it["name"]
return [
_name(it) for it in self.config().get("package", {}).get("require", [])
]
def do_sh_or_script(self, content: Optional[Union[List[str], str]], fs: Vfs, dest: Path, cwd: Path = "/tmp"):
@ -48,10 +54,11 @@ class PackageV1(Package):
pass
elif isinstance(content, list):
return any(self.do_sh_or_script(c, fs, dest) for c in content)
for c in content:
self.do_sh_or_script(c, fs, dest)
elif isinstance(content, dict):
return self.do_sh_or_script(
self.do_sh_or_script(
content["run"],
fs,
dest,
@ -66,14 +73,13 @@ class PackageV1(Package):
installf = self.root / content
if installf.exists():
with open(installf, "r") as fp:
return self.do_sh_or_script(fp.read(), fs, dest)
self.do_sh_or_script(fp.read(), fs, dest)
elif content:
f = tempf(f"{sum}.sh")
with open(f, "w") as fp:
fp.write(content)
fs.exec(cwd, sh([f]))
return True
def do_build(self, fs: Vfs, dest: Path):
self.do_sh_or_script(self.config().get("package", {}).get("build"), fs, dest)
@ -89,6 +95,10 @@ class PackageV1(Package):
self.do_sh_or_script(self.config().get("package", {}).get("post_install"), fs, dest)
def json(self):
return self.config()
class ProfileV1(PackageV1):
"""Unline packages, profiles don't support recursive stow of contents."""