A
wscommand for ROS 2 colcon workspaces. Build, clean, navigate, and inspect packages — without typing long paths or remembering colcon flags. Works with unsourced and uninstalled packages. No dependencies, pure bash.
ws build --all # build every detected workspace
ws build -w dev_ws -p my_pkg # build one package in a specific workspace
ws cd my_package # jump to a package's source directory
ws cd --install my_package # jump to its install prefix instead
ws clean -w dev_ws -p my_pkg # wipe build/install/log for a package
ws list -p # list all workspaces + packages + install status
ws open my_pkg # open package in VS Code (configurable)
ws which my_pkg my_launch.py # show source & install paths for a launch file
ws config set-build-args --symlink-install --continue-on-error
ws doctor # diagnose PATH, ROS env, colcon, config
ws update # git pull + reinstall in one commandWorkspaces are auto-detected from ROS_PACKAGE_PATH / COLCON_PREFIX_PATH. Fallback paths are configurable via WS_DEFAULT_WORKSPACES in ws_config.bash. Tab completion works everywhere.
git clone https://github.com/comrob/crl_ws_manager.git
cd crl_ws_manager
./install.sh
source ~/.bashrcinstall.sh:
- Symlinks all
bin/scripts into~/.local/bin/asws,ws-build, etc. - Symlinks
completion/ws_manager.bashinto~/.config/crl_ws_manager/ - Symlinks
lib/ws_lib.shinto~/.config/crl_ws_manager/for the sourced shell functions - Creates
~/.config/crl_ws_manager/ws_config.bashwith defaults (if absent) - Adds
~/.local/bintoPATHin~/.bashrcif missing - Adds a source block to
~/.bashrcto load shell functions on login - Also configures
~/.zshrcif your login shell is zsh
To uninstall, run ./install.sh --uninstall.
ws build [--all] [-w|--ws <workspace>]... [-p|--packages <pkg>]...
| Flag | Description |
|---|---|
-w / --ws |
Workspace root (name relative to $HOME, or absolute path); repeatable |
-p / --packages |
Package name passed to --packages-select; repeatable |
--all |
Build all detected workspaces |
--clean |
Wipe package artifacts before building |
ws build --all
ws build -w ros2_ws
ws build -w ros2_ws -p my_package
ws build -w ~/ros2_ws -p pkg_a -p pkg_b~/.bashrc is loaded first for ws commands, so the tool sees the same shell
environment you get in a normal terminal. If you want ws-specific overrides,
put them in ~/.config/crl_ws_manager/ws_env.bash and export them there.
See examples/ws_env.bash for a template.
ws config env-editUse this for variables like ROS_DOMAIN_ID, RMW_IMPLEMENTATION, or a source
line for your ROS underlay. The workspace config file is still the right place
for tool settings like build flags, editor commands, and fallback workspaces.
Load order is: ~/.bashrc -> ws_env.bash -> ws_config.bash.
Changes directory to a package's source tree or install prefix.
ws cd [--source|--install] [-s|--include-system] <package_name>
| Flag | Description |
|---|---|
--source |
Navigate to source directory in workspace src/ (default) |
--install / -i |
Navigate to the install prefix |
-s / --include-system |
Completion also includes system packages from ros2 pkg list |
roscd is an alias for ws cd.
ws cd liorf_slam_crl
ws cd --install liorf_slam_crl
ws cd -s <TAB> # completes with local + system packagesws list [-p|--packages] [-w|--ws <workspace>] [--installed] [-q|--quiet]
Lists detected workspaces; with -p also shows packages and install status.
ws open [--source|--install] <package_name>
Opens the package path in the configured editor. Configure via:
ws config set-editor code --reuse-windowConfig keys: WS_EDITOR_PROGRAM (default code), WS_EDITOR_ARGS (default empty).
ws which <package_name> [launchfile]
ws which <package_name> --launch <launchfile>
Shows source path, install prefix, and (optionally) launch file paths — including whether the installed launch file is a symlink and whether it resolves to the same file as the source.
ws clean [--clean-all] [-w|--ws <workspace>]... [-p|--packages <pkg>]... [<pkg>...]
Removes build/, install/, and log/ artifacts for selected packages or entire workspaces.
ws config [show|path|env-path|init|env-init|edit|env-edit|set-editor|set-build-program|set-build-subcommand|set-build-args|set-build-env-command|require-all]
ws config show
ws config edit
ws config env-edit
ws config set-editor code --reuse-window
ws config set-build-env-command jazzy_env
ws config set-build-args --symlink-install --continue-on-error
ws config require-all trueThe environment file is loaded before the workspace config file, so values you export there are visible to workspace discovery and command execution.
If you want the tool to run a shell hook automatically before env-dependent
commands, ws config set-build-env-command is still supported. Use it for
shell-function based setup such as jazzy_env.
To configure fallback workspaces:
# In ~/.config/crl_ws_manager/ws_config.bash:
WS_DEFAULT_WORKSPACES=(
"$HOME/ros2_ws"
"$HOME/dev_ws"
)See examples/ws_config.bash for a fully annotated template.
ws doctorChecks all prerequisites and reports any problems:
wsand all subcommand binaries onPATH- Config file present
- Shell functions file present
ROS_DISTROsetcolconavailable- At least one workspace detected
ws updateRuns git pull in the repository root and re-runs install.sh.
Requires the tool to have been installed from a git clone.
ws --version
ws versionPrints the installed version string from the VERSION file.
Lower-level executable used by the ws cd shell function. Prints the resolved path to stdout — useful in scripts.
ws-cd-resolve my_package # prints source dir
ws-cd-resolve --install my_pkg # prints install prefixRegistered automatically when ~/.config/crl_ws_manager/ws_manager.bash is sourced.
| Context | Completes |
|---|---|
ws <TAB> |
build, clean, cd, list, open, config, help |
ws build -p <TAB> |
Package names from active workspace src/ directories |
ws build -w <TAB> |
Detected workspace names or path completion |
ws cd <TAB> |
Package names from active workspace src/ directories |
ws cd -s <TAB> |
Package names including system packages (ros2 pkg list) |
ws open <TAB> |
Package names from active workspace src/ directories |
ws which <TAB> |
Package names from active workspace src/ directories |
ws which <pkg> <TAB> |
Installed launch files for <pkg> |
Workspaces are detected dynamically — no paths are hardcoded. Completion does not require the workspace or package to be sourced or installed.
To run the full Bats test suite:
make testThe Bats suite is split into one file per command under tests/bats/:
| File | Command | What it covers |
|---|---|---|
ws_manager_cmd.bats |
ws main dispatcher |
--version, cd --help, shell wrapper delegation |
ws_build_cmd.bats |
ws build |
help output, duplicate package → both workspaces built |
ws_clean_cmd.bats |
ws clean |
help output, duplicate package → both workspaces cleaned |
ws_cd_resolve_cmd.bats |
ws cd / ws-cd-resolve |
source/install resolution, symlink source, duplicate package order |
ws_list_cmd.bats |
ws list |
quiet-mode symlink metadata, --installed filter |
ws_open_cmd.bats |
ws open |
symlink source path, not-installed error, launch artifact |
ws_config_cmd.bats |
ws config |
idempotent set-build-program, set-editor with args |
ws_which_cmd.bats |
ws which |
machine-mode symlink metadata, launch completion fallback |
A shared helper (tests/bats/test_helper.bash) provides make_pkg, make_pkg_at, and set_test_editor_echo used across suites.
For quick local validation (same flow as CI):
make ci-localci-local runs in an isolated fixture root under /tmp/ws_manager_ci_local and uses a temporary HOME inside that root. You can override this root with:
WS_CI_TMP_ROOT=/tmp/my_ws_ci_fixture make ci-localThis runs:
- shell syntax checks
- install smoke
- command smoke (
ws --version,ws build --help,ws-cd-resolve --help,ws doctor) - Bats tests
- uninstall smoke
Works with any installed ROS 2 distro (Humble, Iron, Jazzy, Kilted, Rolling, etc.).
The tool reads $ROS_DISTRO at runtime — no distro-specific configuration is required or assumed.
ws build sources /opt/ros/$ROS_DISTRO/setup.bash when that file exists and ROS_DISTRO is set;
all other commands (ws cd, ws list, ws which, ws open, ws config) work without any ROS
environment sourced.
If you use ws_manager in your research, please cite it:
@software{ws_manager,
author = {Hulchuk, Vsevolod},
title = {ws\_manager: A workspace manager for ROS 2 colcon workspaces},
year = {2026},
url = {https://github.com/comrob/crl_ws_manager},
license = {MIT}
}A CITATION.cff file is also provided for automatic citation tools (GitHub "Cite this repository" button, Zenodo, etc.).
MIT © 2026 Computational Robotics Lab (CRL), Czech Technical University in Prague