From 658cb1be348ac55f19d81dd95256b61c0c1e4ba5 Mon Sep 17 00:00:00 2001
From: Jonathan Maw <jonathan.maw@codethink.co.uk>
Date: Thu, 1 Nov 2018 16:50:23 +0000
Subject: [PATCH] _project.py: Find project from workspace if outside of a
 project

---
 buildstream/_project.py | 31 +++++++++++++++++++++++--------
 1 file changed, 23 insertions(+), 8 deletions(-)

diff --git a/buildstream/_project.py b/buildstream/_project.py
index bf25244d32..2c7f6607b8 100644
--- a/buildstream/_project.py
+++ b/buildstream/_project.py
@@ -40,6 +40,7 @@ from .element import Element
 from ._message import Message, MessageType
 from ._includes import Includes
 from ._platform import Platform
+from ._workspaces import WorkspaceLocal
 
 
 # Project Configuration file
@@ -94,8 +95,8 @@ class Project():
         # The project name
         self.name = None
 
-        # The project directory
-        self.directory = self._find_project_dir(directory)
+        # The project directory, and whether the project was found from an external workspace
+        self.directory, self._required_workspace_element = self._find_project_dir(directory)
 
         # Absolute path to where elements are loaded from within the project
         self.element_path = None
@@ -370,6 +371,14 @@ class Project():
 
         self._load_second_pass()
 
+    # required_workspace_element()
+    #
+    # Returns the element whose workspace is required to load this project,
+    # if any.
+    #
+    def required_workspace_element(self):
+        return self._required_workspace_element
+
     # cleanup()
     #
     # Cleans up resources used loading elements
@@ -662,18 +671,24 @@ class Project():
     # Raises:
     #    LoadError if project.conf is not found
     #
+    # Returns:
+    #    (str) - the directory that contains the project, and
+    #    (str) - the name of the element required to find the project, or an empty string
     def _find_project_dir(self, directory):
-        directory = os.path.abspath(directory)
-        while not os.path.isfile(os.path.join(directory, _PROJECT_CONF_FILE)):
-            parent_dir = os.path.dirname(directory)
-            if directory == parent_dir:
+        workspace_element = ""
+        project_directory = utils._search_upward_for_file(directory, _PROJECT_CONF_FILE)
+        if not project_directory:
+            workspace_local = WorkspaceLocal.load(directory)
+            if workspace_local:
+                project_directory = workspace_local.get_default_path()
+                workspace_element = workspace_local.get_default_element()
+            else:
                 raise LoadError(
                     LoadErrorReason.MISSING_PROJECT_CONF,
                     '{} not found in current directory or any of its parent directories'
                     .format(_PROJECT_CONF_FILE))
-            directory = parent_dir
 
-        return directory
+        return project_directory, workspace_element
 
     def _load_plugin_factories(self, config, output):
         plugin_source_origins = []   # Origins of custom sources
-- 
GitLab