diff --git a/README.md b/README.md index 22f3c2b60..a6781dd6e 100644 --- a/README.md +++ b/README.md @@ -232,6 +232,37 @@ Taking the above into account, the following combinations for `install.yaml` are Both ROS distro specific as default can be 'null'. Preferred usage is default for current and feature distributions and exceptions for old distributions. +##### ROS package source removal + +When switching from a source installation to a system installation, the source installation must be removed. +This can be done by adding a `ros-remove-source` target to the `install.yaml` file. +It removes the package from the workspace, including uninstalling. +It checks whether there are still references to the repository in the workspace, +otherwise it will delete the repository as well. + +```yaml +- type: ros-remove-source + remove: + type: git + url: + eol: + path: (Optional field) +``` + +Again, this can be distro-specific. + +```yaml +- type: ros-remove-source + default: + source: + type: git + url: + eol: + path: (Optional field) + noetic: + remove: null +``` + #### Catkin package install ```yaml diff --git a/installer/parse_install_yaml.py b/installer/parse_install_yaml.py index 10e14dbb7..fa7837cb8 100755 --- a/installer/parse_install_yaml.py +++ b/installer/parse_install_yaml.py @@ -162,7 +162,7 @@ def get_distro_item(item: Mapping, key: str, release_version: str, release_type: if install_type == "empty": return {"system_packages": system_packages, "commands": commands} - elif install_type == "ros": + elif install_type == "ros" or install_type == "ros-remove-source": ros_release = environ["TUE_ROS_DISTRO"] try: source = get_distro_item(install_item, "source", ros_release, "ROS") @@ -173,14 +173,24 @@ def get_distro_item(item: Mapping, key: str, release_version: str, release_type: if source is None: continue - source_type = source["type"] - if source_type == "git": - command = f"tue-install-ros {catkin_git(source)}" - elif source_type == "system": - system_packages.append(f"ros-{ros_release}-{source['name']}") - command = f"tue-install-ros system {source['name']}" - else: - raise ValueError(f"Unknown ROS install type: '{source_type}'") + if install_type == "ros": + source_type = source["type"] + if source_type == "git": + command = f"tue-install-ros {catkin_git(source)}" + elif source_type == "system": + system_packages.append(f"ros-{ros_release}-{source['name']}") + command = f"tue-install-ros system {source['name']}" + else: + raise ValueError(f"Unknown ROS install type: '{source_type}'") + elif install_type == "ros-remove-source": + command_list = ["tue-install-ros-remove-source"] + command_list.append(type_git(source, ["eol"])) + + if "eol" not in source: + raise KeyError("EOL is a mandatory key for install type 'ros-remove-source'") + command_list.append(f"--eol={source['eol']}") + + command = " ".join(command_list) # Non ros targets that are packaged to be built with catkin elif install_type == "catkin": diff --git a/installer/tue-install-impl.bash b/installer/tue-install-impl.bash index 302c062fe..537f1ac64 100755 --- a/installer/tue-install-impl.bash +++ b/installer/tue-install-impl.bash @@ -1515,6 +1515,107 @@ function tue-install-ros # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +function tue-install-ros-remove-source +{ + tue-install-debug "tue-install-ros-remove-source $*" + + local repo repo_pre + repo=$1 + repo_pre="${repo}" + + # Change url to https/ssh + repo=$(_git_https_or_ssh "${repo}") + if [[ -z "${repo}" ]] + then + # shellcheck disable=SC2140 + tue-install-error "repo: '${repo}' is invalid. It is generated from: '${repo_pre}'\n"\ +"The problem will probably be solved by resourcing the setup" + fi + + local repos_dir eol + repos_dir=$(_git_url_to_repos_dir "${repo_pre}") + + # The shift here is to ensure that all options are explicitly checked as they can be at most 2 + # and are optional + shift + if [[ $# -gt 2 ]] + then + tue-install-error "Invalid number of arguments" + fi + + if [[ -n $1 ]] + then + for i in "$@" + do + case $i in + --target-dir=* ) + repos_dir="${i#*=}" + repos_dir="${repos_dir/#\~/$HOME}" + ;; + --eol=* ) + eol="${i#*=}" ;; + * ) + tue-install-error "Unknown input variable ${i}" ;; + esac + done + fi + + if [[ -z "${repos_dir}" ]] + then + tue-install-error "Repo directory path cannot be empty" + fi + + [[ -n "${TUE_ROS_VERSION}" ]] || tue-install-error "Environment variable 'TUE_ROS_VERSION' is not set." + + local ros_pkg_name + ros_pkg_name=${TUE_INSTALL_CURRENT_TARGET#ros-} + + local ros_pkg_dir + ros_pkg_dir="${ROS_PACKAGE_INSTALL_DIR}"/"${ros_pkg_name}" + + if [[ -e "${ros_pkg_dir}" ]] + then + tue-install-debug "Source package found in the workspace, removing it, so the system installed version is used" + tue-install-pipe rm "${ros_pkg_dir}" + + # Clean the package from the workspace + if [[ "${TUE_ROS_VERSION}" != "1" ]] + then + tue-install-pipe /usr/bin/python3 -m colcon clean packages --log-base "${TUE_WS_DIR}"/log --base-paths "${TUE_WS_DIR}"/src --build-base "${TUE_WS_DIR}"/build --install-base "${TUE_WS_DIR}"/install --packages-select "${ros_pkg_name}" -y + else + tue-install-pipe catkin clean --workspace "${TUE_WS_DIR}" --orphans + fi + else + tue-install-debug "Source package was already removed" + fi + + if [[ -n ${repos_dir} ]] && [[ -d ${repos_dir} ]] + then + links=$(find "${TUE_WS_DIR}"/src -lname "${repos_dir}*") + if [[ -n ${repos_dir} ]] && [[ -z ${links} ]] + then + tue-install-debug "No symlinks left to the repo or a sub-folder of it, deleting it" + tue-install-pipe rm -rf ${repos_dir} + else + tue-install-debug "Keeping the repo as there still exist symlinks to it in the workspace" + fi + else + tue-install-debug "Repo already removed" + fi + + # Warn about the eol of removing the source + local today_date eol_date + today_date=$(date +%s) + eol_date=$(date -d ${eol} +%s) + + if [[ ${today_date} -ge ${eol_date} ]] + then + tue-install-warning "The remove instruction of the source of the package '${ros_pkg_name}' has reached its end-of-life (${eol}). You should remove it from the target." + fi +} + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + function _missing_targets_check { tue-install-debug "_missing_targets_check $*"