This is an automated email from the ASF dual-hosted git repository.

juergbi pushed a commit to branch jbilleter/no-project
in repository https://gitbox.apache.org/repos/asf/buildstream.git

commit d824668a4735583e30025c4de577768efcfe6866
Author: Jürg Billeter <[email protected]>
AuthorDate: Fri Oct 3 11:53:31 2025 +0800

    _frontend: Fix error for commands without targets outside project dir
    
    If, e.g., `bst build` or `bst show` is invoked without targets and
    outside a BuildStream project or workspace directory, fail with a normal
    error message instead of an exception traceback.
---
 src/buildstream/_frontend/cli.py | 24 ++++++++++++------------
 src/buildstream/_stream.py       | 19 +++++++++++++++++++
 2 files changed, 31 insertions(+), 12 deletions(-)

diff --git a/src/buildstream/_frontend/cli.py b/src/buildstream/_frontend/cli.py
index 6cf2e187d..9a6e863ee 100644
--- a/src/buildstream/_frontend/cli.py
+++ b/src/buildstream/_frontend/cli.py
@@ -525,7 +525,7 @@ def build(
             deps = app.context.build_dependencies
 
         if not elements:
-            elements = app.project.get_default_targets()
+            elements = app.stream.get_default_targets()
             # Junction elements cannot be built, exclude them from default 
targets
             ignore_junction_targets = True
 
@@ -655,7 +655,7 @@ def show(app, elements, deps, except_, order, format_):
         need_state = bool(state_match or key_match or full_key_match or 
artifact_cas_digest_match)
 
         if not elements:
-            elements = app.project.get_default_targets()
+            elements = app.stream.get_default_targets()
 
         dependencies = app.stream.load_selection(
             elements, selection=deps, except_targets=except_, 
need_state=need_state
@@ -763,7 +763,7 @@ def shell(
 
     with app.initialized():
         if not target:
-            target = app.project.get_default_target()
+            target = app.stream.get_default_target()
             if not target:
                 raise AppError('Missing argument "TARGET".')
 
@@ -860,7 +860,7 @@ def source_fetch(app, elements, deps, except_, 
source_remotes, ignore_project_so
     """
     with app.initialized(session_name="Fetch"):
         if not elements:
-            elements = app.project.get_default_targets()
+            elements = app.stream.get_default_targets()
 
         app.stream.fetch(
             elements,
@@ -933,7 +933,7 @@ def source_push(app, elements, deps, except_, 
source_remotes, ignore_project_sou
     """
     with app.initialized(session_name="Push"):
         if not elements:
-            elements = app.project.get_default_targets()
+            elements = app.stream.get_default_targets()
 
         app.stream.source_push(
             elements,
@@ -993,7 +993,7 @@ def source_track(app, elements, deps, except_, 
cross_junctions):
     """
     with app.initialized(session_name="Track"):
         if not elements:
-            elements = app.project.get_default_targets()
+            elements = app.stream.get_default_targets()
 
         # Substitute 'none' for 'redirect' so that element redirections
         # will be done
@@ -1086,7 +1086,7 @@ def source_checkout(
 
     with app.initialized():
         if not element:
-            element = app.project.get_default_target()
+            element = app.stream.get_default_target()
             if not element:
                 raise AppError('Missing argument "ELEMENT".')
 
@@ -1171,7 +1171,7 @@ def workspace_close(app, remove_dir, all_, elements):
         if not (all_ or elements):
             # NOTE: I may need to revisit this when implementing multiple 
projects
             # opening one workspace.
-            element = app.project.get_default_target()
+            element = app.stream.get_default_target()
             if element:
                 elements = (element,)
             else:
@@ -1219,7 +1219,7 @@ def workspace_reset(app, soft, all_, elements):
     with app.initialized():
 
         if not (all_ or elements):
-            element = app.project.get_default_target()
+            element = app.stream.get_default_target()
             if element:
                 elements = (element,)
             else:
@@ -1412,7 +1412,7 @@ def artifact_checkout(
 
     with app.initialized():
         if not target:
-            target = app.project.get_default_target()
+            target = app.stream.get_default_target()
             if not target:
                 raise AppError('Missing argument "ELEMENT".')
 
@@ -1494,7 +1494,7 @@ def artifact_pull(app, deps, artifact_remotes, 
ignore_project_artifact_remotes,
         ignore_junction_targets = False
 
         if not artifacts:
-            artifacts = app.project.get_default_targets()
+            artifacts = app.stream.get_default_targets()
             # Junction elements cannot be pulled, exclude them from default 
targets
             ignore_junction_targets = True
 
@@ -1562,7 +1562,7 @@ def artifact_push(app, deps, artifact_remotes, 
ignore_project_artifact_remotes,
         ignore_junction_targets = False
 
         if not artifacts:
-            artifacts = app.project.get_default_targets()
+            artifacts = app.stream.get_default_targets()
             # Junction elements cannot be pushed, exclude them from default 
targets
             ignore_junction_targets = True
 
diff --git a/src/buildstream/_stream.py b/src/buildstream/_stream.py
index da8d48550..4358341ba 100644
--- a/src/buildstream/_stream.py
+++ b/src/buildstream/_stream.py
@@ -1242,6 +1242,25 @@ class Stream:
     def get_state(self):
         return self._state
 
+    # get_default_target()
+    #
+    # Attempts to interpret which element the user intended to run a command 
on.
+    # This is for commands that only accept a single target element and thus,
+    # this only uses the workspace element (if invoked from workspace 
directory)
+    # and does not use the project default targets.
+    #
+    def get_default_target(self):
+        return self._project.get_default_target() if self._project else None
+
+    # get_default_targets()
+    #
+    # Attempts to interpret which elements the user intended to run a command 
on.
+    # This is for commands that accept multiple target elements.
+    #
+    def get_default_targets(self):
+        self._assert_project("Unable to determine default targets")
+        return self._project.get_default_targets()
+
     #############################################################
     #                 Scheduler API forwarding                  #
     #############################################################

Reply via email to