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

devonfw / IDEasy / 15930453039

27 Jun 2025 03:51PM UTC coverage: 68.695% (+0.4%) from 68.252%
15930453039

Pull #1375

github

web-flow
Merge 649f4ade0 into e6e2881bb
Pull Request #1375: #742: Show warning when git repo name does not meet name convention.

3284 of 5190 branches covered (63.28%)

Branch coverage included in aggregate %.

8377 of 11785 relevant lines covered (71.08%)

3.14 hits per line

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

72.26
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.MavenRepository;
28
import com.devonfw.tools.ide.tool.repository.ToolRepository;
29
import com.devonfw.tools.ide.url.model.UrlMetadata;
30
import com.devonfw.tools.ide.variable.IdeVariables;
31
import com.devonfw.tools.ide.version.IdeVersion;
32
import com.devonfw.tools.ide.version.VersionIdentifier;
33

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

218
  /**
219
   * Asks the user for a single string input.
220
   *
221
   * @param message The information message to display.
222
   * @param defaultValue The default value to return when no input is provided.
223
   * @return The string input from the user, or the default value if no input is provided.
224
   */
225
  String askForInput(String message, String defaultValue);
226

227
  /**
228
   * Asks the user for a single string input.
229
   *
230
   * @param message The information message to display.
231
   * @return The string input from the user, or the default value if no input is provided.
232
   */
233
  String askForInput(String message);
234

235
  /**
236
   * @param question the question to ask.
237
   * @return {@code true} if the user answered with "yes", {@code false} otherwise ("no").
238
   */
239
  default boolean question(String question) {
240

241
    String yes = "yes";
×
242
    String option = question(new String[] { yes, "no" }, question, new Object[0]);
×
243
    if (yes.equals(option)) {
×
244
      return true;
×
245
    }
246
    return false;
×
247
  }
248

249
  /**
250
   * @param question the question to ask.
251
   * @param args
252
   * @return {@code true} if the user answered with "yes", {@code false} otherwise ("no").
253
   */
254
  default boolean question(String question, Object... args) {
255

256
    String yes = "yes";
2✔
257
    String option = question(new String[] { yes, "no" }, question, args);
16✔
258
    if (yes.equals(option)) {
4!
259
      return true;
2✔
260
    }
261
    return false;
×
262
  }
263

264
  /**
265
   * @param <O> type of the option. E.g. {@link String}.
266
   * @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.
267
   * @param question the question to ask.
268
   * @return the option selected by the user as answer.
269
   */
270
  @SuppressWarnings("unchecked")
271
  <O> O question(O[] options, String question, Object... args);
272

273

274
  /**
275
   * 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
276
   * exception is thrown to abort further processing.
277
   *
278
   * @param question the yes/no question to {@link #question(String) ask}.
279
   * @throws CliAbortException if the user answered with "no" and further processing shall be aborted.
280
   */
281
  default void askToContinue(String question) {
282

283
    boolean yesContinue = question(question);
×
284
    if (!yesContinue) {
×
285
      throw new CliAbortException();
×
286
    }
287
  }
×
288

289
  /**
290
   * 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
291
   * exception is thrown to abort further processing.
292
   *
293
   * @param questionTemplate the yes/no question to {@link #question(String) ask}.
294
   * @param args the arguments to fill the placeholders in the question template.
295
   * @throws CliAbortException if the user answered with "no" and further processing shall be aborted.
296
   */
297
  default void askToContinue(String questionTemplate, Object... args) {
298
    boolean yesContinue = question(questionTemplate, args);
5✔
299
    if (!yesContinue) {
2!
300
      throw new CliAbortException();
×
301
    }
302
  }
1✔
303

304
  /**
305
   * @param purpose the purpose why Internet connection is required.
306
   * @param explicitOnlineCheck if {@code true}, perform an explicit {@link #isOffline()} check; if {@code false} use {@link #isOfflineMode()}.
307
   * @throws CliException if you are {@link #isOffline() offline}.
308
   */
309
  default void requireOnline(String purpose, boolean explicitOnlineCheck) {
310

311
    if (explicitOnlineCheck) {
2✔
312
      if (isOffline()) {
3✔
313
        throw CliOfflineException.ofPurpose(purpose);
3✔
314
      }
315
    } else {
316
      if (isOfflineMode()) {
3!
317
        throw CliOfflineException.ofPurpose(purpose);
3✔
318
      }
319
    }
320
  }
1✔
321

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

327
  /**
328
   * @return the {@link EnvironmentVariables} with full inheritance.
329
   */
330
  EnvironmentVariables getVariables();
331

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

337
  /**
338
   * @return the {@link CommandletManager}.
339
   */
340
  CommandletManager getCommandletManager();
341

342
  /**
343
   * @return the default {@link ToolRepository}.
344
   */
345
  ToolRepository getDefaultToolRepository();
346

347
  /**
348
   * @return the {@link CustomToolRepository}.
349
   */
350
  CustomToolRepository getCustomToolRepository();
351

352
  /**
353
   * @return the {@link MavenRepository}.
354
   */
355
  MavenRepository getMavenToolRepository();
356

357
  /**
358
   * @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
359
   *     isolated projects.
360
   * @see com.devonfw.tools.ide.variable.IdeVariables#IDE_HOME
361
   */
362
  Path getIdeHome();
363

364
  /**
365
   * @return the name of the current project.
366
   * @see com.devonfw.tools.ide.variable.IdeVariables#PROJECT_NAME
367
   */
368
  String getProjectName();
369

370
  /**
371
   * @return the IDEasy version the {@link #getIdeHome() current project} was created with or migrated to.
372
   */
373
  VersionIdentifier getProjectVersion();
374

375
  /**
376
   * @param version the new value of {@link #getProjectVersion()}.
377
   */
378
  void setProjectVersion(VersionIdentifier version);
379

380
  /**
381
   * @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
382
   *     sub-folder. There is a reserved ".ide" folder where central IDE data is stored such as the {@link #getUrlsPath() download metadata} and the central
383
   *     software repository.
384
   * @see com.devonfw.tools.ide.variable.IdeVariables#IDE_ROOT
385
   */
386
  Path getIdeRoot();
387

388
  /**
389
   * @return the {@link Path} to the {@link #FOLDER_UNDERSCORE_IDE}.
390
   * @see #getIdeRoot()
391
   * @see #FOLDER_UNDERSCORE_IDE
392
   */
393
  Path getIdePath();
394

395
  /**
396
   * @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
397
   *     upgrade a new release is installed and the link is switched to the new release.
398
   */
399
  default Path getIdeInstallationPath() {
400

401
    return getIdePath().resolve(FOLDER_INSTALLATION);
×
402
  }
403

404
  /**
405
   * @return the current working directory ("user.dir"). This is the directory where the user's shell was located when the IDE CLI was invoked.
406
   */
407
  Path getCwd();
408

409
  /**
410
   * @return the {@link Path} for the temporary directory to use. Will be different from the OS specific temporary directory (java.io.tmpDir).
411
   */
412
  Path getTempPath();
413

414
  /**
415
   * @return the {@link Path} for the temporary download directory to use.
416
   */
417
  Path getTempDownloadPath();
418

419
  /**
420
   * @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
421
   *     download tools.
422
   * @see com.devonfw.tools.ide.url.model.folder.UrlRepository
423
   */
424
  Path getUrlsPath();
425

426
  /**
427
   * @return the {@link UrlMetadata}. Will be lazily instantiated and thereby automatically be cloned or pulled (by default).
428
   */
429
  UrlMetadata getUrls();
430

431
  /**
432
   * @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
433
   *     the same artifact is requested again it will be taken from the cache to avoid downloading it again.
434
   */
435
  Path getDownloadPath();
436

437
  /**
438
   * @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
439
   *     {@link #getSoftwareRepositoryPath() software repository} as sub-folder named after the according tool.
440
   */
441
  Path getSoftwarePath();
442

443
  /**
444
   * @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
445
   *     here from the {@link #getSoftwareRepositoryPath() software repository} as sub-folder named after the according tool.
446
   */
447
  Path getSoftwareExtraPath();
448

449
  /**
450
   * @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
451
   *     are shared among all IDE instances (see {@link #getIdeHome() IDE_HOME}) via symbolic links (see {@link #getSoftwarePath()}). Therefore this repository
452
   *     follows the sub-folder structure {@code «repository»/«tool»/«edition»/«version»/}. So multiple versions of the same tool exist here as different
453
   *     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
454
   *     of the scope of this folders.
455
   */
456
  Path getSoftwareRepositoryPath();
457

458
  /**
459
   * @return the {@link Path} to the {@link #FOLDER_PLUGINS plugins folder} inside {@link #getIdeHome() IDE_HOME}. All plugins of the IDE instance will be
460
   *     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.
461
   */
462
  Path getPluginsPath();
463

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

473
  /**
474
   * @return the {@link Path} to the users home directory. Typically initialized via the {@link System#getProperty(String) system property} "user.home".
475
   * @see com.devonfw.tools.ide.variable.IdeVariables#HOME
476
   */
477
  Path getUserHome();
478

479
  /**
480
   * @return the {@link Path} to the ".ide" subfolder in the {@link #getUserHome() users home directory}.
481
   */
482
  Path getUserHomeIde();
483

484
  /**
485
   * @return the {@link Path} to the {@link #FOLDER_SETTINGS settings} folder with the cloned git repository containing the project configuration.
486
   */
487
  Path getSettingsPath();
488

489
  /**
490
   * @return the {@link Path} to the {@link #FOLDER_REPOSITORIES repositories} folder with legacy fallback if not present or {@code null} if not found.
491
   */
492
  default Path getRepositoriesPath() {
493

494
    Path settingsPath = getSettingsPath();
3✔
495
    if (settingsPath == null) {
2!
496
      return null;
×
497
    }
498
    Path repositoriesPath = settingsPath.resolve(IdeContext.FOLDER_REPOSITORIES);
4✔
499
    if (Files.isDirectory(repositoriesPath)) {
5✔
500
      return repositoriesPath;
2✔
501
    }
502
    Path legacyRepositoriesPath = settingsPath.resolve(IdeContext.FOLDER_LEGACY_REPOSITORIES);
4✔
503
    if (Files.isDirectory(legacyRepositoriesPath)) {
5!
504
      return legacyRepositoriesPath;
×
505
    }
506
    return null;
2✔
507
  }
508

509
  /**
510
   * @return the {@link Path} to the {@code settings} folder with the cloned git repository containing the project configuration only if the settings repository
511
   *     is in fact a git repository.
512
   */
513
  Path getSettingsGitRepository();
514

515
  /**
516
   * @return {@code true} if the settings repository is a symlink or a junction.
517
   */
518
  boolean isSettingsRepositorySymlinkOrJunction();
519

520
  /**
521
   * @return the {@link Path} to the file containing the last tracked commit Id of the settings repository.
522
   */
523
  Path getSettingsCommitIdPath();
524

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

544
  /**
545
   * @return the {@link Path} to the {@code conf} folder with instance specific tool configurations and the
546
   *     {@link EnvironmentVariablesType#CONF user specific project configuration}.
547
   */
548
  Path getConfPath();
549

550
  /**
551
   * @return the {@link Path} to the workspace.
552
   * @see #getWorkspaceName()
553
   */
554
  Path getWorkspacePath();
555

556
  /**
557
   * @return the name of the workspace. Defaults to {@link #WORKSPACE_MAIN}.
558
   */
559
  String getWorkspaceName();
560

561
  /**
562
   * @return the value of the system {@link IdeVariables#PATH PATH} variable. It is automatically extended according to the tools available in
563
   *     {@link #getSoftwarePath() software path} unless {@link #getIdeHome() IDE_HOME} was not found.
564
   */
565
  SystemPath getPath();
566

567
  /**
568
   * @return a new {@link ProcessContext} to {@link ProcessContext#run() run} external commands.
569
   */
570
  ProcessContext newProcess();
571

572
  /**
573
   * @param title the {@link IdeProgressBar#getTitle() title}.
574
   * @param size the {@link IdeProgressBar#getMaxSize() expected maximum size}.
575
   * @param unitName the {@link IdeProgressBar#getUnitName() unit name}.
576
   * @param unitSize the {@link IdeProgressBar#getUnitSize() unit size}.
577
   * @return the new {@link IdeProgressBar} to use.
578
   */
579
  IdeProgressBar newProgressBar(String title, long size, String unitName, long unitSize);
580

581
  /**
582
   * @param title the {@link IdeProgressBar#getTitle() title}.
583
   * @param size the {@link IdeProgressBar#getMaxSize() expected maximum size} in bytes.
584
   * @return the new {@link IdeProgressBar} to use.
585
   */
586
  default IdeProgressBar newProgressBarInMib(String title, long size) {
587

588
    if ((size > 0) && (size < 1024)) {
8✔
589
      return new IdeProgressBarNone(title, size, IdeProgressBar.UNIT_NAME_MB, IdeProgressBar.UNIT_SIZE_MB);
8✔
590
    }
591
    return newProgressBar(title, size, IdeProgressBar.UNIT_NAME_MB, IdeProgressBar.UNIT_SIZE_MB);
7✔
592
  }
593

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

600
    return newProgressBarInMib(IdeProgressBar.TITLE_DOWNLOADING, size);
5✔
601
  }
602

603
  /**
604
   * @param size the {@link IdeProgressBar#getMaxSize() expected maximum size} in bytes.
605
   * @return the new {@link IdeProgressBar} for extracting.
606
   */
607
  default IdeProgressBar newProgressbarForExtracting(long size) {
608

609
    return newProgressBarInMib(IdeProgressBar.TITLE_EXTRACTING, size);
5✔
610
  }
611

612
  /**
613
   * @param size the {@link IdeProgressBar#getMaxSize() expected maximum size} in bytes.
614
   * @return the new {@link IdeProgressBar} for copy.
615
   */
616
  default IdeProgressBar newProgressbarForCopying(long size) {
617

618
    return newProgressBarInMib(IdeProgressBar.TITLE_COPYING, size);
5✔
619
  }
620

621
  /**
622
   * @param size the {@link IdeProgressBar#getMaxSize() expected maximum} plugin count.
623
   * @return the new {@link IdeProgressBar} to use.
624
   */
625
  default IdeProgressBar newProgressBarForPlugins(long size) {
626
    return newProgressBar(IdeProgressBar.TITLE_INSTALL_PLUGIN, size, IdeProgressBar.UNIT_NAME_PLUGIN, IdeProgressBar.UNIT_SIZE_PLUGIN);
7✔
627
  }
628

629
  /**
630
   * @return the {@link DirectoryMerger} used to configure and merge the workspace for an {@link com.devonfw.tools.ide.tool.ide.IdeToolCommandlet IDE}.
631
   */
632
  DirectoryMerger getWorkspaceMerger();
633

634
  /**
635
   * @return the {@link Path} to the working directory from where the command is executed.
636
   */
637
  Path getDefaultExecutionDirectory();
638

639
  /**
640
   * @return the {@link IdeSystem} instance wrapping {@link System}.
641
   */
642
  IdeSystem getSystem();
643

644
  /**
645
   * @return the {@link GitContext} used to run several git commands.
646
   */
647
  GitContext getGitContext();
648

649
  /**
650
   * @return the String value for the variable MAVEN_ARGS, or null if called outside an IDEasy installation.
651
   */
652
  default String getMavenArgs() {
653

654
    if (getIdeHome() == null) {
3!
655
      return null;
×
656
    }
657
    Mvn mvn = getCommandletManager().getCommandlet(Mvn.class);
6✔
658
    return mvn.getMavenArgs();
3✔
659
  }
660

661
  /**
662
   * @return the path for the variable GRADLE_USER_HOME, or null if called outside an IDEasy installation.
663
   */
664
  default Path getGradleUserHome() {
665

666
    if (getIdeHome() == null) {
3!
667
      return null;
×
668
    }
669
    Gradle gradle = getCommandletManager().getCommandlet(Gradle.class);
6✔
670
    return gradle.getOrCreateGradleConfFolder();
3✔
671
  }
672

673
  /**
674
   * @return the {@link Path} pointing to the maven configuration directory (where "settings.xml" or "settings-security.xml" are located).
675
   */
676
  default Path getMavenConfigurationFolder() {
677

678
    Path confPath = getConfPath();
3✔
679
    Path mvnConfFolder = null;
2✔
680
    if (confPath != null) {
2✔
681
      mvnConfFolder = confPath.resolve(Mvn.MVN_CONFIG_FOLDER);
4✔
682
      if (!Files.isDirectory(mvnConfFolder)) {
5✔
683
        Path m2LegacyFolder = confPath.resolve(Mvn.MVN_CONFIG_LEGACY_FOLDER);
4✔
684
        if (Files.isDirectory(m2LegacyFolder)) {
5!
685
          mvnConfFolder = m2LegacyFolder;
×
686
        } else {
687
          mvnConfFolder = null; // see fallback below
2✔
688
        }
689
      }
690
    }
691
    if (mvnConfFolder == null) {
2✔
692
      // fallback to USER_HOME/.m2 folder
693
      mvnConfFolder = getUserHome().resolve(Mvn.MVN_CONFIG_LEGACY_FOLDER);
5✔
694
    }
695
    return mvnConfFolder;
2✔
696
  }
697

698
  /**
699
   * Updates the current working directory (CWD) and configures the environment paths according to the specified parameters. This method is central to changing
700
   * the IDE's notion of where it operates, affecting where configurations, workspaces, settings, and other resources are located or loaded from.
701
   *
702
   * @return the current {@link Step} of processing.
703
   */
704
  Step getCurrentStep();
705

706
  /**
707
   * @param name the {@link Step#getName() name} of the new {@link Step}.
708
   * @return the new {@link Step} that has been created and started.
709
   */
710
  default Step newStep(String name) {
711

712
    return newStep(name, Step.NO_PARAMS);
5✔
713
  }
714

715
  /**
716
   * @param name the {@link Step#getName() name} of the new {@link Step}.
717
   * @param parameters the {@link Step#getParameter(int) parameters} of the {@link Step}.
718
   * @return the new {@link Step} that has been created and started.
719
   */
720
  default Step newStep(String name, Object... parameters) {
721

722
    return newStep(false, name, parameters);
6✔
723
  }
724

725
  /**
726
   * @param silent the {@link Step#isSilent() silent flag}.
727
   * @param name the {@link Step#getName() name} of the new {@link Step}.
728
   * @param parameters the {@link Step#getParameter(int) parameters} of the {@link Step}.
729
   * @return the new {@link Step} that has been created and started.
730
   */
731
  Step newStep(boolean silent, String name, Object... parameters);
732

733
  /**
734
   * @param lambda the {@link Runnable} to {@link Runnable#run() run} while the {@link com.devonfw.tools.ide.log.IdeLogger logging} is entirely disabled.
735
   *     After this the logging will be enabled again. Collected log messages will then be logged at the end.
736
   */
737
  default void runWithoutLogging(Runnable lambda) {
738

739
    runWithoutLogging(lambda, IdeLogLevel.TRACE);
4✔
740
  }
1✔
741

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

751
  /**
752
   * Updates the current working directory (CWD) and configures the environment paths according to the specified parameters. This method is central to changing
753
   * the IDE's notion of where it operates, affecting where configurations, workspaces, settings, and other resources are located or loaded from.
754
   *
755
   * @param ideHome The path to the IDE home directory.
756
   */
757
  default void setIdeHome(Path ideHome) {
758

759
    setCwd(ideHome, WORKSPACE_MAIN, ideHome);
5✔
760
  }
1✔
761

762
  /**
763
   * Updates the current working directory (CWD) and configures the environment paths according to the specified parameters. This method is central to changing
764
   * the IDE's notion of where it operates, affecting where configurations, workspaces, settings, and other resources are located or loaded from.
765
   *
766
   * @param userDir The path to set as the current working directory.
767
   * @param workspace The name of the workspace within the IDE's environment.
768
   * @param ideHome The path to the IDE home directory.
769
   */
770
  void setCwd(Path userDir, String workspace, Path ideHome);
771

772
  /**
773
   * Finds the path to the Bash executable.
774
   *
775
   * @return the {@link String} to the Bash executable, or {@code null} if Bash is not found
776
   */
777
  String findBash();
778

779
  /**
780
   * Finds the path to the Bash executable.
781
   *
782
   * @return the {@link String} to the Bash executable. Throws an {@link IllegalStateException} if no bash was found.
783
   */
784
  default String findBashRequired() {
785
    String bash = findBash();
3✔
786
    if (bash == null) {
2!
787
      String message = "Could not find bash what is a prerequisite of IDEasy.";
×
788
      if (getSystemInfo().isWindows()) {
×
789
        message = message + "\nPlease install Git for Windows and rerun.";
×
790
      }
791
      throw new IllegalStateException(message);
×
792
    }
793
    return bash;
2✔
794
  }
795

796
  /**
797
   * @return the {@link WindowsPathSyntax} used for {@link Path} conversion or {@code null} for no such conversion (typically if not on Windows).
798
   */
799
  WindowsPathSyntax getPathSyntax();
800

801
  /**
802
   * logs the status of {@link #getIdeHome() IDE_HOME} and {@link #getIdeRoot() IDE_ROOT}.
803
   */
804
  void logIdeHomeAndRootStatus();
805

806
  /**
807
   * @param version the {@link VersionIdentifier} to write.
808
   * @param installationPath the {@link Path directory} where to write the version to a {@link #FILE_SOFTWARE_VERSION version file}.
809
   */
810
  void writeVersionFile(VersionIdentifier version, Path installationPath);
811

812
  /**
813
   * Verifies that current {@link IdeVersion} satisfies {@link IdeVariables#IDE_MIN_VERSION}.
814
   *
815
   * @param throwException whether to throw a {@link CliException} or just log a warning.
816
   */
817
  void verifyIdeMinVersion(boolean throwException);
818

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