def test_get_workspaces(self): try: root_dir = tempfile.mkdtemp() ws1 = os.path.join(root_dir, 'ws1') ws2 = os.path.join(root_dir, 'ws2') os.makedirs(ws1) os.makedirs(ws2) with open(os.path.join(ws1, CATKIN_WORKSPACE_MARKER_FILE), 'w') as fhand: fhand.write('loc1;loc2') with open(os.path.join(ws2, CATKIN_WORKSPACE_MARKER_FILE), 'w') as fhand: fhand.write('loc3;loc4') catkin.workspace.os.environ = {} self.assertEqual([], get_workspaces()) catkin.workspace.os.environ = {'CMAKE_PREFIX_PATH': ''} self.assertEqual([], get_workspaces()) catkin.workspace.os.environ = {'CMAKE_PREFIX_PATH': ws1} self.assertEqual([ws1], get_workspaces()) catkin.workspace.os.environ = {'CMAKE_PREFIX_PATH': 'nowhere'} self.assertEqual([], get_workspaces()) catkin.workspace.os.environ = { 'CMAKE_PREFIX_PATH': ws2 + os.pathsep + ws1 } self.assertEqual([ws2, ws1], get_workspaces()) finally: shutil.rmtree(root_dir) catkin.workspace.os.environ = os.environ
def test_get_workspaces(self): old_environ = os.environ try: root_dir = tempfile.mkdtemp() ws1 = os.path.join(root_dir, 'ws1') ws2 = os.path.join(root_dir, 'ws2') os.makedirs(ws1) os.makedirs(ws2) with open(os.path.join(ws1, CATKIN_MARKER_FILE), 'w') as fhand: fhand.write('loc1;loc2') with open(os.path.join(ws2, CATKIN_MARKER_FILE), 'w') as fhand: fhand.write('loc3;loc4') catkin.workspace.os.environ = {} self.assertEqual([], get_workspaces()) catkin.workspace.os.environ = {'CMAKE_PREFIX_PATH': ''} self.assertEqual([], get_workspaces()) catkin.workspace.os.environ = {'CMAKE_PREFIX_PATH': ws1} self.assertEqual([ws1], get_workspaces()) catkin.workspace.os.environ = {'CMAKE_PREFIX_PATH': 'nowhere'} self.assertEqual([], get_workspaces()) catkin.workspace.os.environ = {'CMAKE_PREFIX_PATH': ws2 + os.pathsep + ws1} self.assertEqual([ws2, ws1], get_workspaces()) finally: shutil.rmtree(root_dir) os.environ = old_environ catkin.workspace.os.environ = os.environ
def find_in_workspaces(search_dirs=None, project=None, path=None, _workspaces=get_workspaces()): ''' Find all paths which match the search criteria. All workspaces are searched in order. Each workspace, each search_in subfolder, the project name and the path are concatenated to define a candidate path. If the candidate path exists it is appended to the result list. Note: the search might return multiple paths for a 'share' from build- and source-space. :param search_dir: The list of subfolders to search in (default contains all valid values: 'bin', 'etc', 'lib', 'libexec', 'share'), ``list`` :param project: The project name to search for (optional, not possible with the global search_in folders 'bin' and 'lib'), ``str`` :param path: The path, ``str`` :param _workspaces: (optional, used for unit tests), the list of workspaces to use. :raises ValueError: if search_dirs contains an invalid folder name :returns: List of paths, ``list`` ''' search_dirs = _get_valid_search_dirs(search_dirs, project) # collect candidate paths paths = [] for workspace in (_workspaces or []): for sub in search_dirs: # search in workspace p = os.path.join(workspace, sub if sub != 'libexec' else 'lib') if project: p = os.path.join(p, project) if path: p = os.path.join(p, path) paths.append(p) # for search in share also consider source spaces if project is not None and sub == 'share': source_paths = get_source_paths(workspace) for source_path in source_paths: p = os.path.join(source_path, project) if path is not None: p = os.path.join(p, path) paths.append(p) # find all existing candidates existing = [p for p in paths if os.path.exists(p)] return (existing, paths)
def init_workspace(workspace_dir): """ Create a toplevel CMakeLists.txt in the root of a workspace. The toplevel.cmake file is looked up either in the catkin workspaces contained in the CMAKE_PREFIX_PATH or relative to this file. Then it tries to create a symlink first and if that fails copies the file. It installs ``manifest.xml`` to ``share/${PROJECT_NAME}``. .. note:: The symlink is absolute when catkin is found outside the workspace_dir (since that indicates a different workspace and it may change relative location to the workspace referenced as a parameter). The symlink is relative when catkin is part of the to-be-initialized workspace. :param workspace_dir: the path to the workspace where the CMakeLists.txt should be created :type workspace_dir: string """ # verify that destination file does not exist dst = os.path.join(workspace_dir, 'CMakeLists.txt') if os.path.exists(dst): raise RuntimeError('File "%s" already exists' % dst) src_file_path = None checked = [] # look in to-be-initialized workspace first src = os.path.join(workspace_dir, 'catkin', 'cmake', 'toplevel.cmake') if os.path.isfile(src): src_file_path = os.path.relpath(src, workspace_dir) else: checked.append(src) # search for toplevel file in all workspaces if src_file_path is None: workspaces = get_workspaces() for workspace in workspaces: source_paths = get_source_paths(workspace) if len(source_paths) == 0: # try from install space src = os.path.join(workspace, 'catkin', 'cmake', 'toplevel.cmake') if os.path.isfile(src): src_file_path = src break else: checked.append(src) else: # try from all source spaces for source_path in source_paths: src = os.path.join(source_path, 'catkin', 'cmake', 'toplevel.cmake') if os.path.isfile(src): src_file_path = src break else: checked.append(src) # search for toplevel file in relative locations if src_file_path is None: relative_cmake_paths = [] # when catkin is in source space relative_cmake_paths.append(os.path.join('..', '..', 'cmake')) # when catkin is installed (with Python code in lib/pythonX.Y/[dist|site]-packages) relative_cmake_paths.append(os.path.join('..', '..', '..', '..', 'share', 'catkin', 'cmake')) # when catkin is installed (with Python code in lib/site-packages) relative_cmake_paths.append(os.path.join('..', '..', '..', 'share', 'catkin', 'cmake')) for relative_cmake_path in relative_cmake_paths: src = os.path.abspath(os.path.join(os.path.dirname(__file__), relative_cmake_path, 'toplevel.cmake')) if os.path.isfile(src): src_file_path = src break else: checked.append(src) if src_file_path is None: raise RuntimeError('Could neither find file "toplevel.cmake" in any workspace nor relative, checked the following paths:\n%s' % ('\n'.join(checked))) _symlink_or_copy(src_file_path, dst)
def find_in_workspaces(search_dirs=None, project=None, path=None, _workspaces=get_workspaces(), considered_paths=None, first_matching_workspace_only=False, first_match_only=False, workspace_to_source_spaces=None, source_path_to_packages=None): ''' Find all paths which match the search criteria. All workspaces are searched in order. Each workspace, each search_in subfolder, the project name and the path are concatenated to define a candidate path. If the candidate path exists it is appended to the result list. Note: the search might return multiple paths for 'share' from devel- and source-space. :param search_dir: The list of subfolders to search in (default contains all valid values: 'bin', 'etc', 'lib', 'libexec', 'share'), ``list`` :param project: The project name to search for (optional, not possible with the global search_in folders 'bin' and 'lib'), ``str`` :param path: The path, ``str`` :param _workspaces: (optional, used for unit tests), the list of workspaces to use. :param considered_paths: If not None, function will append all path that were searched :param first_matching_workspace_only: if True returns all results found for first workspace with results :param first_match_only: if True returns first path found (supercedes first_matching_workspace_only) :param workspace_to_source_spaces: the dictionary is populated with mappings from workspaces to source paths, pass in the same dictionary to avoid repeated reading of the catkin marker file :param source_path_to_packages: the dictionary is populated with mappings from source paths to packages, pass in the same dictionary to avoid repeated crawling :raises ValueError: if search_dirs contains an invalid folder name :returns: List of paths ''' search_dirs = _get_valid_search_dirs(search_dirs, project) if 'libexec' in search_dirs: search_dirs.insert(search_dirs.index('libexec'), 'lib') if workspace_to_source_spaces is None: workspace_to_source_spaces = {} if source_path_to_packages is None: source_path_to_packages = {} paths = [] existing_paths = [] try: for workspace in (_workspaces or []): for sub in search_dirs: # search in workspace p = os.path.join(workspace, sub) if project: p = os.path.join(p, project) if path: p = os.path.join(p, path) paths.append(p) if os.path.exists(p): existing_paths.append(p) if first_match_only: raise StopIteration # for search in share also consider source spaces if project is not None and sub == 'share': if workspace not in workspace_to_source_spaces: workspace_to_source_spaces[workspace] = get_source_paths(workspace) for source_path in workspace_to_source_spaces[workspace]: if source_path not in source_path_to_packages: source_path_to_packages[source_path] = find_packages(source_path) matching_packages = [p for p, pkg in source_path_to_packages[source_path].items() if pkg.name == project] if matching_packages: p = source_path if matching_packages[0] != os.curdir: p = os.path.join(p, matching_packages[0]) if path is not None: p = os.path.join(p, path) paths.append(p) if os.path.exists(p): existing_paths.append(p) if first_match_only: raise StopIteration if first_matching_workspace_only and existing_paths: break except StopIteration: pass if considered_paths is not None: considered_paths.extend(paths) return existing_paths
def find_in_workspaces(search_dirs=None, project=None, path=None, _workspaces=get_workspaces(), considered_paths=None, first_matching_workspace_only=False, first_match_only=False, workspace_to_source_spaces=None, source_path_to_packages=None): ''' Find all paths which match the search criteria. All workspaces are searched in order. Each workspace, each search_in subfolder, the project name and the path are concatenated to define a candidate path. If the candidate path exists it is appended to the result list. Note: the search might return multiple paths for 'share' from devel- and source-space. :param search_dir: The list of subfolders to search in (default contains all valid values: 'bin', 'etc', 'lib', 'libexec', 'share'), ``list`` :param project: The project name to search for (optional, not possible with the global search_in folders 'bin' and 'lib'), ``str`` :param path: The path, ``str`` :param _workspaces: (optional, used for unit tests), the list of workspaces to use. :param considered_paths: If not None, function will append all path that were searched :param first_matching_workspace_only: if True returns all results found for first workspace with results :param first_match_only: if True returns first path found (supercedes first_matching_workspace_only) :param workspace_to_source_spaces: the dictionary is populated with mappings from workspaces to source paths, pass in the same dictionary to avoid repeated reading of the catkin marker file :param source_path_to_packages: the dictionary is populated with mappings from source paths to packages, pass in the same dictionary to avoid repeated crawling :raises ValueError: if search_dirs contains an invalid folder name :returns: List of paths ''' search_dirs = _get_valid_search_dirs(search_dirs, project) if 'libexec' in search_dirs: search_dirs.insert(search_dirs.index('libexec'), 'lib') if workspace_to_source_spaces is None: workspace_to_source_spaces = {} if source_path_to_packages is None: source_path_to_packages = {} paths = [] existing_paths = [] try: for workspace in (_workspaces or []): for sub in search_dirs: # search in workspace p = os.path.join(workspace, sub) if project: p = os.path.join(p, project) if path: p = os.path.join(p, path) paths.append(p) if os.path.exists(p): existing_paths.append(p) if first_match_only: raise StopIteration # for search in share also consider source spaces if project is not None and sub == 'share': if workspace not in workspace_to_source_spaces: workspace_to_source_spaces[ workspace] = get_source_paths(workspace) for source_path in workspace_to_source_spaces[workspace]: if source_path not in source_path_to_packages: source_path_to_packages[ source_path] = find_packages(source_path) matching_packages = [ p for p, pkg in source_path_to_packages[source_path].items() if pkg.name == project ] if matching_packages: p = source_path if matching_packages[0] != os.curdir: p = os.path.join(p, matching_packages[0]) if path is not None: p = os.path.join(p, path) paths.append(p) if os.path.exists(p): existing_paths.append(p) if first_match_only: raise StopIteration if first_matching_workspace_only and existing_paths: break except StopIteration: pass if considered_paths is not None: considered_paths.extend(paths) return existing_paths