Skip to content

#218: add possibility to start a command in a new window with the process builder - #2239

Open
samuelkos17 wants to merge 4 commits into
devonfw:mainfrom
samuelkos17:feature/218-add-possibility-to-start-a-command-in-a-new-window-with-the-process-builder
Open

#218: add possibility to start a command in a new window with the process builder#2239
samuelkos17 wants to merge 4 commits into
devonfw:mainfrom
samuelkos17:feature/218-add-possibility-to-start-a-command-in-a-new-window-with-the-process-builder

Conversation

@samuelkos17

@samuelkos17 samuelkos17 commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

This PR fixes #218

Implemented changes:

  • Added a new ProcessMode#BACKGROUND_NEW_WINDOW mode that starts a command in a new terminal window while detaching it from the parent process.
  • Implemented platform-specific new-window command builders in ProcessContextImpl:
    • Linux: Detects available terminal emulators (gnome-terminal, konsole, xfce4-terminal, tilix, alacritty, xterm, x-terminal-emulator) and uses the correct flag syntax for each, with a disown fallback when no terminal emulator is available.
    • macOS: Uses osascript to launch a new Terminal.app or iTerm2 window via AppleScript.
    • Windows: Uses cmd.exe /c start to open a new CMD window.
  • Added launchesNewWindow() method to ProcessMode to check whether the mode should launch a process in a new window.
  • Updated isBackground() to include the new BACKGROUND_NEW_WINDOW mode.
  • Added comprehensive tests in BackgroundNewWindowTest.java:
    • Structural (mock-based) tests for each platform verifying the generated command shape.
    • E2E tests for each platform using a marker-file polling approach to verify the subprocess actually executes.
    • Windows/macOS E2E tests skip in CI (windows would leak in headless CI runners); Linux E2E runs in CI via the disown fallback.

Testing instructions

  1. Run mvn clean test — all tests should pass, including the 10 new tests in BackgroundNewWindowTest.java.
  2. Pay special attention to the E2E tests on your platform:
    • Windows: backgroundNewWindowShouldActuallyExecuteViaStartOnWindows — observe a new CMD window opening.
    • macOS: backgroundNewWindowShouldActuallyExecuteViaOsascriptOnMac — observe a new Terminal.app (or iTerm2) window opening.
    • Linux: backgroundNewWindowShouldActuallyExecuteOnLinux — observe a new terminal window opening (if a desktop environment is available), or the test passing via the disown fallback in headless environments.
    • These E2E tests are opening new windows that might not close by themselves, this is intentional and made so that we can verify that a new window opens on each of the three OS. Before merging this I intend to either change or completly remove them since we don't want to have terminal windows opening on our local dev environments every time we run tests. (I would be happy for suggestions on how to change them)

Checklist for this PR

Make sure everything is checked before merging this PR. For further info please also see
our DoD.

  • When running mvn clean test locally all tests pass and build is successful
  • PR title is of the form #«issue-id»: «brief summary» (e.g. #921: fixed setup.bat). If no issue ID exists, title only.
  • PR top-level comment summarizes what has been done and contains link to addressed issue(s)
  • PR and issue(s) have suitable labels
  • Issue is set to In Progress and assigned to you or there is no issue (might happen for very small PRs)
  • You followed all coding conventions
  • You have added the issue implemented by your PR in CHANGELOG.adoc unless issue is labeled
    with internal
  • You have formulated clear instructions on how to test your contribution under "Testing instructions"

@github-project-automation github-project-automation Bot moved this to 🆕 New in IDEasy board Jul 31, 2026
@samuelkos17 samuelkos17 self-assigned this Jul 31, 2026
@samuelkos17 samuelkos17 moved this from 🆕 New to Team Review in IDEasy board Jul 31, 2026
@samuelkos17 samuelkos17 added enhancement New feature or request process executing external programs (ProcessContext) labels Jul 31, 2026
@coveralls

Copy link
Copy Markdown
Collaborator

Coverage Report for CI Build 30622595516

Coverage decreased (-0.1%) to 72.527%

Details

  • Coverage decreased (-0.1%) from the base build.
  • Patch coverage: No coverable lines changed in this PR.
  • 72 coverage regressions across 2 files.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

72 previously-covered lines in 2 files lost coverage.

File Lines Losing Coverage Coverage
com/devonfw/tools/ide/process/ProcessContextImpl.java 69 68.85%
com/devonfw/tools/ide/process/ProcessMode.java 3 91.43%

Coverage Stats

Coverage Status
Relevant Lines: 17357
Covered Lines: 13123
Line Coverage: 75.61%
Relevant Branches: 7697
Covered Branches: 5048
Branch Coverage: 65.58%
Branches in Coverage %: Yes
Coverage Strength: 3.21 hits per line

💛 - Coveralls

@Ali-Shariati-Najafabadi Ali-Shariati-Najafabadi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice approach overall, but I ran this locally and found a few things.

cli/src/test/resources/process-context/write-marker.sh
Root cause of the above, needs chmod +x before committing.

cli/src/test/java/com/devonfw/tools/ide/process/BackgroundNewWindowTest.java:218, :267, :319
The three "actually execute" E2E tests only skip in CI, not on a normal local run, so anyone running mvn clean test on Windows/Mac gets a CMD or Terminal window popping up. You called this out yourself in the PR description as a TODO, just don't want it to slip through review. Might be worth gating them behind a system property; the structural/mocked tests already cover the command shape fine on their own.

Comment thread CHANGELOG.adoc
* https://github.com/devonfw/IDEasy/issues/1917[#1917]: Allow the creation of a desktop shortcut for the GUI
* https://github.com/devonfw/IDEasy/issues/2134[#2134]: Add auto-completion for icd command
* https://github.com/devonfw/IDEasy/issues/2145[#2145]: Improve documentation on symlink regarding ide ln
* https://github.com/devonfw/IDEasy/issues/2145[#218]: Added possibility to start a command in a new window using the process builder

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CHANGELOG.adoc:17
Wrong issue link (points to #2145 instead of #218):

Suggested change
* https://github.com/devonfw/IDEasy/issues/2145[#218]: Added possibility to start a command in a new window using the process builder
* https://github.com/devonfw/IDEasy/issues/218[#218]: Added possibility to start a command in a new window using the process builder

s -> assertThat(s).contains("Terminal"));
// Should NOT fall back to plain disown anymore
assertThat(bashCommand).as("Bash command should NOT contain disown on macOS (has terminal support)")
.doesNotContain("disown");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This asserts the mac command shouldn't contain disown, but it does. ProcessContextImpl always appends ; disown for new-window mode regardless of OS (see ProcessContextImpl.java:454), so the test's just wrong about what the code actually does. Ran it locally, fails every time.


# Writes a marker to stdout — used to verify background processes actually execute.
# The caller should provide $1 as the marker file path.
echo "background-process-ran" > "$1" No newline at end of file

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cli/src/test/resources/process-context/write-marker.sh
Root cause of the above needs chmod +x before committing.

}

// Quote unconditionally and escape cmd.exe metacharacters
String escaped = value.replace("^", "^^").replace("%", "%%").replace("\"", "\\\"");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cli/src/main/java/com/devonfw/tools/ide/process/ProcessContextImpl.java:580
windowsQuote() escapes ^, %, " but not &, |, <, >, which cmd.exe treats as operators even inside quotes sometimes. Worth a test with & or | in an argument. Also doubling % to %% only works inside .bat files, not on a plain cmd /c line.

assert processMode.isBackground() : "Cannot handle non background process mode!";
String commandToRunInBackground = buildCommand(args);

if (this.context.getSystemInfo().isWindows()) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This routes all background modes through cmd.exe /c start on Windows now, not just the new one. Before this PR, BACKGROUND/BACKGROUND_SILENT on Windows went through git-bash. That's a real behavior change for existing callers (Eclipse, Gui, IdeToolCommandlet, Tomcat, the IdeasyCommandlet self-update cleanup that runs sleep 10 && rm -rf ...) with no tests for the new Windows path. Intentional? If yes, worth a test; if not, maybe keep those on the old bash path.

Comment on lines +319 to +342
void backgroundNewWindowShouldActuallyExecuteViaOsascriptOnMac() throws Exception {
// arrange
if (isCiEnvironment()) {
return; // Skip — opening a terminal window would leak in CI
}
IdeTestContext context = newContext(PROJECT_BASIC, null, false);
if (context.findBash() == null) {
return; // Skip when no bash is available
}

// Verify osascript is available (required for Terminal.app / iTerm2 AppleScript)
if (!isOsascriptAvailable()) {
// Skip - no GUI session or osascript not available (e.g. headless CI)
return;
}

Path markerFile = Files.createTempFile("bg-marker-mac-", ".txt");
Files.delete(markerFile); // Remove so polling can detect when the script creates it
Path scriptPath = TEST_RESOURCES.resolve("process-context").resolve("write-marker.sh");

ProcessContextImpl processContext = new ProcessContextImpl(context);
// act
ProcessResult result = processContext.executable(scriptPath).addArg(markerFile.toString())
.run(ProcessMode.BACKGROUND_NEW_WINDOW);

@Ali-Shariati-Najafabadi Ali-Shariati-Najafabadi Aug 3, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blows up with End of answers reached! at line 342. write-marker.sh got committed without the executable bit, so IDEasy prompts to chmod it and this test never answers that prompt,unlike the Linux test at BackgroundNewWindowTest.java:276, which does context.setAnswers("1"). Missing that here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request process executing external programs (ProcessContext)

Projects

Status: Team Review

Development

Successfully merging this pull request may close these issues.

Add possibility to start a command in a new window with the process builder

3 participants