diff options
author | André Erdmann <dywi@mailerd.de> | 2013-07-05 18:51:55 +0200 |
---|---|---|
committer | André Erdmann <dywi@mailerd.de> | 2013-07-05 18:51:55 +0200 |
commit | 38a83a4e3db660c79c7449ef484e13f09eedf531 (patch) | |
tree | 3073616fd2d1bf3df984d641fe7c9006ce47d122 /roverlay/overlay | |
parent | giles/hooks: create metadata cache (NOT TESTED) (diff) | |
download | R_overlay-38a83a4e3db660c79c7449ef484e13f09eedf531.tar.gz R_overlay-38a83a4e3db660c79c7449ef484e13f09eedf531.tar.bz2 R_overlay-38a83a4e3db660c79c7449ef484e13f09eedf531.zip |
roverlay/overlay: "selfdep reduction"
This commit adds support for "selfdep reduction", which removes packages/ebuilds
with "internal" dependencies (on other R packages, so-called "selfdeps") that
are effectively unsatisfiable (which is now recognized _after_ overlay creation,
but before writing the overlay).
Diffstat (limited to 'roverlay/overlay')
-rw-r--r-- | roverlay/overlay/category.py | 8 | ||||
-rw-r--r-- | roverlay/overlay/pkgdir/packagedir_base.py | 5 | ||||
-rw-r--r-- | roverlay/overlay/root.py | 87 |
3 files changed, 91 insertions, 9 deletions
diff --git a/roverlay/overlay/category.py b/roverlay/overlay/category.py index 9c5c79f..8038141 100644 --- a/roverlay/overlay/category.py +++ b/roverlay/overlay/category.py @@ -112,7 +112,7 @@ class Category ( object ): def get_nonempty ( self, name ): subdir = self._subdirs.get ( name, None ) return subdir if ( subdir and not subdir.empty() ) else None - # --- end of has_nonempty (...) --- + # --- end of get_nonempty (...) --- def has ( self, subdir ): return subdir in self._subdirs @@ -136,6 +136,12 @@ class Category ( object ): ) # --- end of import_ebuilds (...) --- + def iter_package_info ( self ): + for subdir in self._subdirs.values(): + for p_info in subdir.iter_package_info(): + yield p_info + # --- end of iter_package_info (...) --- + def list_package_names ( self ): for name, subdir in self._subdirs.items(): if not subdir.empty(): diff --git a/roverlay/overlay/pkgdir/packagedir_base.py b/roverlay/overlay/pkgdir/packagedir_base.py index 8b5b634..3c28703 100644 --- a/roverlay/overlay/pkgdir/packagedir_base.py +++ b/roverlay/overlay/pkgdir/packagedir_base.py @@ -37,6 +37,7 @@ import roverlay.overlay.additionsdir import roverlay.overlay.pkgdir.distroot.static import roverlay.overlay.pkgdir.metadata + class PackageDirBase ( object ): """The PackageDir base class that implements most functionality except for Manifest file creation.""" @@ -119,6 +120,10 @@ class PackageDirBase ( object ): self._need_metadata = False # --- end of __init__ (...) --- + def iter_package_info ( self ): + return self._packages.values() + # --- end of iter_package_info (...) -- + def _remove_ebuild_file ( self, pkg_info ): """Removes the ebuild file of a pkg_info object. Returns True on success, else False. diff --git a/roverlay/overlay/root.py b/roverlay/overlay/root.py index a5e847c..c754cd3 100644 --- a/roverlay/overlay/root.py +++ b/roverlay/overlay/root.py @@ -624,7 +624,7 @@ class Overlay ( object ): def remove_empty_categories ( self ): """Removes empty categories.""" - catlist = self._categories.items() + catlist = list ( self._categories.items() ) for cat in catlist: cat[1].remove_empty() if cat[1].empty(): @@ -671,7 +671,14 @@ class Overlay ( object ): ) # --- end of import_ebuilds (...) --- + def iter_package_info ( self ): + for cat in self._categories.values(): + for p_info in cat.iter_package_info(): + yield p_info + # --- end of iter_package_info (...) --- + def remove_bad_packages ( self ): + # # "prepare" # ## collect: @@ -679,30 +686,94 @@ class Overlay ( object ): ## p->selfdeps->prepare_selfdep_reduction() ## add p->selfdeps to a list/listlike object S ## + selfdeps = set() + add_selfdeps = selfdeps.update + + for cat in self._categories.values(): + for p_info in cat.iter_package_info(): + if p_info.init_selfdep_validate(): + add_selfdeps ( p_info.selfdeps ) + # -- end for cat; + del add_selfdeps + + ## ## link: ## foreach selfdep in S loop ## find <PackageInfo> candidates in overlay and link them to selfdep ## end loop + ## + for selfdep in selfdeps: + cat = self._categories.get ( selfdep.category, None ) + if cat: + pkgdir = cat.get_nonempty ( selfdep.package ) + if pkgdir: + selfdep.linkall_if_version_matches ( + pkgdir.iter_package_info() + ) + # -- end for selfdep; + # # "reduce" # - ## num_removed <- 0 - ## first <- True + ## num_removed <- 1 + ## + ## while num_removed > 0 loop + ## num_removed <- 0 ## - ## while num_removed > 0 or first loop - ## first <- False ## foreach selfdep in S loop ## num_removed += selfdep.reduce() ## end loop + ## + ## num_removed <- 0 ## end loop ## + num_removed = 1 + num_removed_total = 0 + + while num_removed > 0: + num_removed = 0 + for selfdep in selfdeps: + num_removed += selfdep.do_reduce() + num_removed_total += num_removed + # -- end while num_removed; + # - # "balance" [if <anything removed>] + # "balance" # - ## find all <PackageInfo> p with valid == False + ## find all <PackageInfo> p with p.has_valid_selfdeps() == False ## drop p ## - raise NotImplementedError ( "TODO" ) + + num_pkg_removed = 0 + for cat in self._categories.values(): + for pkgdir in cat._subdirs.values(): + for pvr, p_info in pkgdir._packages.items(): + if not p_info.has_valid_selfdeps(): + pkgdir.purge_package ( pvr ) + num_pkg_removed += 1 + # -- end for cat; + + + if num_pkg_removed > 0: + # remove_empty_categories() could be done in the loop above + self.remove_empty_categories() + + print ( + 'REMOVE_BAD_PACKAGES: found {:d} unsatisfied selfdeps, ' + 'which caused {:d} \'broken\' ebuild to be removed.'.format ( + num_removed_total + ) + ) + elif num_removed_total > 0: + raise Exception ( + "num_removed_total > 0, but no packages removed?!".format ( + num_removed_total + ) + ) + else: + print ( "REMOVE_BAD_PACKAGES: nothing done." ) + + return num_pkg_removed # --- end of remove_bad_packages (...) --- def scan ( self, **kw ): |