• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

devonfw / IDEasy / 19640865660

24 Nov 2025 04:05PM UTC coverage: 69.024% (+0.1%) from 68.924%
19640865660

push

github

web-flow
#1561: Fix BASH_PATH not used properly (#1577)

Co-authored-by: Jörg Hohwiller <hohwille@users.noreply.github.com>

3562 of 5651 branches covered (63.03%)

Branch coverage included in aggregate %.

9262 of 12928 relevant lines covered (71.64%)

3.15 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

77.69
cli/src/main/java/com/devonfw/tools/ide/context/IdeContext.java
1
package com.devonfw.tools.ide.context;
2

3
import java.nio.file.Files;
4
import java.nio.file.Path;
5

6
import com.devonfw.tools.ide.cli.CliAbortException;
7
import com.devonfw.tools.ide.cli.CliException;
8
import com.devonfw.tools.ide.cli.CliOfflineException;
9
import com.devonfw.tools.ide.commandlet.CommandletManager;
10
import com.devonfw.tools.ide.common.SystemPath;
11
import com.devonfw.tools.ide.environment.EnvironmentVariables;
12
import com.devonfw.tools.ide.environment.EnvironmentVariablesType;
13
import com.devonfw.tools.ide.environment.IdeSystem;
14
import com.devonfw.tools.ide.git.GitContext;
15
import com.devonfw.tools.ide.io.FileAccess;
16
import com.devonfw.tools.ide.io.IdeProgressBar;
17
import com.devonfw.tools.ide.io.IdeProgressBarNone;
18
import com.devonfw.tools.ide.log.IdeLogLevel;
19
import com.devonfw.tools.ide.merge.DirectoryMerger;
20
import com.devonfw.tools.ide.network.NetworkStatus;
21
import com.devonfw.tools.ide.os.SystemInfo;
22
import com.devonfw.tools.ide.os.WindowsPathSyntax;
23
import com.devonfw.tools.ide.process.ProcessContext;
24
import com.devonfw.tools.ide.step.Step;
25
import com.devonfw.tools.ide.tool.corepack.Corepack;
26
import com.devonfw.tools.ide.tool.gradle.Gradle;
27
import com.devonfw.tools.ide.tool.mvn.Mvn;
28
import com.devonfw.tools.ide.tool.npm.Npm;
29
import com.devonfw.tools.ide.tool.repository.CustomToolRepository;
30
import com.devonfw.tools.ide.tool.repository.MvnRepository;
31
import com.devonfw.tools.ide.tool.repository.NpmRepository;
32
import com.devonfw.tools.ide.tool.repository.ToolRepository;
33
import com.devonfw.tools.ide.url.model.UrlMetadata;
34
import com.devonfw.tools.ide.variable.IdeVariables;
35
import com.devonfw.tools.ide.version.IdeVersion;
36
import com.devonfw.tools.ide.version.VersionIdentifier;
37

38
/**
39
 * Interface for interaction with the user allowing to input and output information.
40
 */
41
public interface IdeContext extends IdeStartContext {
42

43
  /**
44
   * The default settings URL.
45
   *
46
   * @see com.devonfw.tools.ide.commandlet.AbstractUpdateCommandlet
47
   */
48
  String DEFAULT_SETTINGS_REPO_URL = "https://github.com/devonfw/ide-settings.git";
49

50
  /** The name of the workspaces folder. */
51
  String FOLDER_WORKSPACES = "workspaces";
52

53
  /** The name of the {@link #getSettingsPath() settings} folder. */
54
  String FOLDER_SETTINGS = "settings";
55

56
  /** The name of the {@link #getSoftwarePath() software} folder. */
57
  String FOLDER_SOFTWARE = "software";
58

59
  /** The name of the {@link #getUrlsPath() urls} folder. */
60
  String FOLDER_URLS = "urls";
61

62
  /** The name of the conf folder for project specific user configurations. */
63
  String FOLDER_CONF = "conf";
64

65
  /**
66
   * The name of the folder inside IDE_ROOT reserved for IDEasy. Intentionally starting with an underscore and not a dot to prevent effects like OS hiding,
67
   * maven filtering, .gitignore and to distinguish from {@link #FOLDER_DOT_IDE}.
68
   *
69
   * @see #getIdePath()
70
   */
71
  String FOLDER_UNDERSCORE_IDE = "_ide";
72

73
  /**
74
   * The name of the folder inside {@link #FOLDER_UNDERSCORE_IDE} with the current IDEasy installation.
75
   *
76
   * @see #getIdeInstallationPath()
77
   */
78
  String FOLDER_INSTALLATION = "installation";
79

80
  /**
81
   * The name of the hidden folder for IDE configuration in the users home directory or status information in the IDE_HOME directory.
82
   *
83
   * @see #getUserHomeIde()
84
   */
85
  String FOLDER_DOT_IDE = ".ide";
86

87
  /** The name of the updates folder for temporary data and backup. */
88
  String FOLDER_UPDATES = "updates";
89

90
  /** The name of the volume folder for mounting archives like *.dmg. */
91
  String FOLDER_VOLUME = "volume";
92

93
  /** The name of the backups folder for backup. */
94
  String FOLDER_BACKUPS = "backups";
95

96
  /** The name of the downloads folder. */
97
  String FOLDER_DOWNLOADS = "Downloads";
98

99
  /** The name of the bin folder where executable files are found by default. */
100
  String FOLDER_BIN = "bin";
101

102
  /** The name of the repositories folder where properties files are stores for each repository */
103
  String FOLDER_REPOSITORIES = "repositories";
104

105
  /** The name of the repositories folder where properties files are stores for each repository */
106
  String FOLDER_LEGACY_REPOSITORIES = "projects";
107

108
  /** The name of the Contents folder inside a MacOS app. */
109
  String FOLDER_CONTENTS = "Contents";
110

111
  /** The name of the Resources folder inside a MacOS app. */
112
  String FOLDER_RESOURCES = "Resources";
113

114
  /** The name of the app folder inside a MacOS app. */
115
  String FOLDER_APP = "app";
116

117
  /** The name of the extra folder inside the software folder */
118
  String FOLDER_EXTRA = "extra";
119

120
  /**
121
   * The name of the {@link #getPluginsPath() plugins folder} and also the plugins folder inside the IDE folders of {@link #getSettingsPath() settings} (e.g.
122
   * settings/eclipse/plugins).
123
   */
124
  String FOLDER_PLUGINS = "plugins";
125

126
  /**
127
   * The name of the workspace folder inside the IDE specific {@link #FOLDER_SETTINGS settings} containing the configuration templates in #FOLDER_SETUP
128
   * #FOLDER_UPDATE.
129
   */
130
  String FOLDER_WORKSPACE = "workspace";
131

132
  /**
133
   * The name of the setup folder inside the {@link #FOLDER_WORKSPACE workspace} folder containing the templates for the configuration templates for the initial
134
   * setup of a workspace. This is closely related with the {@link #FOLDER_UPDATE update} folder.
135
   */
136
  String FOLDER_SETUP = "setup";
137

138
  /**
139
   * The name of the update folder inside the {@link #FOLDER_WORKSPACE workspace} folder containing the templates for the configuration templates for the update
140
   * of a workspace. Configurations in this folder will be applied every time the IDE is started. They will override the settings the user may have manually
141
   * configured every time. This is only for settings that have to be the same for every developer in the project. An example would be the number of spaces used
142
   * for indentation and other code-formatting settings. If all developers in a project team use the same formatter settings, this will actively prevent
143
   * diff-wars. However, the entire team needs to agree on these settings.<br> Never configure aspects inside this update folder that may be of personal flavor
144
   * such as the color theme. Otherwise developers will hate you as you actively take away their freedom to customize the IDE to their personal needs and
145
   * wishes. Therefore do all "biased" or "flavored" configurations in {@link #FOLDER_SETUP setup} so these are only pre-configured but can be changed by the
146
   * user as needed.
147
   */
148
  String FOLDER_UPDATE = "update";
149

150
  /**
151
   * The name of the folder inside {@link #FOLDER_UNDERSCORE_IDE _ide} folder containing internal resources and scripts of IDEasy.
152
   */
153
  String FOLDER_INTERNAL = "internal";
154

155
  /** The file where the installed software version is written to as plain text. */
156
  String FILE_SOFTWARE_VERSION = ".ide.software.version";
157

158
  /** The file where the installed software version is written to as plain text. */
159
  String FILE_LEGACY_SOFTWARE_VERSION = ".devon.software.version";
160

161
  /** The file for the license agreement. */
162
  String FILE_LICENSE_AGREEMENT = ".license.agreement";
163

164
  /** The file extension for a {@link java.util.Properties} file. */
165
  String EXT_PROPERTIES = ".properties";
166

167
  /** The default for {@link #getWorkspaceName()}. */
168
  String WORKSPACE_MAIN = "main";
169

170
  /** The folder with the configuration template files from the settings. */
171
  String FOLDER_TEMPLATES = "templates";
172

173
  /** Legacy folder name used as compatibility fallback if {@link #FOLDER_TEMPLATES} does not exist. */
174
  String FOLDER_LEGACY_TEMPLATES = "devon";
175

176
  /** The default folder name for {@link #getIdeRoot() IDE_ROOT}. */
177
  String FOLDER_PROJECTS = "projects";
178

179
  /** The filename of the configuration file in the settings for this {@link CustomToolRepository}. */
180
  String FILE_CUSTOM_TOOLS = "ide-custom-tools.json";
181

182
  /**
183
   * file containing the current local commit hash of the settings repository.
184
   */
185
  String SETTINGS_COMMIT_ID = ".commit.id";
186

187
  /** The IDEasy ASCII logo. */
188
  String LOGO = """
4✔
189
      __       ___ ___  ___
190
      ╲ ╲     |_ _|   ╲| __|__ _ ____ _
191
       > >     | || |) | _|/ _` (_-< || |
192
      /_/ ___ |___|___/|___╲__,_/__/╲_, |
193
         |___|                       |__/
194
      """.replace('╲', '\\');
2✔
195

196
  /**
197
   * The keyword for project name convention.
198
   */
199
  String SETTINGS_REPOSITORY_KEYWORD = "settings";
200
  String IS_NOT_INSTALLED_BUT_REQUIRED = "is not installed on your computer but required by IDEasy.";
201
  String WINDOWS_GIT_DOWNLOAD_URL = "https://git-scm.com/download/";
202
  String PLEASE_DOWNLOAD_AND_INSTALL_GIT = "Please download and install git";
203

204
  /**
205
   * @return the {@link NetworkStatus} for online check and related operations.
206
   */
207
  NetworkStatus getNetworkStatus();
208

209
  /**
210
   * @return {@code true} if {@link #isOfflineMode() offline mode} is active or we are NOT {@link #isOnline() online}, {@code false} otherwise.
211
   * @deprecated use {@link #getNetworkStatus()}
212
   */
213
  default boolean isOffline() {
214

215
    return getNetworkStatus().isOffline();
4✔
216
  }
217

218
  /**
219
   * @return {@code true} if we are currently online (Internet access is available), {@code false} otherwise.
220
   * @deprecated use {@link #getNetworkStatus()}
221
   */
222
  default boolean isOnline() {
223

224
    return getNetworkStatus().isOnline();
×
225
  }
226

227
  /**
228
   * Print the IDEasy {@link #LOGO logo}.
229
   */
230
  default void printLogo() {
231

232
    info(LOGO);
3✔
233
  }
1✔
234

235
  /**
236
   * Asks the user for a single string input.
237
   *
238
   * @param message The information message to display.
239
   * @param defaultValue The default value to return when no input is provided or {@code null} to keep asking until the user entered a non empty value.
240
   * @return The string input from the user, or the default value if no input is provided.
241
   */
242
  String askForInput(String message, String defaultValue);
243

244
  /**
245
   * Asks the user for a single string input.
246
   *
247
   * @param message The information message to display.
248
   * @return The string input from the user.
249
   */
250
  default String askForInput(String message) {
251
    return askForInput(message, null);
5✔
252
  }
253

254
  /**
255
   * @param question the question to ask.
256
   * @param args arguments for filling the templates
257
   * @return {@code true} if the user answered with "yes", {@code false} otherwise ("no").
258
   */
259
  default boolean question(String question, Object... args) {
260

261
    String yes = "yes";
2✔
262
    String option = question(new String[] { yes, "no" }, question, args);
16✔
263
    if (yes.equals(option)) {
4!
264
      return true;
2✔
265
    }
266
    return false;
×
267
  }
268

269
  /**
270
   * @param <O> type of the option. E.g. {@link String}.
271
   * @param options the available options for the user to answer. There should be at least two options given as otherwise the question cannot make sense.
272
   * @param question the question to ask.
273
   * @return the option selected by the user as answer.
274
   */
275
  @SuppressWarnings("unchecked")
276
  <O> O question(O[] options, String question, Object... args);
277

278
  /**
279
   * Will ask the given question. If the user answers with "yes" the method will return and the process can continue. Otherwise if the user answers with "no" an
280
   * exception is thrown to abort further processing.
281
   *
282
   * @param questionTemplate the yes/no question to {@link #question(String, Object...) ask}.
283
   * @param args the arguments to fill the placeholders in the question template.
284
   * @throws CliAbortException if the user answered with "no" and further processing shall be aborted.
285
   */
286
  default void askToContinue(String questionTemplate, Object... args) {
287
    boolean yesContinue = question(questionTemplate, args);
5✔
288
    if (!yesContinue) {
2!
289
      throw new CliAbortException();
×
290
    }
291
  }
1✔
292

293
  /**
294
   * @param purpose the purpose why Internet connection is required.
295
   * @param explicitOnlineCheck if {@code true}, perform an explicit {@link #isOffline()} check; if {@code false} use {@link #isOfflineMode()}.
296
   * @throws CliException if you are {@link #isOffline() offline}.
297
   */
298
  default void requireOnline(String purpose, boolean explicitOnlineCheck) {
299

300
    if (explicitOnlineCheck) {
2✔
301
      if (isOffline()) {
3✔
302
        throw CliOfflineException.ofPurpose(purpose);
3✔
303
      }
304
    } else {
305
      if (isOfflineMode()) {
3!
306
        throw CliOfflineException.ofPurpose(purpose);
3✔
307
      }
308
    }
309
  }
1✔
310

311
  /**
312
   * @return the {@link SystemInfo}.
313
   */
314
  SystemInfo getSystemInfo();
315

316
  /**
317
   * @return the {@link EnvironmentVariables} with full inheritance.
318
   */
319
  EnvironmentVariables getVariables();
320

321
  /**
322
   * @return the {@link FileAccess}.
323
   */
324
  FileAccess getFileAccess();
325

326
  /**
327
   * @return the {@link CommandletManager}.
328
   */
329
  CommandletManager getCommandletManager();
330

331
  /**
332
   * @return the default {@link ToolRepository}.
333
   */
334
  ToolRepository getDefaultToolRepository();
335

336
  /**
337
   * @return the {@link CustomToolRepository}.
338
   */
339
  CustomToolRepository getCustomToolRepository();
340

341
  /**
342
   * @return the {@link MvnRepository}.
343
   */
344
  MvnRepository getMvnRepository();
345

346
  /**
347
   * @return the {@link NpmRepository}.
348
   */
349
  NpmRepository getNpmRepository();
350

351
  /**
352
   * @return the {@link Path} to the IDE instance directory. You can have as many IDE instances on the same computer as independent tenants for different
353
   *     isolated projects.
354
   * @see com.devonfw.tools.ide.variable.IdeVariables#IDE_HOME
355
   */
356
  Path getIdeHome();
357

358
  /**
359
   * @return the name of the current project.
360
   * @see com.devonfw.tools.ide.variable.IdeVariables#PROJECT_NAME
361
   */
362
  String getProjectName();
363

364
  /**
365
   * @return the IDEasy version the {@link #getIdeHome() current project} was created with or migrated to.
366
   */
367
  VersionIdentifier getProjectVersion();
368

369
  /**
370
   * @param version the new value of {@link #getProjectVersion()}.
371
   */
372
  void setProjectVersion(VersionIdentifier version);
373

374
  /**
375
   * @return the {@link Path} to the IDE installation root directory. This is the top-level folder where the {@link #getIdeHome() IDE instances} are located as
376
   *     sub-folder. There is a reserved ".ide" folder where central IDE data is stored such as the {@link #getUrlsPath() download metadata} and the central
377
   *     software repository.
378
   * @see com.devonfw.tools.ide.variable.IdeVariables#IDE_ROOT
379
   */
380
  Path getIdeRoot();
381

382
  /**
383
   * @return the {@link Path} to the {@link #FOLDER_UNDERSCORE_IDE}.
384
   * @see #getIdeRoot()
385
   * @see #FOLDER_UNDERSCORE_IDE
386
   */
387
  Path getIdePath();
388

389
  /**
390
   * @return the {@link Path} to the {@link #FOLDER_INSTALLATION installation} folder of IDEasy. This is a link to the (latest) installed release of IDEasy. On
391
   *     upgrade a new release is installed and the link is switched to the new release.
392
   */
393
  default Path getIdeInstallationPath() {
394

395
    return getIdePath().resolve(FOLDER_INSTALLATION);
×
396
  }
397

398
  /**
399
   * @return the current working directory ("user.dir"). This is the directory where the user's shell was located when the IDE CLI was invoked.
400
   */
401
  Path getCwd();
402

403
  /**
404
   * @return the {@link Path} for the temporary directory to use. Will be different from the OS specific temporary directory (java.io.tmpDir).
405
   */
406
  Path getTempPath();
407

408
  /**
409
   * @return the {@link Path} for the temporary download directory to use.
410
   */
411
  Path getTempDownloadPath();
412

413
  /**
414
   * @return the {@link Path} to the download metadata (ide-urls). Here a git repository is cloned and updated (pulled) to always have the latest metadata to
415
   *     download tools.
416
   * @see com.devonfw.tools.ide.url.model.folder.UrlRepository
417
   */
418
  Path getUrlsPath();
419

420
  /**
421
   * @return the {@link UrlMetadata}. Will be lazily instantiated and thereby automatically be cloned or pulled (by default).
422
   */
423
  UrlMetadata getUrls();
424

425
  /**
426
   * @return the {@link Path} to the download cache. All downloads will be placed here using a unique naming pattern that allows to reuse these artifacts. So if
427
   *     the same artifact is requested again it will be taken from the cache to avoid downloading it again.
428
   */
429
  Path getDownloadPath();
430

431
  /**
432
   * @return the {@link Path} to the software folder inside {@link #getIdeHome() IDE_HOME}. All tools for that IDE instance will be linked here from the
433
   *     {@link #getSoftwareRepositoryPath() software repository} as sub-folder named after the according tool.
434
   */
435
  Path getSoftwarePath();
436

437
  /**
438
   * @return the {@link Path} to the extra folder inside software folder inside {@link #getIdeHome() IDE_HOME}. All tools for that IDE instance will be linked
439
   *     here from the {@link #getSoftwareRepositoryPath() software repository} as sub-folder named after the according tool.
440
   */
441
  Path getSoftwareExtraPath();
442

443
  /**
444
   * @return the {@link Path} to the global software repository. This is the central directory where the tools are extracted physically on the local disc. Those
445
   *     are shared among all IDE instances (see {@link #getIdeHome() IDE_HOME}) via symbolic links (see {@link #getSoftwarePath()}). Therefore this repository
446
   *     follows the sub-folder structure {@code «repository»/«tool»/«edition»/«version»/}. So multiple versions of the same tool exist here as different
447
   *     folders. Further, such software may not be modified so e.g. installation of plugins and other kind of changes to such tool need to happen strictly out
448
   *     of the scope of this folders.
449
   */
450
  Path getSoftwareRepositoryPath();
451

452
  /**
453
   * @return the {@link Path} to the {@link #FOLDER_PLUGINS plugins folder} inside {@link #getIdeHome() IDE_HOME}. All plugins of the IDE instance will be
454
   *     stored here. For each tool that supports plugins a sub-folder with the tool name will be created where the plugins for that tool get installed.
455
   */
456
  Path getPluginsPath();
457

458
  /**
459
   * @return the {@link Path} to the central tool repository. All tools will be installed in this location using the directory naming schema of
460
   *     {@code «repository»/«tool»/«edition»/«version»/}. Actual {@link #getIdeHome() IDE instances} will only contain symbolic links to the physical tool
461
   *     installations in this repository. This allows to share and reuse tool installations across multiple {@link #getIdeHome() IDE instances}. The variable
462
   *     {@code «repository»} is typically {@code default} for the tools from our standard {@link #getUrlsPath() ide-urls download metadata} but this will
463
   *     differ for custom tools from a private repository.
464
   */
465
  Path getToolRepositoryPath();
466

467
  /**
468
   * @return the {@link Path} to the users home directory. Typically initialized via the {@link System#getProperty(String) system property} "user.home".
469
   * @see com.devonfw.tools.ide.variable.IdeVariables#HOME
470
   */
471
  Path getUserHome();
472

473
  /**
474
   * @return the {@link Path} to the ".ide" subfolder in the {@link #getUserHome() users home directory}.
475
   */
476
  Path getUserHomeIde();
477

478
  /**
479
   * @return the {@link Path} to the {@link #FOLDER_SETTINGS settings} folder with the cloned git repository containing the project configuration.
480
   */
481
  Path getSettingsPath();
482

483
  /**
484
   * @return the {@link Path} to the {@link #FOLDER_REPOSITORIES repositories} folder with legacy fallback if not present or {@code null} if not found.
485
   */
486
  default Path getRepositoriesPath() {
487

488
    Path settingsPath = getSettingsPath();
3✔
489
    if (settingsPath == null) {
2!
490
      return null;
×
491
    }
492
    Path repositoriesPath = settingsPath.resolve(IdeContext.FOLDER_REPOSITORIES);
4✔
493
    if (Files.isDirectory(repositoriesPath)) {
5✔
494
      return repositoriesPath;
2✔
495
    }
496
    Path legacyRepositoriesPath = settingsPath.resolve(IdeContext.FOLDER_LEGACY_REPOSITORIES);
4✔
497
    if (Files.isDirectory(legacyRepositoriesPath)) {
5!
498
      return legacyRepositoriesPath;
×
499
    }
500
    return null;
2✔
501
  }
502

503
  /**
504
   * @return the {@link Path} to the {@code settings} folder with the cloned git repository containing the project configuration only if the settings repository
505
   *     is in fact a git repository.
506
   */
507
  Path getSettingsGitRepository();
508

509
  /**
510
   * @return {@code true} if the settings repository is a symlink or a junction.
511
   */
512
  boolean isSettingsRepositorySymlinkOrJunction();
513

514
  /**
515
   * @return the {@link Path} to the file containing the last tracked commit Id of the settings repository.
516
   */
517
  Path getSettingsCommitIdPath();
518

519
  /**
520
   * @return the {@link Path} to the templates folder inside the {@link #getSettingsPath() settings}. The relative directory structure in this templates folder
521
   *     is to be applied to {@link #getIdeHome() IDE_HOME} when the project is set up.
522
   */
523
  default Path getSettingsTemplatePath() {
524
    Path settingsFolder = getSettingsPath();
3✔
525
    Path templatesFolder = settingsFolder.resolve(IdeContext.FOLDER_TEMPLATES);
4✔
526
    if (!Files.isDirectory(templatesFolder)) {
5✔
527
      Path templatesFolderLegacy = settingsFolder.resolve(IdeContext.FOLDER_LEGACY_TEMPLATES);
4✔
528
      if (Files.isDirectory(templatesFolderLegacy)) {
5!
529
        templatesFolder = templatesFolderLegacy;
×
530
      } else {
531
        warning("No templates found in settings git repo neither in {} nor in {} - configuration broken", templatesFolder, templatesFolderLegacy);
13✔
532
        return null;
2✔
533
      }
534
    }
535
    return templatesFolder;
2✔
536
  }
537

538
  /**
539
   * @return the {@link Path} to the {@code conf} folder with instance specific tool configurations and the
540
   *     {@link EnvironmentVariablesType#CONF user specific project configuration}.
541
   */
542
  Path getConfPath();
543

544
  /**
545
   * @return the {@link Path} to the workspace.
546
   * @see #getWorkspaceName()
547
   */
548
  Path getWorkspacePath();
549

550
  /**
551
   * @return the name of the workspace. Defaults to {@link #WORKSPACE_MAIN}.
552
   */
553
  String getWorkspaceName();
554

555
  /**
556
   * @return the value of the system {@link IdeVariables#PATH PATH} variable. It is automatically extended according to the tools available in
557
   *     {@link #getSoftwarePath() software path} unless {@link #getIdeHome() IDE_HOME} was not found.
558
   */
559
  SystemPath getPath();
560

561
  /**
562
   * @return a new {@link ProcessContext} to {@link ProcessContext#run() run} external commands.
563
   */
564
  ProcessContext newProcess();
565

566
  /**
567
   * @param title the {@link IdeProgressBar#getTitle() title}.
568
   * @param size the {@link IdeProgressBar#getMaxSize() expected maximum size}.
569
   * @param unitName the {@link IdeProgressBar#getUnitName() unit name}.
570
   * @param unitSize the {@link IdeProgressBar#getUnitSize() unit size}.
571
   * @return the new {@link IdeProgressBar} to use.
572
   */
573
  IdeProgressBar newProgressBar(String title, long size, String unitName, long unitSize);
574

575
  /**
576
   * @param title the {@link IdeProgressBar#getTitle() title}.
577
   * @param size the {@link IdeProgressBar#getMaxSize() expected maximum size} in bytes.
578
   * @return the new {@link IdeProgressBar} to use.
579
   */
580
  default IdeProgressBar newProgressBarInMib(String title, long size) {
581

582
    if ((size > 0) && (size < 1024)) {
8✔
583
      return new IdeProgressBarNone(title, size, IdeProgressBar.UNIT_NAME_MB, IdeProgressBar.UNIT_SIZE_MB);
8✔
584
    }
585
    return newProgressBar(title, size, IdeProgressBar.UNIT_NAME_MB, IdeProgressBar.UNIT_SIZE_MB);
7✔
586
  }
587

588
  /**
589
   * @param size the {@link IdeProgressBar#getMaxSize() expected maximum size} in bytes.
590
   * @return the new {@link IdeProgressBar} for copy.
591
   */
592
  default IdeProgressBar newProgressBarForDownload(long size) {
593

594
    return newProgressBarInMib(IdeProgressBar.TITLE_DOWNLOADING, size);
5✔
595
  }
596

597
  /**
598
   * @param size the {@link IdeProgressBar#getMaxSize() expected maximum size} in bytes.
599
   * @return the new {@link IdeProgressBar} for extracting.
600
   */
601
  default IdeProgressBar newProgressbarForExtracting(long size) {
602

603
    return newProgressBarInMib(IdeProgressBar.TITLE_EXTRACTING, size);
5✔
604
  }
605

606
  /**
607
   * @param size the {@link IdeProgressBar#getMaxSize() expected maximum size} in bytes.
608
   * @return the new {@link IdeProgressBar} for copy.
609
   */
610
  default IdeProgressBar newProgressbarForCopying(long size) {
611

612
    return newProgressBarInMib(IdeProgressBar.TITLE_COPYING, size);
5✔
613
  }
614

615
  /**
616
   * @param size the {@link IdeProgressBar#getMaxSize() expected maximum} plugin count.
617
   * @return the new {@link IdeProgressBar} to use.
618
   */
619
  default IdeProgressBar newProgressBarForPlugins(long size) {
620
    return newProgressBar(IdeProgressBar.TITLE_INSTALL_PLUGIN, size, IdeProgressBar.UNIT_NAME_PLUGIN, IdeProgressBar.UNIT_SIZE_PLUGIN);
7✔
621
  }
622

623
  /**
624
   * @return the {@link DirectoryMerger} used to configure and merge the workspace for an {@link com.devonfw.tools.ide.tool.ide.IdeToolCommandlet IDE}.
625
   */
626
  DirectoryMerger getWorkspaceMerger();
627

628
  /**
629
   * @return the {@link Path} to the working directory from where the command is executed.
630
   */
631
  Path getDefaultExecutionDirectory();
632

633
  /**
634
   * @return the {@link IdeSystem} instance wrapping {@link System}.
635
   */
636
  IdeSystem getSystem();
637

638
  /**
639
   * @return the {@link GitContext} used to run several git commands.
640
   */
641
  GitContext getGitContext();
642

643
  /**
644
   * @return the String value for the variable MAVEN_ARGS, or null if called outside an IDEasy installation.
645
   */
646
  default String getMavenArgs() {
647

648
    if (getIdeHome() == null) {
3✔
649
      return null;
2✔
650
    }
651
    Mvn mvn = getCommandletManager().getCommandlet(Mvn.class);
6✔
652
    return mvn.getMavenArgs();
3✔
653
  }
654

655
  /**
656
   * @return the path for the variable GRADLE_USER_HOME, or null if called outside an IDEasy installation.
657
   */
658
  default Path getGradleUserHome() {
659

660
    if (getIdeHome() == null) {
3✔
661
      return null;
2✔
662
    }
663
    Gradle gradle = getCommandletManager().getCommandlet(Gradle.class);
6✔
664
    return gradle.getOrCreateGradleConfFolder();
3✔
665
  }
666

667
  /**
668
   * @return the {@link Path} pointing to the maven configuration directory (where "settings.xml" or "settings-security.xml" are located).
669
   */
670
  default Path getMavenConfigurationFolder() {
671

672
    if (getIdeHome() == null) {
3✔
673
      // fallback to USER_HOME/.m2 folder if called outside an IDEasy project
674
      return getUserHome().resolve(Mvn.MVN_CONFIG_LEGACY_FOLDER);
5✔
675
    }
676
    Mvn mvn = getCommandletManager().getCommandlet(Mvn.class);
6✔
677
    return mvn.getMavenConfigurationFolder();
3✔
678
  }
679

680
  /**
681
   * Updates the current working directory (CWD) and configures the environment paths according to the specified parameters. This method is central to changing
682
   * the IDE's notion of where it operates, affecting where configurations, workspaces, settings, and other resources are located or loaded from.
683
   *
684
   * @return the current {@link Step} of processing.
685
   */
686
  Step getCurrentStep();
687

688
  /**
689
   * @param name the {@link Step#getName() name} of the new {@link Step}.
690
   * @return the new {@link Step} that has been created and started.
691
   */
692
  default Step newStep(String name) {
693

694
    return newStep(name, Step.NO_PARAMS);
5✔
695
  }
696

697
  /**
698
   * @param name the {@link Step#getName() name} of the new {@link Step}.
699
   * @param parameters the {@link Step#getParameter(int) parameters} of the {@link Step}.
700
   * @return the new {@link Step} that has been created and started.
701
   */
702
  default Step newStep(String name, Object... parameters) {
703

704
    return newStep(false, name, parameters);
6✔
705
  }
706

707
  /**
708
   * @param silent the {@link Step#isSilent() silent flag}.
709
   * @param name the {@link Step#getName() name} of the new {@link Step}.
710
   * @param parameters the {@link Step#getParameter(int) parameters} of the {@link Step}.
711
   * @return the new {@link Step} that has been created and started.
712
   */
713
  Step newStep(boolean silent, String name, Object... parameters);
714

715
  /**
716
   * @param lambda the {@link Runnable} to {@link Runnable#run() run} while the {@link com.devonfw.tools.ide.log.IdeLogger logging} is entirely disabled.
717
   *     After this the logging will be enabled again. Collected log messages will then be logged at the end.
718
   */
719
  default void runWithoutLogging(Runnable lambda) {
720

721
    runWithoutLogging(lambda, IdeLogLevel.TRACE);
4✔
722
  }
1✔
723

724
  /**
725
   * @param lambda the {@link Runnable} to {@link Runnable#run() run} while the {@link com.devonfw.tools.ide.log.IdeLogger logging} is entirely disabled.
726
   *     After this the logging will be enabled again. Collected log messages will then be logged at the end.
727
   * @param threshold the {@link IdeLogLevel} to use as threshold for filtering logs while logging is disabled and log messages are collected. Use
728
   *     {@link IdeLogLevel#TRACE} to collect all logs and ensure nothing gets lost (will still not log anything that is generally not active in regular
729
   *     logging) and e.g. use {@link IdeLogLevel#ERROR} to discard all logs except errors.
730
   */
731
  void runWithoutLogging(Runnable lambda, IdeLogLevel threshold);
732

733
  /**
734
   * Updates the current working directory (CWD) and configures the environment paths according to the specified parameters. This method is central to changing
735
   * the IDE's notion of where it operates, affecting where configurations, workspaces, settings, and other resources are located or loaded from.
736
   *
737
   * @param ideHome The path to the IDE home directory.
738
   */
739
  default void setIdeHome(Path ideHome) {
740

741
    setCwd(ideHome, WORKSPACE_MAIN, ideHome);
5✔
742
  }
1✔
743

744
  /**
745
   * Updates the current working directory (CWD) and configures the environment paths according to the specified parameters. This method is central to changing
746
   * the IDE's notion of where it operates, affecting where configurations, workspaces, settings, and other resources are located or loaded from.
747
   *
748
   * @param userDir The path to set as the current working directory.
749
   * @param workspace The name of the workspace within the IDE's environment.
750
   * @param ideHome The path to the IDE home directory.
751
   */
752
  void setCwd(Path userDir, String workspace, Path ideHome);
753

754
  /**
755
   * Finds the path to the Bash executable.
756
   *
757
   * @return the {@link Path} to the Bash executable, or {@code null} if Bash is not found.
758
   */
759
  Path findBash();
760

761
  /**
762
   * Finds the path to the Bash executable.
763
   *
764
   * @return the {@link Path} to the Bash executable. Throws a {@link CliException} if no bash was found.
765
   */
766
  default Path findBashRequired() {
767
    Path bash = findBash();
3✔
768
    if (bash == null) {
2!
769
      String message = "Bash " + IS_NOT_INSTALLED_BUT_REQUIRED;
×
770
      if (getSystemInfo().isWindows()) {
×
771
        message += " " + PLEASE_DOWNLOAD_AND_INSTALL_GIT + ":\n " + WINDOWS_GIT_DOWNLOAD_URL;
×
772
        throw new CliException(message);
×
773
      }
774
      bash = Path.of("bash");
×
775
    }
776

777
    return bash;
2✔
778
  }
779

780
  /**
781
   * @return the {@link WindowsPathSyntax} used for {@link Path} conversion or {@code null} for no such conversion (typically if not on Windows).
782
   */
783
  WindowsPathSyntax getPathSyntax();
784

785
  /**
786
   * logs the status of {@link #getIdeHome() IDE_HOME} and {@link #getIdeRoot() IDE_ROOT}.
787
   */
788
  void logIdeHomeAndRootStatus();
789

790
  /**
791
   * @param version the {@link VersionIdentifier} to write.
792
   * @param installationPath the {@link Path directory} where to write the version to a {@link #FILE_SOFTWARE_VERSION version file}.
793
   */
794
  void writeVersionFile(VersionIdentifier version, Path installationPath);
795

796
  /**
797
   * Verifies that current {@link IdeVersion} satisfies {@link IdeVariables#IDE_MIN_VERSION}.
798
   *
799
   * @param throwException whether to throw a {@link CliException} or just log a warning.
800
   */
801
  void verifyIdeMinVersion(boolean throwException);
802

803
  /**
804
   * @return the path for the variable COREPACK_HOME, or null if called outside an IDEasy installation.
805
   */
806
  default Path getCorePackHome() {
807
    if (getIdeHome() == null) {
×
808
      return null;
×
809
    }
810
    Corepack corepack = getCommandletManager().getCommandlet(Corepack.class);
×
811
    return corepack.getOrCreateCorepackHomeFolder();
×
812
  }
813

814
  /**
815
   * @return the path for the variable NPM_CONFIG_USERCONFIG, or null if called outside an IDEasy installation.
816
   */
817
  default Path getNpmConfigUserConfig() {
818
    if (getIdeHome() == null) {
3✔
819
      return null;
2✔
820
    }
821
    Npm npm = getCommandletManager().getCommandlet(Npm.class);
6✔
822
    return npm.getOrCreateNpmConfigUserConfig();
3✔
823
  }
824
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc