From 888c3f3c5a9f031de241efbe0caac4a518f36541 Mon Sep 17 00:00:00 2001 From: Malte Brunnlieb Date: Tue, 7 Jul 2026 09:47:58 +0200 Subject: [PATCH] #1808: do not report a workspace when icd navigates to the project root --- CHANGELOG.adoc | 1 + cli/src/main/package/bin/ide.bat | 18 ++++- cli/src/main/package/functions | 6 +- cli/src/test/functions-test.sh | 125 ++++++++++++++++++++++++++++++- documentation/cli.adoc | 4 +- documentation/features.adoc | 2 +- 6 files changed, 147 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 3450719c05..5a13fc66e3 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -17,6 +17,7 @@ Release with new features and bugfixes: * https://github.com/devonfw/IDEasy/issues/1227[#1227]: Added Setup instrcutions to the Windows installer * https://github.com/devonfw/IDEasy/issues/2114[#2114]: Fix false "Cygwin is not supported" warning in Git Bash * https://github.com/devonfw/IDEasy/issues/865[#865]: az not working on Mac +* https://github.com/devonfw/IDEasy/issues/1808[#1808]: Do not report a workspace when `icd` navigates to the project root The full list of changes for this release can be found in https://github.com/devonfw/IDEasy/milestone/46?closed=1[milestone 2026.07.001]. diff --git a/cli/src/main/package/bin/ide.bat b/cli/src/main/package/bin/ide.bat index 9eb19eda22..6639bdd47e 100644 --- a/cli/src/main/package/bin/ide.bat +++ b/cli/src/main/package/bin/ide.bat @@ -44,14 +44,26 @@ for /f "tokens=*" %%i in ('"ideasy %IDE_OPTIONS% env"') do ( ideasy %IDE_OPTIONS% env >nul if %ERRORLEVEL% EQU 0 ( - if "%~1" == "" ( - echo IDE environment variables have been set for %IDE_HOME% in workspace %WORKSPACE% - ) + if "%~1" == "" call :printIdeHomeMessage ) call :echoUseBash goto :eof +REM prints the "environment variables have been set" line. Only mention the workspace when the +REM current directory is actually inside one; at the project root no workspace is reported (see #1808) +:printIdeHomeMessage + setlocal enabledelayedexpansion + set "_IDE_CWD=!CD!" + if defined WORKSPACE_PATH if not "!_IDE_CWD:%WORKSPACE_PATH%=!" == "!_IDE_CWD!" ( + endlocal + echo IDE environment variables have been set for %IDE_HOME% in workspace %WORKSPACE% + exit /b + ) + endlocal + echo IDE environment variables have been set for %IDE_HOME% + exit /b + :handleCreateCd if "%~1" == "" exit /b if "%~1" == "create" goto :findCreateProject diff --git a/cli/src/main/package/functions b/cli/src/main/package/functions index 3bf1cfd4cd..172c1cfb0e 100644 --- a/cli/src/main/package/functions +++ b/cli/src/main/package/functions @@ -42,7 +42,11 @@ function ide() { if [ $? = 0 ]; then eval "${ide_env}" if [ $# = 0 ] && [ -n "${IDE_HOME}" ]; then - echo "IDE environment variables have been set for ${IDE_HOME} in workspace ${WORKSPACE}" + if [ -n "${WORKSPACE_PATH}" ] && [ "${PWD#"${WORKSPACE_PATH}"}" != "${PWD}" ]; then + echo "IDE environment variables have been set for ${IDE_HOME} in workspace ${WORKSPACE}" + else + echo "IDE environment variables have been set for ${IDE_HOME}" + fi fi fi if _ide_is_cygwin && [ "$#" != 0 ]; then diff --git a/cli/src/test/functions-test.sh b/cli/src/test/functions-test.sh index 64a3026597..8c9f129222 100644 --- a/cli/src/test/functions-test.sh +++ b/cli/src/test/functions-test.sh @@ -18,13 +18,46 @@ source "${SCRIPT_DIR}/all-tests-functions.sh" STUB_DIR="$(mktemp -d)" trap 'rm -rf "${STUB_DIR}"' EXIT -# minimal fake "ideasy" binary so sourcing the functions file has no side effects +# fake "ideasy" binary. For the "env" subcommand it derives IDE_HOME, WORKSPACE and WORKSPACE_PATH +# from the current directory just like the real binary would, so that the icd message tests below +# can observe the project-root vs workspace behavior. For anything else it is a no-op. cat > "${STUB_DIR}/ideasy" <<'EOS' #!/usr/bin/env bash +case "$*" in + *env*) + home="" + dir="${PWD}" + while [ -n "${dir}" ] && [ "${dir}" != "/" ]; do + if [ -d "${dir}/workspaces" ] && [ -d "${dir}/settings" ]; then + home="${dir}" + break + fi + dir="$(dirname "${dir}")" + done + if [ -n "${home}" ]; then + workspace="main" + relative="${PWD#"${home}/"}" + if [ "${relative}" != "${PWD}" ]; then + case "${relative}" in + workspaces/*) + workspace="${relative#workspaces/}" + workspace="${workspace%%/*}" + ;; + esac + fi + echo "IDE_HOME=${home}" + echo "WORKSPACE=${workspace}" + echo "WORKSPACE_PATH=${home}/workspaces/${workspace}" + fi + ;; +esac exit 0 EOS chmod +x "${STUB_DIR}/ideasy" -mkdir -p "${STUB_DIR}/root" +# fake IDEasy project so the stub above recognizes it as an IDE_HOME +mkdir -p "${STUB_DIR}/root/project/settings" +mkdir -p "${STUB_DIR}/root/project/workspaces/main" +mkdir -p "${STUB_DIR}/root/project/workspaces/foo" total=0 failed=0 @@ -63,6 +96,94 @@ check() { fi } +# runIcd : sources the functions file in a fresh shell, exports +# IDE_ROOT (and IDE_HOME if given) and prints the output of "icd ". +runIcd() { + local initial_home="$1" + shift + # strip any inherited IDEasy state (and BASH_ENV, which may re-initialize it) so the test is hermetic + FUNCTIONS_FILE="${FUNCTIONS_FILE}" STUB_DIR="${STUB_DIR}" INITIAL_HOME="${initial_home}" \ + env -u IDE_HOME -u WORKSPACE -u WORKSPACE_PATH -u IDE_OPTIONS -u BASH_ENV \ + bash --noprofile --norc -c ' + export PATH="${STUB_DIR}:${PATH}" + export IDE_ROOT="${STUB_DIR}/root" + cygpath() { echo "${@: -1}"; } + # source from the (project-less) IDE_ROOT so the "ide" call at the end of the functions file + # does not pick up a surrounding IDEasy project, then set the desired state for the test. + cd "${IDE_ROOT}" || exit 1 + source "${FUNCTIONS_FILE}" >/dev/null 2>&1 + unset IDE_HOME WORKSPACE WORKSPACE_PATH + [ -n "${INITIAL_HOME}" ] && export IDE_HOME="${INITIAL_HOME}" + icd "$@" 2>&1 + ' _ "$@" +} + +# checkIcdInWorkspace +checkIcdInWorkspace() { + local description="$1" expected="$2" initial_home="$3" + shift 3 + total=$((total + 1)) + local output + output="$(runIcd "${initial_home}" "$@")" + if echo "${output}" | grep -qF "${expected}"; then + doSuccess "PASSED: ${description}" + else + doError "FAILED: ${description} - expected to contain '${expected}' but was '${output}'" + failed=$((failed + 1)) + fi +} + +# checkIcdProjectRoot : asserts the message reports the +# project home without mentioning any workspace (see #1808). +checkIcdProjectRoot() { + local description="$1" initial_home="$2" + shift 2 + total=$((total + 1)) + local output + output="$(runIcd "${initial_home}" "$@")" + if echo "${output}" | grep -qF "have been set for" && ! echo "${output}" | grep -q "workspace"; then + doSuccess "PASSED: ${description}" + else + doError "FAILED: ${description} - expected a project-root message without any workspace but was '${output}'" + failed=$((failed + 1)) + fi +} + +# checkIcdNoSetup : asserts that no environment is set +# up and no "have been set" message is printed (icd only navigates to the projects root, see #1808). +checkIcdNoSetup() { + local description="$1" initial_home="$2" + shift 2 + total=$((total + 1)) + local output + output="$(runIcd "${initial_home}" "$@")" + if ! echo "${output}" | grep -q "have been set"; then + doSuccess "PASSED: ${description}" + else + doError "FAILED: ${description} - expected no environment setup message but was '${output}'" + failed=$((failed + 1)) + fi +} + +echo "Testing project-root vs workspace message via icd in ${FUNCTIONS_FILE}" + +# icd -p navigates to the project root, so the message must not mention any workspace at all (see #1808) +checkIcdProjectRoot "icd -p project reports the project home without any workspace" \ + "" -p project +# icd -p -w navigates into the (default main) workspace, so the established "in workspace " wording is kept +checkIcdInWorkspace "icd -p project -w reports 'in workspace main'" \ + "in workspace main" "" -p project -w +# icd -p -w navigates into the named workspace +checkIcdInWorkspace "icd -p project -w foo reports 'in workspace foo'" \ + "in workspace foo" "" -p project -w foo +# inside a project, bare icd jumps to IDE_HOME (the project root), so it must not mention any workspace +checkIcdProjectRoot "icd (no args, inside a project) reports the project home without any workspace" \ + "${STUB_DIR}/root/project" +# outside any project, bare icd only navigates to IDE_ROOT (the projects root) without any env setup or message +checkIcdNoSetup "icd (no args, no project) navigates to the projects root without any setup message" \ + "" + +echo echo "Testing Cygwin warning detection in ${FUNCTIONS_FILE}" # genuine Cygwin -> warning is intended diff --git a/documentation/cli.adoc b/documentation/cli.adoc index b82fddb404..d76999ee24 100644 --- a/documentation/cli.adoc +++ b/documentation/cli.adoc @@ -18,7 +18,7 @@ In case you are not inside of a `IDEasy` folder the command will echo a message You are not inside an IDEasy installation: / [~]$ cd projects/my-project/workspaces/test/my-git-repo [my-git-repo]$ ide -IDEasy environment variables have been set for /projects/my-project in workspace main +IDEasy environment variables have been set for /projects/my-project in workspace test [my-git-repo]$ echo $IDE_HOME ~/projects/my-project [my-git-repo]$ echo $JAVA_HOME @@ -129,6 +129,6 @@ IDE environment variables have been set for /~/projects/myproject in workspace m [~/projects/myproject/workspaces/myworkspace]$ cd myrepo/mymodule/src/main/java/com/foo/bar/some/path [.../some/path]$ echo "do something here but now I want to go back to my project root dir" [.../some/path]$ icd -IDE environment variables have been set for /~/projects/myproject in workspace main +IDE environment variables have been set for /~/projects/myproject [~/projects/myproject]$ echo "Wow! IDEasy is awesome!" ``` diff --git a/documentation/features.adoc b/documentation/features.adoc index 46d5eb7b2e..834f5748f3 100644 --- a/documentation/features.adoc +++ b/documentation/features.adoc @@ -66,7 +66,7 @@ Here are some examples with `IDEasy`: [cool-project]$ mvn command not found: mvn [cool-project]$ ide -Environment variables have been set for ~/projects/cool-project in workspace main +Environment variables have been set for ~/projects/cool-project [devonfw]$ mvn -v Apache Maven 3.9.9 (8e8579a9e76f7d015ee5ec7bfcdc97d260186937) Maven home: ~/projects/cool-project/software/mvn