Merge branch 'tristan/remove-some-internal-api' into 'master'

Remove a not very important message from the cli

See merge request BuildStream/buildstream!1963
diff --git a/src/buildstream/_frontend/cli.py b/src/buildstream/_frontend/cli.py
index 11d6dfe..18bb03c 100644
--- a/src/buildstream/_frontend/cli.py
+++ b/src/buildstream/_frontend/cli.py
@@ -1040,8 +1040,6 @@
 def workspace_close(app, remove_dir, all_, elements):
     """Close a workspace"""
 
-    removed_required_element = False
-
     with app.initialized():
         if not (all_ or elements):
             # NOTE: I may need to revisit this when implementing multiple projects
@@ -1073,17 +1071,6 @@
 
         for element_name in elements:
             app.stream.workspace_close(element_name, remove_dir=remove_dir)
-            if app.stream.workspace_is_required(element_name):
-                removed_required_element = True
-
-    # This message is echo'd last, as it's most relevant to the next
-    # thing the user will type.
-    if removed_required_element:
-        click.echo(
-            "Removed '{}', therefore you can no longer run BuildStream "
-            "commands from the current directory.".format(element_name),
-            err=True,
-        )
 
 
 ##################################################################
diff --git a/src/buildstream/_project.py b/src/buildstream/_project.py
index 96a2ead..3006e29 100644
--- a/src/buildstream/_project.py
+++ b/src/buildstream/_project.py
@@ -179,6 +179,10 @@
     def source_overrides(self):
         return self.config.source_overrides
 
+    ########################################################
+    #                     Public Methods                   #
+    ########################################################
+
     # translate_url():
     #
     # Translates the given url which may be specified with an alias
@@ -320,35 +324,6 @@
 
         return path_str
 
-    def _validate_node(self, node):
-        node.validate_keys(
-            [
-                "min-version",
-                "element-path",
-                "variables",
-                "environment",
-                "environment-nocache",
-                "split-rules",
-                "elements",
-                "plugins",
-                "aliases",
-                "name",
-                "defaults",
-                "artifacts",
-                "options",
-                "fail-on-overlap",
-                "shell",
-                "fatal-warnings",
-                "ref-storage",
-                "sandbox",
-                "mirrors",
-                "remote-execution",
-                "sources",
-                "source-caches",
-                "(@)",
-            ]
-        )
-
     # create_element()
     #
     # Instantiate and return an element
@@ -509,14 +484,6 @@
 
         self._load_second_pass()
 
-    # invoked_from_workspace_element()
-    #
-    # Returns the element whose workspace was used to invoke buildstream
-    # if buildstream was invoked from an external workspace
-    #
-    def invoked_from_workspace_element(self):
-        return self._invoked_from_workspace_element
-
     # cleanup()
     #
     # Cleans up resources used loading elements
@@ -567,6 +534,46 @@
 
         return tuple(default_targets)
 
+    ########################################################
+    #                    Private Methods                   #
+    ########################################################
+
+    # _validate_toplevel_node()
+    #
+    # Validates the toplevel project.conf keys
+    #
+    # Args:
+    #    node (MappingNode): The toplevel project.conf node
+    #
+    def _validate_toplevel_node(self, node):
+        node.validate_keys(
+            [
+                "min-version",
+                "element-path",
+                "variables",
+                "environment",
+                "environment-nocache",
+                "split-rules",
+                "elements",
+                "plugins",
+                "aliases",
+                "name",
+                "defaults",
+                "artifacts",
+                "options",
+                "fail-on-overlap",
+                "shell",
+                "fatal-warnings",
+                "ref-storage",
+                "sandbox",
+                "mirrors",
+                "remote-execution",
+                "sources",
+                "source-caches",
+                "(@)",
+            ]
+        )
+
     # _validate_version()
     #
     # Asserts that we have a BuildStream installation which is recent
@@ -663,7 +670,7 @@
         # Assert project's minimum required version early, before validating toplevel keys
         self._validate_version(pre_config_node)
 
-        self._validate_node(pre_config_node)
+        self._validate_toplevel_node(pre_config_node)
 
         # The project name, element path and option declarations
         # are constant and cannot be overridden by option conditional statements
@@ -723,7 +730,7 @@
 
         self._load_pass(config, self.config)
 
-        self._validate_node(config)
+        self._validate_toplevel_node(config)
 
         #
         # Now all YAML composition is done, from here on we just load
diff --git a/src/buildstream/_stream.py b/src/buildstream/_stream.py
index dc91db6..44faf2b 100644
--- a/src/buildstream/_stream.py
+++ b/src/buildstream/_stream.py
@@ -956,20 +956,6 @@
 
         return False
 
-    # workspace_is_required()
-    #
-    # Checks whether the workspace belonging to element_name is required to
-    # load the project
-    #
-    # Args:
-    #    element_name (str): The element whose workspace may be required
-    #
-    # Returns:
-    #    (bool): True if the workspace is required
-    def workspace_is_required(self, element_name):
-        invoked_elm = self._project.invoked_from_workspace_element()
-        return invoked_elm == element_name
-
     # workspace_list
     #
     # Serializes the workspaces and dumps them in YAML to stdout.
diff --git a/tests/frontend/workspace.py b/tests/frontend/workspace.py
index b450d18..4aae61a 100644
--- a/tests/frontend/workspace.py
+++ b/tests/frontend/workspace.py
@@ -1100,36 +1100,6 @@
 
 
 @pytest.mark.datafiles(DATA_DIR)
-def test_external_close_other(cli, datafiles, tmpdir_factory):
-    # From inside an external workspace, close the other workspace
-    tmpdir1 = tmpdir_factory.mktemp(BASE_FILENAME)
-    tmpdir2 = tmpdir_factory.mktemp(BASE_FILENAME)
-    # Making use of the assumption that it's the same project in both invocations of open_workspace
-    _, project, alpha_workspace = open_workspace(cli, tmpdir1, datafiles, "git", suffix="-alpha")
-    beta_element, _, _ = open_workspace(cli, tmpdir2, datafiles, "git", suffix="-beta")
-
-    result = cli.run(project=project, args=["-C", alpha_workspace, "workspace", "close", beta_element])
-    result.assert_success()
-    assert "you can no longer run BuildStream" not in result.stderr
-
-
-@pytest.mark.datafiles(DATA_DIR)
-@pytest.mark.parametrize("guess_element", [True, False], ids=["guess", "no-guess"])
-def test_external_close_self(cli, datafiles, tmpdir_factory, guess_element):
-    # From inside an external workspace, close it
-    tmpdir1 = tmpdir_factory.mktemp(BASE_FILENAME)
-    tmpdir2 = tmpdir_factory.mktemp(BASE_FILENAME)
-    # Making use of the assumption that it's the same project in both invocations of open_workspace
-    alpha_element, project, alpha_workspace = open_workspace(cli, tmpdir1, datafiles, "git", suffix="-alpha")
-    _, _, _ = open_workspace(cli, tmpdir2, datafiles, "git", suffix="-beta")
-    arg_elm = [alpha_element] if not guess_element else []
-
-    result = cli.run(project=project, args=["-C", alpha_workspace, "workspace", "close", *arg_elm])
-    result.assert_success()
-    assert "you can no longer run BuildStream" in result.stderr
-
-
-@pytest.mark.datafiles(DATA_DIR)
 def test_external_reset_other(cli, datafiles, tmpdir_factory):
     tmpdir1 = tmpdir_factory.mktemp(BASE_FILENAME)
     tmpdir2 = tmpdir_factory.mktemp(BASE_FILENAME)