summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChandan Singh <csingh43@bloomberg.net>2018-06-19 19:58:28 +0100
committerChandan Singh <csingh43@bloomberg.net>2018-06-21 12:53:45 +0100
commitbec79852ca14c3932048e7bfd4a9f21c240dc3b4 (patch)
tree1559a0409a42aab1f8e1629760669b2dbabd864f
parent4f168b9b6a02216e2fae24d758ae6b778e545869 (diff)
downloadbuildstream-chandan/bst-from-workspace.tar.gz
WIP: Allow running bst commands from worksapce directorychandan/bst-from-workspace
-rw-r--r--buildstream/_context.py15
-rw-r--r--buildstream/_frontend/app.py15
-rw-r--r--buildstream/_project.py21
-rw-r--r--buildstream/_workspaces.py52
4 files changed, 87 insertions, 16 deletions
diff --git a/buildstream/_context.py b/buildstream/_context.py
index 1a59af2b9..62a67cb8f 100644
--- a/buildstream/_context.py
+++ b/buildstream/_context.py
@@ -104,9 +104,6 @@ class Context():
# Whether elements must be rebuilt when their dependencies have changed
self._strict_build_plan = None
- # Make sure the XDG vars are set in the environment before loading anything
- self._init_xdg()
-
# Private variables
self._cache_key = None
self._message_handler = None
@@ -412,15 +409,3 @@ class Context():
def _pop_message_depth(self):
assert self._message_depth
self._message_depth.popleft()
-
- # Force the resolved XDG variables into the environment,
- # this is so that they can be used directly to specify
- # preferred locations of things from user configuration
- # files.
- def _init_xdg(self):
- if not os.environ.get('XDG_CACHE_HOME'):
- os.environ['XDG_CACHE_HOME'] = os.path.expanduser('~/.cache')
- if not os.environ.get('XDG_CONFIG_HOME'):
- os.environ['XDG_CONFIG_HOME'] = os.path.expanduser('~/.config')
- if not os.environ.get('XDG_DATA_HOME'):
- os.environ['XDG_DATA_HOME'] = os.path.expanduser('~/.local/share')
diff --git a/buildstream/_frontend/app.py b/buildstream/_frontend/app.py
index 4675b0eb0..1158e3997 100644
--- a/buildstream/_frontend/app.py
+++ b/buildstream/_frontend/app.py
@@ -123,6 +123,9 @@ class App():
# Set soft limit to hard limit
resource.setrlimit(resource.RLIMIT_NOFILE, (limits[1], limits[1]))
+ # Make sure the XDG vars are set in the environment before loading anything
+ self._init_xdg()
+
# create()
#
# Should be used instead of the regular constructor.
@@ -811,6 +814,18 @@ class App():
return (project_name, format_version, element_path)
+ # Force the resolved XDG variables into the environment,
+ # this is so that they can be used directly to specify
+ # preferred locations of things from user configuration
+ # files.
+ def _init_xdg(self):
+ if not os.environ.get('XDG_CACHE_HOME'):
+ os.environ['XDG_CACHE_HOME'] = os.path.expanduser('~/.cache')
+ if not os.environ.get('XDG_CONFIG_HOME'):
+ os.environ['XDG_CONFIG_HOME'] = os.path.expanduser('~/.config')
+ if not os.environ.get('XDG_DATA_HOME'):
+ os.environ['XDG_DATA_HOME'] = os.path.expanduser('~/.local/share')
+
#
# Return a value processor for partial choice matching.
diff --git a/buildstream/_project.py b/buildstream/_project.py
index b568cf852..fe55df343 100644
--- a/buildstream/_project.py
+++ b/buildstream/_project.py
@@ -459,7 +459,9 @@ class Project():
# _ensure_project_dir()
#
# Returns path of the project directory, if a configuration file is found
- # in given directory or any of its parent directories.
+ # in given directory or any of its parent directories. If current
+ # directory has a workspace associated with it, try to find the
+ # corresponding project
#
# Args:
# directory (str) - directory from where the command was invoked
@@ -469,6 +471,11 @@ class Project():
#
def _ensure_project_dir(self, directory):
directory = os.path.abspath(directory)
+
+ workspaced_project = self._get_project_from_workspace()
+ if workspaced_project is not None:
+ return workspaced_project
+
while not os.path.isfile(os.path.join(directory, _PROJECT_CONF_FILE)):
parent_dir = os.path.dirname(directory)
if directory == parent_dir:
@@ -479,3 +486,15 @@ class Project():
directory = parent_dir
return directory
+
+ def _get_project_from_workspace(self):
+ workspaces_file = os.path.join(os.environ['XDG_DATA_HOME'],
+ 'buildstream', 'workspaces.yml')
+ if not os.path.isfile(workspaces_file):
+ return
+ workspaces = _yaml.load(workspaces_file)
+ fullpath = os.path.realpath(os.getcwd())
+ try:
+ return workspaces['workspaces'][fullpath]['project']
+ except KeyError:
+ return None
diff --git a/buildstream/_workspaces.py b/buildstream/_workspaces.py
index 3f474b8ca..7b219240d 100644
--- a/buildstream/_workspaces.py
+++ b/buildstream/_workspaces.py
@@ -214,7 +214,9 @@ class Workspaces():
def __init__(self, toplevel_project):
self._toplevel_project = toplevel_project
self._bst_directory = os.path.join(toplevel_project.directory, ".bst")
+ self._local_data_directory = os.path.join(os.environ['XDG_DATA_HOME'], 'buildstream')
self._workspaces = self._load_config()
+ self._workspace_mapping = self._load_local_config()
# list()
#
@@ -309,6 +311,24 @@ class Workspaces():
_yaml.dump(_yaml.node_sanitize(config),
self._get_filename())
+ self._save_local_config()
+
+ # _save_local_config()
+ #
+ # Edit local workspace config in round-trip manner since this file
+ # is shared by all projects.
+ #
+ def _save_local_config(self):
+ workspaces = self._load_local_config()
+ for element, workspace in self._workspaces.items():
+ workspaces[workspace.path] = {'project': self._toplevel_project.directory,
+ 'element': element}
+ config = {'workspaces': workspaces}
+ os.makedirs(self._local_data_directory, exist_ok=True)
+ _yaml.dump(_yaml.node_sanitize(config),
+ self._get_local_filename())
+
+
# _load_config()
#
# Loads and parses the workspace configuration
@@ -331,6 +351,29 @@ class Workspaces():
return self._parse_workspace_config(node)
+
+ # _load_local_config()
+ #
+ # Loads and parses the workspace configuration
+ #
+ # Returns:
+ # (dict) The extracted workspaces
+ #
+ # Raises: LoadError if there was a problem with the workspace config
+ #
+ def _load_local_config(self):
+ workspace_file = self._get_local_filename()
+ try:
+ node = _yaml.load(workspace_file)
+ except LoadError as e:
+ if e.reason == LoadErrorReason.MISSING_FILE:
+ # Return an empty dict if there was no workspace file
+ return {}
+
+ raise
+
+ return _yaml.node_get(node, dict, "workspaces", default_value={})
+
# _parse_workspace_config_format()
#
# If workspace config is in old-style format, i.e. it is using
@@ -414,3 +457,12 @@ class Workspaces():
# (str): The path to workspaces.yml file.
def _get_filename(self):
return os.path.join(self._bst_directory, "workspaces.yml")
+
+ # _get_local_filename():
+ #
+ # Get the workspaces.yml file path.
+ #
+ # Returns:
+ # (str): The path to workspaces.yml file.
+ def _get_local_filename(self):
+ return os.path.join(self._local_data_directory, 'workspaces.yml')