Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Detect nested workspaces and use the outermost workspace by default #705

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion catkin_tools/argument_parsing.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def add_workspace_arg(parser):

add = parser.add_argument
add('--workspace', '-w', default=None,
help='The path to the catkin_tools workspace or a directory contained within it (default: ".")')
help='The path to the catkin_tools workspace (default: autodetect)')


def add_cmake_and_make_and_catkin_make_args(parser):
Expand Down
17 changes: 12 additions & 5 deletions catkin_tools/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
from .common import remove_ansi_escape
from .common import terminal_width

from .metadata import find_enclosing_workspace
from .metadata import find_enclosing_workspaces

from .resultspace import get_resultspace_environment

Expand Down Expand Up @@ -183,9 +183,16 @@ def load(
# Initialize dictionary version of opts namespace
opts_vars = vars(opts) if opts else {}

# Get the workspace (either the given directory or the enclosing ws)
workspace_hint = workspace_hint or opts_vars.get('workspace', None) or getcwd()
workspace = find_enclosing_workspace(workspace_hint)
# Get the workspace (either the given directory or the outermost ws enclosing cwd)
workspace = workspace_hint or opts_vars.get('workspace', None)
if not workspace:
workspace_hint = getcwd()
workspaces = find_enclosing_workspaces(workspace_hint)
if workspaces:
workspace = workspaces[-1]
else:
workspace = workspace_hint

if not workspace:
if strict or not workspace_hint:
return None
Expand Down Expand Up @@ -684,7 +691,7 @@ def extend_path(self, value):

def initialized(self):
"""Check if this context is initialized."""
return self.workspace == find_enclosing_workspace(self.workspace)
return self.workspace in (find_enclosing_workspaces(self.workspace) or [])

@property
def destdir(self):
Expand Down
42 changes: 25 additions & 17 deletions catkin_tools/metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,31 +101,48 @@ def get_paths(workspace_path, profile_name, verb=None):

return metadata_path, metadata_file_path


def find_enclosing_workspace(search_start_path):
"""Find a catkin workspace based on the existence of a catkin_tools
def find_enclosing_workspaces(search_start_path):
"""Find a catkin workspaces based on the existence of a catkin_tools
metadata directory starting in the path given by search_path and traversing
each parent directory until either finding such a directory or getting to
the root of the filesystem.
each parent directory and returns a list of workspaces.

:search_start_path: Directory which either is a catkin workspace or is
contained in a catkin workspace

:returns: Path to the workspace if found, `None` if not found.
:returns: List of path to the workspaces if found, an empty list otherwise.
"""
workspaces = []
while search_start_path:
# Check if marker file exists
candidate_path = os.path.join(search_start_path, METADATA_DIR_NAME)
if os.path.exists(candidate_path) and os.path.isdir(candidate_path):
return search_start_path
workspaces.append(search_start_path)

# Update search path or end
(search_start_path, child_path) = os.path.split(search_start_path)
if len(child_path) == 0:
break

return None
return workspaces

def find_enclosing_workspace(search_start_path):
"""Find a catkin workspace based on the existence of a catkin_tools
metadata directory starting in the path given by search_path and traversing
each parent directory until either finding such a directory or getting to
the root of the filesystem.

If more than one candidate exists, returns the topmost workspace (closest
to the root of the filesystem.

:search_start_path: Directory which either is a catkin workspace or is
contained in a catkin workspace

:returns: Path to the workspace if found, `None` if not found.
"""
workspaces = find_enclosing_workspaces(search_start_path)
if not workspaces:
return None
return workspaces[-1]

def migrate_metadata(workspace_path):
"""Migrate metadata if it's out of date."""
Expand Down Expand Up @@ -212,15 +229,6 @@ def init_metadata_root(workspace_path, reset=False):
"Can't initialize Catkin workspace in path %s because it does "
"not exist." % workspace_path)

# Check if the desired workspace is enclosed in another workspace
marked_workspace = find_enclosing_workspace(workspace_path)

if marked_workspace and marked_workspace != workspace_path:
raise IOError(
"Can't initialize Catkin workspace in path %s because it is "
"already contained in another workspace: %s." %
(workspace_path, marked_workspace))

# Construct the full path to the metadata directory
metadata_root_path = get_metadata_root_path(workspace_path)

Expand Down
2 changes: 1 addition & 1 deletion catkin_tools/verbs/catkin_config/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ def main(opts):

except IOError as exc:
# Usually happens if workspace is already underneath another catkin_tools workspace
print('error: could not configure catkin workspace: %s' % exc.message)
print('error: could not configure catkin workspace: %s' % str(exc))
return 1

return 0
2 changes: 1 addition & 1 deletion catkin_tools/verbs/catkin_init/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def main(opts):

except IOError as exc:
# Usually happens if workspace is already underneath another catkin_tools workspace
print('error: could not initialize catkin workspace: %s' % exc.message)
print('error: could not initialize catkin workspace: %s' % str(exc))
return 1

return 0
4 changes: 2 additions & 2 deletions docs/verbs/cli/catkin_build.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ the `catkin config` command.
optional arguments:
-h, --help show this help message and exit
--workspace WORKSPACE, -w WORKSPACE
The path to the catkin_tools workspace or a directory
contained within it (default: ".")
The path to the catkin_tools workspace (default:
autodetect)
--profile PROFILE The name of a config profile to use (default: active
profile)
--dry-run, -n List the packages which will be built with the given
Expand Down
4 changes: 2 additions & 2 deletions docs/verbs/cli/catkin_clean.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ Deletes various products of the build verb.
optional arguments:
-h, --help show this help message and exit
--workspace WORKSPACE, -w WORKSPACE
The path to the catkin_tools workspace or a directory
contained within it (default: ".")
The path to the catkin_tools workspace (default:
autodetect)
--profile PROFILE The name of a config profile to use (default: active
profile)
--dry-run, -n Show the effects of the clean action without modifying
Expand Down
4 changes: 2 additions & 2 deletions docs/verbs/cli/catkin_config.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ profile.
optional arguments:
-h, --help show this help message and exit
--workspace WORKSPACE, -w WORKSPACE
The path to the catkin_tools workspace or a directory
contained within it (default: ".")
The path to the catkin_tools workspace (default:
autodetect)
--profile PROFILE The name of a config profile to use (default: active
profile)

Expand Down
4 changes: 2 additions & 2 deletions docs/verbs/cli/catkin_init.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Initializes a given folder as a catkin workspace.
optional arguments:
-h, --help show this help message and exit
--workspace WORKSPACE, -w WORKSPACE
The path to the catkin_tools workspace or a directory
contained within it (default: ".")
The path to the catkin_tools workspace (default:
autodetect)
--reset Reset (delete) all of the metadata for the given
workspace.
4 changes: 2 additions & 2 deletions docs/verbs/cli/catkin_list.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ Lists catkin packages in the workspace or other arbitrary folders.
optional arguments:
-h, --help show this help message and exit
--workspace WORKSPACE, -w WORKSPACE
The path to the catkin_tools workspace or a directory
contained within it (default: ".")
The path to the catkin_tools workspace (default:
autodetect)
--profile PROFILE The name of a config profile to use (default: active
profile)

Expand Down
4 changes: 2 additions & 2 deletions docs/verbs/cli/catkin_locate.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ Get the paths to various locations in a workspace.
optional arguments:
-h, --help show this help message and exit
--workspace WORKSPACE, -w WORKSPACE
The path to the catkin_tools workspace or a directory
contained within it (default: ".")
The path to the catkin_tools workspace (default:
autodetect)
--profile PROFILE The name of a config profile to use (default: active
profile)

Expand Down