Skip to content

Commit

Permalink
xbstrap: add discard command for nuking packages
Browse files Browse the repository at this point in the history
  • Loading branch information
no92 committed May 20, 2022
1 parent 314222b commit 09eb845
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 12 deletions.
21 changes: 21 additions & 0 deletions xbstrap/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -915,6 +915,25 @@ def resolve_host_paths(x):
# ----------------------------------------------------------------------------------------


def do_discard(args):
cfg = config_for_args(args)
sel = select_pkgs(cfg, args)
plan = xbstrap.base.Plan(cfg)
handle_plan_args(cfg, plan, args)
plan.wanted.update([(xbstrap.base.Action.DISCARD_PKG, pkg) for pkg in sel])
plan.run_plan()


do_discard.parser = main_subparsers.add_parser(
"discard",
parents=[handle_plan_args.parser, select_pkgs.parser],
formatter_class=argparse.RawDescriptionHelpFormatter,
description="Discard a package from your tree",
)

# ----------------------------------------------------------------------------------------


def do_execute_manifest(args):
if args.c is not None:
manifest = yaml.load(args.c, Loader=xbstrap.base.global_yaml_loader)
Expand Down Expand Up @@ -990,6 +1009,8 @@ def main():
do_run_task(args)
elif args.command == "lsp":
do_lsp(args)
elif args.command == "discard":
do_discard(args)
else:
assert not "Unexpected command"
except (
Expand Down
90 changes: 78 additions & 12 deletions xbstrap/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import tempfile
import urllib.request
import zipfile
from contextlib import suppress
from enum import Enum

import colorama
Expand Down Expand Up @@ -951,8 +952,11 @@ def check_if_mirrord(self, settings):

return ItemState()

def mark_as_fetched(self):
touch(os.path.join(self.source_dir, "fetched.xbstrap"))
def mark_as_fetched(self, mark=True):
if mark:
touch(os.path.join(self.source_dir, "fetched.xbstrap"))
else:
os.unlink(os.path.join(self.source_dir, "fetched.xbstrap"))

def check_if_checkedout(self, settings):
path = os.path.join(self.source_dir, "checkedout.xbstrap")
Expand All @@ -962,8 +966,11 @@ def check_if_checkedout(self, settings):
return ItemState(missing=True)
return ItemState(timestamp=stat.st_mtime)

def mark_as_checkedout(self):
touch(os.path.join(self.source_dir, "checkedout.xbstrap"))
def mark_as_checkedout(self, mark=True):
if mark:
touch(os.path.join(self.source_dir, "checkedout.xbstrap"))
else:
os.unlink(os.path.join(self.source_dir, "checkedout.xbstrap"))

def check_if_patched(self, settings):
path = os.path.join(self.source_dir, "patched.xbstrap")
Expand All @@ -973,8 +980,11 @@ def check_if_patched(self, settings):
return ItemState(missing=True)
return ItemState(timestamp=stat.st_mtime)

def mark_as_patched(self):
touch(os.path.join(self.source_dir, "patched.xbstrap"))
def mark_as_patched(self, mark=True):
if mark:
touch(os.path.join(self.source_dir, "patched.xbstrap"))
else:
os.unlink(os.path.join(self.source_dir, "patched.xbstrap"))

def check_if_regenerated(self, settings):
path = os.path.join(self.source_dir, "regenerated.xbstrap")
Expand All @@ -984,8 +994,11 @@ def check_if_regenerated(self, settings):
return ItemState(missing=True)
return ItemState(timestamp=stat.st_mtime)

def mark_as_regenerated(self):
touch(os.path.join(self.source_dir, "regenerated.xbstrap"))
def mark_as_regenerated(self, mark=True):
if mark:
touch(os.path.join(self.source_dir, "regenerated.xbstrap"))
else:
os.unlink(os.path.join(self.source_dir, "regenerated.xbstrap"))


class HostStage(RequirementsMixin):
Expand Down Expand Up @@ -1060,7 +1073,7 @@ def check_if_installed(self, settings):
return ItemState(missing=True)
return ItemState(timestamp=stat.st_mtime)

def mark_as_installed(self):
def mark_as_installed(self, mark=True):
stage_spec = ""
if not self._inherited:
stage_spec = "@" + self.stage_name
Expand All @@ -1069,7 +1082,10 @@ def mark_as_installed(self):
path = os.path.join(
self._pkg.prefix_dir, "etc", "xbstrap", self._pkg.name + stage_spec + ".installed"
)
touch(path)
if mark:
touch(path)
else:
os.unlink(path)


class HostPackage(RequirementsMixin):
Expand Down Expand Up @@ -1448,11 +1464,14 @@ def check_if_installed(self, settings):
return ItemState(missing=True)
return ItemState()

def mark_as_installed(self):
def mark_as_installed(self, mark=True):
_util.try_mkdir(os.path.join(self._cfg.sysroot_dir, "etc"))
_util.try_mkdir(os.path.join(self._cfg.sysroot_dir, "etc", "xbstrap"))
path = os.path.join(self._cfg.sysroot_dir, "etc", "xbstrap", self.name + ".installed")
touch(path)
if mark:
touch(path)
else:
os.unlink(path)


class PackageRunTask(RequirementsMixin):
Expand Down Expand Up @@ -2610,6 +2629,36 @@ def run_tool_task(cfg, task):
)


def discard_src(cfg, src):
with suppress(Exception):
src.mark_as_fetched(mark=False)
src.mark_as_checkedout(mark=False)
src.mark_as_patched(mark=False)
src.mark_as_regenerated(mark=False)
with suppress(Exception):
shutil.rmtree(os.path.join(cfg.source_root, src.source_subdir))


def discard_pkg(cfg, pkg):
with suppress(Exception):
pkg.mark_as_configured(mark=False)
pkg.mark_as_installed(mark=False)
with suppress(Exception):
shutil.rmtree(os.path.join(cfg.build_root, pkg.build_subdir))
shutil.rmtree(os.path.join(cfg.build_root, pkg.collect_subdir))

output = subprocess.DEVNULL
if verbosity:
output = None
effective_arch = pkg.architecture
environ = os.environ.copy()
_util.build_environ_paths(environ, "PATH", prepend=[os.path.join(_util.find_home(), "bin")])
environ["XBPS_ARCH"] = effective_arch
args = ["xbps-remove", "-Fy", "-r", cfg.sysroot_dir, pkg.name]
_util.log_info("Running {}".format(args))
subprocess.call(args, env=environ, stdout=output)


# ---------------------------------------------------------------------------------------
# Build planning.
# ---------------------------------------------------------------------------------------
Expand Down Expand Up @@ -2662,6 +2711,8 @@ class Action(Enum):
WANT_PKG = 21
# xbstrap-mirror functionality.
MIRROR_SRC = 22
DISCARD_SRC = 23
DISCARD_PKG = 24


Action.strings = {
Expand All @@ -2687,6 +2738,8 @@ class Action(Enum):
Action.WANT_TOOL: "want-tool",
Action.WANT_PKG: "want-pkg",
Action.MIRROR_SRC: "mirror",
Action.DISCARD_SRC: "discard-source",
Action.DISCARD_PKG: "discard-package",
}


Expand Down Expand Up @@ -2766,6 +2819,8 @@ def _determine_state(self):
Action.WANT_TOOL: lambda s, c: s.check_if_fully_installed(c),
Action.WANT_PKG: lambda s, c: s.check_staging(c),
Action.MIRROR_SRC: lambda s, c: s.check_if_mirrord(c),
Action.DISCARD_SRC: lambda s, c: ItemState(missing=True),
Action.DISCARD_PKG: lambda s, c: ItemState(missing=True),
}
self._state = visitors[self.action](self.subject, self.settings)

Expand Down Expand Up @@ -2965,6 +3020,13 @@ def add_task_dependencies(s):
add_pkg_dependencies(subject)
add_task_dependencies(subject)

elif action == Action.DISCARD_SRC:
pass

elif action == Action.DISCARD_PKG:
src = self._cfg.get_source(subject.source)
item.build_edges.add((action.DISCARD_SRC, src))

return item

def _do_materialization_visit(self, edges):
Expand Down Expand Up @@ -3308,6 +3370,10 @@ def emit_progress(status):
raise ExecutionFailureError(action, subject)
elif action == Action.MIRROR_SRC:
mirror_src(self._cfg, subject)
elif action == Action.DISCARD_SRC:
discard_src(self._cfg, subject)
elif action == Action.DISCARD_PKG:
discard_pkg(self._cfg, subject)
else:
raise AssertionError("Unexpected action")
item.exec_status = ExecutionStatus.SUCCESS
Expand Down

0 comments on commit 09eb845

Please sign in to comment.