diff --git a/.gitignore b/.gitignore
index 1345657..cf145f1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,2 @@
build/
-install/
log/
diff --git a/install/.colcon_install_layout b/install/.colcon_install_layout
new file mode 100644
index 0000000..3aad533
--- /dev/null
+++ b/install/.colcon_install_layout
@@ -0,0 +1 @@
+isolated
diff --git a/install/COLCON_IGNORE b/install/COLCON_IGNORE
new file mode 100644
index 0000000..e69de29
diff --git a/install/_local_setup_util_ps1.py b/install/_local_setup_util_ps1.py
new file mode 100644
index 0000000..83abe63
--- /dev/null
+++ b/install/_local_setup_util_ps1.py
@@ -0,0 +1,407 @@
+# Copyright 2016-2019 Dirk Thomas
+# Licensed under the Apache License, Version 2.0
+
+import argparse
+from collections import OrderedDict
+import os
+from pathlib import Path
+import sys
+
+
+FORMAT_STR_COMMENT_LINE = '# {comment}'
+FORMAT_STR_SET_ENV_VAR = 'Set-Item -Path "Env:{name}" -Value "{value}"'
+FORMAT_STR_USE_ENV_VAR = '$env:{name}'
+FORMAT_STR_INVOKE_SCRIPT = '_colcon_prefix_powershell_source_script "{script_path}"'
+FORMAT_STR_REMOVE_LEADING_SEPARATOR = ''
+FORMAT_STR_REMOVE_TRAILING_SEPARATOR = ''
+
+DSV_TYPE_APPEND_NON_DUPLICATE = 'append-non-duplicate'
+DSV_TYPE_PREPEND_NON_DUPLICATE = 'prepend-non-duplicate'
+DSV_TYPE_PREPEND_NON_DUPLICATE_IF_EXISTS = 'prepend-non-duplicate-if-exists'
+DSV_TYPE_SET = 'set'
+DSV_TYPE_SET_IF_UNSET = 'set-if-unset'
+DSV_TYPE_SOURCE = 'source'
+
+
+def main(argv=sys.argv[1:]): # noqa: D103
+ parser = argparse.ArgumentParser(
+ description='Output shell commands for the packages in topological '
+ 'order')
+ parser.add_argument(
+ 'primary_extension',
+ help='The file extension of the primary shell')
+ parser.add_argument(
+ 'additional_extension', nargs='?',
+ help='The additional file extension to be considered')
+ parser.add_argument(
+ '--merged-install', action='store_true',
+ help='All install prefixes are merged into a single location')
+ args = parser.parse_args(argv)
+
+ packages = get_packages(Path(__file__).parent, args.merged_install)
+
+ ordered_packages = order_packages(packages)
+ for pkg_name in ordered_packages:
+ if _include_comments():
+ print(
+ FORMAT_STR_COMMENT_LINE.format_map(
+ {'comment': 'Package: ' + pkg_name}))
+ prefix = os.path.abspath(os.path.dirname(__file__))
+ if not args.merged_install:
+ prefix = os.path.join(prefix, pkg_name)
+ for line in get_commands(
+ pkg_name, prefix, args.primary_extension,
+ args.additional_extension
+ ):
+ print(line)
+
+ for line in _remove_ending_separators():
+ print(line)
+
+
+def get_packages(prefix_path, merged_install):
+ """
+ Find packages based on colcon-specific files created during installation.
+
+ :param Path prefix_path: The install prefix path of all packages
+ :param bool merged_install: The flag if the packages are all installed
+ directly in the prefix or if each package is installed in a subdirectory
+ named after the package
+ :returns: A mapping from the package name to the set of runtime
+ dependencies
+ :rtype: dict
+ """
+ packages = {}
+ # since importing colcon_core isn't feasible here the following constant
+ # must match colcon_core.location.get_relative_package_index_path()
+ subdirectory = 'share/colcon-core/packages'
+ if merged_install:
+ # return if workspace is empty
+ if not (prefix_path / subdirectory).is_dir():
+ return packages
+ # find all files in the subdirectory
+ for p in (prefix_path / subdirectory).iterdir():
+ if not p.is_file():
+ continue
+ if p.name.startswith('.'):
+ continue
+ add_package_runtime_dependencies(p, packages)
+ else:
+ # for each subdirectory look for the package specific file
+ for p in prefix_path.iterdir():
+ if not p.is_dir():
+ continue
+ if p.name.startswith('.'):
+ continue
+ p = p / subdirectory / p.name
+ if p.is_file():
+ add_package_runtime_dependencies(p, packages)
+
+ # remove unknown dependencies
+ pkg_names = set(packages.keys())
+ for k in packages.keys():
+ packages[k] = {d for d in packages[k] if d in pkg_names}
+
+ return packages
+
+
+def add_package_runtime_dependencies(path, packages):
+ """
+ Check the path and if it exists extract the packages runtime dependencies.
+
+ :param Path path: The resource file containing the runtime dependencies
+ :param dict packages: A mapping from package names to the sets of runtime
+ dependencies to add to
+ """
+ content = path.read_text()
+ dependencies = set(content.split(os.pathsep) if content else [])
+ packages[path.name] = dependencies
+
+
+def order_packages(packages):
+ """
+ Order packages topologically.
+
+ :param dict packages: A mapping from package name to the set of runtime
+ dependencies
+ :returns: The package names
+ :rtype: list
+ """
+ # select packages with no dependencies in alphabetical order
+ to_be_ordered = list(packages.keys())
+ ordered = []
+ while to_be_ordered:
+ pkg_names_without_deps = [
+ name for name in to_be_ordered if not packages[name]]
+ if not pkg_names_without_deps:
+ reduce_cycle_set(packages)
+ raise RuntimeError(
+ 'Circular dependency between: ' + ', '.join(sorted(packages)))
+ pkg_names_without_deps.sort()
+ pkg_name = pkg_names_without_deps[0]
+ to_be_ordered.remove(pkg_name)
+ ordered.append(pkg_name)
+ # remove item from dependency lists
+ for k in list(packages.keys()):
+ if pkg_name in packages[k]:
+ packages[k].remove(pkg_name)
+ return ordered
+
+
+def reduce_cycle_set(packages):
+ """
+ Reduce the set of packages to the ones part of the circular dependency.
+
+ :param dict packages: A mapping from package name to the set of runtime
+ dependencies which is modified in place
+ """
+ last_depended = None
+ while len(packages) > 0:
+ # get all remaining dependencies
+ depended = set()
+ for pkg_name, dependencies in packages.items():
+ depended = depended.union(dependencies)
+ # remove all packages which are not dependent on
+ for name in list(packages.keys()):
+ if name not in depended:
+ del packages[name]
+ if last_depended:
+ # if remaining packages haven't changed return them
+ if last_depended == depended:
+ return packages.keys()
+ # otherwise reduce again
+ last_depended = depended
+
+
+def _include_comments():
+ # skipping comment lines when COLCON_TRACE is not set speeds up the
+ # processing especially on Windows
+ return bool(os.environ.get('COLCON_TRACE'))
+
+
+def get_commands(pkg_name, prefix, primary_extension, additional_extension):
+ commands = []
+ package_dsv_path = os.path.join(prefix, 'share', pkg_name, 'package.dsv')
+ if os.path.exists(package_dsv_path):
+ commands += process_dsv_file(
+ package_dsv_path, prefix, primary_extension, additional_extension)
+ return commands
+
+
+def process_dsv_file(
+ dsv_path, prefix, primary_extension=None, additional_extension=None
+):
+ commands = []
+ if _include_comments():
+ commands.append(FORMAT_STR_COMMENT_LINE.format_map({'comment': dsv_path}))
+ with open(dsv_path, 'r') as h:
+ content = h.read()
+ lines = content.splitlines()
+
+ basenames = OrderedDict()
+ for i, line in enumerate(lines):
+ # skip over empty or whitespace-only lines
+ if not line.strip():
+ continue
+ # skip over comments
+ if line.startswith('#'):
+ continue
+ try:
+ type_, remainder = line.split(';', 1)
+ except ValueError:
+ raise RuntimeError(
+ "Line %d in '%s' doesn't contain a semicolon separating the "
+ 'type from the arguments' % (i + 1, dsv_path))
+ if type_ != DSV_TYPE_SOURCE:
+ # handle non-source lines
+ try:
+ commands += handle_dsv_types_except_source(
+ type_, remainder, prefix)
+ except RuntimeError as e:
+ raise RuntimeError(
+ "Line %d in '%s' %s" % (i + 1, dsv_path, e)) from e
+ else:
+ # group remaining source lines by basename
+ path_without_ext, ext = os.path.splitext(remainder)
+ if path_without_ext not in basenames:
+ basenames[path_without_ext] = set()
+ assert ext.startswith('.')
+ ext = ext[1:]
+ if ext in (primary_extension, additional_extension):
+ basenames[path_without_ext].add(ext)
+
+ # add the dsv extension to each basename if the file exists
+ for basename, extensions in basenames.items():
+ if not os.path.isabs(basename):
+ basename = os.path.join(prefix, basename)
+ if os.path.exists(basename + '.dsv'):
+ extensions.add('dsv')
+
+ for basename, extensions in basenames.items():
+ if not os.path.isabs(basename):
+ basename = os.path.join(prefix, basename)
+ if 'dsv' in extensions:
+ # process dsv files recursively
+ commands += process_dsv_file(
+ basename + '.dsv', prefix, primary_extension=primary_extension,
+ additional_extension=additional_extension)
+ elif primary_extension in extensions and len(extensions) == 1:
+ # source primary-only files
+ commands += [
+ FORMAT_STR_INVOKE_SCRIPT.format_map({
+ 'prefix': prefix,
+ 'script_path': basename + '.' + primary_extension})]
+ elif additional_extension in extensions:
+ # source non-primary files
+ commands += [
+ FORMAT_STR_INVOKE_SCRIPT.format_map({
+ 'prefix': prefix,
+ 'script_path': basename + '.' + additional_extension})]
+
+ return commands
+
+
+def handle_dsv_types_except_source(type_, remainder, prefix):
+ commands = []
+ if type_ in (DSV_TYPE_SET, DSV_TYPE_SET_IF_UNSET):
+ try:
+ env_name, value = remainder.split(';', 1)
+ except ValueError:
+ raise RuntimeError(
+ "doesn't contain a semicolon separating the environment name "
+ 'from the value')
+ try_prefixed_value = os.path.join(prefix, value) if value else prefix
+ if os.path.exists(try_prefixed_value):
+ value = try_prefixed_value
+ if type_ == DSV_TYPE_SET:
+ commands += _set(env_name, value)
+ elif type_ == DSV_TYPE_SET_IF_UNSET:
+ commands += _set_if_unset(env_name, value)
+ else:
+ assert False
+ elif type_ in (
+ DSV_TYPE_APPEND_NON_DUPLICATE,
+ DSV_TYPE_PREPEND_NON_DUPLICATE,
+ DSV_TYPE_PREPEND_NON_DUPLICATE_IF_EXISTS
+ ):
+ try:
+ env_name_and_values = remainder.split(';')
+ except ValueError:
+ raise RuntimeError(
+ "doesn't contain a semicolon separating the environment name "
+ 'from the values')
+ env_name = env_name_and_values[0]
+ values = env_name_and_values[1:]
+ for value in values:
+ if not value:
+ value = prefix
+ elif not os.path.isabs(value):
+ value = os.path.join(prefix, value)
+ if (
+ type_ == DSV_TYPE_PREPEND_NON_DUPLICATE_IF_EXISTS and
+ not os.path.exists(value)
+ ):
+ comment = f'skip extending {env_name} with not existing ' \
+ f'path: {value}'
+ if _include_comments():
+ commands.append(
+ FORMAT_STR_COMMENT_LINE.format_map({'comment': comment}))
+ elif type_ == DSV_TYPE_APPEND_NON_DUPLICATE:
+ commands += _append_unique_value(env_name, value)
+ else:
+ commands += _prepend_unique_value(env_name, value)
+ else:
+ raise RuntimeError(
+ 'contains an unknown environment hook type: ' + type_)
+ return commands
+
+
+env_state = {}
+
+
+def _append_unique_value(name, value):
+ global env_state
+ if name not in env_state:
+ if os.environ.get(name):
+ env_state[name] = set(os.environ[name].split(os.pathsep))
+ else:
+ env_state[name] = set()
+ # append even if the variable has not been set yet, in case a shell script sets the
+ # same variable without the knowledge of this Python script.
+ # later _remove_ending_separators() will cleanup any unintentional leading separator
+ extend = FORMAT_STR_USE_ENV_VAR.format_map({'name': name}) + os.pathsep
+ line = FORMAT_STR_SET_ENV_VAR.format_map(
+ {'name': name, 'value': extend + value})
+ if value not in env_state[name]:
+ env_state[name].add(value)
+ else:
+ if not _include_comments():
+ return []
+ line = FORMAT_STR_COMMENT_LINE.format_map({'comment': line})
+ return [line]
+
+
+def _prepend_unique_value(name, value):
+ global env_state
+ if name not in env_state:
+ if os.environ.get(name):
+ env_state[name] = set(os.environ[name].split(os.pathsep))
+ else:
+ env_state[name] = set()
+ # prepend even if the variable has not been set yet, in case a shell script sets the
+ # same variable without the knowledge of this Python script.
+ # later _remove_ending_separators() will cleanup any unintentional trailing separator
+ extend = os.pathsep + FORMAT_STR_USE_ENV_VAR.format_map({'name': name})
+ line = FORMAT_STR_SET_ENV_VAR.format_map(
+ {'name': name, 'value': value + extend})
+ if value not in env_state[name]:
+ env_state[name].add(value)
+ else:
+ if not _include_comments():
+ return []
+ line = FORMAT_STR_COMMENT_LINE.format_map({'comment': line})
+ return [line]
+
+
+# generate commands for removing prepended underscores
+def _remove_ending_separators():
+ # do nothing if the shell extension does not implement the logic
+ if FORMAT_STR_REMOVE_TRAILING_SEPARATOR is None:
+ return []
+
+ global env_state
+ commands = []
+ for name in env_state:
+ # skip variables that already had values before this script started prepending
+ if name in os.environ:
+ continue
+ commands += [
+ FORMAT_STR_REMOVE_LEADING_SEPARATOR.format_map({'name': name}),
+ FORMAT_STR_REMOVE_TRAILING_SEPARATOR.format_map({'name': name})]
+ return commands
+
+
+def _set(name, value):
+ global env_state
+ env_state[name] = value
+ line = FORMAT_STR_SET_ENV_VAR.format_map(
+ {'name': name, 'value': value})
+ return [line]
+
+
+def _set_if_unset(name, value):
+ global env_state
+ line = FORMAT_STR_SET_ENV_VAR.format_map(
+ {'name': name, 'value': value})
+ if env_state.get(name, os.environ.get(name)):
+ line = FORMAT_STR_COMMENT_LINE.format_map({'comment': line})
+ return [line]
+
+
+if __name__ == '__main__': # pragma: no cover
+ try:
+ rc = main()
+ except RuntimeError as e:
+ print(str(e), file=sys.stderr)
+ rc = 1
+ sys.exit(rc)
diff --git a/install/_local_setup_util_sh.py b/install/_local_setup_util_sh.py
new file mode 100644
index 0000000..ff31198
--- /dev/null
+++ b/install/_local_setup_util_sh.py
@@ -0,0 +1,407 @@
+# Copyright 2016-2019 Dirk Thomas
+# Licensed under the Apache License, Version 2.0
+
+import argparse
+from collections import OrderedDict
+import os
+from pathlib import Path
+import sys
+
+
+FORMAT_STR_COMMENT_LINE = '# {comment}'
+FORMAT_STR_SET_ENV_VAR = 'export {name}="{value}"'
+FORMAT_STR_USE_ENV_VAR = '${name}'
+FORMAT_STR_INVOKE_SCRIPT = 'COLCON_CURRENT_PREFIX="{prefix}" _colcon_prefix_sh_source_script "{script_path}"'
+FORMAT_STR_REMOVE_LEADING_SEPARATOR = 'if [ "$(echo -n ${name} | head -c 1)" = ":" ]; then export {name}=${{{name}#?}} ; fi'
+FORMAT_STR_REMOVE_TRAILING_SEPARATOR = 'if [ "$(echo -n ${name} | tail -c 1)" = ":" ]; then export {name}=${{{name}%?}} ; fi'
+
+DSV_TYPE_APPEND_NON_DUPLICATE = 'append-non-duplicate'
+DSV_TYPE_PREPEND_NON_DUPLICATE = 'prepend-non-duplicate'
+DSV_TYPE_PREPEND_NON_DUPLICATE_IF_EXISTS = 'prepend-non-duplicate-if-exists'
+DSV_TYPE_SET = 'set'
+DSV_TYPE_SET_IF_UNSET = 'set-if-unset'
+DSV_TYPE_SOURCE = 'source'
+
+
+def main(argv=sys.argv[1:]): # noqa: D103
+ parser = argparse.ArgumentParser(
+ description='Output shell commands for the packages in topological '
+ 'order')
+ parser.add_argument(
+ 'primary_extension',
+ help='The file extension of the primary shell')
+ parser.add_argument(
+ 'additional_extension', nargs='?',
+ help='The additional file extension to be considered')
+ parser.add_argument(
+ '--merged-install', action='store_true',
+ help='All install prefixes are merged into a single location')
+ args = parser.parse_args(argv)
+
+ packages = get_packages(Path(__file__).parent, args.merged_install)
+
+ ordered_packages = order_packages(packages)
+ for pkg_name in ordered_packages:
+ if _include_comments():
+ print(
+ FORMAT_STR_COMMENT_LINE.format_map(
+ {'comment': 'Package: ' + pkg_name}))
+ prefix = os.path.abspath(os.path.dirname(__file__))
+ if not args.merged_install:
+ prefix = os.path.join(prefix, pkg_name)
+ for line in get_commands(
+ pkg_name, prefix, args.primary_extension,
+ args.additional_extension
+ ):
+ print(line)
+
+ for line in _remove_ending_separators():
+ print(line)
+
+
+def get_packages(prefix_path, merged_install):
+ """
+ Find packages based on colcon-specific files created during installation.
+
+ :param Path prefix_path: The install prefix path of all packages
+ :param bool merged_install: The flag if the packages are all installed
+ directly in the prefix or if each package is installed in a subdirectory
+ named after the package
+ :returns: A mapping from the package name to the set of runtime
+ dependencies
+ :rtype: dict
+ """
+ packages = {}
+ # since importing colcon_core isn't feasible here the following constant
+ # must match colcon_core.location.get_relative_package_index_path()
+ subdirectory = 'share/colcon-core/packages'
+ if merged_install:
+ # return if workspace is empty
+ if not (prefix_path / subdirectory).is_dir():
+ return packages
+ # find all files in the subdirectory
+ for p in (prefix_path / subdirectory).iterdir():
+ if not p.is_file():
+ continue
+ if p.name.startswith('.'):
+ continue
+ add_package_runtime_dependencies(p, packages)
+ else:
+ # for each subdirectory look for the package specific file
+ for p in prefix_path.iterdir():
+ if not p.is_dir():
+ continue
+ if p.name.startswith('.'):
+ continue
+ p = p / subdirectory / p.name
+ if p.is_file():
+ add_package_runtime_dependencies(p, packages)
+
+ # remove unknown dependencies
+ pkg_names = set(packages.keys())
+ for k in packages.keys():
+ packages[k] = {d for d in packages[k] if d in pkg_names}
+
+ return packages
+
+
+def add_package_runtime_dependencies(path, packages):
+ """
+ Check the path and if it exists extract the packages runtime dependencies.
+
+ :param Path path: The resource file containing the runtime dependencies
+ :param dict packages: A mapping from package names to the sets of runtime
+ dependencies to add to
+ """
+ content = path.read_text()
+ dependencies = set(content.split(os.pathsep) if content else [])
+ packages[path.name] = dependencies
+
+
+def order_packages(packages):
+ """
+ Order packages topologically.
+
+ :param dict packages: A mapping from package name to the set of runtime
+ dependencies
+ :returns: The package names
+ :rtype: list
+ """
+ # select packages with no dependencies in alphabetical order
+ to_be_ordered = list(packages.keys())
+ ordered = []
+ while to_be_ordered:
+ pkg_names_without_deps = [
+ name for name in to_be_ordered if not packages[name]]
+ if not pkg_names_without_deps:
+ reduce_cycle_set(packages)
+ raise RuntimeError(
+ 'Circular dependency between: ' + ', '.join(sorted(packages)))
+ pkg_names_without_deps.sort()
+ pkg_name = pkg_names_without_deps[0]
+ to_be_ordered.remove(pkg_name)
+ ordered.append(pkg_name)
+ # remove item from dependency lists
+ for k in list(packages.keys()):
+ if pkg_name in packages[k]:
+ packages[k].remove(pkg_name)
+ return ordered
+
+
+def reduce_cycle_set(packages):
+ """
+ Reduce the set of packages to the ones part of the circular dependency.
+
+ :param dict packages: A mapping from package name to the set of runtime
+ dependencies which is modified in place
+ """
+ last_depended = None
+ while len(packages) > 0:
+ # get all remaining dependencies
+ depended = set()
+ for pkg_name, dependencies in packages.items():
+ depended = depended.union(dependencies)
+ # remove all packages which are not dependent on
+ for name in list(packages.keys()):
+ if name not in depended:
+ del packages[name]
+ if last_depended:
+ # if remaining packages haven't changed return them
+ if last_depended == depended:
+ return packages.keys()
+ # otherwise reduce again
+ last_depended = depended
+
+
+def _include_comments():
+ # skipping comment lines when COLCON_TRACE is not set speeds up the
+ # processing especially on Windows
+ return bool(os.environ.get('COLCON_TRACE'))
+
+
+def get_commands(pkg_name, prefix, primary_extension, additional_extension):
+ commands = []
+ package_dsv_path = os.path.join(prefix, 'share', pkg_name, 'package.dsv')
+ if os.path.exists(package_dsv_path):
+ commands += process_dsv_file(
+ package_dsv_path, prefix, primary_extension, additional_extension)
+ return commands
+
+
+def process_dsv_file(
+ dsv_path, prefix, primary_extension=None, additional_extension=None
+):
+ commands = []
+ if _include_comments():
+ commands.append(FORMAT_STR_COMMENT_LINE.format_map({'comment': dsv_path}))
+ with open(dsv_path, 'r') as h:
+ content = h.read()
+ lines = content.splitlines()
+
+ basenames = OrderedDict()
+ for i, line in enumerate(lines):
+ # skip over empty or whitespace-only lines
+ if not line.strip():
+ continue
+ # skip over comments
+ if line.startswith('#'):
+ continue
+ try:
+ type_, remainder = line.split(';', 1)
+ except ValueError:
+ raise RuntimeError(
+ "Line %d in '%s' doesn't contain a semicolon separating the "
+ 'type from the arguments' % (i + 1, dsv_path))
+ if type_ != DSV_TYPE_SOURCE:
+ # handle non-source lines
+ try:
+ commands += handle_dsv_types_except_source(
+ type_, remainder, prefix)
+ except RuntimeError as e:
+ raise RuntimeError(
+ "Line %d in '%s' %s" % (i + 1, dsv_path, e)) from e
+ else:
+ # group remaining source lines by basename
+ path_without_ext, ext = os.path.splitext(remainder)
+ if path_without_ext not in basenames:
+ basenames[path_without_ext] = set()
+ assert ext.startswith('.')
+ ext = ext[1:]
+ if ext in (primary_extension, additional_extension):
+ basenames[path_without_ext].add(ext)
+
+ # add the dsv extension to each basename if the file exists
+ for basename, extensions in basenames.items():
+ if not os.path.isabs(basename):
+ basename = os.path.join(prefix, basename)
+ if os.path.exists(basename + '.dsv'):
+ extensions.add('dsv')
+
+ for basename, extensions in basenames.items():
+ if not os.path.isabs(basename):
+ basename = os.path.join(prefix, basename)
+ if 'dsv' in extensions:
+ # process dsv files recursively
+ commands += process_dsv_file(
+ basename + '.dsv', prefix, primary_extension=primary_extension,
+ additional_extension=additional_extension)
+ elif primary_extension in extensions and len(extensions) == 1:
+ # source primary-only files
+ commands += [
+ FORMAT_STR_INVOKE_SCRIPT.format_map({
+ 'prefix': prefix,
+ 'script_path': basename + '.' + primary_extension})]
+ elif additional_extension in extensions:
+ # source non-primary files
+ commands += [
+ FORMAT_STR_INVOKE_SCRIPT.format_map({
+ 'prefix': prefix,
+ 'script_path': basename + '.' + additional_extension})]
+
+ return commands
+
+
+def handle_dsv_types_except_source(type_, remainder, prefix):
+ commands = []
+ if type_ in (DSV_TYPE_SET, DSV_TYPE_SET_IF_UNSET):
+ try:
+ env_name, value = remainder.split(';', 1)
+ except ValueError:
+ raise RuntimeError(
+ "doesn't contain a semicolon separating the environment name "
+ 'from the value')
+ try_prefixed_value = os.path.join(prefix, value) if value else prefix
+ if os.path.exists(try_prefixed_value):
+ value = try_prefixed_value
+ if type_ == DSV_TYPE_SET:
+ commands += _set(env_name, value)
+ elif type_ == DSV_TYPE_SET_IF_UNSET:
+ commands += _set_if_unset(env_name, value)
+ else:
+ assert False
+ elif type_ in (
+ DSV_TYPE_APPEND_NON_DUPLICATE,
+ DSV_TYPE_PREPEND_NON_DUPLICATE,
+ DSV_TYPE_PREPEND_NON_DUPLICATE_IF_EXISTS
+ ):
+ try:
+ env_name_and_values = remainder.split(';')
+ except ValueError:
+ raise RuntimeError(
+ "doesn't contain a semicolon separating the environment name "
+ 'from the values')
+ env_name = env_name_and_values[0]
+ values = env_name_and_values[1:]
+ for value in values:
+ if not value:
+ value = prefix
+ elif not os.path.isabs(value):
+ value = os.path.join(prefix, value)
+ if (
+ type_ == DSV_TYPE_PREPEND_NON_DUPLICATE_IF_EXISTS and
+ not os.path.exists(value)
+ ):
+ comment = f'skip extending {env_name} with not existing ' \
+ f'path: {value}'
+ if _include_comments():
+ commands.append(
+ FORMAT_STR_COMMENT_LINE.format_map({'comment': comment}))
+ elif type_ == DSV_TYPE_APPEND_NON_DUPLICATE:
+ commands += _append_unique_value(env_name, value)
+ else:
+ commands += _prepend_unique_value(env_name, value)
+ else:
+ raise RuntimeError(
+ 'contains an unknown environment hook type: ' + type_)
+ return commands
+
+
+env_state = {}
+
+
+def _append_unique_value(name, value):
+ global env_state
+ if name not in env_state:
+ if os.environ.get(name):
+ env_state[name] = set(os.environ[name].split(os.pathsep))
+ else:
+ env_state[name] = set()
+ # append even if the variable has not been set yet, in case a shell script sets the
+ # same variable without the knowledge of this Python script.
+ # later _remove_ending_separators() will cleanup any unintentional leading separator
+ extend = FORMAT_STR_USE_ENV_VAR.format_map({'name': name}) + os.pathsep
+ line = FORMAT_STR_SET_ENV_VAR.format_map(
+ {'name': name, 'value': extend + value})
+ if value not in env_state[name]:
+ env_state[name].add(value)
+ else:
+ if not _include_comments():
+ return []
+ line = FORMAT_STR_COMMENT_LINE.format_map({'comment': line})
+ return [line]
+
+
+def _prepend_unique_value(name, value):
+ global env_state
+ if name not in env_state:
+ if os.environ.get(name):
+ env_state[name] = set(os.environ[name].split(os.pathsep))
+ else:
+ env_state[name] = set()
+ # prepend even if the variable has not been set yet, in case a shell script sets the
+ # same variable without the knowledge of this Python script.
+ # later _remove_ending_separators() will cleanup any unintentional trailing separator
+ extend = os.pathsep + FORMAT_STR_USE_ENV_VAR.format_map({'name': name})
+ line = FORMAT_STR_SET_ENV_VAR.format_map(
+ {'name': name, 'value': value + extend})
+ if value not in env_state[name]:
+ env_state[name].add(value)
+ else:
+ if not _include_comments():
+ return []
+ line = FORMAT_STR_COMMENT_LINE.format_map({'comment': line})
+ return [line]
+
+
+# generate commands for removing prepended underscores
+def _remove_ending_separators():
+ # do nothing if the shell extension does not implement the logic
+ if FORMAT_STR_REMOVE_TRAILING_SEPARATOR is None:
+ return []
+
+ global env_state
+ commands = []
+ for name in env_state:
+ # skip variables that already had values before this script started prepending
+ if name in os.environ:
+ continue
+ commands += [
+ FORMAT_STR_REMOVE_LEADING_SEPARATOR.format_map({'name': name}),
+ FORMAT_STR_REMOVE_TRAILING_SEPARATOR.format_map({'name': name})]
+ return commands
+
+
+def _set(name, value):
+ global env_state
+ env_state[name] = value
+ line = FORMAT_STR_SET_ENV_VAR.format_map(
+ {'name': name, 'value': value})
+ return [line]
+
+
+def _set_if_unset(name, value):
+ global env_state
+ line = FORMAT_STR_SET_ENV_VAR.format_map(
+ {'name': name, 'value': value})
+ if env_state.get(name, os.environ.get(name)):
+ line = FORMAT_STR_COMMENT_LINE.format_map({'comment': line})
+ return [line]
+
+
+if __name__ == '__main__': # pragma: no cover
+ try:
+ rc = main()
+ except RuntimeError as e:
+ print(str(e), file=sys.stderr)
+ rc = 1
+ sys.exit(rc)
diff --git a/install/diagnostics/lib/diagnostics/diagnostics b/install/diagnostics/lib/diagnostics/diagnostics
new file mode 100755
index 0000000..e5b284d
Binary files /dev/null and b/install/diagnostics/lib/diagnostics/diagnostics differ
diff --git a/install/diagnostics/share/ament_index/resource_index/package_run_dependencies/diagnostics b/install/diagnostics/share/ament_index/resource_index/package_run_dependencies/diagnostics
new file mode 100644
index 0000000..25ce83a
--- /dev/null
+++ b/install/diagnostics/share/ament_index/resource_index/package_run_dependencies/diagnostics
@@ -0,0 +1 @@
+ament_lint_auto;ament_lint_common
\ No newline at end of file
diff --git a/install/diagnostics/share/ament_index/resource_index/packages/diagnostics b/install/diagnostics/share/ament_index/resource_index/packages/diagnostics
new file mode 100644
index 0000000..e69de29
diff --git a/install/diagnostics/share/ament_index/resource_index/parent_prefix_path/diagnostics b/install/diagnostics/share/ament_index/resource_index/parent_prefix_path/diagnostics
new file mode 100644
index 0000000..4f81acd
--- /dev/null
+++ b/install/diagnostics/share/ament_index/resource_index/parent_prefix_path/diagnostics
@@ -0,0 +1 @@
+/workspaces/sailbot_workspace/src/diagnostics/install/diagnostics:/workspaces/sailbot_workspace/install:/opt/ros/humble
\ No newline at end of file
diff --git a/install/diagnostics/share/colcon-core/packages/diagnostics b/install/diagnostics/share/colcon-core/packages/diagnostics
new file mode 100644
index 0000000..e69de29
diff --git a/install/diagnostics/share/diagnostics/cmake/diagnosticsConfig-version.cmake b/install/diagnostics/share/diagnostics/cmake/diagnosticsConfig-version.cmake
new file mode 100644
index 0000000..7beb732
--- /dev/null
+++ b/install/diagnostics/share/diagnostics/cmake/diagnosticsConfig-version.cmake
@@ -0,0 +1,14 @@
+# generated from ament/cmake/core/templates/nameConfig-version.cmake.in
+set(PACKAGE_VERSION "0.0.0")
+
+set(PACKAGE_VERSION_EXACT False)
+set(PACKAGE_VERSION_COMPATIBLE False)
+
+if("${PACKAGE_FIND_VERSION}" VERSION_EQUAL "${PACKAGE_VERSION}")
+ set(PACKAGE_VERSION_EXACT True)
+ set(PACKAGE_VERSION_COMPATIBLE True)
+endif()
+
+if("${PACKAGE_FIND_VERSION}" VERSION_LESS "${PACKAGE_VERSION}")
+ set(PACKAGE_VERSION_COMPATIBLE True)
+endif()
diff --git a/install/diagnostics/share/diagnostics/cmake/diagnosticsConfig.cmake b/install/diagnostics/share/diagnostics/cmake/diagnosticsConfig.cmake
new file mode 100644
index 0000000..6813e93
--- /dev/null
+++ b/install/diagnostics/share/diagnostics/cmake/diagnosticsConfig.cmake
@@ -0,0 +1,42 @@
+# generated from ament/cmake/core/templates/nameConfig.cmake.in
+
+# prevent multiple inclusion
+if(_diagnostics_CONFIG_INCLUDED)
+ # ensure to keep the found flag the same
+ if(NOT DEFINED diagnostics_FOUND)
+ # explicitly set it to FALSE, otherwise CMake will set it to TRUE
+ set(diagnostics_FOUND FALSE)
+ elseif(NOT diagnostics_FOUND)
+ # use separate condition to avoid uninitialized variable warning
+ set(diagnostics_FOUND FALSE)
+ endif()
+ return()
+endif()
+set(_diagnostics_CONFIG_INCLUDED TRUE)
+
+# output package information
+if(NOT diagnostics_FIND_QUIETLY)
+ message(STATUS "Found diagnostics: 0.0.0 (${diagnostics_DIR})")
+endif()
+
+# warn when using a deprecated package
+if(NOT "" STREQUAL "")
+ set(_msg "Package 'diagnostics' is deprecated")
+ # append custom deprecation text if available
+ if(NOT "" STREQUAL "TRUE")
+ set(_msg "${_msg} ()")
+ endif()
+ # optionally quiet the deprecation message
+ if(NOT ${diagnostics_DEPRECATED_QUIET})
+ message(DEPRECATION "${_msg}")
+ endif()
+endif()
+
+# flag package as ament-based to distinguish it after being find_package()-ed
+set(diagnostics_FOUND_AMENT_PACKAGE TRUE)
+
+# include all config extra files
+set(_extras "")
+foreach(_extra ${_extras})
+ include("${diagnostics_DIR}/${_extra}")
+endforeach()
diff --git a/install/diagnostics/share/diagnostics/environment/ament_prefix_path.dsv b/install/diagnostics/share/diagnostics/environment/ament_prefix_path.dsv
new file mode 100644
index 0000000..79d4c95
--- /dev/null
+++ b/install/diagnostics/share/diagnostics/environment/ament_prefix_path.dsv
@@ -0,0 +1 @@
+prepend-non-duplicate;AMENT_PREFIX_PATH;
diff --git a/install/diagnostics/share/diagnostics/environment/ament_prefix_path.sh b/install/diagnostics/share/diagnostics/environment/ament_prefix_path.sh
new file mode 100644
index 0000000..02e441b
--- /dev/null
+++ b/install/diagnostics/share/diagnostics/environment/ament_prefix_path.sh
@@ -0,0 +1,4 @@
+# copied from
+# ament_cmake_core/cmake/environment_hooks/environment/ament_prefix_path.sh
+
+ament_prepend_unique_value AMENT_PREFIX_PATH "$AMENT_CURRENT_PREFIX"
diff --git a/install/diagnostics/share/diagnostics/environment/path.dsv b/install/diagnostics/share/diagnostics/environment/path.dsv
new file mode 100644
index 0000000..b94426a
--- /dev/null
+++ b/install/diagnostics/share/diagnostics/environment/path.dsv
@@ -0,0 +1 @@
+prepend-non-duplicate-if-exists;PATH;bin
diff --git a/install/diagnostics/share/diagnostics/environment/path.sh b/install/diagnostics/share/diagnostics/environment/path.sh
new file mode 100644
index 0000000..e59b749
--- /dev/null
+++ b/install/diagnostics/share/diagnostics/environment/path.sh
@@ -0,0 +1,5 @@
+# copied from ament_cmake_core/cmake/environment_hooks/environment/path.sh
+
+if [ -d "$AMENT_CURRENT_PREFIX/bin" ]; then
+ ament_prepend_unique_value PATH "$AMENT_CURRENT_PREFIX/bin"
+fi
diff --git a/install/diagnostics/share/diagnostics/hook/cmake_prefix_path.dsv b/install/diagnostics/share/diagnostics/hook/cmake_prefix_path.dsv
new file mode 100644
index 0000000..e119f32
--- /dev/null
+++ b/install/diagnostics/share/diagnostics/hook/cmake_prefix_path.dsv
@@ -0,0 +1 @@
+prepend-non-duplicate;CMAKE_PREFIX_PATH;
diff --git a/install/diagnostics/share/diagnostics/hook/cmake_prefix_path.ps1 b/install/diagnostics/share/diagnostics/hook/cmake_prefix_path.ps1
new file mode 100644
index 0000000..d03facc
--- /dev/null
+++ b/install/diagnostics/share/diagnostics/hook/cmake_prefix_path.ps1
@@ -0,0 +1,3 @@
+# generated from colcon_powershell/shell/template/hook_prepend_value.ps1.em
+
+colcon_prepend_unique_value CMAKE_PREFIX_PATH "$env:COLCON_CURRENT_PREFIX"
diff --git a/install/diagnostics/share/diagnostics/hook/cmake_prefix_path.sh b/install/diagnostics/share/diagnostics/hook/cmake_prefix_path.sh
new file mode 100644
index 0000000..a948e68
--- /dev/null
+++ b/install/diagnostics/share/diagnostics/hook/cmake_prefix_path.sh
@@ -0,0 +1,3 @@
+# generated from colcon_core/shell/template/hook_prepend_value.sh.em
+
+_colcon_prepend_unique_value CMAKE_PREFIX_PATH "$COLCON_CURRENT_PREFIX"
diff --git a/install/diagnostics/share/diagnostics/local_setup.bash b/install/diagnostics/share/diagnostics/local_setup.bash
new file mode 100644
index 0000000..49782f2
--- /dev/null
+++ b/install/diagnostics/share/diagnostics/local_setup.bash
@@ -0,0 +1,46 @@
+# generated from ament_package/template/package_level/local_setup.bash.in
+
+# source local_setup.sh from same directory as this file
+_this_path=$(builtin cd "`dirname "${BASH_SOURCE[0]}"`" && pwd)
+# provide AMENT_CURRENT_PREFIX to shell script
+AMENT_CURRENT_PREFIX=$(builtin cd "`dirname "${BASH_SOURCE[0]}"`/../.." && pwd)
+# store AMENT_CURRENT_PREFIX to restore it before each environment hook
+_package_local_setup_AMENT_CURRENT_PREFIX=$AMENT_CURRENT_PREFIX
+
+# trace output
+if [ -n "$AMENT_TRACE_SETUP_FILES" ]; then
+ echo "# . \"$_this_path/local_setup.sh\""
+fi
+. "$_this_path/local_setup.sh"
+unset _this_path
+
+# unset AMENT_ENVIRONMENT_HOOKS
+# if not appending to them for return
+if [ -z "$AMENT_RETURN_ENVIRONMENT_HOOKS" ]; then
+ unset AMENT_ENVIRONMENT_HOOKS
+fi
+
+# restore AMENT_CURRENT_PREFIX before evaluating the environment hooks
+AMENT_CURRENT_PREFIX=$_package_local_setup_AMENT_CURRENT_PREFIX
+# list all environment hooks of this package
+
+# source all shell-specific environment hooks of this package
+# if not returning them
+if [ -z "$AMENT_RETURN_ENVIRONMENT_HOOKS" ]; then
+ _package_local_setup_IFS=$IFS
+ IFS=":"
+ for _hook in $AMENT_ENVIRONMENT_HOOKS; do
+ # restore AMENT_CURRENT_PREFIX for each environment hook
+ AMENT_CURRENT_PREFIX=$_package_local_setup_AMENT_CURRENT_PREFIX
+ # restore IFS before sourcing other files
+ IFS=$_package_local_setup_IFS
+ . "$_hook"
+ done
+ unset _hook
+ IFS=$_package_local_setup_IFS
+ unset _package_local_setup_IFS
+ unset AMENT_ENVIRONMENT_HOOKS
+fi
+
+unset _package_local_setup_AMENT_CURRENT_PREFIX
+unset AMENT_CURRENT_PREFIX
diff --git a/install/diagnostics/share/diagnostics/local_setup.dsv b/install/diagnostics/share/diagnostics/local_setup.dsv
new file mode 100644
index 0000000..3ebb4fc
--- /dev/null
+++ b/install/diagnostics/share/diagnostics/local_setup.dsv
@@ -0,0 +1,2 @@
+source;share/diagnostics/environment/ament_prefix_path.sh
+source;share/diagnostics/environment/path.sh
diff --git a/install/diagnostics/share/diagnostics/local_setup.sh b/install/diagnostics/share/diagnostics/local_setup.sh
new file mode 100644
index 0000000..2b85f6e
--- /dev/null
+++ b/install/diagnostics/share/diagnostics/local_setup.sh
@@ -0,0 +1,184 @@
+# generated from ament_package/template/package_level/local_setup.sh.in
+
+# since this file is sourced use either the provided AMENT_CURRENT_PREFIX
+# or fall back to the destination set at configure time
+: ${AMENT_CURRENT_PREFIX:="/workspaces/sailbot_workspace/src/diagnostics/install/diagnostics"}
+if [ ! -d "$AMENT_CURRENT_PREFIX" ]; then
+ if [ -z "$COLCON_CURRENT_PREFIX" ]; then
+ echo "The compile time prefix path '$AMENT_CURRENT_PREFIX' doesn't " \
+ "exist. Consider sourcing a different extension than '.sh'." 1>&2
+ else
+ AMENT_CURRENT_PREFIX="$COLCON_CURRENT_PREFIX"
+ fi
+fi
+
+# function to append values to environment variables
+# using colons as separators and avoiding leading separators
+ament_append_value() {
+ # arguments
+ _listname="$1"
+ _value="$2"
+ #echo "listname $_listname"
+ #eval echo "list value \$$_listname"
+ #echo "value $_value"
+
+ # avoid leading separator
+ eval _values=\"\$$_listname\"
+ if [ -z "$_values" ]; then
+ eval export $_listname=\"$_value\"
+ #eval echo "set list \$$_listname"
+ else
+ # field separator must not be a colon
+ _ament_append_value_IFS=$IFS
+ unset IFS
+ eval export $_listname=\"\$$_listname:$_value\"
+ #eval echo "append list \$$_listname"
+ IFS=$_ament_append_value_IFS
+ unset _ament_append_value_IFS
+ fi
+ unset _values
+
+ unset _value
+ unset _listname
+}
+
+# function to append non-duplicate values to environment variables
+# using colons as separators and avoiding leading separators
+ament_append_unique_value() {
+ # arguments
+ _listname=$1
+ _value=$2
+ #echo "listname $_listname"
+ #eval echo "list value \$$_listname"
+ #echo "value $_value"
+
+ # check if the list contains the value
+ eval _values=\$$_listname
+ _duplicate=
+ _ament_append_unique_value_IFS=$IFS
+ IFS=":"
+ if [ "$AMENT_SHELL" = "zsh" ]; then
+ ament_zsh_to_array _values
+ fi
+ for _item in $_values; do
+ # ignore empty strings
+ if [ -z "$_item" ]; then
+ continue
+ fi
+ if [ $_item = $_value ]; then
+ _duplicate=1
+ fi
+ done
+ unset _item
+
+ # append only non-duplicates
+ if [ -z "$_duplicate" ]; then
+ # avoid leading separator
+ if [ -z "$_values" ]; then
+ eval $_listname=\"$_value\"
+ #eval echo "set list \$$_listname"
+ else
+ # field separator must not be a colon
+ unset IFS
+ eval $_listname=\"\$$_listname:$_value\"
+ #eval echo "append list \$$_listname"
+ fi
+ fi
+ IFS=$_ament_append_unique_value_IFS
+ unset _ament_append_unique_value_IFS
+ unset _duplicate
+ unset _values
+
+ unset _value
+ unset _listname
+}
+
+# function to prepend non-duplicate values to environment variables
+# using colons as separators and avoiding trailing separators
+ament_prepend_unique_value() {
+ # arguments
+ _listname="$1"
+ _value="$2"
+ #echo "listname $_listname"
+ #eval echo "list value \$$_listname"
+ #echo "value $_value"
+
+ # check if the list contains the value
+ eval _values=\"\$$_listname\"
+ _duplicate=
+ _ament_prepend_unique_value_IFS=$IFS
+ IFS=":"
+ if [ "$AMENT_SHELL" = "zsh" ]; then
+ ament_zsh_to_array _values
+ fi
+ for _item in $_values; do
+ # ignore empty strings
+ if [ -z "$_item" ]; then
+ continue
+ fi
+ if [ "$_item" = "$_value" ]; then
+ _duplicate=1
+ fi
+ done
+ unset _item
+
+ # prepend only non-duplicates
+ if [ -z "$_duplicate" ]; then
+ # avoid trailing separator
+ if [ -z "$_values" ]; then
+ eval export $_listname=\"$_value\"
+ #eval echo "set list \$$_listname"
+ else
+ # field separator must not be a colon
+ unset IFS
+ eval export $_listname=\"$_value:\$$_listname\"
+ #eval echo "prepend list \$$_listname"
+ fi
+ fi
+ IFS=$_ament_prepend_unique_value_IFS
+ unset _ament_prepend_unique_value_IFS
+ unset _duplicate
+ unset _values
+
+ unset _value
+ unset _listname
+}
+
+# unset AMENT_ENVIRONMENT_HOOKS
+# if not appending to them for return
+if [ -z "$AMENT_RETURN_ENVIRONMENT_HOOKS" ]; then
+ unset AMENT_ENVIRONMENT_HOOKS
+fi
+
+# list all environment hooks of this package
+ament_append_value AMENT_ENVIRONMENT_HOOKS "$AMENT_CURRENT_PREFIX/share/diagnostics/environment/ament_prefix_path.sh"
+ament_append_value AMENT_ENVIRONMENT_HOOKS "$AMENT_CURRENT_PREFIX/share/diagnostics/environment/path.sh"
+
+# source all shell-specific environment hooks of this package
+# if not returning them
+if [ -z "$AMENT_RETURN_ENVIRONMENT_HOOKS" ]; then
+ _package_local_setup_IFS=$IFS
+ IFS=":"
+ if [ "$AMENT_SHELL" = "zsh" ]; then
+ ament_zsh_to_array AMENT_ENVIRONMENT_HOOKS
+ fi
+ for _hook in $AMENT_ENVIRONMENT_HOOKS; do
+ if [ -f "$_hook" ]; then
+ # restore IFS before sourcing other files
+ IFS=$_package_local_setup_IFS
+ # trace output
+ if [ -n "$AMENT_TRACE_SETUP_FILES" ]; then
+ echo "# . \"$_hook\""
+ fi
+ . "$_hook"
+ fi
+ done
+ unset _hook
+ IFS=$_package_local_setup_IFS
+ unset _package_local_setup_IFS
+ unset AMENT_ENVIRONMENT_HOOKS
+fi
+
+# reset AMENT_CURRENT_PREFIX after each package
+# allowing to source multiple package-level setup files
+unset AMENT_CURRENT_PREFIX
diff --git a/install/diagnostics/share/diagnostics/local_setup.zsh b/install/diagnostics/share/diagnostics/local_setup.zsh
new file mode 100644
index 0000000..fe161be
--- /dev/null
+++ b/install/diagnostics/share/diagnostics/local_setup.zsh
@@ -0,0 +1,59 @@
+# generated from ament_package/template/package_level/local_setup.zsh.in
+
+AMENT_SHELL=zsh
+
+# source local_setup.sh from same directory as this file
+_this_path=$(builtin cd -q "`dirname "${(%):-%N}"`" > /dev/null && pwd)
+# provide AMENT_CURRENT_PREFIX to shell script
+AMENT_CURRENT_PREFIX=$(builtin cd -q "`dirname "${(%):-%N}"`/../.." > /dev/null && pwd)
+# store AMENT_CURRENT_PREFIX to restore it before each environment hook
+_package_local_setup_AMENT_CURRENT_PREFIX=$AMENT_CURRENT_PREFIX
+
+# function to convert array-like strings into arrays
+# to wordaround SH_WORD_SPLIT not being set
+ament_zsh_to_array() {
+ local _listname=$1
+ local _dollar="$"
+ local _split="{="
+ local _to_array="(\"$_dollar$_split$_listname}\")"
+ eval $_listname=$_to_array
+}
+
+# trace output
+if [ -n "$AMENT_TRACE_SETUP_FILES" ]; then
+ echo "# . \"$_this_path/local_setup.sh\""
+fi
+# the package-level local_setup file unsets AMENT_CURRENT_PREFIX
+. "$_this_path/local_setup.sh"
+unset _this_path
+
+# unset AMENT_ENVIRONMENT_HOOKS
+# if not appending to them for return
+if [ -z "$AMENT_RETURN_ENVIRONMENT_HOOKS" ]; then
+ unset AMENT_ENVIRONMENT_HOOKS
+fi
+
+# restore AMENT_CURRENT_PREFIX before evaluating the environment hooks
+AMENT_CURRENT_PREFIX=$_package_local_setup_AMENT_CURRENT_PREFIX
+# list all environment hooks of this package
+
+# source all shell-specific environment hooks of this package
+# if not returning them
+if [ -z "$AMENT_RETURN_ENVIRONMENT_HOOKS" ]; then
+ _package_local_setup_IFS=$IFS
+ IFS=":"
+ for _hook in $AMENT_ENVIRONMENT_HOOKS; do
+ # restore AMENT_CURRENT_PREFIX for each environment hook
+ AMENT_CURRENT_PREFIX=$_package_local_setup_AMENT_CURRENT_PREFIX
+ # restore IFS before sourcing other files
+ IFS=$_package_local_setup_IFS
+ . "$_hook"
+ done
+ unset _hook
+ IFS=$_package_local_setup_IFS
+ unset _package_local_setup_IFS
+ unset AMENT_ENVIRONMENT_HOOKS
+fi
+
+unset _package_local_setup_AMENT_CURRENT_PREFIX
+unset AMENT_CURRENT_PREFIX
diff --git a/install/diagnostics/share/diagnostics/package.bash b/install/diagnostics/share/diagnostics/package.bash
new file mode 100644
index 0000000..519ff87
--- /dev/null
+++ b/install/diagnostics/share/diagnostics/package.bash
@@ -0,0 +1,39 @@
+# generated from colcon_bash/shell/template/package.bash.em
+
+# This script extends the environment for this package.
+
+# a bash script is able to determine its own path if necessary
+if [ -z "$COLCON_CURRENT_PREFIX" ]; then
+ # the prefix is two levels up from the package specific share directory
+ _colcon_package_bash_COLCON_CURRENT_PREFIX="$(builtin cd "`dirname "${BASH_SOURCE[0]}"`/../.." > /dev/null && pwd)"
+else
+ _colcon_package_bash_COLCON_CURRENT_PREFIX="$COLCON_CURRENT_PREFIX"
+fi
+
+# function to source another script with conditional trace output
+# first argument: the path of the script
+# additional arguments: arguments to the script
+_colcon_package_bash_source_script() {
+ if [ -f "$1" ]; then
+ if [ -n "$COLCON_TRACE" ]; then
+ echo "# . \"$1\""
+ fi
+ . "$@"
+ else
+ echo "not found: \"$1\"" 1>&2
+ fi
+}
+
+# source sh script of this package
+_colcon_package_bash_source_script "$_colcon_package_bash_COLCON_CURRENT_PREFIX/share/diagnostics/package.sh"
+
+# setting COLCON_CURRENT_PREFIX avoids determining the prefix in the sourced scripts
+COLCON_CURRENT_PREFIX="$_colcon_package_bash_COLCON_CURRENT_PREFIX"
+
+# source bash hooks
+_colcon_package_bash_source_script "$COLCON_CURRENT_PREFIX/share/diagnostics/local_setup.bash"
+
+unset COLCON_CURRENT_PREFIX
+
+unset _colcon_package_bash_source_script
+unset _colcon_package_bash_COLCON_CURRENT_PREFIX
diff --git a/install/diagnostics/share/diagnostics/package.dsv b/install/diagnostics/share/diagnostics/package.dsv
new file mode 100644
index 0000000..b4d7108
--- /dev/null
+++ b/install/diagnostics/share/diagnostics/package.dsv
@@ -0,0 +1,8 @@
+source;share/diagnostics/hook/cmake_prefix_path.ps1
+source;share/diagnostics/hook/cmake_prefix_path.dsv
+source;share/diagnostics/hook/cmake_prefix_path.sh
+source;share/diagnostics/local_setup.bash
+source;share/diagnostics/local_setup.dsv
+source;share/diagnostics/local_setup.ps1
+source;share/diagnostics/local_setup.sh
+source;share/diagnostics/local_setup.zsh
diff --git a/install/diagnostics/share/diagnostics/package.ps1 b/install/diagnostics/share/diagnostics/package.ps1
new file mode 100644
index 0000000..9b06198
--- /dev/null
+++ b/install/diagnostics/share/diagnostics/package.ps1
@@ -0,0 +1,116 @@
+# generated from colcon_powershell/shell/template/package.ps1.em
+
+# function to append a value to a variable
+# which uses colons as separators
+# duplicates as well as leading separators are avoided
+# first argument: the name of the result variable
+# second argument: the value to be prepended
+function colcon_append_unique_value {
+ param (
+ $_listname,
+ $_value
+ )
+
+ # get values from variable
+ if (Test-Path Env:$_listname) {
+ $_values=(Get-Item env:$_listname).Value
+ } else {
+ $_values=""
+ }
+ $_duplicate=""
+ # start with no values
+ $_all_values=""
+ # iterate over existing values in the variable
+ if ($_values) {
+ $_values.Split(";") | ForEach {
+ # not an empty string
+ if ($_) {
+ # not a duplicate of _value
+ if ($_ -eq $_value) {
+ $_duplicate="1"
+ }
+ if ($_all_values) {
+ $_all_values="${_all_values};$_"
+ } else {
+ $_all_values="$_"
+ }
+ }
+ }
+ }
+ # append only non-duplicates
+ if (!$_duplicate) {
+ # avoid leading separator
+ if ($_all_values) {
+ $_all_values="${_all_values};${_value}"
+ } else {
+ $_all_values="${_value}"
+ }
+ }
+
+ # export the updated variable
+ Set-Item env:\$_listname -Value "$_all_values"
+}
+
+# function to prepend a value to a variable
+# which uses colons as separators
+# duplicates as well as trailing separators are avoided
+# first argument: the name of the result variable
+# second argument: the value to be prepended
+function colcon_prepend_unique_value {
+ param (
+ $_listname,
+ $_value
+ )
+
+ # get values from variable
+ if (Test-Path Env:$_listname) {
+ $_values=(Get-Item env:$_listname).Value
+ } else {
+ $_values=""
+ }
+ # start with the new value
+ $_all_values="$_value"
+ # iterate over existing values in the variable
+ if ($_values) {
+ $_values.Split(";") | ForEach {
+ # not an empty string
+ if ($_) {
+ # not a duplicate of _value
+ if ($_ -ne $_value) {
+ # keep non-duplicate values
+ $_all_values="${_all_values};$_"
+ }
+ }
+ }
+ }
+ # export the updated variable
+ Set-Item env:\$_listname -Value "$_all_values"
+}
+
+# function to source another script with conditional trace output
+# first argument: the path of the script
+# additional arguments: arguments to the script
+function colcon_package_source_powershell_script {
+ param (
+ $_colcon_package_source_powershell_script
+ )
+ # source script with conditional trace output
+ if (Test-Path $_colcon_package_source_powershell_script) {
+ if ($env:COLCON_TRACE) {
+ echo ". '$_colcon_package_source_powershell_script'"
+ }
+ . "$_colcon_package_source_powershell_script"
+ } else {
+ Write-Error "not found: '$_colcon_package_source_powershell_script'"
+ }
+}
+
+
+# a powershell script is able to determine its own path
+# the prefix is two levels up from the package specific share directory
+$env:COLCON_CURRENT_PREFIX=(Get-Item $PSCommandPath).Directory.Parent.Parent.FullName
+
+colcon_package_source_powershell_script "$env:COLCON_CURRENT_PREFIX\share/diagnostics/hook/cmake_prefix_path.ps1"
+colcon_package_source_powershell_script "$env:COLCON_CURRENT_PREFIX\share/diagnostics/local_setup.ps1"
+
+Remove-Item Env:\COLCON_CURRENT_PREFIX
diff --git a/install/diagnostics/share/diagnostics/package.sh b/install/diagnostics/share/diagnostics/package.sh
new file mode 100644
index 0000000..3d4955b
--- /dev/null
+++ b/install/diagnostics/share/diagnostics/package.sh
@@ -0,0 +1,87 @@
+# generated from colcon_core/shell/template/package.sh.em
+
+# This script extends the environment for this package.
+
+# function to prepend a value to a variable
+# which uses colons as separators
+# duplicates as well as trailing separators are avoided
+# first argument: the name of the result variable
+# second argument: the value to be prepended
+_colcon_prepend_unique_value() {
+ # arguments
+ _listname="$1"
+ _value="$2"
+
+ # get values from variable
+ eval _values=\"\$$_listname\"
+ # backup the field separator
+ _colcon_prepend_unique_value_IFS=$IFS
+ IFS=":"
+ # start with the new value
+ _all_values="$_value"
+ # workaround SH_WORD_SPLIT not being set in zsh
+ if [ "$(command -v colcon_zsh_convert_to_array)" ]; then
+ colcon_zsh_convert_to_array _values
+ fi
+ # iterate over existing values in the variable
+ for _item in $_values; do
+ # ignore empty strings
+ if [ -z "$_item" ]; then
+ continue
+ fi
+ # ignore duplicates of _value
+ if [ "$_item" = "$_value" ]; then
+ continue
+ fi
+ # keep non-duplicate values
+ _all_values="$_all_values:$_item"
+ done
+ unset _item
+ # restore the field separator
+ IFS=$_colcon_prepend_unique_value_IFS
+ unset _colcon_prepend_unique_value_IFS
+ # export the updated variable
+ eval export $_listname=\"$_all_values\"
+ unset _all_values
+ unset _values
+
+ unset _value
+ unset _listname
+}
+
+# since a plain shell script can't determine its own path when being sourced
+# either use the provided COLCON_CURRENT_PREFIX
+# or fall back to the build time prefix (if it exists)
+_colcon_package_sh_COLCON_CURRENT_PREFIX="/workspaces/sailbot_workspace/src/diagnostics/install/diagnostics"
+if [ -z "$COLCON_CURRENT_PREFIX" ]; then
+ if [ ! -d "$_colcon_package_sh_COLCON_CURRENT_PREFIX" ]; then
+ echo "The build time path \"$_colcon_package_sh_COLCON_CURRENT_PREFIX\" doesn't exist. Either source a script for a different shell or set the environment variable \"COLCON_CURRENT_PREFIX\" explicitly." 1>&2
+ unset _colcon_package_sh_COLCON_CURRENT_PREFIX
+ return 1
+ fi
+ COLCON_CURRENT_PREFIX="$_colcon_package_sh_COLCON_CURRENT_PREFIX"
+fi
+unset _colcon_package_sh_COLCON_CURRENT_PREFIX
+
+# function to source another script with conditional trace output
+# first argument: the path of the script
+# additional arguments: arguments to the script
+_colcon_package_sh_source_script() {
+ if [ -f "$1" ]; then
+ if [ -n "$COLCON_TRACE" ]; then
+ echo "# . \"$1\""
+ fi
+ . "$@"
+ else
+ echo "not found: \"$1\"" 1>&2
+ fi
+}
+
+# source sh hooks
+_colcon_package_sh_source_script "$COLCON_CURRENT_PREFIX/share/diagnostics/hook/cmake_prefix_path.sh"
+_colcon_package_sh_source_script "$COLCON_CURRENT_PREFIX/share/diagnostics/local_setup.sh"
+
+unset _colcon_package_sh_source_script
+unset COLCON_CURRENT_PREFIX
+
+# do not unset _colcon_prepend_unique_value since it might be used by non-primary shell hooks
diff --git a/install/diagnostics/share/diagnostics/package.xml b/install/diagnostics/share/diagnostics/package.xml
new file mode 100644
index 0000000..a561f12
--- /dev/null
+++ b/install/diagnostics/share/diagnostics/package.xml
@@ -0,0 +1,18 @@
+
+
+
+ diagnostics
+ 0.0.0
+ TODO: Package description
+ ros
+ TODO: License declaration
+
+ ament_cmake
+
+ ament_lint_auto
+ ament_lint_common
+
+
+ ament_cmake
+
+
diff --git a/install/diagnostics/share/diagnostics/package.zsh b/install/diagnostics/share/diagnostics/package.zsh
new file mode 100644
index 0000000..cf529f7
--- /dev/null
+++ b/install/diagnostics/share/diagnostics/package.zsh
@@ -0,0 +1,50 @@
+# generated from colcon_zsh/shell/template/package.zsh.em
+
+# This script extends the environment for this package.
+
+# a zsh script is able to determine its own path if necessary
+if [ -z "$COLCON_CURRENT_PREFIX" ]; then
+ # the prefix is two levels up from the package specific share directory
+ _colcon_package_zsh_COLCON_CURRENT_PREFIX="$(builtin cd -q "`dirname "${(%):-%N}"`/../.." > /dev/null && pwd)"
+else
+ _colcon_package_zsh_COLCON_CURRENT_PREFIX="$COLCON_CURRENT_PREFIX"
+fi
+
+# function to source another script with conditional trace output
+# first argument: the path of the script
+# additional arguments: arguments to the script
+_colcon_package_zsh_source_script() {
+ if [ -f "$1" ]; then
+ if [ -n "$COLCON_TRACE" ]; then
+ echo "# . \"$1\""
+ fi
+ . "$@"
+ else
+ echo "not found: \"$1\"" 1>&2
+ fi
+}
+
+# function to convert array-like strings into arrays
+# to workaround SH_WORD_SPLIT not being set
+colcon_zsh_convert_to_array() {
+ local _listname=$1
+ local _dollar="$"
+ local _split="{="
+ local _to_array="(\"$_dollar$_split$_listname}\")"
+ eval $_listname=$_to_array
+}
+
+# source sh script of this package
+_colcon_package_zsh_source_script "$_colcon_package_zsh_COLCON_CURRENT_PREFIX/share/diagnostics/package.sh"
+unset convert_zsh_to_array
+
+# setting COLCON_CURRENT_PREFIX avoids determining the prefix in the sourced scripts
+COLCON_CURRENT_PREFIX="$_colcon_package_zsh_COLCON_CURRENT_PREFIX"
+
+# source zsh hooks
+_colcon_package_zsh_source_script "$COLCON_CURRENT_PREFIX/share/diagnostics/local_setup.zsh"
+
+unset COLCON_CURRENT_PREFIX
+
+unset _colcon_package_zsh_source_script
+unset _colcon_package_zsh_COLCON_CURRENT_PREFIX
diff --git a/install/local_setup.bash b/install/local_setup.bash
new file mode 100644
index 0000000..03f0025
--- /dev/null
+++ b/install/local_setup.bash
@@ -0,0 +1,121 @@
+# generated from colcon_bash/shell/template/prefix.bash.em
+
+# This script extends the environment with all packages contained in this
+# prefix path.
+
+# a bash script is able to determine its own path if necessary
+if [ -z "$COLCON_CURRENT_PREFIX" ]; then
+ _colcon_prefix_bash_COLCON_CURRENT_PREFIX="$(builtin cd "`dirname "${BASH_SOURCE[0]}"`" > /dev/null && pwd)"
+else
+ _colcon_prefix_bash_COLCON_CURRENT_PREFIX="$COLCON_CURRENT_PREFIX"
+fi
+
+# function to prepend a value to a variable
+# which uses colons as separators
+# duplicates as well as trailing separators are avoided
+# first argument: the name of the result variable
+# second argument: the value to be prepended
+_colcon_prefix_bash_prepend_unique_value() {
+ # arguments
+ _listname="$1"
+ _value="$2"
+
+ # get values from variable
+ eval _values=\"\$$_listname\"
+ # backup the field separator
+ _colcon_prefix_bash_prepend_unique_value_IFS="$IFS"
+ IFS=":"
+ # start with the new value
+ _all_values="$_value"
+ _contained_value=""
+ # iterate over existing values in the variable
+ for _item in $_values; do
+ # ignore empty strings
+ if [ -z "$_item" ]; then
+ continue
+ fi
+ # ignore duplicates of _value
+ if [ "$_item" = "$_value" ]; then
+ _contained_value=1
+ continue
+ fi
+ # keep non-duplicate values
+ _all_values="$_all_values:$_item"
+ done
+ unset _item
+ if [ -z "$_contained_value" ]; then
+ if [ -n "$COLCON_TRACE" ]; then
+ if [ "$_all_values" = "$_value" ]; then
+ echo "export $_listname=$_value"
+ else
+ echo "export $_listname=$_value:\$$_listname"
+ fi
+ fi
+ fi
+ unset _contained_value
+ # restore the field separator
+ IFS="$_colcon_prefix_bash_prepend_unique_value_IFS"
+ unset _colcon_prefix_bash_prepend_unique_value_IFS
+ # export the updated variable
+ eval export $_listname=\"$_all_values\"
+ unset _all_values
+ unset _values
+
+ unset _value
+ unset _listname
+}
+
+# add this prefix to the COLCON_PREFIX_PATH
+_colcon_prefix_bash_prepend_unique_value COLCON_PREFIX_PATH "$_colcon_prefix_bash_COLCON_CURRENT_PREFIX"
+unset _colcon_prefix_bash_prepend_unique_value
+
+# check environment variable for custom Python executable
+if [ -n "$COLCON_PYTHON_EXECUTABLE" ]; then
+ if [ ! -f "$COLCON_PYTHON_EXECUTABLE" ]; then
+ echo "error: COLCON_PYTHON_EXECUTABLE '$COLCON_PYTHON_EXECUTABLE' doesn't exist"
+ return 1
+ fi
+ _colcon_python_executable="$COLCON_PYTHON_EXECUTABLE"
+else
+ # try the Python executable known at configure time
+ _colcon_python_executable="/usr/bin/python3"
+ # if it doesn't exist try a fall back
+ if [ ! -f "$_colcon_python_executable" ]; then
+ if ! /usr/bin/env python3 --version > /dev/null 2> /dev/null; then
+ echo "error: unable to find python3 executable"
+ return 1
+ fi
+ _colcon_python_executable=`/usr/bin/env python3 -c "import sys; print(sys.executable)"`
+ fi
+fi
+
+# function to source another script with conditional trace output
+# first argument: the path of the script
+_colcon_prefix_sh_source_script() {
+ if [ -f "$1" ]; then
+ if [ -n "$COLCON_TRACE" ]; then
+ echo "# . \"$1\""
+ fi
+ . "$1"
+ else
+ echo "not found: \"$1\"" 1>&2
+ fi
+}
+
+# get all commands in topological order
+_colcon_ordered_commands="$($_colcon_python_executable "$_colcon_prefix_bash_COLCON_CURRENT_PREFIX/_local_setup_util_sh.py" sh bash)"
+unset _colcon_python_executable
+if [ -n "$COLCON_TRACE" ]; then
+ echo "$(declare -f _colcon_prefix_sh_source_script)"
+ echo "# Execute generated script:"
+ echo "# <<<"
+ echo "${_colcon_ordered_commands}"
+ echo "# >>>"
+ echo "unset _colcon_prefix_sh_source_script"
+fi
+eval "${_colcon_ordered_commands}"
+unset _colcon_ordered_commands
+
+unset _colcon_prefix_sh_source_script
+
+unset _colcon_prefix_bash_COLCON_CURRENT_PREFIX
diff --git a/install/local_setup.ps1 b/install/local_setup.ps1
new file mode 100644
index 0000000..6f68c8d
--- /dev/null
+++ b/install/local_setup.ps1
@@ -0,0 +1,55 @@
+# generated from colcon_powershell/shell/template/prefix.ps1.em
+
+# This script extends the environment with all packages contained in this
+# prefix path.
+
+# check environment variable for custom Python executable
+if ($env:COLCON_PYTHON_EXECUTABLE) {
+ if (!(Test-Path "$env:COLCON_PYTHON_EXECUTABLE" -PathType Leaf)) {
+ echo "error: COLCON_PYTHON_EXECUTABLE '$env:COLCON_PYTHON_EXECUTABLE' doesn't exist"
+ exit 1
+ }
+ $_colcon_python_executable="$env:COLCON_PYTHON_EXECUTABLE"
+} else {
+ # use the Python executable known at configure time
+ $_colcon_python_executable="/usr/bin/python3"
+ # if it doesn't exist try a fall back
+ if (!(Test-Path "$_colcon_python_executable" -PathType Leaf)) {
+ if (!(Get-Command "python3" -ErrorAction SilentlyContinue)) {
+ echo "error: unable to find python3 executable"
+ exit 1
+ }
+ $_colcon_python_executable="python3"
+ }
+}
+
+# function to source another script with conditional trace output
+# first argument: the path of the script
+function _colcon_prefix_powershell_source_script {
+ param (
+ $_colcon_prefix_powershell_source_script_param
+ )
+ # source script with conditional trace output
+ if (Test-Path $_colcon_prefix_powershell_source_script_param) {
+ if ($env:COLCON_TRACE) {
+ echo ". '$_colcon_prefix_powershell_source_script_param'"
+ }
+ . "$_colcon_prefix_powershell_source_script_param"
+ } else {
+ Write-Error "not found: '$_colcon_prefix_powershell_source_script_param'"
+ }
+}
+
+# get all commands in topological order
+$_colcon_ordered_commands = & "$_colcon_python_executable" "$(Split-Path $PSCommandPath -Parent)/_local_setup_util_ps1.py" ps1
+
+# execute all commands in topological order
+if ($env:COLCON_TRACE) {
+ echo "Execute generated script:"
+ echo "<<<"
+ $_colcon_ordered_commands.Split([Environment]::NewLine, [StringSplitOptions]::RemoveEmptyEntries) | Write-Output
+ echo ">>>"
+}
+if ($_colcon_ordered_commands) {
+ $_colcon_ordered_commands.Split([Environment]::NewLine, [StringSplitOptions]::RemoveEmptyEntries) | Invoke-Expression
+}
diff --git a/install/local_setup.sh b/install/local_setup.sh
new file mode 100644
index 0000000..31a72bf
--- /dev/null
+++ b/install/local_setup.sh
@@ -0,0 +1,137 @@
+# generated from colcon_core/shell/template/prefix.sh.em
+
+# This script extends the environment with all packages contained in this
+# prefix path.
+
+# since a plain shell script can't determine its own path when being sourced
+# either use the provided COLCON_CURRENT_PREFIX
+# or fall back to the build time prefix (if it exists)
+_colcon_prefix_sh_COLCON_CURRENT_PREFIX="/workspaces/sailbot_workspace/src/diagnostics/install"
+if [ -z "$COLCON_CURRENT_PREFIX" ]; then
+ if [ ! -d "$_colcon_prefix_sh_COLCON_CURRENT_PREFIX" ]; then
+ echo "The build time path \"$_colcon_prefix_sh_COLCON_CURRENT_PREFIX\" doesn't exist. Either source a script for a different shell or set the environment variable \"COLCON_CURRENT_PREFIX\" explicitly." 1>&2
+ unset _colcon_prefix_sh_COLCON_CURRENT_PREFIX
+ return 1
+ fi
+else
+ _colcon_prefix_sh_COLCON_CURRENT_PREFIX="$COLCON_CURRENT_PREFIX"
+fi
+
+# function to prepend a value to a variable
+# which uses colons as separators
+# duplicates as well as trailing separators are avoided
+# first argument: the name of the result variable
+# second argument: the value to be prepended
+_colcon_prefix_sh_prepend_unique_value() {
+ # arguments
+ _listname="$1"
+ _value="$2"
+
+ # get values from variable
+ eval _values=\"\$$_listname\"
+ # backup the field separator
+ _colcon_prefix_sh_prepend_unique_value_IFS="$IFS"
+ IFS=":"
+ # start with the new value
+ _all_values="$_value"
+ _contained_value=""
+ # iterate over existing values in the variable
+ for _item in $_values; do
+ # ignore empty strings
+ if [ -z "$_item" ]; then
+ continue
+ fi
+ # ignore duplicates of _value
+ if [ "$_item" = "$_value" ]; then
+ _contained_value=1
+ continue
+ fi
+ # keep non-duplicate values
+ _all_values="$_all_values:$_item"
+ done
+ unset _item
+ if [ -z "$_contained_value" ]; then
+ if [ -n "$COLCON_TRACE" ]; then
+ if [ "$_all_values" = "$_value" ]; then
+ echo "export $_listname=$_value"
+ else
+ echo "export $_listname=$_value:\$$_listname"
+ fi
+ fi
+ fi
+ unset _contained_value
+ # restore the field separator
+ IFS="$_colcon_prefix_sh_prepend_unique_value_IFS"
+ unset _colcon_prefix_sh_prepend_unique_value_IFS
+ # export the updated variable
+ eval export $_listname=\"$_all_values\"
+ unset _all_values
+ unset _values
+
+ unset _value
+ unset _listname
+}
+
+# add this prefix to the COLCON_PREFIX_PATH
+_colcon_prefix_sh_prepend_unique_value COLCON_PREFIX_PATH "$_colcon_prefix_sh_COLCON_CURRENT_PREFIX"
+unset _colcon_prefix_sh_prepend_unique_value
+
+# check environment variable for custom Python executable
+if [ -n "$COLCON_PYTHON_EXECUTABLE" ]; then
+ if [ ! -f "$COLCON_PYTHON_EXECUTABLE" ]; then
+ echo "error: COLCON_PYTHON_EXECUTABLE '$COLCON_PYTHON_EXECUTABLE' doesn't exist"
+ return 1
+ fi
+ _colcon_python_executable="$COLCON_PYTHON_EXECUTABLE"
+else
+ # try the Python executable known at configure time
+ _colcon_python_executable="/usr/bin/python3"
+ # if it doesn't exist try a fall back
+ if [ ! -f "$_colcon_python_executable" ]; then
+ if ! /usr/bin/env python3 --version > /dev/null 2> /dev/null; then
+ echo "error: unable to find python3 executable"
+ return 1
+ fi
+ _colcon_python_executable=`/usr/bin/env python3 -c "import sys; print(sys.executable)"`
+ fi
+fi
+
+# function to source another script with conditional trace output
+# first argument: the path of the script
+_colcon_prefix_sh_source_script() {
+ if [ -f "$1" ]; then
+ if [ -n "$COLCON_TRACE" ]; then
+ echo "# . \"$1\""
+ fi
+ . "$1"
+ else
+ echo "not found: \"$1\"" 1>&2
+ fi
+}
+
+# get all commands in topological order
+_colcon_ordered_commands="$($_colcon_python_executable "$_colcon_prefix_sh_COLCON_CURRENT_PREFIX/_local_setup_util_sh.py" sh)"
+unset _colcon_python_executable
+if [ -n "$COLCON_TRACE" ]; then
+ echo "_colcon_prefix_sh_source_script() {
+ if [ -f \"\$1\" ]; then
+ if [ -n \"\$COLCON_TRACE\" ]; then
+ echo \"# . \\\"\$1\\\"\"
+ fi
+ . \"\$1\"
+ else
+ echo \"not found: \\\"\$1\\\"\" 1>&2
+ fi
+ }"
+ echo "# Execute generated script:"
+ echo "# <<<"
+ echo "${_colcon_ordered_commands}"
+ echo "# >>>"
+ echo "unset _colcon_prefix_sh_source_script"
+fi
+eval "${_colcon_ordered_commands}"
+unset _colcon_ordered_commands
+
+unset _colcon_prefix_sh_source_script
+
+unset _colcon_prefix_sh_COLCON_CURRENT_PREFIX
diff --git a/install/local_setup.zsh b/install/local_setup.zsh
new file mode 100644
index 0000000..b648710
--- /dev/null
+++ b/install/local_setup.zsh
@@ -0,0 +1,134 @@
+# generated from colcon_zsh/shell/template/prefix.zsh.em
+
+# This script extends the environment with all packages contained in this
+# prefix path.
+
+# a zsh script is able to determine its own path if necessary
+if [ -z "$COLCON_CURRENT_PREFIX" ]; then
+ _colcon_prefix_zsh_COLCON_CURRENT_PREFIX="$(builtin cd -q "`dirname "${(%):-%N}"`" > /dev/null && pwd)"
+else
+ _colcon_prefix_zsh_COLCON_CURRENT_PREFIX="$COLCON_CURRENT_PREFIX"
+fi
+
+# function to convert array-like strings into arrays
+# to workaround SH_WORD_SPLIT not being set
+_colcon_prefix_zsh_convert_to_array() {
+ local _listname=$1
+ local _dollar="$"
+ local _split="{="
+ local _to_array="(\"$_dollar$_split$_listname}\")"
+ eval $_listname=$_to_array
+}
+
+# function to prepend a value to a variable
+# which uses colons as separators
+# duplicates as well as trailing separators are avoided
+# first argument: the name of the result variable
+# second argument: the value to be prepended
+_colcon_prefix_zsh_prepend_unique_value() {
+ # arguments
+ _listname="$1"
+ _value="$2"
+
+ # get values from variable
+ eval _values=\"\$$_listname\"
+ # backup the field separator
+ _colcon_prefix_zsh_prepend_unique_value_IFS="$IFS"
+ IFS=":"
+ # start with the new value
+ _all_values="$_value"
+ _contained_value=""
+ # workaround SH_WORD_SPLIT not being set
+ _colcon_prefix_zsh_convert_to_array _values
+ # iterate over existing values in the variable
+ for _item in $_values; do
+ # ignore empty strings
+ if [ -z "$_item" ]; then
+ continue
+ fi
+ # ignore duplicates of _value
+ if [ "$_item" = "$_value" ]; then
+ _contained_value=1
+ continue
+ fi
+ # keep non-duplicate values
+ _all_values="$_all_values:$_item"
+ done
+ unset _item
+ if [ -z "$_contained_value" ]; then
+ if [ -n "$COLCON_TRACE" ]; then
+ if [ "$_all_values" = "$_value" ]; then
+ echo "export $_listname=$_value"
+ else
+ echo "export $_listname=$_value:\$$_listname"
+ fi
+ fi
+ fi
+ unset _contained_value
+ # restore the field separator
+ IFS="$_colcon_prefix_zsh_prepend_unique_value_IFS"
+ unset _colcon_prefix_zsh_prepend_unique_value_IFS
+ # export the updated variable
+ eval export $_listname=\"$_all_values\"
+ unset _all_values
+ unset _values
+
+ unset _value
+ unset _listname
+}
+
+# add this prefix to the COLCON_PREFIX_PATH
+_colcon_prefix_zsh_prepend_unique_value COLCON_PREFIX_PATH "$_colcon_prefix_zsh_COLCON_CURRENT_PREFIX"
+unset _colcon_prefix_zsh_prepend_unique_value
+unset _colcon_prefix_zsh_convert_to_array
+
+# check environment variable for custom Python executable
+if [ -n "$COLCON_PYTHON_EXECUTABLE" ]; then
+ if [ ! -f "$COLCON_PYTHON_EXECUTABLE" ]; then
+ echo "error: COLCON_PYTHON_EXECUTABLE '$COLCON_PYTHON_EXECUTABLE' doesn't exist"
+ return 1
+ fi
+ _colcon_python_executable="$COLCON_PYTHON_EXECUTABLE"
+else
+ # try the Python executable known at configure time
+ _colcon_python_executable="/usr/bin/python3"
+ # if it doesn't exist try a fall back
+ if [ ! -f "$_colcon_python_executable" ]; then
+ if ! /usr/bin/env python3 --version > /dev/null 2> /dev/null; then
+ echo "error: unable to find python3 executable"
+ return 1
+ fi
+ _colcon_python_executable=`/usr/bin/env python3 -c "import sys; print(sys.executable)"`
+ fi
+fi
+
+# function to source another script with conditional trace output
+# first argument: the path of the script
+_colcon_prefix_sh_source_script() {
+ if [ -f "$1" ]; then
+ if [ -n "$COLCON_TRACE" ]; then
+ echo "# . \"$1\""
+ fi
+ . "$1"
+ else
+ echo "not found: \"$1\"" 1>&2
+ fi
+}
+
+# get all commands in topological order
+_colcon_ordered_commands="$($_colcon_python_executable "$_colcon_prefix_zsh_COLCON_CURRENT_PREFIX/_local_setup_util_sh.py" sh zsh)"
+unset _colcon_python_executable
+if [ -n "$COLCON_TRACE" ]; then
+ echo "$(declare -f _colcon_prefix_sh_source_script)"
+ echo "# Execute generated script:"
+ echo "# <<<"
+ echo "${_colcon_ordered_commands}"
+ echo "# >>>"
+ echo "unset _colcon_prefix_sh_source_script"
+fi
+eval "${_colcon_ordered_commands}"
+unset _colcon_ordered_commands
+
+unset _colcon_prefix_sh_source_script
+
+unset _colcon_prefix_zsh_COLCON_CURRENT_PREFIX
diff --git a/install/setup.bash b/install/setup.bash
new file mode 100644
index 0000000..88dcc3a
--- /dev/null
+++ b/install/setup.bash
@@ -0,0 +1,34 @@
+# generated from colcon_bash/shell/template/prefix_chain.bash.em
+
+# This script extends the environment with the environment of other prefix
+# paths which were sourced when this file was generated as well as all packages
+# contained in this prefix path.
+
+# function to source another script with conditional trace output
+# first argument: the path of the script
+_colcon_prefix_chain_bash_source_script() {
+ if [ -f "$1" ]; then
+ if [ -n "$COLCON_TRACE" ]; then
+ echo "# . \"$1\""
+ fi
+ . "$1"
+ else
+ echo "not found: \"$1\"" 1>&2
+ fi
+}
+
+# source chained prefixes
+# setting COLCON_CURRENT_PREFIX avoids determining the prefix in the sourced script
+COLCON_CURRENT_PREFIX="/opt/ros/humble"
+_colcon_prefix_chain_bash_source_script "$COLCON_CURRENT_PREFIX/local_setup.bash"
+# setting COLCON_CURRENT_PREFIX avoids determining the prefix in the sourced script
+COLCON_CURRENT_PREFIX="/workspaces/sailbot_workspace/install"
+_colcon_prefix_chain_bash_source_script "$COLCON_CURRENT_PREFIX/local_setup.bash"
+
+# source this prefix
+# setting COLCON_CURRENT_PREFIX avoids determining the prefix in the sourced script
+COLCON_CURRENT_PREFIX="$(builtin cd "`dirname "${BASH_SOURCE[0]}"`" > /dev/null && pwd)"
+_colcon_prefix_chain_bash_source_script "$COLCON_CURRENT_PREFIX/local_setup.bash"
+
+unset COLCON_CURRENT_PREFIX
+unset _colcon_prefix_chain_bash_source_script
diff --git a/install/setup.ps1 b/install/setup.ps1
new file mode 100644
index 0000000..da0b9b3
--- /dev/null
+++ b/install/setup.ps1
@@ -0,0 +1,30 @@
+# generated from colcon_powershell/shell/template/prefix_chain.ps1.em
+
+# This script extends the environment with the environment of other prefix
+# paths which were sourced when this file was generated as well as all packages
+# contained in this prefix path.
+
+# function to source another script with conditional trace output
+# first argument: the path of the script
+function _colcon_prefix_chain_powershell_source_script {
+ param (
+ $_colcon_prefix_chain_powershell_source_script_param
+ )
+ # source script with conditional trace output
+ if (Test-Path $_colcon_prefix_chain_powershell_source_script_param) {
+ if ($env:COLCON_TRACE) {
+ echo ". '$_colcon_prefix_chain_powershell_source_script_param'"
+ }
+ . "$_colcon_prefix_chain_powershell_source_script_param"
+ } else {
+ Write-Error "not found: '$_colcon_prefix_chain_powershell_source_script_param'"
+ }
+}
+
+# source chained prefixes
+_colcon_prefix_chain_powershell_source_script "/opt/ros/humble\local_setup.ps1"
+_colcon_prefix_chain_powershell_source_script "/workspaces/sailbot_workspace/install\local_setup.ps1"
+
+# source this prefix
+$env:COLCON_CURRENT_PREFIX=(Split-Path $PSCommandPath -Parent)
+_colcon_prefix_chain_powershell_source_script "$env:COLCON_CURRENT_PREFIX\local_setup.ps1"
diff --git a/install/setup.sh b/install/setup.sh
new file mode 100644
index 0000000..91cd648
--- /dev/null
+++ b/install/setup.sh
@@ -0,0 +1,49 @@
+# generated from colcon_core/shell/template/prefix_chain.sh.em
+
+# This script extends the environment with the environment of other prefix
+# paths which were sourced when this file was generated as well as all packages
+# contained in this prefix path.
+
+# since a plain shell script can't determine its own path when being sourced
+# either use the provided COLCON_CURRENT_PREFIX
+# or fall back to the build time prefix (if it exists)
+_colcon_prefix_chain_sh_COLCON_CURRENT_PREFIX=/workspaces/sailbot_workspace/src/diagnostics/install
+if [ ! -z "$COLCON_CURRENT_PREFIX" ]; then
+ _colcon_prefix_chain_sh_COLCON_CURRENT_PREFIX="$COLCON_CURRENT_PREFIX"
+elif [ ! -d "$_colcon_prefix_chain_sh_COLCON_CURRENT_PREFIX" ]; then
+ echo "The build time path \"$_colcon_prefix_chain_sh_COLCON_CURRENT_PREFIX\" doesn't exist. Either source a script for a different shell or set the environment variable \"COLCON_CURRENT_PREFIX\" explicitly." 1>&2
+ unset _colcon_prefix_chain_sh_COLCON_CURRENT_PREFIX
+ return 1
+fi
+
+# function to source another script with conditional trace output
+# first argument: the path of the script
+_colcon_prefix_chain_sh_source_script() {
+ if [ -f "$1" ]; then
+ if [ -n "$COLCON_TRACE" ]; then
+ echo "# . \"$1\""
+ fi
+ . "$1"
+ else
+ echo "not found: \"$1\"" 1>&2
+ fi
+}
+
+# source chained prefixes
+# setting COLCON_CURRENT_PREFIX avoids relying on the build time prefix of the sourced script
+COLCON_CURRENT_PREFIX="/opt/ros/humble"
+_colcon_prefix_chain_sh_source_script "$COLCON_CURRENT_PREFIX/local_setup.sh"
+
+# setting COLCON_CURRENT_PREFIX avoids relying on the build time prefix of the sourced script
+COLCON_CURRENT_PREFIX="/workspaces/sailbot_workspace/install"
+_colcon_prefix_chain_sh_source_script "$COLCON_CURRENT_PREFIX/local_setup.sh"
+
+
+# source this prefix
+# setting COLCON_CURRENT_PREFIX avoids relying on the build time prefix of the sourced script
+COLCON_CURRENT_PREFIX="$_colcon_prefix_chain_sh_COLCON_CURRENT_PREFIX"
+_colcon_prefix_chain_sh_source_script "$COLCON_CURRENT_PREFIX/local_setup.sh"
+
+unset _colcon_prefix_chain_sh_COLCON_CURRENT_PREFIX
+unset _colcon_prefix_chain_sh_source_script
+unset COLCON_CURRENT_PREFIX
diff --git a/install/setup.zsh b/install/setup.zsh
new file mode 100644
index 0000000..9bddb0d
--- /dev/null
+++ b/install/setup.zsh
@@ -0,0 +1,34 @@
+# generated from colcon_zsh/shell/template/prefix_chain.zsh.em
+
+# This script extends the environment with the environment of other prefix
+# paths which were sourced when this file was generated as well as all packages
+# contained in this prefix path.
+
+# function to source another script with conditional trace output
+# first argument: the path of the script
+_colcon_prefix_chain_zsh_source_script() {
+ if [ -f "$1" ]; then
+ if [ -n "$COLCON_TRACE" ]; then
+ echo "# . \"$1\""
+ fi
+ . "$1"
+ else
+ echo "not found: \"$1\"" 1>&2
+ fi
+}
+
+# source chained prefixes
+# setting COLCON_CURRENT_PREFIX avoids determining the prefix in the sourced script
+COLCON_CURRENT_PREFIX="/opt/ros/humble"
+_colcon_prefix_chain_zsh_source_script "$COLCON_CURRENT_PREFIX/local_setup.zsh"
+# setting COLCON_CURRENT_PREFIX avoids determining the prefix in the sourced script
+COLCON_CURRENT_PREFIX="/workspaces/sailbot_workspace/install"
+_colcon_prefix_chain_zsh_source_script "$COLCON_CURRENT_PREFIX/local_setup.zsh"
+
+# source this prefix
+# setting COLCON_CURRENT_PREFIX avoids determining the prefix in the sourced script
+COLCON_CURRENT_PREFIX="$(builtin cd -q "`dirname "${(%):-%N}"`" > /dev/null && pwd)"
+_colcon_prefix_chain_zsh_source_script "$COLCON_CURRENT_PREFIX/local_setup.zsh"
+
+unset COLCON_CURRENT_PREFIX
+unset _colcon_prefix_chain_zsh_source_script
diff --git a/src/boatTest/CMakeLists.txt b/src/boatTest/CMakeLists.txt
index e4717b2..f6f423b 100644
--- a/src/boatTest/CMakeLists.txt
+++ b/src/boatTest/CMakeLists.txt
@@ -1 +1,3 @@
add_subdirectory(common)
+add_subdirectory(config)
+add_subdirectory(parse_yaml)
diff --git a/src/boatTest/common/boatTest_common.cpp b/src/boatTest/common/boatTest_common.cpp
index 699e36a..b384696 100644
--- a/src/boatTest/common/boatTest_common.cpp
+++ b/src/boatTest/common/boatTest_common.cpp
@@ -1,13 +1,15 @@
#include "boatTest_common.h"
BoatTest::BoatTest() { name = "NONESPECIFIED"; }
-BoatTest::BoatTest(std::string id, std::vector topics, std::vector messages)
+BoatTest::BoatTest(std::string id, testType test_type, int timeout, std::vector test_data)
{
- name = id;
- ROS_topics = topics;
- ROS_messages = messages;
+ name = id;
+ type = test_type;
+ timeout_sec = timeout;
+ data = test_data;
}
-std::string BoatTest::getName() { return name; }
-std::vector BoatTest::getROSTopics() { return ROS_topics; }
-std::vector BoatTest::getROSMessages() { return ROS_messages; }
+std::string BoatTest::getName(BoatTest * test) { return test->name; }
+testType BoatTest::getTestType(BoatTest * test) { return test->type; }
+std::vector BoatTest::getTestData(BoatTest * test) { return test->data; }
+int BoatTest::getTimeout(BoatTest * test) { return test->timeout_sec; }
diff --git a/src/boatTest/common/boatTest_common.h b/src/boatTest/common/boatTest_common.h
index 3c79e12..25ad5cf 100644
--- a/src/boatTest/common/boatTest_common.h
+++ b/src/boatTest/common/boatTest_common.h
@@ -6,18 +6,26 @@
#include
/* Objects */
+typedef enum {
+ ROS,
+ CAN,
+ NONE,
+} testType;
+
class BoatTest
{
std::string name;
- std::vector ROS_topics;
- std::vector ROS_messages;
+ testType type;
+ int timeout_sec;
+ std::vector data;
public:
BoatTest();
- BoatTest(std::string name, std::vector ROS_topics, std::vector ROS_messages);
- std::string getName();
- std::vector getROSTopics();
- std::vector getROSMessages();
+ BoatTest(std::string id, testType test_type, int timeout, std::vector test_data);
+ std::string getName(BoatTest * test);
+ testType getTestType(BoatTest * test);
+ std::vector getTestData(BoatTest * test);
+ int getTimeout(BoatTest * test);
};
#endif
diff --git a/src/boatTest/config/CMakeLists.txt b/src/boatTest/config/CMakeLists.txt
new file mode 100644
index 0000000..298a836
--- /dev/null
+++ b/src/boatTest/config/CMakeLists.txt
@@ -0,0 +1,3 @@
+set(
+ YAML_TEST_PATH_1 ${CMAKE_CURRENT_LIST_DIR}/tests.yaml CACHE INTERNAL "Path to test yaml config file"
+)
diff --git a/src/boatTest/config/tests.yaml b/src/boatTest/config/tests.yaml
new file mode 100644
index 0000000..0fc6a77
--- /dev/null
+++ b/src/boatTest/config/tests.yaml
@@ -0,0 +1,19 @@
+inputs:
+ - type: ROS
+ name: rosTestOne
+ timeout_sec: 5
+ data:
+ dtype: uint64
+ val: 6
+ - type: ROS
+ name: rosTestTwo
+ timeout_sec: 5
+ data:
+ dtype: uint64
+ val: 7
+ - type: CAN
+ name: canTestOne
+ timeout_sec: 5
+ data:
+ dtype: float
+ val: 8.5
diff --git a/src/boatTest/parse_yaml/CMakeLists.txt b/src/boatTest/parse_yaml/CMakeLists.txt
new file mode 100644
index 0000000..dbaebc1
--- /dev/null
+++ b/src/boatTest/parse_yaml/CMakeLists.txt
@@ -0,0 +1,9 @@
+add_library(parseYaml parse_yaml.cpp parse_yaml.h)
+target_include_directories(parseYaml PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
+
+target_link_libraries(parseYaml PRIVATE boatTest_Common)
+target_link_libraries(parseYaml PRIVATE ryml::ryml)
+
+target_compile_definitions(
+ parseYaml PUBLIC YAML_TEST_PATH_1="${YAML_TEST_PATH_1}"
+)
diff --git a/src/boatTest/parse_yaml/parse_yaml.cpp b/src/boatTest/parse_yaml/parse_yaml.cpp
new file mode 100644
index 0000000..9356b27
--- /dev/null
+++ b/src/boatTest/parse_yaml/parse_yaml.cpp
@@ -0,0 +1,54 @@
+#include "parse_yaml.h"
+
+std::string readFile(const char * file_path)
+{
+ std::ifstream in_file(file_path, std::ios::in | std::ios::binary);
+
+ if (!in_file) {
+ std::cerr << "Could not open file: " << file_path << std::endl;
+ throw std::ifstream::failure("ERROR: ifstream could not open file");
+ }
+
+ std::stringstream file_buffer;
+ file_buffer << in_file.rdbuf();
+
+ return file_buffer.str();
+}
+
+testType getTestTypeFromStr(std::string test_type_str)
+{
+ if (test_type_str == "ROS") {
+ return ROS;
+ } else if (test_type_str == "CAN") {
+ return CAN;
+ } else {
+ return NONE;
+ }
+}
+
+std::vector YamlParser::parseYaml(const char * yaml_file_path)
+{
+ std::vector tests;
+ std::string yaml_contents = readFile(yaml_file_path);
+
+ ryml::Tree tree = ryml::parse_in_place(ryml::to_substr(yaml_contents));
+ ryml::NodeRef test_array = tree["inputs"];
+
+ for (ryml::NodeRef const & test : test_array.children()) {
+ std::string test_type_str;
+ std::string test_name;
+ testType test_type;
+ int test_timeout;
+ std::vector test_data;
+
+ test["type"] >> test_type_str;
+ test_type = getTestTypeFromStr(test_type_str);
+ test["name"] >> test_name;
+ test["timeout_sec"] >> test_timeout;
+ // TODO(unknown): add parsing for test data
+
+ BoatTest * new_test = new BoatTest(test_name, test_type, test_timeout, test_data);
+ tests.push_back(new_test);
+ }
+ return tests;
+}
diff --git a/src/boatTest/parse_yaml/parse_yaml.h b/src/boatTest/parse_yaml/parse_yaml.h
new file mode 100644
index 0000000..dbda65d
--- /dev/null
+++ b/src/boatTest/parse_yaml/parse_yaml.h
@@ -0,0 +1,21 @@
+#ifndef PARSE_YAML_H_
+#define PARSE_YAML_H_
+
+/* Include Files */
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "boatTest_common.h"
+
+/* Yaml File Parser*/
+class YamlParser
+{
+public:
+ std::vector parseYaml(const char * yaml_file_path);
+};
+
+#endif
diff --git a/src/main/CMakeLists.txt b/src/main/CMakeLists.txt
index be4b1b3..baef008 100644
--- a/src/main/CMakeLists.txt
+++ b/src/main/CMakeLists.txt
@@ -2,9 +2,12 @@ add_executable(diagnostics diagnostics.cpp)
target_link_libraries(diagnostics PRIVATE
UI_Common
+ parseYaml
)
target_link_libraries(diagnostics PRIVATE boatTest_Common)
target_include_directories(diagnostics PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}
)
+
+target_compile_definitions(diagnostics PUBLIC YAML_TEST_PATH="${YAML_TEST_PATH}")
diff --git a/src/main/diagnostics.cpp b/src/main/diagnostics.cpp
index 57489e9..0148fa3 100644
--- a/src/main/diagnostics.cpp
+++ b/src/main/diagnostics.cpp
@@ -1,20 +1,63 @@
#include "diagnostics.h"
+App::App()
+{
+ CommonUI * new_ui = new CommonUI();
+ YamlParser * new_yaml_parser = new YamlParser();
+
+ ui = new_ui;
+ yaml_parser = new_yaml_parser;
+}
+
+int App::appGetUserSelection(int * selection)
+{
+ while (true) {
+ std::string user_input;
+ std::cout << ">";
+ getline(std::cin, user_input);
+
+ try {
+ if (user_input.compare("q") == 0) {
+ *selection = -1;
+ } else {
+ *selection = stoi(user_input);
+ }
+ return 0;
+ } catch (std::invalid_argument const& ex) {
+ std::cout << "Diagnosics: " << ex.what() << std::endl;
+ }
+ }
+
+
+}
+
+App::~App()
+{
+ delete ui;
+ delete yaml_parser;
+}
+
int main(int argc, char ** argv)
{
(void)argc;
(void)argv;
- CommonUI base_elements;
- base_elements.printDiv();
- std::string title = "Welcome to UBC Sailbot Diagnostics!";
- base_elements.printCenter(title);
- base_elements.printDiv();
+ int status;
+ App diagnostics_app;
+
+ while (true) {
+ int user_select;
+ status = diagnostics_app.appGetUserSelection(&user_select);
+ if (status) {
+ std::cout << "Error in parsing user input. Exiting." << std::endl;
+ }
- std::unordered_map commands;
- commands["ab"] = "Test AB";
- commands["cd"] = "Test CD";
- base_elements.printMenu(commands);
+ if (user_select < 0) {
+ break;
+ } else {
+ std::cout << "Option " << user_select << " chosen." << std::endl;
+ }
+ }
return 0;
}
diff --git a/src/main/diagnostics.h b/src/main/diagnostics.h
index b8edf66..fbffc26 100644
--- a/src/main/diagnostics.h
+++ b/src/main/diagnostics.h
@@ -5,8 +5,22 @@
#include
#include
#include
+#include
#include "boatTest_common.h"
#include "commonUI.h"
+#include "parse_yaml.h"
+
+/* Classes */
+class App
+{
+public:
+ CommonUI * ui;
+ YamlParser * yaml_parser;
+
+ App();
+ int appGetUserSelection(int * selection);
+ ~App();
+};
#endif
diff --git a/src/ui/common/CMakeLists.txt b/src/ui/common/CMakeLists.txt
index 61298e0..28aa49c 100644
--- a/src/ui/common/CMakeLists.txt
+++ b/src/ui/common/CMakeLists.txt
@@ -1,2 +1,3 @@
add_library(UI_Common commonUI.cpp commonUI.h)
+target_link_libraries(UI_Common PUBLIC parseYaml boatTest_Common)
target_include_directories(UI_Common PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
diff --git a/src/ui/common/commonUI.cpp b/src/ui/common/commonUI.cpp
index bbde01c..2c6056b 100644
--- a/src/ui/common/commonUI.cpp
+++ b/src/ui/common/commonUI.cpp
@@ -37,10 +37,3 @@ void CommonUI::printCenter(std::string contents) const
std::cout << contents << std::endl;
}
-
-void CommonUI::printMenu(std::unordered_map commands)
-{
- for (const auto & command : commands) {
- std::cout << '[' << command.first << "]" << command.second << std::endl;
- }
-}
diff --git a/src/ui/common/commonUI.h b/src/ui/common/commonUI.h
index 50e16b6..291a239 100644
--- a/src/ui/common/commonUI.h
+++ b/src/ui/common/commonUI.h
@@ -10,6 +10,9 @@
#include
#include
+#include "boatTest_common.h"
+#include "parse_yaml.h"
+
/* Defines */
#define TERMINAL_WIDTH_SCALE 0.6
@@ -28,7 +31,6 @@ class CommonUI
explicit CommonUI(int user_set_width);
void printDiv() const;
void printCenter(std::string contents) const;
- static void printMenu(std::unordered_map commands);
};
#endif