From bec79852ca14c3932048e7bfd4a9f21c240dc3b4 Mon Sep 17 00:00:00 2001 From: Chandan Singh Date: Tue, 19 Jun 2018 19:58:28 +0100 Subject: WIP: Allow running bst commands from worksapce directory --- buildstream/_context.py | 15 ------------- buildstream/_frontend/app.py | 15 +++++++++++++ buildstream/_project.py | 21 +++++++++++++++++- buildstream/_workspaces.py | 52 ++++++++++++++++++++++++++++++++++++++++++++ 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') -- cgit v1.2.1