Skip to content

Commit

Permalink
Allow extending profiles and merging their contents. (#592)
Browse files Browse the repository at this point in the history
  • Loading branch information
janstrohbeck authored Feb 28, 2020
1 parent 3fa27d5 commit 856bf18
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 8 deletions.
72 changes: 66 additions & 6 deletions catkin_tools/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ class Context(object):
'authors',
'maintainers',
'licenses',
'extends',
]

EXTRA_KEYS = [
Expand Down Expand Up @@ -193,7 +194,28 @@ def load(

# Get the metadata stored in the workspace if it was found
if workspace:
config_metadata = metadata.get_metadata(workspace, profile, 'config')
key_origins = {}
visited_profiles = []

def get_metadata_recursive(profile):
config_metadata = metadata.get_metadata(workspace, profile, 'config')
visited_profiles.append(profile)
if "extends" in config_metadata.keys() and config_metadata["extends"] is not None:
base_profile = config_metadata["extends"]
if base_profile in visited_profiles:
raise IOError("Profile dependency circle detected at dependency from '%s' to '%s'!"
% (profile, base_profile))
base = get_metadata_recursive(base_profile)
base.update(config_metadata)
for key in config_metadata.keys():
key_origins[key] = profile
return base
for key in config_metadata.keys():
key_origins[key] = profile
return config_metadata

config_metadata = get_metadata_recursive(profile)

context_args.update(config_metadata)

# User-supplied args are used to update stored args
Expand All @@ -208,8 +230,14 @@ def load(
context_args[k] = [w for w in context_args[k] if w not in v]
else:
context_args[k] = v
if workspace:
key_origins[k] = profile
else:
context_args[k] = v
if workspace:
key_origins[k] = profile

context_args["key_origins"] = key_origins

# Create the build context
ctx = Context(**context_args)
Expand All @@ -223,11 +251,28 @@ def load(
@classmethod
def save(cls, context):
"""Save a context in the associated workspace and profile."""
metadata.update_metadata(
context.workspace,
context.profile,
'config',
context.get_stored_dict())

data = context.get_stored_dict()
files = {}

def save_in_file(file, key, value):
if file in files.keys():
files[file][key] = value
else:
files[file] = {key: value}

for key, val in data.items():
if key in context.key_origins:
save_in_file(context.key_origins[key], key, val)
else:
save_in_file(context.profile, key, val)

for profile, content in files.items():
metadata.update_metadata(
context.workspace,
profile,
'config',
content)

def get_stored_dict(self):
"""Get the context parameters which should be stored persistently."""
Expand All @@ -253,6 +298,8 @@ def __init__(
authors=None,
maintainers=None,
licenses=None,
extends=None,
key_origins={},
**kwargs
):
"""Creates a new Context object, optionally initializing with parameters
Expand Down Expand Up @@ -304,13 +351,16 @@ def __init__(
:param maintainers: a list of default maintainers
:type licenses: list
:param licenses: a list of default licenses
:type extends: string
:param extends: the name of a profile to use as a base and inherit settings from
"""
self.__locked = False

# Validation is done on assignment
self.workspace = workspace

self.extend_path = extend_path if extend_path else None
self.key_origins = key_origins

self.profile = profile

Expand Down Expand Up @@ -363,6 +413,8 @@ def __init__(
self.env_cmake_prefix_path = None
self.cmake_prefix_path = None

self.extends = extends

def load_env(self):

# Check for CMAKE_PREFIX_PATH in manual cmake args
Expand Down Expand Up @@ -772,6 +824,14 @@ def licenses(self):
def licenses(self, value):
self.__licenses = value

@property
def extends(self):
return self.__extends

@extends.setter
def extends(self, value):
self.__extends = value

@property
def private_devel_path(self):
"""The path to the hidden directory in the develspace that
Expand Down
7 changes: 5 additions & 2 deletions catkin_tools/metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -428,8 +428,11 @@ def update_metadata(workspace_path, profile, verb, new_data={}, no_init=False, m

# Update the metadata for this verb
data.update(new_data)
with open(metadata_file_path, 'w') as metadata_file:
yaml.dump(data, metadata_file, default_flow_style=False)
try:
with open(metadata_file_path, 'w') as metadata_file:
yaml.dump(data, metadata_file, default_flow_style=False)
except PermissionError:
print("Could not write to metadata file '%s'!" % (metadata_file_path))

return data

Expand Down

0 comments on commit 856bf18

Please # to comment.