Implement auto-migrate (aka fmt)
This commit is contained in:
parent
f151e57a12
commit
7a40392253
3 changed files with 64 additions and 8 deletions
|
@ -6,6 +6,7 @@ import os
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import pickle
|
import pickle
|
||||||
from typing import List
|
from typing import List
|
||||||
|
import sys
|
||||||
|
|
||||||
from . import (
|
from . import (
|
||||||
__author__,
|
__author__,
|
||||||
|
@ -17,6 +18,7 @@ from .v0 import PackageV0, ProfileV0
|
||||||
from .v1 import PackageV1, ProfileV1
|
from .v1 import PackageV1, ProfileV1
|
||||||
|
|
||||||
import click
|
import click
|
||||||
|
import toml
|
||||||
from toposort import toposort_flatten
|
from toposort import toposort_flatten
|
||||||
from vfs import Vfs
|
from vfs import Vfs
|
||||||
|
|
||||||
|
@ -294,12 +296,28 @@ def do_state(confdir, state_file):
|
||||||
print(*e)
|
print(*e)
|
||||||
|
|
||||||
|
|
||||||
@cli.command("migrate-to-toml")
|
@cli.command("fmt")
|
||||||
@click.argument("confdir", type=Path)
|
@click.argument("confdir", type=Path)
|
||||||
@click.argument("requirement", type=str)
|
@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"""
|
"""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:
|
if __name__ == "__main__" or 1:
|
||||||
logging.basicConfig(
|
logging.basicConfig(
|
||||||
|
|
|
@ -52,6 +52,34 @@ class PackageV0(Package):
|
||||||
if postf.exists():
|
if postf.exists():
|
||||||
fs.exec(self.root, sh([str(postf)]))
|
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):
|
class ProfileV0(PackageV0):
|
||||||
def requires(self):
|
def requires(self):
|
||||||
|
|
|
@ -39,8 +39,14 @@ class PackageV1(Package):
|
||||||
def requires(self):
|
def requires(self):
|
||||||
"""Get the dependencies of this package."""
|
"""Get the dependencies of this package."""
|
||||||
|
|
||||||
return self.config().get("package", {}).get("requires") or [
|
def _name(it):
|
||||||
it["name"] for it in self.config().get("package", {}).get("require", [])
|
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"):
|
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
|
pass
|
||||||
|
|
||||||
elif isinstance(content, list):
|
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):
|
elif isinstance(content, dict):
|
||||||
return self.do_sh_or_script(
|
self.do_sh_or_script(
|
||||||
content["run"],
|
content["run"],
|
||||||
fs,
|
fs,
|
||||||
dest,
|
dest,
|
||||||
|
@ -66,14 +73,13 @@ class PackageV1(Package):
|
||||||
installf = self.root / content
|
installf = self.root / content
|
||||||
if installf.exists():
|
if installf.exists():
|
||||||
with open(installf, "r") as fp:
|
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:
|
elif content:
|
||||||
f = tempf(f"{sum}.sh")
|
f = tempf(f"{sum}.sh")
|
||||||
with open(f, "w") as fp:
|
with open(f, "w") as fp:
|
||||||
fp.write(content)
|
fp.write(content)
|
||||||
fs.exec(cwd, sh([f]))
|
fs.exec(cwd, sh([f]))
|
||||||
return True
|
|
||||||
|
|
||||||
def do_build(self, fs: Vfs, dest: Path):
|
def do_build(self, fs: Vfs, dest: Path):
|
||||||
self.do_sh_or_script(self.config().get("package", {}).get("build"), fs, dest)
|
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)
|
self.do_sh_or_script(self.config().get("package", {}).get("post_install"), fs, dest)
|
||||||
|
|
||||||
|
|
||||||
|
def json(self):
|
||||||
|
return self.config()
|
||||||
|
|
||||||
|
|
||||||
class ProfileV1(PackageV1):
|
class ProfileV1(PackageV1):
|
||||||
"""Unline packages, profiles don't support recursive stow of contents."""
|
"""Unline packages, profiles don't support recursive stow of contents."""
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue