Skip to content

Commit

Permalink
Enhancement: eclean-dist handle git checkouts
Browse files Browse the repository at this point in the history
A new feature for eclean-dist to clean git3-src.
Optionally, cleaning the git3-src can be skipped with --skip-git.

Bug: https://bugs.gentoo.org/622938

Signed-off-by: Siddhanth Rathod <[email protected]>
  • Loading branch information
hyprsyd committed Oct 18, 2023
1 parent 5146d35 commit 6e8097d
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 19 deletions.
35 changes: 33 additions & 2 deletions pym/gentoolkit/eclean/clean.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@


import os
import shutil
import sys

import gentoolkit.pprinter as pp
Expand All @@ -23,7 +24,7 @@ def __init__(self, controller, quiet):
self.controller = controller
self.quiet = quiet

def clean_dist(self, clean_dict):
def clean_dist(self, clean_dict, git):
"""Calculate size of each entry for display, prompt user if needed,
delete files if approved and return the total size of files that
have been deleted.
Expand All @@ -39,6 +40,7 @@ def clean_dist(self, clean_dict):
for key in sorted(clean_dict):
clean_size += self._clean_files(clean_dict[key], key, file_type)
# return total size of deleted or to delete files
clean_size += self._clean_git_src(git)
return clean_size

def clean_pkgs(self, clean_dict, pkgdir):
Expand Down Expand Up @@ -69,7 +71,7 @@ def clean_pkgs(self, clean_dict, pkgdir):
# return total size of deleted or to delete files
return clean_size

def pretend_clean(self, clean_dict):
def pretend_clean(self, clean_dict, git={}):
"""Shortcut function that calculates total space savings
for the files in clean_dict.
Expand All @@ -80,6 +82,8 @@ def pretend_clean(self, clean_dict):
file_type = "file"
clean_size = 0
# tally all entries one by one; sorting helps reading
if git:
clean_size += self._clean_git_src(git, pretend=True)
for key in sorted(clean_dict):
key_size = self._get_size(clean_dict[key])
self.controller(key_size, key, clean_dict[key], file_type)
Expand Down Expand Up @@ -148,3 +152,30 @@ def _clean_files(self, files, key, file_type):
print(pp.error("Could not delete " + file_), file=sys.stderr)
print(pp.error("Error: %s" % str(er)), file=sys.stderr)
return clean_size

def _clean_git_src(self, deprecated_git, pretend=False):
clean_size = 0
for checkout in deprecated_git:
csize = 0
for path, dirs, files in os.walk(checkout):
for f in files:
fp = os.path.join(path, f)
try:
statinfo = os.stat(fp)
except OSError as er:
print(
pp.error("Could not get stat info for:" + fp),
file=sys.stderr,
)
print(pp.error("Error: %s" % str(er)), file=sys.stderr)
clean_size += statinfo.st_size
csize += statinfo.st_size

try:
self.controller(csize, checkout, checkout, "checkout")
if not pretend:
shutil.rmtree(checkout)
except OSError as er:
print(pp.error("Could not delete " + checkout), file=sys.stderr)
print(pp.error("Error: %s" % str(er)), file=sys.stderr)
return clean_size
42 changes: 29 additions & 13 deletions pym/gentoolkit/eclean/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,25 +13,25 @@
__productname__ = "eclean"
__description__ = "A cleaning tool for Gentoo distfiles and binaries."

import getopt
import os
import sys
import re
import sys
import time
import getopt

import portage
from portage.output import white, yellow, turquoise, green, red
from portage.output import green, red, turquoise, white, yellow

import gentoolkit.pprinter as pp
from gentoolkit.eclean.clean import CleanUp
from gentoolkit.eclean.exclude import ParseExcludeFileException, parseExcludeFile
from gentoolkit.eclean.output import OutputControl
from gentoolkit.eclean.search import (
DistfilesSearch,
findPackages,
port_settings,
pkgdir,
port_settings,
)
from gentoolkit.eclean.exclude import parseExcludeFile, ParseExcludeFileException
from gentoolkit.eclean.clean import CleanUp
from gentoolkit.eclean.output import OutputControl

# from gentoolkit.eclean.dbapi import Dbapi
from gentoolkit.eprefix import EPREFIX
Expand Down Expand Up @@ -309,6 +309,10 @@ def printUsage(_error=None, help=None, unresolved_invalids=None):
" " + '"two hundreds kilobytes", etc. Units are: ' + "G, M, K and B.",
file=out,
)
print(
yellow(" --skip-git") + " - skip cleaning of git3_src ",
file=out,
)
print(file=out)
print(
"More detailed instruction can be found in",
Expand Down Expand Up @@ -420,6 +424,8 @@ def optionSwitch(option, opts, action=None):
options["unique-use"] = True
elif o in ("--no-clean-invalid"):
options["no-clean-invalid"] = True
elif o in ("--skip-git"):
options["skip-git"] = True
else:
return_code = False
# sanity check of --deep only options:
Expand Down Expand Up @@ -457,7 +463,11 @@ def optionSwitch(option, opts, action=None):
"verbose",
]
getopt_options["short"]["distfiles"] = "fs:"
getopt_options["long"]["distfiles"] = ["fetch-restricted", "size-limit="]
getopt_options["long"]["distfiles"] = [
"fetch-restricted",
"size-limit=",
"skip-git",
]
getopt_options["short"]["packages"] = "iu"
getopt_options["long"]["packages"] = [
"ignore-failure",
Expand All @@ -481,6 +491,7 @@ def optionSwitch(option, opts, action=None):
options["ignore-failure"] = False
options["no-clean-invalid"] = False
options["unique-use"] = False
options["skip-git"] = False
# if called by a well-named symlink, set the action accordingly:
action = None
# temp print line to ensure it is the svn/branch code running, etc..
Expand Down Expand Up @@ -546,6 +557,7 @@ def doAction(action, options, exclude={}, output=None):
files_type = "distfiles"
saved = {}
deprecated = {}
git = []
# find files to delete, depending on the action
if not options["quiet"]:
output.einfo("Building file list for " + action + " cleaning...")
Expand All @@ -567,7 +579,7 @@ def doAction(action, options, exclude={}, output=None):
# portdb=Dbapi(portage.db[portage.root]["porttree"].dbapi),
# var_dbapi=Dbapi(portage.db[portage.root]["vartree"].dbapi),
)
clean_me, saved, deprecated = engine.findDistfiles(
clean_me, saved, deprecated, git = engine.findDistfiles(
exclude=exclude,
destructive=options["destructive"],
fetch_restricted=options["fetch-restricted"],
Expand All @@ -581,7 +593,7 @@ def doAction(action, options, exclude={}, output=None):
cleaner = CleanUp(output.progress_controller, options["quiet"])

# actually clean files if something was found
if clean_me:
if clean_me or git:
# verbose pretend message
if options["pretend"] and not options["quiet"]:
output.einfo("Here are the " + files_type + " that would be deleted:")
Expand All @@ -590,9 +602,13 @@ def doAction(action, options, exclude={}, output=None):
output.einfo("Cleaning " + files_type + "...")
# do the cleanup, and get size of deleted files
if options["pretend"]:
clean_size = cleaner.pretend_clean(clean_me)
if options["skip-git"]:
git = {}
clean_size = cleaner.pretend_clean(clean_me, git)
elif action in ["distfiles"]:
clean_size = cleaner.clean_dist(clean_me)
if options["skip-git"]:
git = {}
clean_size = cleaner.clean_dist(clean_me, git)
elif action in ["packages"]:
clean_size = cleaner.clean_pkgs(clean_me, pkgdir)
# vocabulary for final message
Expand All @@ -602,7 +618,7 @@ def doAction(action, options, exclude={}, output=None):
verb = "were"
# display freed space
if not options["quiet"]:
output.total("normal", clean_size, len(clean_me), verb, action)
output.total("normal", clean_size, len(clean_me) + len(git), verb, action)
# nothing was found
elif not options["quiet"]:
output.einfo("Your " + action + " directory was already clean.")
Expand Down
4 changes: 3 additions & 1 deletion pym/gentoolkit/eclean/output.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@


import sys
from portage.output import blue, yellow, teal, green, red

from portage.output import blue, green, red, teal, yellow

from gentoolkit.pprinter import cpv, number


Expand Down
32 changes: 29 additions & 3 deletions pym/gentoolkit/eclean/search.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import os
import stat
import sys
import shlex
from functools import partial
from typing import Optional

Expand All @@ -16,13 +17,12 @@

import gentoolkit.pprinter as pp
from gentoolkit.eclean.exclude import (
exclDictMatchCP,
exclDictExpand,
exclDictExpandPkgname,
exclDictMatchCP,
exclMatchFilename,
)


# Misc. shortcuts to some portage stuff:
port_settings = portage.settings
pkgdir = port_settings["PKGDIR"]
Expand Down Expand Up @@ -134,6 +134,7 @@ def findDistfiles(
# gather the files to be cleaned
self.output("...checking limits for %d ebuild sources" % len(pkgs))

git = self.git_check(_distdir)
checks = self._get_default_checks(size_limit, time_limit, exclude, destructive)
checks.extend(extra_checks)
clean_me = self._check_limits(_distdir, checks, clean_me)
Expand All @@ -148,7 +149,7 @@ def findDistfiles(
+ "%s remaining candidates to clean" % len(clean_me)
)
clean_me, saved = self._check_excludes(exclude, clean_me)
return clean_me, saved, deprecated
return clean_me, saved, deprecated, git

# begin _check_limits code block

Expand Down Expand Up @@ -332,6 +333,31 @@ def _non_destructive(
deprecated.update(_deprecated)
return pkgs, deprecated

def git_check(self, distdir):
"""Checks $DISTDIR/git3-src for checkouts which are not in the vardb"""
git_src = os.path.join(distdir, "git3-src")
expected_dirs = set()
for i in set(self.vardb.cpv_all()):
if "live" in self.vardb.aux_get(i, ["PROPERTIES"]):
try:
# try to get the dir names of the cloned
# repos from the environment file.
vcs_dir = {
i.split("=")[-1].strip('"')
for i in (
shlex.split(
self.vardb._aux_env_search(i, ["EVCS_STORE_DIRS"])[
"EVCS_STORE_DIRS"
].strip("()")
)
)
}
expected_dirs.update(vcs_dir)
except KeyError:
pass
actual_dirs = {os.path.join(git_src, i) for i in os.listdir(git_src)}
return actual_dirs.difference(expected_dirs)

def _fetch_restricted(self, pkgs_, cpvs):
"""perform fetch restricted non-destructive source
filename lookups
Expand Down

0 comments on commit 6e8097d

Please sign in to comment.