proj/portage:master commit in: lib/portage/tests/emerge/, lib/_emerge/

"Matt Turner" <[email protected]>
Newsgroups gmane.linux.gentoo.cvs
Message-ID <1785956472.7a89160a0f501e7b6bdc5bd33289eaaead63f772.mattst88@gentoo>
commit:     7a89160a0f501e7b6bdc5bd33289eaaead63f772
Author:     Matt Turner <mattst88 <AT> gentoo <DOT> org>
AuthorDate: Mon Aug  3 15:58:53 2026 +0000
Commit:     Matt Turner <mattst88 <AT> gentoo <DOT> org>
CommitDate: Wed Aug  5 19:01:12 2026 +0000
URL:        https://gitweb.gentoo.org/proj/portage.git/commit/?id=7a89160a

emerge: tell the user when --status has nothing to report

"emerge --status" prints "No emerge processes are currently running."
whether or not anything could have been reported, so a user who never
enabled FEATURES="observability" gets an answer that looks authoritative
and is really just silence.

Say so instead, but only when there is nothing at all to report: the
feature has to be enabled for the emerge process being observed, not for
the one doing the observing, so an emerge started with it enabled from
the environment or from a different --config-root must still be
reported. Consulting FEATURES only in that case also keeps the
pre-config fast path that the "status" action deliberately lives in,
next to --help and moo.

Based on https://github.com/gentoo/portage/pull/1642
Suggested-by: Florian Schmaus <flow <AT> gentoo.org>
Signed-off-by: Matt Turner <mattst88 <AT> gentoo.org>

 lib/_emerge/_observability.py                  | 25 +++++++++++++++++++++++++
 lib/_emerge/main.py                            | 14 ++++++++++++--
 lib/portage/tests/emerge/test_observability.py | 12 ++++++++++++
 3 files changed, 49 insertions(+), 2 deletions(-)

diff --git a/lib/_emerge/_observability.py b/lib/_emerge/_observability.py
index 116b60490..bf1c99aef 100644
--- a/lib/_emerge/_observability.py
+++ b/lib/_emerge/_observability.py
@@ -202,6 +202,31 @@ def format_snapshots(snapshots):
     return "\n".join(lines) + "\n"
 
 
+NOT_ENABLED_HINT = (
+    "Nothing to report. Note that emerge only publishes status when it is "
+    'started with FEATURES="observability"; see make.conf(5).\n'
+)
+
+
+def missing_feature_hint(snapshots, features=None):
+    """Return a hint about FEATURES="observability", or None.
+
+    There is only something to say when nothing was read, since the
+    feature applies to the emerge being observed rather than to the one
+    observing it.
+
+    `features` defaults to this configuration's FEATURES, looked up only
+    when it is needed, since loading the config is not cheap.
+    """
+    if snapshots:
+        return None
+    if features is None:
+        features = portage.settings.features
+    if "observability" in features:
+        return None
+    return NOT_ENABLED_HINT
+
+
 class ObservabilityMonitor:
     """Owns the status file and streaming socket for one Scheduler.
 

diff --git a/lib/_emerge/main.py b/lib/_emerge/main.py
index 75d8e22f6..07fac6256 100644
--- a/lib/_emerge/main.py
+++ b/lib/_emerge/main.py
@@ -1263,9 +1263,19 @@ def emerge_main(args: Optional[list[str]] = None):
         # (For machine-readable output, use `portageq jobs --json`.)
         from portage.const import EPREFIX
 
-        from _emerge._observability import format_snapshots, read_snapshots
+        from _emerge._observability import (
+            format_snapshots,
+            missing_feature_hint,
+            read_snapshots,
+        )
+
+        snapshots = read_snapshots(EPREFIX)
+        hint = missing_feature_hint(snapshots)
+        if hint is not None:
+            sys.stderr.write(hint)
+            return 1
 
-        sys.stdout.write(format_snapshots(read_snapshots(EPREFIX)))
+        sys.stdout.write(format_snapshots(snapshots))
         return os.EX_OK
     if myaction == "sync":
         # need to set this to True now in order for the repository config

diff --git a/lib/portage/tests/emerge/test_observability.py b/lib/portage/tests/emerge/test_observability.py
index cf352b933..a21f80730 100644
--- a/lib/portage/tests/emerge/test_observability.py
+++ b/lib/portage/tests/emerge/test_observability.py
@@ -10,6 +10,7 @@ from _emerge._observability import (
     ObservabilityMonitor,
     build_snapshot,
     format_snapshots,
+    missing_feature_hint,
     read_snapshots,
     status_dir,
 )
@@ -159,6 +160,17 @@ class ObservabilitySnapshotTestCase(TestCase):
             monitor.close()
             self.assertFalse(os.path.exists(path))
 
+    def test_hint_when_nothing_read_and_feature_absent(self):
+        self.assertIn("observability", missing_feature_hint([], features=set()))
+
+    def test_no_hint_when_nothing_read_but_feature_present(self):
+        self.assertIsNone(missing_feature_hint([], features={"observability"}))
+
+    def test_no_hint_when_something_was_read(self):
+        # The feature is enabled for the emerge being observed, not for the
+        # process observing it, so a readable snapshot is never held back.
+        self.assertIsNone(missing_feature_hint([{"emerge_pid": 1}], features=set()))
+
     def test_stale_file_skipped(self):
         with tempfile.TemporaryDirectory() as tmp:
             d = status_dir(tmp)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.