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

devonfw / IDEasy / 17854514596

19 Sep 2025 09:34AM UTC coverage: 68.475% (-0.06%) from 68.539%
17854514596

push

github

web-flow
#907: add NpmRepository and further node/npm support as preparation for yarn and corepack (#1499)

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

3431 of 5487 branches covered (62.53%)

Branch coverage included in aggregate %.

8978 of 12635 relevant lines covered (71.06%)

3.12 hits per line

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

80.0
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.gradle.Gradle;
25
import com.devonfw.tools.ide.tool.mvn.Mvn;
26
import com.devonfw.tools.ide.tool.repository.CustomToolRepository;
27
import com.devonfw.tools.ide.tool.repository.MvnRepository;
28
import com.devonfw.tools.ide.tool.repository.NpmRepository;
29
import com.devonfw.tools.ide.tool.repository.ToolRepository;
30
import com.devonfw.tools.ide.url.model.UrlMetadata;
31
import com.devonfw.tools.ide.variable.IdeVariables;
32
import com.devonfw.tools.ide.version.IdeVersion;
33
import com.devonfw.tools.ide.version.VersionIdentifier;
34

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

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

47
  /** The name of the workspaces folder. */
48
  String FOLDER_WORKSPACES = "workspaces";
49

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

158
  /** The file for the license agreement. */
159
  String FILE_LICENSE_AGREEMENT = ".license.agreement";
160

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

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

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

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

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

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

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

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

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

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

203
    return isOfflineMode() || !isOnline();
10✔
204
  }
205

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

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

216
    info(LOGO);
3✔
217
  }
1✔
218

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

379
    return getIdePath().resolve(FOLDER_INSTALLATION);
×
380
  }
381

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

578
    return newProgressBarInMib(IdeProgressBar.TITLE_DOWNLOADING, size);
5✔
579
  }
580

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

587
    return newProgressBarInMib(IdeProgressBar.TITLE_EXTRACTING, size);
5✔
588
  }
589

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

596
    return newProgressBarInMib(IdeProgressBar.TITLE_COPYING, size);
5✔
597
  }
598

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

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

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

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

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

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

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

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

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

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

656
    Path confPath = getConfPath();
3✔
657
    Path mvnConfFolder = null;
2✔
658
    if (confPath != null) {
2✔
659
      mvnConfFolder = confPath.resolve(Mvn.MVN_CONFIG_FOLDER);
4✔
660
      if (!Files.isDirectory(mvnConfFolder)) {
5✔
661
        Path m2LegacyFolder = confPath.resolve(Mvn.MVN_CONFIG_LEGACY_FOLDER);
4✔
662
        if (Files.isDirectory(m2LegacyFolder)) {
5!
663
          mvnConfFolder = m2LegacyFolder;
×
664
        } else {
665
          mvnConfFolder = null; // see fallback below
2✔
666
        }
667
      }
668
    }
669
    if (mvnConfFolder == null) {
2✔
670
      // fallback to USER_HOME/.m2 folder
671
      mvnConfFolder = getUserHome().resolve(Mvn.MVN_CONFIG_LEGACY_FOLDER);
5✔
672
    }
673
    return mvnConfFolder;
2✔
674
  }
675

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

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

690
    return newStep(name, Step.NO_PARAMS);
5✔
691
  }
692

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

700
    return newStep(false, name, parameters);
6✔
701
  }
702

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

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

717
    runWithoutLogging(lambda, IdeLogLevel.TRACE);
4✔
718
  }
1✔
719

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

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

737
    setCwd(ideHome, WORKSPACE_MAIN, ideHome);
5✔
738
  }
1✔
739

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

750
  /**
751
   * Finds the path to the Bash executable.
752
   *
753
   * @return the {@link String} to the Bash executable, or {@code null} if Bash is not found
754
   */
755
  String findBash();
756

757
  /**
758
   * Finds the path to the Bash executable.
759
   *
760
   * @return the {@link String} to the Bash executable. Throws an {@link IllegalStateException} if no bash was found.
761
   */
762
  default String findBashRequired() {
763
    String bash = findBash();
3✔
764
    if (bash == null) {
2!
765
      String message = "Could not find bash what is a prerequisite of IDEasy.";
×
766
      if (getSystemInfo().isWindows()) {
×
767
        message = message + "\nPlease install Git for Windows and rerun.";
×
768
      }
769
      throw new IllegalStateException(message);
×
770
    }
771
    return bash;
2✔
772
  }
773

774
  /**
775
   * @return the {@link WindowsPathSyntax} used for {@link Path} conversion or {@code null} for no such conversion (typically if not on Windows).
776
   */
777
  WindowsPathSyntax getPathSyntax();
778

779
  /**
780
   * logs the status of {@link #getIdeHome() IDE_HOME} and {@link #getIdeRoot() IDE_ROOT}.
781
   */
782
  void logIdeHomeAndRootStatus();
783

784
  /**
785
   * @param version the {@link VersionIdentifier} to write.
786
   * @param installationPath the {@link Path directory} where to write the version to a {@link #FILE_SOFTWARE_VERSION version file}.
787
   */
788
  void writeVersionFile(VersionIdentifier version, Path installationPath);
789

790
  /**
791
   * Verifies that current {@link IdeVersion} satisfies {@link IdeVariables#IDE_MIN_VERSION}.
792
   *
793
   * @param throwException whether to throw a {@link CliException} or just log a warning.
794
   */
795
  void verifyIdeMinVersion(boolean throwException);
796

797
}
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