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

devonfw / IDEasy / 19228214501

10 Nov 2025 10:16AM UTC coverage: 68.896% (+0.02%) from 68.872%
19228214501

push

github

web-flow
#1294: Refactor getMavenConfigurationFolder (#1573)

Co-authored-by: jan-vcapgemini <59438728+jan-vcapgemini@users.noreply.github.com>

3487 of 5547 branches covered (62.86%)

Branch coverage included in aggregate %.

9134 of 12772 relevant lines covered (71.52%)

3.14 hits per line

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

74.8
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.os.SystemInfo;
21
import com.devonfw.tools.ide.os.WindowsPathSyntax;
22
import com.devonfw.tools.ide.process.ProcessContext;
23
import com.devonfw.tools.ide.step.Step;
24
import com.devonfw.tools.ide.tool.corepack.Corepack;
25
import com.devonfw.tools.ide.tool.gradle.Gradle;
26
import com.devonfw.tools.ide.tool.mvn.Mvn;
27
import com.devonfw.tools.ide.tool.npm.Npm;
28
import com.devonfw.tools.ide.tool.repository.CustomToolRepository;
29
import com.devonfw.tools.ide.tool.repository.MvnRepository;
30
import com.devonfw.tools.ide.tool.repository.NpmRepository;
31
import com.devonfw.tools.ide.tool.repository.ToolRepository;
32
import com.devonfw.tools.ide.url.model.UrlMetadata;
33
import com.devonfw.tools.ide.variable.IdeVariables;
34
import com.devonfw.tools.ide.version.IdeVersion;
35
import com.devonfw.tools.ide.version.VersionIdentifier;
36

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

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

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

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

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

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

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

64
  /**
65
   * 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,
66
   * maven filtering, .gitignore and to distinguish from {@link #FOLDER_DOT_IDE}.
67
   *
68
   * @see #getIdePath()
69
   */
70
  String FOLDER_UNDERSCORE_IDE = "_ide";
71

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

137
  /**
138
   * The name of the update folder inside the {@link #FOLDER_WORKSPACE workspace} folder containing the templates for the configuration templates for the update
139
   * 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
140
   * 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
141
   * for indentation and other code-formatting settings. If all developers in a project team use the same formatter settings, this will actively prevent
142
   * 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
143
   * 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
144
   * 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
145
   * user as needed.
146
   */
147
  String FOLDER_UPDATE = "update";
148

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

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

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

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

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

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

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

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

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

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

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

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

195
  /**
196
   * The keyword for project name convention.
197
   */
198
  String SETTINGS_REPOSITORY_KEYWORD = "settings";
199

200
  /**
201
   * @return {@code true} if {@link #isOfflineMode() offline mode} is active or we are NOT {@link #isOnline() online}, {@code false} otherwise.
202
   */
203
  default boolean isOffline() {
204

205
    return isOfflineMode() || !isOnline();
10✔
206
  }
207

208
  /**
209
   * @return {@code true} if we are currently online (Internet access is available), {@code false} otherwise.
210
   */
211
  boolean isOnline();
212

213
  /**
214
   * Print the IDEasy {@link #LOGO logo}.
215
   */
216
  default void printLogo() {
217

218
    info(LOGO);
3✔
219
  }
1✔
220

221
  /**
222
   * Asks the user for a single string input.
223
   *
224
   * @param message The information message to display.
225
   * @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.
226
   * @return The string input from the user, or the default value if no input is provided.
227
   */
228
  String askForInput(String message, String defaultValue);
229

230
  /**
231
   * Asks the user for a single string input.
232
   *
233
   * @param message The information message to display.
234
   * @return The string input from the user.
235
   */
236
  default String askForInput(String message) {
237
    return askForInput(message, null);
5✔
238
  }
239

240
  /**
241
   * @param question the question to ask.
242
   * @param args arguments for filling the templates
243
   * @return {@code true} if the user answered with "yes", {@code false} otherwise ("no").
244
   */
245
  default boolean question(String question, Object... args) {
246

247
    String yes = "yes";
2✔
248
    String option = question(new String[] { yes, "no" }, question, args);
16✔
249
    if (yes.equals(option)) {
4!
250
      return true;
2✔
251
    }
252
    return false;
×
253
  }
254

255
  /**
256
   * @param <O> type of the option. E.g. {@link String}.
257
   * @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.
258
   * @param question the question to ask.
259
   * @return the option selected by the user as answer.
260
   */
261
  @SuppressWarnings("unchecked")
262
  <O> O question(O[] options, String question, Object... args);
263

264
  /**
265
   * 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
266
   * exception is thrown to abort further processing.
267
   *
268
   * @param questionTemplate the yes/no question to {@link #question(String, Object...) ask}.
269
   * @param args the arguments to fill the placeholders in the question template.
270
   * @throws CliAbortException if the user answered with "no" and further processing shall be aborted.
271
   */
272
  default void askToContinue(String questionTemplate, Object... args) {
273
    boolean yesContinue = question(questionTemplate, args);
5✔
274
    if (!yesContinue) {
2!
275
      throw new CliAbortException();
×
276
    }
277
  }
1✔
278

279
  /**
280
   * @param purpose the purpose why Internet connection is required.
281
   * @param explicitOnlineCheck if {@code true}, perform an explicit {@link #isOffline()} check; if {@code false} use {@link #isOfflineMode()}.
282
   * @throws CliException if you are {@link #isOffline() offline}.
283
   */
284
  default void requireOnline(String purpose, boolean explicitOnlineCheck) {
285

286
    if (explicitOnlineCheck) {
2✔
287
      if (isOffline()) {
3✔
288
        throw CliOfflineException.ofPurpose(purpose);
3✔
289
      }
290
    } else {
291
      if (isOfflineMode()) {
3!
292
        throw CliOfflineException.ofPurpose(purpose);
3✔
293
      }
294
    }
295
  }
1✔
296

297
  /**
298
   * @return the {@link SystemInfo}.
299
   */
300
  SystemInfo getSystemInfo();
301

302
  /**
303
   * @return the {@link EnvironmentVariables} with full inheritance.
304
   */
305
  EnvironmentVariables getVariables();
306

307
  /**
308
   * @return the {@link FileAccess}.
309
   */
310
  FileAccess getFileAccess();
311

312
  /**
313
   * @return the {@link CommandletManager}.
314
   */
315
  CommandletManager getCommandletManager();
316

317
  /**
318
   * @return the default {@link ToolRepository}.
319
   */
320
  ToolRepository getDefaultToolRepository();
321

322
  /**
323
   * @return the {@link CustomToolRepository}.
324
   */
325
  CustomToolRepository getCustomToolRepository();
326

327
  /**
328
   * @return the {@link MvnRepository}.
329
   */
330
  MvnRepository getMvnRepository();
331

332
  /**
333
   * @return the {@link NpmRepository}.
334
   */
335
  NpmRepository getNpmRepository();
336

337
  /**
338
   * @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
339
   *     isolated projects.
340
   * @see com.devonfw.tools.ide.variable.IdeVariables#IDE_HOME
341
   */
342
  Path getIdeHome();
343

344
  /**
345
   * @return the name of the current project.
346
   * @see com.devonfw.tools.ide.variable.IdeVariables#PROJECT_NAME
347
   */
348
  String getProjectName();
349

350
  /**
351
   * @return the IDEasy version the {@link #getIdeHome() current project} was created with or migrated to.
352
   */
353
  VersionIdentifier getProjectVersion();
354

355
  /**
356
   * @param version the new value of {@link #getProjectVersion()}.
357
   */
358
  void setProjectVersion(VersionIdentifier version);
359

360
  /**
361
   * @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
362
   *     sub-folder. There is a reserved ".ide" folder where central IDE data is stored such as the {@link #getUrlsPath() download metadata} and the central
363
   *     software repository.
364
   * @see com.devonfw.tools.ide.variable.IdeVariables#IDE_ROOT
365
   */
366
  Path getIdeRoot();
367

368
  /**
369
   * @return the {@link Path} to the {@link #FOLDER_UNDERSCORE_IDE}.
370
   * @see #getIdeRoot()
371
   * @see #FOLDER_UNDERSCORE_IDE
372
   */
373
  Path getIdePath();
374

375
  /**
376
   * @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
377
   *     upgrade a new release is installed and the link is switched to the new release.
378
   */
379
  default Path getIdeInstallationPath() {
380

381
    return getIdePath().resolve(FOLDER_INSTALLATION);
×
382
  }
383

384
  /**
385
   * @return the current working directory ("user.dir"). This is the directory where the user's shell was located when the IDE CLI was invoked.
386
   */
387
  Path getCwd();
388

389
  /**
390
   * @return the {@link Path} for the temporary directory to use. Will be different from the OS specific temporary directory (java.io.tmpDir).
391
   */
392
  Path getTempPath();
393

394
  /**
395
   * @return the {@link Path} for the temporary download directory to use.
396
   */
397
  Path getTempDownloadPath();
398

399
  /**
400
   * @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
401
   *     download tools.
402
   * @see com.devonfw.tools.ide.url.model.folder.UrlRepository
403
   */
404
  Path getUrlsPath();
405

406
  /**
407
   * @return the {@link UrlMetadata}. Will be lazily instantiated and thereby automatically be cloned or pulled (by default).
408
   */
409
  UrlMetadata getUrls();
410

411
  /**
412
   * @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
413
   *     the same artifact is requested again it will be taken from the cache to avoid downloading it again.
414
   */
415
  Path getDownloadPath();
416

417
  /**
418
   * @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
419
   *     {@link #getSoftwareRepositoryPath() software repository} as sub-folder named after the according tool.
420
   */
421
  Path getSoftwarePath();
422

423
  /**
424
   * @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
425
   *     here from the {@link #getSoftwareRepositoryPath() software repository} as sub-folder named after the according tool.
426
   */
427
  Path getSoftwareExtraPath();
428

429
  /**
430
   * @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
431
   *     are shared among all IDE instances (see {@link #getIdeHome() IDE_HOME}) via symbolic links (see {@link #getSoftwarePath()}). Therefore this repository
432
   *     follows the sub-folder structure {@code «repository»/«tool»/«edition»/«version»/}. So multiple versions of the same tool exist here as different
433
   *     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
434
   *     of the scope of this folders.
435
   */
436
  Path getSoftwareRepositoryPath();
437

438
  /**
439
   * @return the {@link Path} to the {@link #FOLDER_PLUGINS plugins folder} inside {@link #getIdeHome() IDE_HOME}. All plugins of the IDE instance will be
440
   *     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.
441
   */
442
  Path getPluginsPath();
443

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

453
  /**
454
   * @return the {@link Path} to the users home directory. Typically initialized via the {@link System#getProperty(String) system property} "user.home".
455
   * @see com.devonfw.tools.ide.variable.IdeVariables#HOME
456
   */
457
  Path getUserHome();
458

459
  /**
460
   * @return the {@link Path} to the ".ide" subfolder in the {@link #getUserHome() users home directory}.
461
   */
462
  Path getUserHomeIde();
463

464
  /**
465
   * @return the {@link Path} to the {@link #FOLDER_SETTINGS settings} folder with the cloned git repository containing the project configuration.
466
   */
467
  Path getSettingsPath();
468

469
  /**
470
   * @return the {@link Path} to the {@link #FOLDER_REPOSITORIES repositories} folder with legacy fallback if not present or {@code null} if not found.
471
   */
472
  default Path getRepositoriesPath() {
473

474
    Path settingsPath = getSettingsPath();
3✔
475
    if (settingsPath == null) {
2!
476
      return null;
×
477
    }
478
    Path repositoriesPath = settingsPath.resolve(IdeContext.FOLDER_REPOSITORIES);
4✔
479
    if (Files.isDirectory(repositoriesPath)) {
5✔
480
      return repositoriesPath;
2✔
481
    }
482
    Path legacyRepositoriesPath = settingsPath.resolve(IdeContext.FOLDER_LEGACY_REPOSITORIES);
4✔
483
    if (Files.isDirectory(legacyRepositoriesPath)) {
5!
484
      return legacyRepositoriesPath;
×
485
    }
486
    return null;
2✔
487
  }
488

489
  /**
490
   * @return the {@link Path} to the {@code settings} folder with the cloned git repository containing the project configuration only if the settings repository
491
   *     is in fact a git repository.
492
   */
493
  Path getSettingsGitRepository();
494

495
  /**
496
   * @return {@code true} if the settings repository is a symlink or a junction.
497
   */
498
  boolean isSettingsRepositorySymlinkOrJunction();
499

500
  /**
501
   * @return the {@link Path} to the file containing the last tracked commit Id of the settings repository.
502
   */
503
  Path getSettingsCommitIdPath();
504

505
  /**
506
   * @return the {@link Path} to the templates folder inside the {@link #getSettingsPath() settings}. The relative directory structure in this templates folder
507
   *     is to be applied to {@link #getIdeHome() IDE_HOME} when the project is set up.
508
   */
509
  default Path getSettingsTemplatePath() {
510
    Path settingsFolder = getSettingsPath();
3✔
511
    Path templatesFolder = settingsFolder.resolve(IdeContext.FOLDER_TEMPLATES);
4✔
512
    if (!Files.isDirectory(templatesFolder)) {
5✔
513
      Path templatesFolderLegacy = settingsFolder.resolve(IdeContext.FOLDER_LEGACY_TEMPLATES);
4✔
514
      if (Files.isDirectory(templatesFolderLegacy)) {
5!
515
        templatesFolder = templatesFolderLegacy;
×
516
      } else {
517
        warning("No templates found in settings git repo neither in {} nor in {} - configuration broken", templatesFolder, templatesFolderLegacy);
13✔
518
        return null;
2✔
519
      }
520
    }
521
    return templatesFolder;
2✔
522
  }
523

524
  /**
525
   * @return the {@link Path} to the {@code conf} folder with instance specific tool configurations and the
526
   *     {@link EnvironmentVariablesType#CONF user specific project configuration}.
527
   */
528
  Path getConfPath();
529

530
  /**
531
   * @return the {@link Path} to the workspace.
532
   * @see #getWorkspaceName()
533
   */
534
  Path getWorkspacePath();
535

536
  /**
537
   * @return the name of the workspace. Defaults to {@link #WORKSPACE_MAIN}.
538
   */
539
  String getWorkspaceName();
540

541
  /**
542
   * @return the value of the system {@link IdeVariables#PATH PATH} variable. It is automatically extended according to the tools available in
543
   *     {@link #getSoftwarePath() software path} unless {@link #getIdeHome() IDE_HOME} was not found.
544
   */
545
  SystemPath getPath();
546

547
  /**
548
   * @return a new {@link ProcessContext} to {@link ProcessContext#run() run} external commands.
549
   */
550
  ProcessContext newProcess();
551

552
  /**
553
   * @param title the {@link IdeProgressBar#getTitle() title}.
554
   * @param size the {@link IdeProgressBar#getMaxSize() expected maximum size}.
555
   * @param unitName the {@link IdeProgressBar#getUnitName() unit name}.
556
   * @param unitSize the {@link IdeProgressBar#getUnitSize() unit size}.
557
   * @return the new {@link IdeProgressBar} to use.
558
   */
559
  IdeProgressBar newProgressBar(String title, long size, String unitName, long unitSize);
560

561
  /**
562
   * @param title the {@link IdeProgressBar#getTitle() title}.
563
   * @param size the {@link IdeProgressBar#getMaxSize() expected maximum size} in bytes.
564
   * @return the new {@link IdeProgressBar} to use.
565
   */
566
  default IdeProgressBar newProgressBarInMib(String title, long size) {
567

568
    if ((size > 0) && (size < 1024)) {
8✔
569
      return new IdeProgressBarNone(title, size, IdeProgressBar.UNIT_NAME_MB, IdeProgressBar.UNIT_SIZE_MB);
8✔
570
    }
571
    return newProgressBar(title, size, IdeProgressBar.UNIT_NAME_MB, IdeProgressBar.UNIT_SIZE_MB);
7✔
572
  }
573

574
  /**
575
   * @param size the {@link IdeProgressBar#getMaxSize() expected maximum size} in bytes.
576
   * @return the new {@link IdeProgressBar} for copy.
577
   */
578
  default IdeProgressBar newProgressBarForDownload(long size) {
579

580
    return newProgressBarInMib(IdeProgressBar.TITLE_DOWNLOADING, size);
5✔
581
  }
582

583
  /**
584
   * @param size the {@link IdeProgressBar#getMaxSize() expected maximum size} in bytes.
585
   * @return the new {@link IdeProgressBar} for extracting.
586
   */
587
  default IdeProgressBar newProgressbarForExtracting(long size) {
588

589
    return newProgressBarInMib(IdeProgressBar.TITLE_EXTRACTING, size);
5✔
590
  }
591

592
  /**
593
   * @param size the {@link IdeProgressBar#getMaxSize() expected maximum size} in bytes.
594
   * @return the new {@link IdeProgressBar} for copy.
595
   */
596
  default IdeProgressBar newProgressbarForCopying(long size) {
597

598
    return newProgressBarInMib(IdeProgressBar.TITLE_COPYING, size);
5✔
599
  }
600

601
  /**
602
   * @param size the {@link IdeProgressBar#getMaxSize() expected maximum} plugin count.
603
   * @return the new {@link IdeProgressBar} to use.
604
   */
605
  default IdeProgressBar newProgressBarForPlugins(long size) {
606
    return newProgressBar(IdeProgressBar.TITLE_INSTALL_PLUGIN, size, IdeProgressBar.UNIT_NAME_PLUGIN, IdeProgressBar.UNIT_SIZE_PLUGIN);
7✔
607
  }
608

609
  /**
610
   * @return the {@link DirectoryMerger} used to configure and merge the workspace for an {@link com.devonfw.tools.ide.tool.ide.IdeToolCommandlet IDE}.
611
   */
612
  DirectoryMerger getWorkspaceMerger();
613

614
  /**
615
   * @return the {@link Path} to the working directory from where the command is executed.
616
   */
617
  Path getDefaultExecutionDirectory();
618

619
  /**
620
   * @return the {@link IdeSystem} instance wrapping {@link System}.
621
   */
622
  IdeSystem getSystem();
623

624
  /**
625
   * @return the {@link GitContext} used to run several git commands.
626
   */
627
  GitContext getGitContext();
628

629
  /**
630
   * @return the String value for the variable MAVEN_ARGS, or null if called outside an IDEasy installation.
631
   */
632
  default String getMavenArgs() {
633

634
    if (getIdeHome() == null) {
3!
635
      return null;
×
636
    }
637
    Mvn mvn = getCommandletManager().getCommandlet(Mvn.class);
6✔
638
    return mvn.getMavenArgs();
3✔
639
  }
640

641
  /**
642
   * @return the path for the variable GRADLE_USER_HOME, or null if called outside an IDEasy installation.
643
   */
644
  default Path getGradleUserHome() {
645

646
    if (getIdeHome() == null) {
3!
647
      return null;
×
648
    }
649
    Gradle gradle = getCommandletManager().getCommandlet(Gradle.class);
6✔
650
    return gradle.getOrCreateGradleConfFolder();
3✔
651
  }
652

653
  /**
654
   * @return the {@link Path} pointing to the maven configuration directory (where "settings.xml" or "settings-security.xml" are located).
655
   */
656
  default Path getMavenConfigurationFolder() {
657

658
    if (getIdeHome() == null) {
3✔
659
      // fallback to USER_HOME/.m2 folder if called outside an IDEasy project
660
      return getUserHome().resolve(Mvn.MVN_CONFIG_LEGACY_FOLDER);
5✔
661
    }
662
    Mvn mvn = getCommandletManager().getCommandlet(Mvn.class);
6✔
663
    return mvn.getMavenConfigurationFolder();
3✔
664
  }
665

666
  /**
667
   * Updates the current working directory (CWD) and configures the environment paths according to the specified parameters. This method is central to changing
668
   * the IDE's notion of where it operates, affecting where configurations, workspaces, settings, and other resources are located or loaded from.
669
   *
670
   * @return the current {@link Step} of processing.
671
   */
672
  Step getCurrentStep();
673

674
  /**
675
   * @param name the {@link Step#getName() name} of the new {@link Step}.
676
   * @return the new {@link Step} that has been created and started.
677
   */
678
  default Step newStep(String name) {
679

680
    return newStep(name, Step.NO_PARAMS);
5✔
681
  }
682

683
  /**
684
   * @param name the {@link Step#getName() name} of the new {@link Step}.
685
   * @param parameters the {@link Step#getParameter(int) parameters} of the {@link Step}.
686
   * @return the new {@link Step} that has been created and started.
687
   */
688
  default Step newStep(String name, Object... parameters) {
689

690
    return newStep(false, name, parameters);
6✔
691
  }
692

693
  /**
694
   * @param silent the {@link Step#isSilent() silent flag}.
695
   * @param name the {@link Step#getName() name} of the new {@link Step}.
696
   * @param parameters the {@link Step#getParameter(int) parameters} of the {@link Step}.
697
   * @return the new {@link Step} that has been created and started.
698
   */
699
  Step newStep(boolean silent, String name, Object... parameters);
700

701
  /**
702
   * @param lambda the {@link Runnable} to {@link Runnable#run() run} while the {@link com.devonfw.tools.ide.log.IdeLogger logging} is entirely disabled.
703
   *     After this the logging will be enabled again. Collected log messages will then be logged at the end.
704
   */
705
  default void runWithoutLogging(Runnable lambda) {
706

707
    runWithoutLogging(lambda, IdeLogLevel.TRACE);
4✔
708
  }
1✔
709

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

719
  /**
720
   * Updates the current working directory (CWD) and configures the environment paths according to the specified parameters. This method is central to changing
721
   * the IDE's notion of where it operates, affecting where configurations, workspaces, settings, and other resources are located or loaded from.
722
   *
723
   * @param ideHome The path to the IDE home directory.
724
   */
725
  default void setIdeHome(Path ideHome) {
726

727
    setCwd(ideHome, WORKSPACE_MAIN, ideHome);
5✔
728
  }
1✔
729

730
  /**
731
   * Updates the current working directory (CWD) and configures the environment paths according to the specified parameters. This method is central to changing
732
   * the IDE's notion of where it operates, affecting where configurations, workspaces, settings, and other resources are located or loaded from.
733
   *
734
   * @param userDir The path to set as the current working directory.
735
   * @param workspace The name of the workspace within the IDE's environment.
736
   * @param ideHome The path to the IDE home directory.
737
   */
738
  void setCwd(Path userDir, String workspace, Path ideHome);
739

740
  /**
741
   * Finds the path to the Bash executable.
742
   *
743
   * @return the {@link String} to the Bash executable, or {@code null} if Bash is not found
744
   */
745
  String findBash();
746

747
  /**
748
   * Finds the path to the Bash executable.
749
   *
750
   * @return the {@link String} to the Bash executable. Throws an {@link IllegalStateException} if no bash was found.
751
   */
752
  default String findBashRequired() {
753
    String bash = findBash();
3✔
754
    if (bash == null) {
2!
755
      String message = "Could not find bash what is a prerequisite of IDEasy.";
×
756
      if (getSystemInfo().isWindows()) {
×
757
        message = message + "\nPlease install Git for Windows and rerun.";
×
758
      }
759
      throw new IllegalStateException(message);
×
760
    }
761
    return bash;
2✔
762
  }
763

764
  /**
765
   * @return the {@link WindowsPathSyntax} used for {@link Path} conversion or {@code null} for no such conversion (typically if not on Windows).
766
   */
767
  WindowsPathSyntax getPathSyntax();
768

769
  /**
770
   * logs the status of {@link #getIdeHome() IDE_HOME} and {@link #getIdeRoot() IDE_ROOT}.
771
   */
772
  void logIdeHomeAndRootStatus();
773

774
  /**
775
   * @param version the {@link VersionIdentifier} to write.
776
   * @param installationPath the {@link Path directory} where to write the version to a {@link #FILE_SOFTWARE_VERSION version file}.
777
   */
778
  void writeVersionFile(VersionIdentifier version, Path installationPath);
779

780
  /**
781
   * Verifies that current {@link IdeVersion} satisfies {@link IdeVariables#IDE_MIN_VERSION}.
782
   *
783
   * @param throwException whether to throw a {@link CliException} or just log a warning.
784
   */
785
  void verifyIdeMinVersion(boolean throwException);
786

787
  /**
788
   * @return the path for the variable COREPACK_HOME, or null if called outside an IDEasy installation.
789
   */
790
  default Path getCorePackHome() {
791
    if (getIdeHome() == null) {
×
792
      return null;
×
793
    }
794
    Corepack corepack = getCommandletManager().getCommandlet(Corepack.class);
×
795
    return corepack.getOrCreateCorepackHomeFolder();
×
796
  }
797

798
  /**
799
   * @return the path for the variable NPM_CONFIG_USERCONFIG, or null if called outside an IDEasy installation.
800
   */
801
  default Path getNpmConfigUserConfig() {
802
    if (getIdeHome() == null) {
3!
803
      return null;
×
804
    }
805
    Npm npm = getCommandletManager().getCommandlet(Npm.class);
6✔
806
    return npm.getOrCreateNpmConfigUserConfig();
3✔
807
  }
808
}
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