[gentoo-commits] proj/pkgcore/pkgcore:master commit in: src/pkgcore/scripts/

2023-11-24 Thread Arthur Zamarin
commit: e3276db7fd78c3d7514d97aae24eabbb924a1ff1
Author: Brian Harring  gmail  com>
AuthorDate: Tue Nov 21 01:00:53 2023 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Fri Nov 24 15:17:21 2023 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcore.git/commit/?id=e3276db7

pquery: Fix --environment-re support .

This has been broken for a long while, thus I'm renaming
it to `--environment-re` (from `--environment`) in the
process.

Tests will follow in a later PR (pquery test infra needs some
work).

Signed-off-by: Brian Harring  gmail.com>
Closes: https://github.com/pkgcore/pkgcore/pull/415
Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcore/scripts/pquery.py | 19 +++
 1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/src/pkgcore/scripts/pquery.py b/src/pkgcore/scripts/pquery.py
index 0a01702fd..7211441fc 100644
--- a/src/pkgcore/scripts/pquery.py
+++ b/src/pkgcore/scripts/pquery.py
@@ -16,6 +16,7 @@ running them on source repos makes no sense.
 import errno
 import os
 from functools import partial
+import typing
 
 from snakeoil.cli import arghparse
 from snakeoil.formatters import decorate_forced_wrapping
@@ -35,9 +36,17 @@ from ..util import parserestrict
 class DataSourceRestriction(values.base):
 """Turn a data_source into a line iterator and apply a restriction."""
 
-def __init__(self, childrestriction, **kwargs):
+__slots__ = ("negate", "restriction")
+
+def __init__(
+self,
+childrestriction: typing.Union[values.base, values.AnyMatch],
+negate=False,
+**kwargs,
+):
 super().__init__(**kwargs)
-self.restriction = childrestriction
+object.__setattr__(self, "restriction", childrestriction)
+object.__setattr__(self, "negate", negate)
 
 def __str__(self):
 return f"DataSourceRestriction: {self.restriction} 
negate={self.negate}"
@@ -929,9 +938,11 @@ def parse_maintainer_email(value):
 
 
 @bind_add_query(
-"--environment", action="append", help="regexp search in environment.bz2"
+"--environment-re",
+action="append",
+help="regexp search of lines in environment.bz2",
 )
-def parse_envmatch(value):
+def parse_environment_re(value):
 """Apply a regexp to the environment."""
 return packages.PackageRestriction(
 "environment", 
DataSourceRestriction(values.AnyMatch(values.StrRegex(value)))



[gentoo-commits] proj/pkgcore/pkgcore:master commit in: src/pkgcore/scripts/

2023-11-24 Thread Arthur Zamarin
commit: a65cbd1bbf283e22c908136ca79b8e52cb69a593
Author: Brian Harring  gmail  com>
AuthorDate: Tue Nov 21 00:33:39 2023 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Fri Nov 24 15:17:21 2023 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcore.git/commit/?id=a65cbd1b

pquery: correct minor english typo in comments

Signed-off-by: Brian Harring  gmail.com>
Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcore/scripts/pquery.py | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/pkgcore/scripts/pquery.py b/src/pkgcore/scripts/pquery.py
index 7a8922bad..0a01702fd 100644
--- a/src/pkgcore/scripts/pquery.py
+++ b/src/pkgcore/scripts/pquery.py
@@ -871,7 +871,7 @@ def parse_ownsre(value):
 @bind_add_query("--maintainer", action="append", help="regex to search for 
maintainers")
 def parse_maintainer(value):
 """
-Case insensitive Regex match on the combined 'name ' bit of
+Case-insensitive Regex match on the combined 'name ' bit of
 metadata.xml's maintainer data.
 """
 if value and value != "maintainer-needed":
@@ -895,7 +895,7 @@ def parse_maintainer(value):
 )
 def parse_maintainer_name(value):
 """
-Case insensitive Regex match on the name bit of metadata.xml's
+Case-insensitive Regex match on the name bit of metadata.xml's
 maintainer data.
 """
 return packages.PackageRestriction(
@@ -915,7 +915,7 @@ def parse_maintainer_name(value):
 )
 def parse_maintainer_email(value):
 """
-Case insensitive Regex match on the email bit of metadata.xml's
+Case-insensitive Regex match on the email bit of metadata.xml's
 maintainer data.
 """
 return packages.PackageRestriction(



[gentoo-commits] proj/pkgcore/pkgcore:master commit in: src/pkgcore/scripts/

2023-10-23 Thread Arthur Zamarin
commit: 590658425abffe0253602adc30f7c22172f92b13
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Mon Oct 23 17:03:30 2023 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Mon Oct 23 17:03:30 2023 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcore.git/commit/?id=59065842

pmaint eclass: add better invocation with output filename format

Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcore/scripts/pmaint.py | 26 +++---
 1 file changed, 23 insertions(+), 3 deletions(-)

diff --git a/src/pkgcore/scripts/pmaint.py b/src/pkgcore/scripts/pmaint.py
index 008de533f..c148454a7 100644
--- a/src/pkgcore/scripts/pmaint.py
+++ b/src/pkgcore/scripts/pmaint.py
@@ -496,6 +496,19 @@ eclass_opts = eclass.add_argument_group("subcommand 
options")
 eclass_opts.add_argument(
 "--dir", dest="output_dir", type=arghparse.create_dir, help="output 
directory"
 )
+eclass_opts.add_argument(
+"-o",
+"--output",
+dest="output_format",
+default="{eclass}.eclass.{format}",
+help="output file name format",
+docs="""
+Output file name format. Defaults to ``{eclass}.eclass.{format}``. You
+can use ``{eclass}`` and ``{format}`` placeholders to customize the
+output file name. The filename can have path separator, for example:
+``{eclass}/{eclass}.eclass.{format}``.
+""",
+)
 eclass_opts.add_argument(
 "-f",
 "--format",
@@ -541,9 +554,16 @@ def _eclass_main(options, out, err):
 
 for path in options.eclasses:
 try:
-with open(
-pjoin(options.output_dir, f"{os.path.basename(path)}.{ext}"), 
"wt"
-) as f:
+filename = pjoin(
+options.output_dir,
+options.output_format.format(
+eclass=os.path.basename(path).removesuffix(".eclass"),
+format=ext,
+),
+)
+out.write("Compiling: ", path)
+os.makedirs(os.path.dirname(filename), exist_ok=True)
+with open(filename, "wt") as f:
 obj = EclassDoc(path, sourced=True)
 convert_func = getattr(obj, f"to_{options.format}")
 f.write(convert_func())



[gentoo-commits] proj/pkgcore/pkgcore:master commit in: src/pkgcore/scripts/, src/pkgcore/ebuild/

2023-10-23 Thread Arthur Zamarin
commit: d12bea98c17f10f039ebb2331353c6ea794674cf
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Mon Oct 23 17:03:28 2023 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Mon Oct 23 17:03:28 2023 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcore.git/commit/?id=d12bea98

eclassdoc: output exported phases

Closes: https://bugs.gentoo.org/846503
Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcore/ebuild/eclass.py  | 11 +++
 src/pkgcore/scripts/pmaint.py |  2 +-
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/src/pkgcore/ebuild/eclass.py b/src/pkgcore/ebuild/eclass.py
index 4612d0b33..9859f6571 100644
--- a/src/pkgcore/ebuild/eclass.py
+++ b/src/pkgcore/ebuild/eclass.py
@@ -590,6 +590,17 @@ class EclassDoc(AttrDict):
 rst.append(self.example)
 rst.append("")
 
+raw_eclass_name = self.name[: -len(".eclass")]
+latest_eapi = EAPI.known_eapis[sorted(EAPI.known_eapis)[-1]]
+if exported_phases := [
+x
+for x in latest_eapi.phases.values()
+if f"{raw_eclass_name}_{x}" in self.exported_function_names
+]:
+rst.extend(_rst_header("-", "Exported Phases"))
+rst.extend(f"- ``{phase}``" for phase in exported_phases)
+rst.append("")
+
 if external_funcs := [x for x in self.functions if not x.internal]:
 rst.extend(_header_only("-", "Functions"))
 for func in external_funcs:

diff --git a/src/pkgcore/scripts/pmaint.py b/src/pkgcore/scripts/pmaint.py
index bc930cc0a..390f7b287 100644
--- a/src/pkgcore/scripts/pmaint.py
+++ b/src/pkgcore/scripts/pmaint.py
@@ -544,7 +544,7 @@ def _eclass_main(options, out, err):
 with open(
 pjoin(options.output_dir, f"{os.path.basename(path)}.{ext}"), 
"wt"
 ) as f:
-obj = EclassDoc(path)
+obj = EclassDoc(path, sourced=True)
 convert_func = getattr(obj, f"to_{options.format}")
 f.write(convert_func())
 except ValueError as e:



[gentoo-commits] proj/pkgcore/pkgcore:master commit in: src/pkgcore/scripts/, src/pkgcore/ebuild/, tests/ebuild/

2023-10-23 Thread Arthur Zamarin
commit: 83516bb97445ef81c40c30a567703509fe29445b
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Mon Oct 23 17:03:30 2023 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Mon Oct 23 17:03:30 2023 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcore.git/commit/?id=83516bb9

pmaint eclass: improve rst output

Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcore/ebuild/eclass.py  | 51 ---
 src/pkgcore/scripts/pmaint.py |  3 +++
 tests/ebuild/test_eclass.py   | 28 
 3 files changed, 50 insertions(+), 32 deletions(-)

diff --git a/src/pkgcore/ebuild/eclass.py b/src/pkgcore/ebuild/eclass.py
index f5ae214f7..23e970f75 100644
--- a/src/pkgcore/ebuild/eclass.py
+++ b/src/pkgcore/ebuild/eclass.py
@@ -118,17 +118,23 @@ class ParseEclassDoc:
 return None
 
 # use literal blocks for all multiline text
-data = ["::", "\n\n"]
+data = ["\n\n"]
 
+inside_code = False
 for i, line in enumerate(lines, 1):
 if self._code_tag.match(line):
-continue
+if not inside_code:
+data.append("::")
+data.append("\n\n")
+inside_code = not inside_code
 elif mo := self._subsection_tag.match(line):
 header = _rst_header("~", mo.group("title"))
 data.extend(f"{x}\n" for x in header)
-data.extend(["::", "\n\n"])
+data.extend(["\n\n"])
 elif line:
-data.append(f"  {line}\n")
+indent = "  " if inside_code else ""
+formatted_line = line
+data.append(f"{indent}{formatted_line}\n")
 else:
 data.append("\n")
 
@@ -572,7 +578,9 @@ class EclassDoc(AttrDict):
 
 rst = _header_only("=", self.name, leading=True)
 if self.blurb:
-rst.extend(_header_only("-", self.blurb, leading=True))
+rst.extend(_rst_header("-", "Name"))
+rst.append(f"``{self.name}`` -- {self.blurb}")
+rst.append("")
 
 if self.description:
 rst.extend(_rst_header("-", "Description"))
@@ -592,7 +600,7 @@ class EclassDoc(AttrDict):
 rst.append("")
 if self.raw_provides:
 rst.extend(_rst_header("-", "Transitively Provided Eclasses"))
-rst.append(" ".join(self.raw_provides))
+rst.extend(f"- ``{provide}``" for provide in self.raw_provides)
 rst.append("")
 if self.example:
 rst.extend(_rst_header("-", "Example"))
@@ -616,22 +624,25 @@ class EclassDoc(AttrDict):
 header = [func.name]
 if func.usage:
 header.append(func.usage)
-rst.extend(_rst_header("~", " ".join(header)))
+rst.append(f'**{" ".join(header)}**')
 if func.description:
-rst.append(func.description)
+rst.append(
+"  " + func.description.lstrip("\n").replace("\n", "\n 
 ")
+)
 if func.returns:
 if func.description:
-rst.append("")
-rst.append(f"Return value: {func.returns}")
+rst.append("  ")
+rst.append(f"  **Return value**: {func.returns}")
 rst.append("")
 if external_vars := [x for x in self.variables if not x.internal]:
 rst.extend(_header_only("-", "Variables"))
 for var in external_vars:
 vartype = ""
+var_value = ""
 if default_value := getattr(var, "default_value", None):
-vartype += f" ?= *{default_value}*"
+var_value = f" ?= *{default_value}*"
 elif initial_value := getattr(var, "initial_value", None):
-vartype += f" = *{initial_value}*"
+var_value = f" = *{initial_value}*"
 if var.required:
 vartype += " (REQUIRED)"
 if var.pre_inherit:
@@ -639,11 +650,12 @@ class EclassDoc(AttrDict):
 if var.user_variable:
 vartype += " (USER VARIABLE)"
 if var.output_variable:
-vartype += " (OUTPUT VARIABLE)"
-
-rst.extend(_rst_header("~", var.name + vartype))
+vartype += " (GENERATED BY ECLASS)"
+rst.append(f"**{var.name}**{var_value}{vartype}")
 if var.description:
-rst.append(var.description)
+rst.append(
+"  " + var.description.lstrip("\n").replace("\n", "\n  
")
+)
 rst.append("")
 if external_func_vars := [x for x in self.function_variables if not 

[gentoo-commits] proj/pkgcore/pkgcore:master commit in: src/pkgcore/scripts/, src/pkgcore/ebuild/, src/pkgcore/config/

2022-12-26 Thread Arthur Zamarin
commit: bf99e1ae914c636e285f548c5ae9da79265116b3
Author: Brian Harring  gmail  com>
AuthorDate: Wed Dec 21 06:39:36 2022 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Mon Dec 26 17:27:20 2022 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcore.git/commit/?id=bf99e1ae

Rename domain.pkg_operations to domain.get_pkg_operations

Operations isn't a verb on it's own, so this naming isn't explanatory
on it's own.  'get_pkg_operations'- plus a docstring- is clearer, thus
the rename.

Signed-off-by: Brian Harring  gmail.com>
Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcore/config/domain.py | 9 +++--
 src/pkgcore/ebuild/ebd.py| 2 +-
 src/pkgcore/ebuild/misc.py   | 2 +-
 src/pkgcore/ebuild/repository.py | 2 +-
 src/pkgcore/scripts/pconfig.py   | 2 +-
 src/pkgcore/scripts/pmerge.py| 4 ++--
 6 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/src/pkgcore/config/domain.py b/src/pkgcore/config/domain.py
index f1b37ccc6..8d790ba81 100644
--- a/src/pkgcore/config/domain.py
+++ b/src/pkgcore/config/domain.py
@@ -40,13 +40,18 @@ class domain:
 def triggers(self):
 return tuple(self._triggers)
 
-def pkg_operations(self, pkg, observer=None):
+def get_pkg_operations(self, pkg, observer=None):
+"""Get the manager of package operations for the given package
+
+If you wish to modify a package- invoke setup, install, etc- this is 
what's responsible
+for giving you a common interface despite the format implementation 
varying.
+"""
 domain = self.get_package_domain(pkg)
 return pkg.operations(domain, observer=observer)
 
 def build_pkg(self, pkg, observer=None, failed=False, clean=True, 
**kwargs):
 domain = self.get_package_domain(pkg)
-return domain.pkg_operations(pkg, observer=observer).build(
+return domain.get_pkg_operations(pkg, observer=observer).build(
 observer=observer, failed=failed, clean=clean, **kwargs
 )
 

diff --git a/src/pkgcore/ebuild/ebd.py b/src/pkgcore/ebuild/ebd.py
index 10e26fb91..f85b5792d 100644
--- a/src/pkgcore/ebuild/ebd.py
+++ b/src/pkgcore/ebuild/ebd.py
@@ -788,7 +788,7 @@ class buildable(ebd, setup_mixin, format.build):
 def _setup_distfiles(self):
 # fetch distfiles
 if not self.verified_files:
-ops = self.domain.pkg_operations(self.pkg, observer=self.observer)
+ops = self.domain.get_pkg_operations(self.pkg, 
observer=self.observer)
 if ops.fetch():
 # this break encapsulation and should be refactored.  Trace
 # f35f2 and 6561eac for where this was refactored.

diff --git a/src/pkgcore/ebuild/misc.py b/src/pkgcore/ebuild/misc.py
index 19fa5270a..8c22b277f 100644
--- a/src/pkgcore/ebuild/misc.py
+++ b/src/pkgcore/ebuild/misc.py
@@ -598,7 +598,7 @@ def run_sanity_checks(pkgs, domain, threads=None):
 sanity_failures = defaultdict(list)
 # TODO: parallelize this across separate processes
 for pkg in pkgs:
-pkg_ops = domain.pkg_operations(pkg)
+pkg_ops = domain.get_pkg_operations(pkg)
 if pkg_ops.supports("sanity_check") and (failures := 
pkg_ops.sanity_check()):
 sanity_failures[pkg] = failures
 return sanity_failures

diff --git a/src/pkgcore/ebuild/repository.py b/src/pkgcore/ebuild/repository.py
index 2e27ada7a..f63521f5a 100644
--- a/src/pkgcore/ebuild/repository.py
+++ b/src/pkgcore/ebuild/repository.py
@@ -114,7 +114,7 @@ class repo_operations(_repo_ops.operations):
 continue
 
 # fetch distfiles
-pkg_ops = domain.pkg_operations(pkgs[0], observer=observer)
+pkg_ops = domain.get_pkg_operations(pkgs[0], observer=observer)
 try:
 if not pkg_ops.fetch(
 list(fetchables.values()), observer, distdir=distdir

diff --git a/src/pkgcore/scripts/pconfig.py b/src/pkgcore/scripts/pconfig.py
index ff5b06cde..2965430b8 100644
--- a/src/pkgcore/scripts/pconfig.py
+++ b/src/pkgcore/scripts/pconfig.py
@@ -421,7 +421,7 @@ def package_func(options, out, err):
 domain = options.domain
 for pkg in domain.installed_repos.combined.itermatch(options.query):
 matched = True
-ops = domain.pkg_operations(pkg)
+ops = domain.get_pkg_operations(pkg)
 if not ops.supports("configure"):
 out.write(f"package {pkg}: nothing to configure, ignoring")
 continue

diff --git a/src/pkgcore/scripts/pmerge.py b/src/pkgcore/scripts/pmerge.py
index 30135a250..6d21bc53e 100644
--- a/src/pkgcore/scripts/pmerge.py
+++ b/src/pkgcore/scripts/pmerge.py
@@ -1140,7 +1140,7 @@ def main(options, out, err):
 if not options.fetchonly and options.debug:
 out.write("Forcing a clean of workdir")
 
-pkg_ops = domain.pkg_operations(op.pkg, observer=build_obs)
+pkg_ops = 

[gentoo-commits] proj/pkgcore/pkgcore:master commit in: src/pkgcore/scripts/, src/pkgcore/resolver/

2022-12-21 Thread Arthur Zamarin
commit: 0663781cdc625358e873e44e91e725228d88b16d
Author: Brian Harring  gmail  com>
AuthorDate: Wed Dec 21 22:55:34 2022 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Thu Dec 22 03:10:33 2022 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcore.git/commit/?id=0663781c

add pmerge --pdb-intercept as a way to pdb.set_trace() into the resolver.

This is fairly hackish, but will be extended as a way to jump into the resolver
decision making for debugging and development.

Signed-off-by: Brian Harring  gmail.com>

 src/pkgcore/resolver/plan.py  | 11 ++-
 src/pkgcore/scripts/pmerge.py | 15 +++
 2 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/src/pkgcore/resolver/plan.py b/src/pkgcore/resolver/plan.py
index 696c3ec04..21d44c72f 100644
--- a/src/pkgcore/resolver/plan.py
+++ b/src/pkgcore/resolver/plan.py
@@ -251,7 +251,8 @@ class merge_plan:
 
 def __init__(self, dbs, per_repo_strategy, global_strategy=None,
  depset_reorder_strategy=None, process_built_depends=False,
- drop_cycles=False, debug=False, debug_handle=None):
+ drop_cycles=False, debug=False, debug_handle=None,
+ pdb_intercept=None):
 if debug:
 if debug_handle is None:
 debug_handle = sys.stdout
@@ -260,6 +261,12 @@ class merge_plan:
 # don't run debug func when debugging is disabled
 self._dprint = lambda *args, **kwargs: None
 
+if not pdb_intercept:
+pdb_intercept = packages.AlwaysFalse
+elif not isinstance(pdb_intercept, packages.PackageRestriction):
+pdb_intercept = packages.AndRestriction(*pdb_intercept)
+self.pdb_intercept = pdb_intercept
+
 if not isinstance(dbs, (util.RepositoryGroup, list, tuple)):
 dbs = [dbs]
 
@@ -563,6 +570,8 @@ class merge_plan:
 :return: 3 possible; None (not viable), True (presolved),
   :obj:`caching_iter` (not solved, but viable), :obj:`choice_point`
 """
+if self.pdb_intercept.match(atom):
+import pdb;pdb.set_trace()
 choices = ret = None
 if atom in self.insoluble:
 ret = ((False, "globally insoluble"),{})

diff --git a/src/pkgcore/scripts/pmerge.py b/src/pkgcore/scripts/pmerge.py
index ffc13cef9..77046feb1 100644
--- a/src/pkgcore/scripts/pmerge.py
+++ b/src/pkgcore/scripts/pmerge.py
@@ -274,6 +274,19 @@ output_options.add_argument(
 closely emulates portage output and is used by default.
 """)
 
+debug_options = argparser.add_argument_group("resolver debugging options")
+debug_options.add_argument(
+'--pdb-intercept', dest='pdb_intercept', metavar='TARGET[,TARGET,...]',
+action=commandline.StoreTarget, separator=',',
+help='trigger a pdb.set_trace() for any resolver decisions that match this 
restriction',
+docs="""
+Comma-seperated list of targets to trigger a pdb.set_trace() within 
resolver code for investigation.
+
+This is primarily used for debugging resolver implementation, being 
able to walk through
+what it has decided and why.
+"""
+)
+
 
 class AmbiguousQuery(parserestrict.ParseError):
 """Exception for multiple matches where a single match is required."""
@@ -730,6 +743,8 @@ def main(options, out, err):
 #hp = hpy()
 #hp.setrelheap()
 
+extra_kwargs['pdb_intercept'] = tuple(x[1] for x in options.pdb_intercept)
+
 resolver_inst = options.resolver_kls(
 vdbs=installed_repos, dbs=source_repos,
 verify_vdb=options.deep, nodeps=options.nodeps,



[gentoo-commits] proj/pkgcore/pkgcore:master commit in: src/pkgcore/scripts/

2022-12-21 Thread Arthur Zamarin
commit: 322a5f0b4f92731d36bb1922697a59472e20eace
Author: Brian Harring  gmail  com>
AuthorDate: Wed Dec 21 23:26:15 2022 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Thu Dec 22 03:10:33 2022 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcore.git/commit/?id=322a5f0b

pmerge: sort target processing to stabilize the graph.

The current resolver is effectively brute force graph exploration,
iteratively adding results to the graph changing previously decisions
based on new requests.  This means that the resolver *can* produce
different solutions if the order of constraints added to it differ.

It's desirable the resolver behaviour be reproducible, thus change the default
behaviour to sort the target list given to the resolver.

As to why we don't force sorting within the resolver itself; for processing
of package dependencies, those are already stably ordered.  A future
enhancement would be to modify the resolver to be explicit, but that's for
when the resolver is rewritten.

Currently the source of instability is the atoms fed to the resolver from
pmerge, thus why I'm adding the sorting in pmerge.

Finally: the resolver must always produce a solution, or must always not, 
irregardless
of the argument ordering it's given.  Thus '--disable-resolver-target-sorting' 
is
added to allow disabling the sorting and doing something of a random entry/walk
into the depgraph.  This can produce differing solutions than what a sorted 
entry
would produce; that is working as intended (there is no global optimizer of 
solutions,
thus 'first solution' is what pmerge uses).

Basically, these two invocations should agree that a solution exists, or 
doesn't.
If they disagree this directly shows that the resolver is failing to explore 
solution
space fully:
* `pmerge  --disable-resolver-target-sorting`
* `pmerge 

Signed-off-by: Brian Harring  gmail.com>

 src/pkgcore/scripts/pmerge.py | 20 
 1 file changed, 20 insertions(+)

diff --git a/src/pkgcore/scripts/pmerge.py b/src/pkgcore/scripts/pmerge.py
index 77046feb1..8ea24c8c6 100644
--- a/src/pkgcore/scripts/pmerge.py
+++ b/src/pkgcore/scripts/pmerge.py
@@ -286,6 +286,23 @@ debug_options.add_argument(
 what it has decided and why.
 """
 )
+debug_options.add_argument(
+'--disable-resolver-target-sorting', 
dest='force_stable_ordering_of_targets',
+action='store_false', default=True,
+help='disable stabilization of resolver graph processing',
+docs="""
+Resolution of package dependencies can grossly vary depending on which 
nodes you start from.
+
+Pmerge by default sorts the targets it's asked to resolve; this in 
turn stabilizes the resolvers
+output.  This option allows disabling that sort.
+
+This should be only used if you're debugging the resolver and wish to 
effectively fuzz the resolvers
+ability to find solutions; for a properly working resolver if a 
solution can be found, it *must*
+be found.  If a solution can't be found, then this flag should also 
result in no solution found.
+
+Any deviation from this is a bug in the resolver and should be 
reported.
+"""
+)
 
 
 class AmbiguousQuery(parserestrict.ParseError):
@@ -640,6 +657,7 @@ def main(options, out, err):
 
 # This mode does not care about sets and packages so bypass all that.
 if options.unmerge:
+# TODO: this logic should be updated to honor 
self.force_stable_ordering_of_targets
 if not options.oneshot:
 if world_set is None:
 argparser.error("disable world updating via --oneshot, "
@@ -702,6 +720,8 @@ def main(options, out, err):
 return 1
 
 atoms = stable_unique(atoms)
+if options.force_stable_ordering_of_targets:
+atoms = sorted(atoms)
 
 if options.clean and not options.oneshot:
 if world_set is None:



[gentoo-commits] proj/pkgcore/pkgcore:master commit in: src/pkgcore/scripts/, src/pkgcore/plugins/

2022-12-18 Thread Arthur Zamarin
commit: 1a0f3aa7dcbc1464c56c16ac85ffb3d9ebdd5acb
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Fri Dec  2 10:21:33 2022 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Sun Dec 18 18:58:27 2022 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcore.git/commit/?id=1a0f3aa7

remove builtin_configurables plugins

Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcore/plugins/builtin_configurables.py | 23 ---
 src/pkgcore/scripts/pconfig.py   | 25 +++--
 2 files changed, 23 insertions(+), 25 deletions(-)

diff --git a/src/pkgcore/plugins/builtin_configurables.py 
b/src/pkgcore/plugins/builtin_configurables.py
deleted file mode 100644
index 801b0eb59..0
--- a/src/pkgcore/plugins/builtin_configurables.py
+++ /dev/null
@@ -1,23 +0,0 @@
-from snakeoil.test.mixins import PythonNamespaceWalker
-
-
-class walker(PythonNamespaceWalker):
-
-ignore_all_import_failures = True
-
-def _default_module_blacklister(self, target):
-if target.startswith("pkgcore.test.") or 
target.startswith('pkgcore.plugins.') \
-or 'pkgcore.test' == target:
-return True
-return PythonNamespaceWalker._default_module_blacklister(self, target)
-
-targets = []
-for module in walker().walk_namespace('pkgcore'):
-for name in dir(module):
-obj = getattr(module, name)
-if getattr(obj, 'pkgcore_config_type', None) is not None:
-targets.append(f'{module.__name__}.{name}')
-
-pkgcore_plugins = {
-'configurable': targets
-}

diff --git a/src/pkgcore/scripts/pconfig.py b/src/pkgcore/scripts/pconfig.py
index 37fb008db..95f00bb36 100644
--- a/src/pkgcore/scripts/pconfig.py
+++ b/src/pkgcore/scripts/pconfig.py
@@ -5,10 +5,10 @@ import traceback
 from functools import partial
 
 from snakeoil.errors import dump_error
+from snakeoil.test.mixins import PythonNamespaceWalker
 
 from ..config import basics, errors
 from ..ebuild import atom
-from ..plugin import get_plugins
 from ..util import commandline
 
 
@@ -207,6 +207,27 @@ def dump_main(options, out, err):
 out.write('}')
 
 
+def all_configurables():
+class walker(PythonNamespaceWalker):
+
+ignore_all_import_failures = True
+
+def _default_module_blacklister(self, target):
+if target.startswith(("pkgcore.test.", 'pkgcore.plugins.')) \
+or 'pkgcore.test' == target:
+return True
+return super()._default_module_blacklister(target)
+
+return (
+obj
+for module in walker().walk_namespace('pkgcore')
+for name in dir(module)
+if getattr(obj := getattr(module, name), 'pkgcore_config_type', None) 
is not None
+if not getattr(obj, 'disabled', False)
+if not getattr(obj, '_plugin_disabled_check', lambda: False)()
+)
+
+
 configurables = subparsers.add_parser(
 "configurables", parents=shared_options,
 description='list registered configurables (may not be complete)')
@@ -223,7 +244,7 @@ def configurables_main(options, out, err):
 return "%s.%s" % (getattr(obj, '__module__', ''),
   getattr(obj, '__name__', ''))
 
-for configurable in sorted(get_plugins('configurable'), key=key_func):
+for configurable in sorted(all_configurables(), key=key_func):
 type_obj = basics.ConfigType(configurable)
 if options.typename is not None and type_obj.name != options.typename:
 continue



[gentoo-commits] proj/pkgcore/pkgcore:master commit in: src/pkgcore/scripts/

2022-11-12 Thread Arthur Zamarin
commit: fa5153ff81b8159fa59dc2495f5bf9cdf36a99a4
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Sat Nov 12 10:49:25 2022 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Sat Nov 12 10:49:25 2022 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcore.git/commit/?id=fa5153ff

pquery: fix crash with verbose single uris attr

When the `uris` attribute has only one value, and the `verbose` option
was used, pquery was crashing because `node.uri` isn't subscriptable.
Use more agnostic `next(iter(node.uris))` instead.

Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcore/scripts/pquery.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/pkgcore/scripts/pquery.py b/src/pkgcore/scripts/pquery.py
index 6bc04994d..eaba242f3 100644
--- a/src/pkgcore/scripts/pquery.py
+++ b/src/pkgcore/scripts/pquery.py
@@ -269,7 +269,7 @@ def format_attr(config, out, pkg, attr):
 if not node.uri:
 return False
 if len(node.uri) == 1:
-out.write(node.uri[0], autoline=False)
+out.write(next(iter(node.uri)), autoline=False)
 return False
 out.write('|| (')
 out.first_prefix.append('')