def main(opts): actions = ['all', 'build', 'devel', 'install', 'cmake_cache', 'orphans', 'setup_files'] if not any([v for (k, v) in vars(opts).items() if k in actions]): print("[clean] No actions performed. See `catkin clean -h` for usage.") return 0 needs_force = False # Load the context ctx = Context.load(opts.workspace, opts.profile, opts, strict=True, load_env=False) if not ctx: if not opts.workspace: print( "catkin clean: error: The current or desired workspace could not be " "determined. Please run `catkin clean` from within a catkin " "workspace or specify the workspace explicitly with the " "`--workspace` option.") else: print( "catkin clean: error: Could not clean workspace \"%s\" because it " "either does not exist or it has no catkin_tools metadata." % opts.workspace) return 1 # Remove the requested spaces if opts.all: opts.build = opts.devel = opts.install = True if opts.build: if os.path.exists(ctx.build_space_abs): print("[clean] Removing buildspace: %s" % ctx.build_space_abs) shutil.rmtree(ctx.build_space_abs) else: # Orphan removal if opts.orphans: if os.path.exists(ctx.build_space_abs): # TODO: Check for merged build and report error # Get all enabled packages in source space # Suppress warnings since this is looking for packages which no longer exist found_source_packages = [ pkg.name for (path, pkg) in find_packages(ctx.source_space_abs, warnings=[]).items()] # Iterate over all packages with build dirs print("[clean] Removing orphaned build directories from %s" % ctx.build_space_abs) no_orphans = True for pkg_build_name in os.listdir(ctx.build_space_abs): if pkg_build_name not in exempt_build_files: pkg_build_path = os.path.join(ctx.build_space_abs, pkg_build_name) # Remove package build dir if not found if pkg_build_name not in found_source_packages: no_orphans = False print(" - Removing %s" % pkg_build_path) shutil.rmtree(pkg_build_path) if no_orphans: print("[clean] No orphans found, nothing removed from buildspace.") else: # Remove the develspace # TODO: For isolated devel, this could just remove individual packages if os.path.exists(ctx.devel_space_abs): print("Removing develspace: %s" % ctx.devel_space_abs) shutil.rmtree(ctx.devel_space_abs) needs_force = True else: print("[clean] No buildspace exists, no potential for orphans.") return 0 # CMake Cache removal if opts.cmake_cache: # Clear the CMakeCache for each package if os.path.exists(ctx.build_space_abs): # Remove CMakeCaches print("[clean] Removing CMakeCache.txt files from %s" % ctx.build_space_abs) for pkg_build_name in os.listdir(ctx.build_space_abs): if pkg_build_name not in exempt_build_files: pkg_build_path = os.path.join(ctx.build_space_abs, pkg_build_name) ccache_path = os.path.join(pkg_build_path, 'CMakeCache.txt') if os.path.exists(ccache_path): print(" - Removing %s" % ccache_path) os.remove(ccache_path) needs_force = True else: print("[clean] No buildspace exists, no CMake caches to clear.") if opts.devel: if os.path.exists(ctx.devel_space_abs): print("[clean] Removing develspace: %s" % ctx.devel_space_abs) shutil.rmtree(ctx.devel_space_abs) else: if opts.setup_files: print("[clean] Removing setup files from develspace: %s" % ctx.devel_space_abs) for filename in setup_files: full_path = os.path.join(ctx.devel_space_abs, filename) if os.path.exists(full_path): print(" - Removing %s" % full_path) os.remove(full_path) needs_force = True if opts.install: if os.path.exists(ctx.install_space_abs): print("[clean] Removing installspace: %s" % ctx.install_space_abs) shutil.rmtree(ctx.install_space_abs) if needs_force: print( "NOTE: Parts of the workspace have been cleaned which will " "necessitate re-configuring CMake on the next build.") update_metadata(ctx.workspace, ctx.profile, 'build', {'needs_force': True}) return 0
def main(opts): # Context-aware args if opts.build_this or opts.start_with_this: # Determine the enclosing package try: this_package = find_enclosing_package() except InvalidPackage: pass # Handle context-based package building if opts.build_this: if this_package: opts.packages += [this_package] else: sys.exit("catkin build: --this was specified, but this directory is not contained by a catkin package.") # If --start--with was used without any packages and --this was specified, start with this package if opts.start_with_this: if this_package: opts.start_with = this_package else: sys.exit("catkin build: --this was specified, but this directory is not contained by a catkin package.") if opts.no_deps and not opts.packages: sys.exit("With --no-deps, you must specify packages to build.") if not opts.force_color and not is_tty(sys.stdout): set_color(False) # Load the context ctx = Context.Load(opts.workspace, opts.profile, opts) # Load the environment of the workspace to extend if ctx.extend_path is not None: try: load_resultspace_environment(ctx.extend_path) except IOError as exc: log(clr("@!@{rf}Error:@| Unable to extend workspace from \"%s\": %s" % (ctx.extend_path, exc.message))) return 1 # Display list and leave the filesystem untouched if opts.dry_run: dry_run(ctx, opts.packages, opts.no_deps, opts.start_with) return # Check if the context is valid before writing any metadata if not ctx.source_space_exists(): print("catkin build: error: Unable to find source space `%s`" % ctx.source_space_abs) return 1 # Always save the last context under the build verb update_metadata(ctx.workspace, ctx.profile, 'build', ctx.get_stored_dict()) build_metadata = get_metadata(ctx.workspace, ctx.profile, 'build') if build_metadata.get('needs_force', False): opts.force_cmake = True update_metadata(ctx.workspace, ctx.profile, 'build', {'needs_force': False}) # Save the context as the configuration if opts.save_config: Context.Save(ctx) start = time.time() try: return build_isolated_workspace( ctx, packages=opts.packages, start_with=opts.start_with, no_deps=opts.no_deps, jobs=opts.parallel_jobs, force_cmake=opts.force_cmake, force_color=opts.force_color, quiet=not opts.verbose, interleave_output=opts.interleave_output, no_status=opts.no_status, lock_install=not opts.no_install_lock, no_notify=opts.no_notify ) finally: log("[build] Runtime: {0}".format(format_time_delta(time.time() - start)))
def main(opts): # Check for develdebug mode if opts.develdebug is not None: os.environ['TROLLIUSDEBUG'] = opts.develdebug.lower() logging.basicConfig(level=opts.develdebug.upper()) # Set color options if (opts.force_color or is_tty(sys.stdout)) and not opts.no_color: set_color(True) else: set_color(False) # Context-aware args if opts.build_this or opts.start_with_this: # Determine the enclosing package try: ws_path = find_enclosing_workspace(getcwd()) # Suppress warnings since this won't necessaraly find all packages # in the workspace (it stops when it finds one package), and # relying on it for warnings could mislead people. this_package = find_enclosing_package( search_start_path=getcwd(), ws_path=ws_path, warnings=[]) except (InvalidPackage, RuntimeError): this_package = None # Handle context-based package building if opts.build_this: if this_package: opts.packages += [this_package] else: sys.exit( "[build] Error: In order to use --this, the current directory must be part of a catkin package.") # If --start--with was used without any packages and --this was specified, start with this package if opts.start_with_this: if this_package: opts.start_with = this_package else: sys.exit( "[build] Error: In order to use --this, the current directory must be part of a catkin package.") if opts.no_deps and not opts.packages and not opts.unbuilt: sys.exit(clr("[build] @!@{rf}Error:@| With --no-deps, you must specify packages to build.")) # Load the context ctx = Context.load(opts.workspace, opts.profile, opts, append=True) # Initialize the build configuration make_args, makeflags, cli_flags, jobserver = configure_make_args( ctx.make_args, ctx.jobs_args, ctx.use_internal_make_jobserver) # Set the jobserver memory limit if jobserver and opts.mem_limit: log(clr("@!@{pf}EXPERIMENTAL: limit memory to '%s'@|" % str(opts.mem_limit))) # At this point psuitl will be required, check for it and bail out if not set try: import psutil # noqa except ImportError as exc: log("Could not import psutil, but psutil is required when using --mem-limit.") log("Please either install psutil or avoid using --mem-limit.") sys.exit("Exception: {0}".format(exc)) job_server.set_max_mem(opts.mem_limit) ctx.make_args = make_args # Load the environment of the workspace to extend if ctx.extend_path is not None: try: load_resultspace_environment(ctx.extend_path) except IOError as exc: sys.exit(clr("[build] @!@{rf}Error:@| Unable to extend workspace from \"%s\": %s" % (ctx.extend_path, exc.message))) # Check if the context is valid before writing any metadata if not ctx.source_space_exists(): sys.exit(clr("[build] @!@{rf}Error:@| Unable to find source space `%s`") % ctx.source_space_abs) # ensure the build space was previously built by catkin_tools previous_tool = get_previous_tool_used_on_the_space(ctx.build_space_abs) if previous_tool is not None and previous_tool != 'catkin build': if opts.override_build_tool_check: log(clr( "@{yf}Warning: build space at '%s' was previously built by '%s', " "but --override-build-tool-check was passed so continuing anyways." % (ctx.build_space_abs, previous_tool))) else: sys.exit(clr( "@{rf}The build space at '%s' was previously built by '%s'. " "Please remove the build space or pick a different build space." % (ctx.build_space_abs, previous_tool))) # the build space will be marked as catkin build's if dry run doesn't return # ensure the devel space was previously built by catkin_tools previous_tool = get_previous_tool_used_on_the_space(ctx.devel_space_abs) if previous_tool is not None and previous_tool != 'catkin build': if opts.override_build_tool_check: log(clr( "@{yf}Warning: devel space at '%s' was previously built by '%s', " "but --override-build-tool-check was passed so continuing anyways." % (ctx.devel_space_abs, previous_tool))) else: sys.exit(clr( "@{rf}The devel space at '%s' was previously built by '%s'. " "Please remove the devel space or pick a different devel space." % (ctx.devel_space_abs, previous_tool))) # the devel space will be marked as catkin build's if dry run doesn't return # Display list and leave the file system untouched if opts.dry_run: # TODO: Add unbuilt dry_run(ctx, opts.packages, opts.no_deps, opts.start_with) return # Print the build environment for a given package and leave the filesystem untouched if opts.get_env: return print_build_env(ctx, opts.get_env[0]) # Now mark the build and devel spaces as catkin build's since dry run didn't return. mark_space_as_built_by(ctx.build_space_abs, 'catkin build') mark_space_as_built_by(ctx.devel_space_abs, 'catkin build') # Get the last build context build_metadata = get_metadata(ctx.workspace, ctx.profile, 'build') if build_metadata.get('cmake_args') != ctx.cmake_args or build_metadata.get('cmake_args') != opts.cmake_args: opts.force_cmake = True if build_metadata.get('needs_force', False): opts.force_cmake = True update_metadata(ctx.workspace, ctx.profile, 'build', {'needs_force': False}) # Always save the last context under the build verb update_metadata(ctx.workspace, ctx.profile, 'build', ctx.get_stored_dict()) # Save the context as the configuration if opts.save_config: Context.save(ctx) # Get parallel toplevel jobs try: parallel_jobs = int(opts.parallel_jobs) except TypeError: parallel_jobs = None # Set VERBOSE environment variable if opts.verbose: os.environ['VERBOSE'] = '1' return build_isolated_workspace( ctx, packages=opts.packages, start_with=opts.start_with, no_deps=opts.no_deps, unbuilt=opts.unbuilt, n_jobs=parallel_jobs, force_cmake=opts.force_cmake, pre_clean=opts.pre_clean, force_color=opts.force_color, quiet=not opts.verbose, interleave_output=opts.interleave_output, no_status=opts.no_status, limit_status_rate=opts.limit_status_rate, lock_install=not opts.no_install_lock, no_notify=opts.no_notify, continue_on_failure=opts.continue_on_failure, summarize_build=opts.summarize # Can be True, False, or None )
def main(opts): # Context-aware args if opts.build_this or opts.start_with_this: # Determine the enclosing package try: ws_path = find_enclosing_workspace(getcwd()) # Suppress warnings since this won't necessaraly find all packages # in the workspace (it stops when it finds one package), and # relying on it for warnings could mislead people. this_package = find_enclosing_package( search_start_path=getcwd(), ws_path=ws_path, warnings=[]) except (InvalidPackage, RuntimeError): this_package = None # Handle context-based package building if opts.build_this: if this_package: opts.packages += [this_package] else: sys.exit("catkin build: --this was specified, but this directory is not in a catkin package.") # If --start--with was used without any packages and --this was specified, start with this package if opts.start_with_this: if this_package: opts.start_with = this_package else: sys.exit("catkin build: --this was specified, but this directory is not in a catkin package.") if opts.no_deps and not opts.packages: sys.exit("With --no-deps, you must specify packages to build.") # Load the context ctx = Context.load(opts.workspace, opts.profile, opts, append=True) # Initialize the build configuration make_args, makeflags, cli_flags, jobserver = configure_make_args(ctx.make_args, ctx.use_internal_make_jobserver) # Set the jobserver memory limit if jobserver and opts.mem_limit: log(clr("@!@{pf}EXPERIMENTAL: limit memory to '%s'@|" % str(opts.mem_limit))) # At this point psuitl will be required, check for it and bail out if not set try: import psutil # noqa except ImportError as exc: log("Could not import psutil, but psutil is required when using --mem-limit.") log("Please either install psutil or avoid using --mem-limit.") sys.exit("Exception: {0}".format(exc)) set_jobserver_max_mem(opts.mem_limit) ctx.make_args = make_args # Load the environment of the workspace to extend if ctx.extend_path is not None: try: load_resultspace_environment(ctx.extend_path) except IOError as exc: log(clr("@!@{rf}Error:@| Unable to extend workspace from \"%s\": %s" % (ctx.extend_path, exc.message))) return 1 # Display list and leave the file system untouched if opts.dry_run: dry_run(ctx, opts.packages, opts.no_deps, opts.start_with) return # Check if the context is valid before writing any metadata if not ctx.source_space_exists(): print("catkin build: error: Unable to find source space `%s`" % ctx.source_space_abs) return 1 # Always save the last context under the build verb update_metadata(ctx.workspace, ctx.profile, 'build', ctx.get_stored_dict()) build_metadata = get_metadata(ctx.workspace, ctx.profile, 'build') if build_metadata.get('needs_force', False): opts.force_cmake = True update_metadata(ctx.workspace, ctx.profile, 'build', {'needs_force': False}) # Save the context as the configuration if opts.save_config: Context.save(ctx) start = time.time() try: return build_isolated_workspace( ctx, packages=opts.packages, start_with=opts.start_with, no_deps=opts.no_deps, jobs=opts.parallel_jobs, force_cmake=opts.force_cmake, force_color=opts.force_color, quiet=not opts.verbose, interleave_output=opts.interleave_output, no_status=opts.no_status, limit_status_rate=opts.limit_status_rate, lock_install=not opts.no_install_lock, no_notify=opts.no_notify, continue_on_failure=opts.continue_on_failure, summarize_build=opts.summarize # Can be True, False, or None ) finally: log("[build] Runtime: {0}".format(format_time_delta(time.time() - start)))
def clean_profile(opts, profile): # Load the context ctx = Context.load(opts.workspace, profile, opts, strict=True, load_env=False) if not ctx: if not opts.workspace: log( "[clean] Error: The current or desired workspace could not be " "determined. Please run `catkin clean` from within a catkin " "workspace or specify the workspace explicitly with the " "`--workspace` option.") else: log( "[clean] Error: Could not clean workspace \"%s\" because it " "either does not exist or it has no catkin_tools metadata." % opts.workspace) return False profile = ctx.profile # Check if the user wants to do something explicit actions = [ 'build', 'devel', 'install', 'logs', 'packages', 'orphans', 'deinit', 'setup_files'] logs_exists = os.path.exists(ctx.log_space_abs) build_exists = os.path.exists(ctx.build_space_abs) devel_exists = os.path.exists(ctx.devel_space_abs) install_path = ( os.path.join(ctx.destdir, ctx.install_space_abs.lstrip(os.sep)) if ctx.destdir else ctx.install_space_abs) install_exists = os.path.exists(install_path) # Default is to clean all products for this profile no_specific_action = not any([ v for (k, v) in vars(opts).items() if k in actions]) clean_all = opts.deinit or no_specific_action # Initialize action options if clean_all: opts.logs = opts.build = opts.devel = opts.install = True # Make sure the user intends to clena everything spaces_to_clean = (opts.logs or opts.build or opts.devel or opts.install) spaces_to_clean_msgs = [] if spaces_to_clean and not (opts.yes or opts.dry_run): if opts.logs and logs_exists: spaces_to_clean_msgs.append(clr("[clean] Log Space: @{yf}{}").format(ctx.log_space_abs)) if opts.build and build_exists: spaces_to_clean_msgs.append(clr("[clean] Build Space: @{yf}{}").format(ctx.build_space_abs)) if opts.devel and devel_exists: spaces_to_clean_msgs.append(clr("[clean] Devel Space: @{yf}{}").format(ctx.devel_space_abs)) if opts.install and install_exists: spaces_to_clean_msgs.append(clr("[clean] Install Space: @{yf}{}").format(install_path)) if len(spaces_to_clean_msgs) == 0 and not opts.deinit: log("[clean] Nothing to be cleaned for profile: `{}`".format(profile)) return True if len(spaces_to_clean_msgs) > 0: log("") log(clr("[clean] @!@{yf}Warning:@| This will completely remove the " "following directories. (Use `--yes` to skip this check)")) for msg in spaces_to_clean_msgs: log(msg) try: yes = yes_no_loop( "\n[clean] Are you sure you want to completely remove the directories listed above?") if not yes: log(clr("[clean] Not removing any workspace directories for" " this profile.")) return True except KeyboardInterrupt: log("\n[clean] No actions performed.") sys.exit(0) # Initialize flag to be used on the next invocation needs_force = False try: # Remove all installspace files if opts.install and install_exists: log("[clean] Removing installspace: %s" % install_path) if not opts.dry_run: safe_rmtree(install_path, ctx.workspace, opts.force) # Remove all develspace files if opts.devel: if devel_exists: log("[clean] Removing develspace: %s" % ctx.devel_space_abs) if not opts.dry_run: safe_rmtree(ctx.devel_space_abs, ctx.workspace, opts.force) # Clear the cached metadata from the last build run _, build_metadata_file = get_metadata_paths(ctx.workspace, profile, 'build') if os.path.exists(build_metadata_file): os.unlink(build_metadata_file) # Clear the cached packages data, if it exists packages_metadata_path = ctx.package_metadata_path() if os.path.exists(packages_metadata_path): safe_rmtree(packages_metadata_path, ctx.workspace, opts.force) # Remove all buildspace files if opts.build and build_exists: log("[clean] Removing buildspace: %s" % ctx.build_space_abs) if not opts.dry_run: safe_rmtree(ctx.build_space_abs, ctx.workspace, opts.force) # Setup file removal if opts.setup_files: if devel_exists: log("[clean] Removing setup files from develspace: %s" % ctx.devel_space_abs) opts.packages.append('catkin') opts.packages.append('catkin_tools_prebuild') else: log("[clean] No develspace exists, no setup files to clean.") # Clean log files if opts.logs and logs_exists: log("[clean] Removing log space: {}".format(ctx.log_space_abs)) if not opts.dry_run: safe_rmtree(ctx.log_space_abs, ctx.workspace, opts.force) # Find orphaned packages if ctx.link_devel and not any([opts.build, opts.devel]): if opts.orphans: if os.path.exists(ctx.build_space_abs): log("[clean] Determining orphaned packages...") # Get all existing packages in source space and the # Suppress warnings since this is looking for packages which no longer exist found_source_packages = [ pkg.name for (path, pkg) in find_packages(ctx.source_space_abs, warnings=[]).items()] built_packages = [ pkg.name for (path, pkg) in find_packages(ctx.package_metadata_path(), warnings=[]).items()] # Look for orphaned products in the build space orphans = [p for p in built_packages if (p not in found_source_packages and p != 'catkin_tools_prebuild')] if len(orphans) > 0: opts.packages.extend(list(orphans)) else: log("[clean] No orphans in the workspace.") else: log("[clean] No buildspace exists, no potential for orphans.") # Remove specific packages if len(opts.packages) > 0: try: # Clean the packages needs_force = clean_packages( ctx, opts.packages, opts.dependents, opts.verbose, opts.dry_run) except KeyboardInterrupt: wide_log("[build] User interrupted!") return False elif opts.orphans or len(opts.packages) > 0: log("[clean] Error: Individual packages can only be cleaned from " "workspaces with symbolically-linked develspaces (`catkin " "config --link-devel`).") except: log("[clean] Failed to clean profile `{}`".format(profile)) needs_force = True raise finally: if needs_force: log(clr( "[clean] @/@!Note:@| @/Parts of the workspace have been cleaned which will " "necessitate re-configuring CMake on the next build.@|")) update_metadata(ctx.workspace, ctx.profile, 'build', {'needs_force': True}) return True
def clean_profile(opts, profile): # Load the context ctx = Context.load(opts.workspace, profile, opts, strict=True, load_env=False) if not ctx: if not opts.workspace: log( "[clean] Error: The current or desired workspace could not be " "determined. Please run `catkin clean` from within a catkin " "workspace or specify the workspace explicitly with the " "`--workspace` option.") else: log( "[clean] Error: Could not clean workspace \"%s\" because it " "either does not exist or it has no catkin_tools metadata." % opts.workspace) return False profile = ctx.profile # Check if the user wants to do something explicit actions = [ 'build', 'devel', 'install', 'logs', 'packages', 'orphans', 'deinit', 'setup_files'] logs_exists = os.path.exists(ctx.log_space_abs) build_exists = os.path.exists(ctx.build_space_abs) devel_exists = os.path.exists(ctx.devel_space_abs) install_path = ( os.path.join(ctx.destdir, ctx.install_space_abs.lstrip(os.sep)) if ctx.destdir else ctx.install_space_abs) install_exists = os.path.exists(install_path) # Default is to clean all products for this profile no_specific_action = not any([ v for (k, v) in vars(opts).items() if k in actions]) clean_all = opts.deinit or no_specific_action # Initialize action options if clean_all: opts.logs = opts.build = opts.devel = opts.install = True # Make sure the user intends to clena everything spaces_to_clean = (opts.logs or opts.build or opts.devel or opts.install) spaces_to_clean_msgs = [] if spaces_to_clean and not (opts.yes or opts.dry_run): if opts.logs and logs_exists: spaces_to_clean_msgs.append(clr("[clean] Log Space: @{yf}{}").format(ctx.log_space_abs)) if opts.build and build_exists: spaces_to_clean_msgs.append(clr("[clean] Build Space: @{yf}{}").format(ctx.build_space_abs)) if opts.devel and devel_exists: spaces_to_clean_msgs.append(clr("[clean] Devel Space: @{yf}{}").format(ctx.devel_space_abs)) if opts.install and install_exists: spaces_to_clean_msgs.append(clr("[clean] Install Space: @{yf}{}").format(install_path)) if len(spaces_to_clean_msgs) == 0 and not opts.deinit: log("[clean] Nothing to be cleaned for profile: `{}`".format(profile)) return True if len(spaces_to_clean_msgs) > 0: log("") log(clr("[clean] @!@{yf}Warning:@| This will completely remove the " "following directories. (Use `--yes` to skip this check)")) for msg in spaces_to_clean_msgs: log(msg) try: yes = yes_no_loop( "\n[clean] Are you sure you want to completely remove the directories listed above?") if not yes: log(clr("[clean] Not removing any workspace directories for" " this profile.")) return True except KeyboardInterrupt: log("\n[clean] No actions performed.") sys.exit(0) # Initialize flag to be used on the next invocation needs_force = False try: # Remove all installspace files if opts.install and install_exists: log("[clean] Removing installspace: %s" % install_path) if not opts.dry_run: safe_rmtree(install_path, ctx.workspace, opts.force) # Remove all develspace files if opts.devel: if devel_exists: log("[clean] Removing develspace: %s" % ctx.devel_space_abs) if not opts.dry_run: safe_rmtree(ctx.devel_space_abs, ctx.workspace, opts.force) # Clear the cached metadata from the last build run _, build_metadata_file = get_metadata_paths(ctx.workspace, profile, 'build') if os.path.exists(build_metadata_file): os.unlink(build_metadata_file) # Clear the cached packages data, if it exists packages_metadata_path = ctx.package_metadata_path() if os.path.exists(packages_metadata_path): safe_rmtree(packages_metadata_path, ctx.workspace, opts.force) # Remove all buildspace files if opts.build and build_exists: log("[clean] Removing buildspace: %s" % ctx.build_space_abs) if not opts.dry_run: safe_rmtree(ctx.build_space_abs, ctx.workspace, opts.force) # Setup file removal if opts.setup_files: if devel_exists: log("[clean] Removing setup files from develspace: %s" % ctx.devel_space_abs) opts.packages.append('catkin') opts.packages.append('catkin_tools_prebuild') else: log("[clean] No develspace exists, no setup files to clean.") # Clean log files if opts.logs and logs_exists: log("[clean] Removing log space: {}".format(ctx.log_space_abs)) if not opts.dry_run: safe_rmtree(ctx.log_space_abs, ctx.workspace, opts.force) # Find orphaned packages if ctx.link_devel and not any([opts.build, opts.devel]): if opts.orphans: if os.path.exists(ctx.build_space_abs): log("[clean] Determining orphaned packages...") # Get all existing packages in source space and the # Suppress warnings since this is looking for packages which no longer exist found_source_packages = [ pkg.name for (path, pkg) in find_packages(ctx.source_space_abs, warnings=[]).items()] built_packages = [ pkg.name for (path, pkg) in find_packages(ctx.package_metadata_path(), warnings=[]).items()] # Look for orphaned products in the build space orphans = [p for p in built_packages if (p not in found_source_packages and p != 'catkin_tools_prebuild')] if len(orphans) > 0: opts.packages.extend(list(orphans)) else: log("[clean] No orphans in the workspace.") else: log("[clean] No buildspace exists, no potential for orphans.") # Remove specific packages if len(opts.packages) > 0: try: # Clean the packages needs_force = clean_packages( ctx, opts.packages, opts.dependents, opts.verbose, opts.dry_run) except KeyboardInterrupt: wide_log("[build] User interrupted!") return False elif opts.orphans or len(opts.packages) > 0: log("[clean] Error: Individual packages can only be cleaned from " "workspaces with symbolically-linked develspaces (`catkin " "config --link-devel`).") except: # noqa: E722 # Silencing E722 here since we immediately re-raise the exception. log("[clean] Failed to clean profile `{}`".format(profile)) needs_force = True raise finally: if needs_force: log(clr( "[clean] @/@!Note:@| @/Parts of the workspace have been cleaned which will " "necessitate re-configuring CMake on the next build.@|")) update_metadata(ctx.workspace, ctx.profile, 'build', {'needs_force': True}) return True