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

devonfw / IDEasy / 13063267543

30 Jan 2025 11:34PM UTC coverage: 68.379% (-0.2%) from 68.557%
13063267543

push

github

web-flow
#954: improve repository support (#990)

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

2857 of 4597 branches covered (62.15%)

Branch coverage included in aggregate %.

7391 of 10390 relevant lines covered (71.14%)

3.1 hits per line

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

63.92
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.merge.DirectoryMerger;
18
import com.devonfw.tools.ide.os.SystemInfo;
19
import com.devonfw.tools.ide.os.WindowsPathSyntax;
20
import com.devonfw.tools.ide.process.ProcessContext;
21
import com.devonfw.tools.ide.step.Step;
22
import com.devonfw.tools.ide.tool.mvn.Mvn;
23
import com.devonfw.tools.ide.tool.repository.CustomToolRepository;
24
import com.devonfw.tools.ide.tool.repository.ToolRepository;
25
import com.devonfw.tools.ide.url.model.UrlMetadata;
26
import com.devonfw.tools.ide.variable.IdeVariables;
27

28
/**
29
 * Interface for interaction with the user allowing to input and output information.
30
 */
31
public interface IdeContext extends IdeStartContext {
32

33
  /**
34
   * The default settings URL.
35
   *
36
   * @see com.devonfw.tools.ide.commandlet.AbstractUpdateCommandlet
37
   */
38
  String DEFAULT_SETTINGS_REPO_URL = "https://github.com/devonfw/ide-settings.git";
39

40
  /** The name of the workspaces folder. */
41
  String FOLDER_WORKSPACES = "workspaces";
42

43
  /** The name of the settings folder. */
44
  String FOLDER_SETTINGS = "settings";
45

46
  /** The name of the software folder. */
47
  String FOLDER_SOFTWARE = "software";
48

49
  /** The name of the conf folder for project specific user configurations. */
50
  String FOLDER_CONF = "conf";
51

52
  /**
53
   * The base folder name of the IDE inside IDE_ROOT. Intentionally starting with an underscore and not a dot (to prevent effects like OS hiding, maven
54
   * filtering, .gitignore, etc.).
55
   *
56
   * @see #getIdeInstallationPath()
57
   */
58
  String FOLDER_IDE_INSTALLATION = "_ide";
59

60
  /**
61
   * The name of the hidden folder for IDE configuration in the users home directory or status information in the IDE_HOME directory.
62
   *
63
   * @see #getUserHomeIde()
64
   */
65
  String FOLDER_DOT_IDE = ".ide";
66

67
  /** The name of the updates folder for temporary data and backup. */
68
  String FOLDER_UPDATES = "updates";
69

70
  /** The name of the volume folder for mounting archives like *.dmg. */
71
  String FOLDER_VOLUME = "volume";
72

73
  /** The name of the backups folder for backup. */
74
  String FOLDER_BACKUPS = "backups";
75

76
  /** The name of the downloads folder. */
77
  String FOLDER_DOWNLOADS = "Downloads";
78

79
  /** The name of the bin folder where executable files are found by default. */
80
  String FOLDER_BIN = "bin";
81

82
  /** The name of the repositories folder where properties files are stores for each repository */
83
  String FOLDER_REPOSITORIES = "repositories";
84

85
  /** The name of the repositories folder where properties files are stores for each repository */
86
  String FOLDER_LEGACY_REPOSITORIES = "projects";
87

88
  /** The name of the Contents folder inside a MacOS app. */
89
  String FOLDER_CONTENTS = "Contents";
90

91
  /** The name of the Resources folder inside a MacOS app. */
92
  String FOLDER_RESOURCES = "Resources";
93

94
  /** The name of the app folder inside a MacOS app. */
95
  String FOLDER_APP = "app";
96

97
  /** The name of the extra folder inside the software folder */
98
  String FOLDER_EXTRA = "extra";
99

100
  /**
101
   * The name of the {@link #getPluginsPath() plugins folder} and also the plugins folder inside the IDE folders of {@link #getSettingsPath() settings} (e.g.
102
   * settings/eclipse/plugins).
103
   */
104
  String FOLDER_PLUGINS = "plugins";
105

106
  /**
107
   * The name of the workspace folder inside the IDE specific {@link #FOLDER_SETTINGS settings} containing the configuration templates in #FOLDER_SETUP
108
   * #FOLDER_UPDATE.
109
   */
110
  String FOLDER_WORKSPACE = "workspace";
111

112
  /**
113
   * The name of the setup folder inside the {@link #FOLDER_WORKSPACE workspace} folder containing the templates for the configuration templates for the initial
114
   * setup of a workspace. This is closely related with the {@link #FOLDER_UPDATE update} folder.
115
   */
116
  String FOLDER_SETUP = "setup";
117

118
  /**
119
   * The name of the update folder inside the {@link #FOLDER_WORKSPACE workspace} folder containing the templates for the configuration templates for the update
120
   * 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
121
   * 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
122
   * for indentation and other code-formatting settings. If all developers in a project team use the same formatter settings, this will actively prevent
123
   * 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
124
   * 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
125
   * 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
126
   * user as needed.
127
   */
128
  String FOLDER_UPDATE = "update";
129

130
  /**
131
   * The name of the folder inside {@link #FOLDER_IDE_INSTALLATION _ide} folder containing internal resources and scripts of IDEasy.
132
   */
133
  String FOLDER_INTERNAL = "internal";
134

135
  /** The file where the installed software version is written to as plain text. */
136
  String FILE_SOFTWARE_VERSION = ".ide.software.version";
137

138
  /** The file where the installed software version is written to as plain text. */
139
  String FILE_LEGACY_SOFTWARE_VERSION = ".devon.software.version";
140

141
  /** The file for the license agreement. */
142
  String FILE_LICENSE_AGREEMENT = ".license.agreement";
143

144
  /** The file extension for a {@link java.util.Properties} file. */
145
  String EXT_PROPERTIES = ".properties";
146

147
  /** The default for {@link #getWorkspaceName()}. */
148
  String WORKSPACE_MAIN = "main";
149

150
  /** The folder with the configuration template files from the settings. */
151
  String FOLDER_TEMPLATES = "templates";
152

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

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

159
  /**
160
   * file containing the current local commit hash of the settings repository.
161
   */
162
  String SETTINGS_COMMIT_ID = ".commit.id";
163

164
  /** The IDEasy ASCII logo. */
165
  String LOGO = """
4✔
166
      __       ___ ___  ___
167
      ╲ ╲     |_ _|   ╲| __|__ _ ____ _
168
       > >     | || |) | _|/ _` (_-< || |
169
      /_/ ___ |___|___/|___╲__,_/__/╲_, |
170
         |___|                       |__/
171
      """.replace('╲', '\\');
2✔
172

173
  /**
174
   * @return {@code true} if {@link #isOfflineMode() offline mode} is active or we are NOT {@link #isOnline() online}, {@code false} otherwise.
175
   */
176
  default boolean isOffline() {
177

178
    return isOfflineMode() || !isOnline();
10!
179
  }
180

181
  /**
182
   * @return {@code true} if we are currently online (Internet access is available), {@code false} otherwise.
183
   */
184
  boolean isOnline();
185

186
  /**
187
   * Print the IDEasy {@link #LOGO logo}.
188
   */
189
  default void printLogo() {
190

191
    info(LOGO);
3✔
192
  }
1✔
193

194
  /**
195
   * Asks the user for a single string input.
196
   *
197
   * @param message The information message to display.
198
   * @param defaultValue The default value to return when no input is provided.
199
   * @return The string input from the user, or the default value if no input is provided.
200
   */
201
  String askForInput(String message, String defaultValue);
202

203
  /**
204
   * Asks the user for a single string input.
205
   *
206
   * @param message The information message to display.
207
   * @return The string input from the user, or the default value if no input is provided.
208
   */
209
  String askForInput(String message);
210

211
  /**
212
   * @param question the question to ask.
213
   * @return {@code true} if the user answered with "yes", {@code false} otherwise ("no").
214
   */
215
  default boolean question(String question) {
216

217
    String yes = "yes";
×
218
    String option = question(question, yes, "no");
×
219
    if (yes.equals(option)) {
×
220
      return true;
×
221
    }
222
    return false;
×
223
  }
224

225
  /**
226
   * @param <O> type of the option. E.g. {@link String}.
227
   * @param question the question to ask.
228
   * @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.
229
   * @return the option selected by the user as answer.
230
   */
231
  @SuppressWarnings("unchecked")
232
  <O> O question(String question, O... options);
233

234
  /**
235
   * 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
236
   * exception is thrown to abort further processing.
237
   *
238
   * @param question the yes/no question to {@link #question(String) ask}.
239
   * @throws CliAbortException if the user answered with "no" and further processing shall be aborted.
240
   */
241
  default void askToContinue(String question) {
242

243
    boolean yesContinue = question(question);
×
244
    if (!yesContinue) {
×
245
      throw new CliAbortException();
×
246
    }
247
  }
×
248

249
  /**
250
   * @param purpose the purpose why Internet connection is required.
251
   * @throws CliException if you are {@link #isOffline() offline}.
252
   */
253
  default void requireOnline(String purpose) {
254

255
    if (isOfflineMode()) {
3!
256
      throw CliOfflineException.ofPurpose(purpose);
3✔
257
    }
258
  }
×
259

260
  /**
261
   * @return the {@link SystemInfo}.
262
   */
263
  SystemInfo getSystemInfo();
264

265
  /**
266
   * @return the {@link EnvironmentVariables} with full inheritance.
267
   */
268
  EnvironmentVariables getVariables();
269

270
  /**
271
   * @return the {@link FileAccess}.
272
   */
273
  FileAccess getFileAccess();
274

275
  /**
276
   * @return the {@link CommandletManager}.
277
   */
278
  CommandletManager getCommandletManager();
279

280
  /**
281
   * @return the default {@link ToolRepository}.
282
   */
283
  ToolRepository getDefaultToolRepository();
284

285
  /**
286
   * @return the {@link CustomToolRepository}.
287
   */
288
  CustomToolRepository getCustomToolRepository();
289

290
  /**
291
   * @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
292
   *     isolated projects.
293
   * @see com.devonfw.tools.ide.variable.IdeVariables#IDE_HOME
294
   */
295
  Path getIdeHome();
296

297
  /**
298
   * @return the name of the current project.
299
   * @see com.devonfw.tools.ide.variable.IdeVariables#PROJECT_NAME
300
   */
301
  String getProjectName();
302

303
  /**
304
   * @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
305
   *     sub-folder. There is a reserved ".ide" folder where central IDE data is stored such as the {@link #getUrlsPath() download metadata} and the central
306
   *     software repository.
307
   * @see com.devonfw.tools.ide.variable.IdeVariables#IDE_ROOT
308
   */
309
  Path getIdeRoot();
310

311
  /**
312
   * @return the {@link Path} to the {@link #FOLDER_IDE_INSTALLATION IDE installation}.
313
   * @see #getIdeRoot()
314
   * @see #FOLDER_IDE_INSTALLATION
315
   */
316
  Path getIdeInstallationPath();
317

318
  /**
319
   * @return the current working directory ("user.dir"). This is the directory where the user's shell was located when the IDE CLI was invoked.
320
   */
321
  Path getCwd();
322

323
  /**
324
   * @return the {@link Path} for the temporary directory to use. Will be different from the OS specific temporary directory (java.io.tmpDir).
325
   */
326
  Path getTempPath();
327

328
  /**
329
   * @return the {@link Path} for the temporary download directory to use.
330
   */
331
  Path getTempDownloadPath();
332

333
  /**
334
   * @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
335
   *     download tools.
336
   * @see com.devonfw.tools.ide.url.model.folder.UrlRepository
337
   */
338
  Path getUrlsPath();
339

340
  /**
341
   * @return the {@link UrlMetadata}. Will be lazily instantiated and thereby automatically be cloned or pulled (by default).
342
   */
343
  UrlMetadata getUrls();
344

345
  /**
346
   * @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
347
   *     the same artifact is requested again it will be taken from the cache to avoid downloading it again.
348
   */
349
  Path getDownloadPath();
350

351
  /**
352
   * @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
353
   *     {@link #getSoftwareRepositoryPath() software repository} as sub-folder named after the according tool.
354
   */
355
  Path getSoftwarePath();
356

357
  /**
358
   * @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
359
   *     here from the {@link #getSoftwareRepositoryPath() software repository} as sub-folder named after the according tool.
360
   */
361
  Path getSoftwareExtraPath();
362

363
  /**
364
   * @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
365
   *     are shared among all IDE instances (see {@link #getIdeHome() IDE_HOME}) via symbolic links (see {@link #getSoftwarePath()}). Therefore this repository
366
   *     follows the sub-folder structure {@code «repository»/«tool»/«edition»/«version»/}. So multiple versions of the same tool exist here as different
367
   *     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
368
   *     of the scope of this folders.
369
   */
370
  Path getSoftwareRepositoryPath();
371

372
  /**
373
   * @return the {@link Path} to the {@link #FOLDER_PLUGINS plugins folder} inside {@link #getIdeHome() IDE_HOME}. All plugins of the IDE instance will be
374
   *     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.
375
   */
376
  Path getPluginsPath();
377

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

387
  /**
388
   * @return the {@link Path} to the users home directory. Typically initialized via the {@link System#getProperty(String) system property} "user.home".
389
   * @see com.devonfw.tools.ide.variable.IdeVariables#HOME
390
   */
391
  Path getUserHome();
392

393
  /**
394
   * @return the {@link Path} to the ".ide" subfolder in the {@link #getUserHome() users home directory}.
395
   */
396
  Path getUserHomeIde();
397

398
  /**
399
   * @return the {@link Path} to the {@link #FOLDER_SETTINGS settings} folder with the cloned git repository containing the project configuration.
400
   */
401
  Path getSettingsPath();
402

403
  /**
404
   * @return the {@link Path} to the {@link #FOLDER_REPOSITORIES repositories} folder with legacy fallback if not present or {@code null} if not found.
405
   */
406
  default Path getRepositoriesPath() {
407

408
    Path settingsPath = getSettingsPath();
3✔
409
    if (settingsPath == null) {
2!
410
      return null;
×
411
    }
412
    Path repositoriesPath = settingsPath.resolve(IdeContext.FOLDER_REPOSITORIES);
4✔
413
    if (Files.isDirectory(repositoriesPath)) {
5✔
414
      return repositoriesPath;
2✔
415
    }
416
    Path legacyRepositoriesPath = settingsPath.resolve(IdeContext.FOLDER_LEGACY_REPOSITORIES);
4✔
417
    if (Files.isDirectory(legacyRepositoriesPath)) {
5!
418
      return legacyRepositoriesPath;
×
419
    }
420
    return null;
2✔
421
  }
422

423
  /**
424
   * @return the {@link Path} to the {@code settings} folder with the cloned git repository containing the project configuration only if the settings repository
425
   *     is in fact a git repository.
426
   */
427
  Path getSettingsGitRepository();
428

429
  /**
430
   * @return {@code true} if the settings repository is a symlink or a junction.
431
   */
432
  boolean isSettingsRepositorySymlinkOrJunction();
433

434
  /**
435
   * @return the {@link Path} to the file containing the last tracked commit Id of the settings repository.
436
   */
437
  Path getSettingsCommitIdPath();
438

439
  /**
440
   * @return the {@link Path} to the templates folder inside the {@link #getSettingsPath() settings}. The relative directory structure in this templates folder
441
   *     is to be applied to {@link #getIdeHome() IDE_HOME} when the project is set up.
442
   */
443
  default Path getSettingsTemplatePath() {
444
    Path settingsFolder = getSettingsPath();
3✔
445
    Path templatesFolder = settingsFolder.resolve(IdeContext.FOLDER_TEMPLATES);
4✔
446
    if (!Files.isDirectory(templatesFolder)) {
5✔
447
      Path templatesFolderLegacy = settingsFolder.resolve(IdeContext.FOLDER_LEGACY_TEMPLATES);
4✔
448
      if (Files.isDirectory(templatesFolderLegacy)) {
5!
449
        templatesFolder = templatesFolderLegacy;
×
450
      } else {
451
        warning("No templates found in settings git repo neither in {} nor in {} - configuration broken", templatesFolder, templatesFolderLegacy);
13✔
452
        return null;
2✔
453
      }
454
    }
455
    return templatesFolder;
2✔
456
  }
457

458
  /**
459
   * @return the {@link Path} to the {@code conf} folder with instance specific tool configurations and the
460
   *     {@link EnvironmentVariablesType#CONF user specific project configuration}.
461
   */
462
  Path getConfPath();
463

464
  /**
465
   * @return the {@link Path} to the workspace.
466
   * @see #getWorkspaceName()
467
   */
468
  Path getWorkspacePath();
469

470
  /**
471
   * @return the name of the workspace. Defaults to {@link #WORKSPACE_MAIN}.
472
   */
473
  String getWorkspaceName();
474

475
  /**
476
   * @return the value of the system {@link IdeVariables#PATH PATH} variable. It is automatically extended according to the tools available in
477
   *     {@link #getSoftwarePath() software path} unless {@link #getIdeHome() IDE_HOME} was not found.
478
   */
479
  SystemPath getPath();
480

481
  /**
482
   * @return a new {@link ProcessContext} to {@link ProcessContext#run() run} external commands.
483
   */
484
  ProcessContext newProcess();
485

486
  /**
487
   * @param title the {@link IdeProgressBar#getTitle() title}.
488
   * @param size the {@link IdeProgressBar#getMaxSize() expected maximum size}.
489
   * @param unitName the {@link IdeProgressBar#getUnitName() unit name}.
490
   * @param unitSize the {@link IdeProgressBar#getUnitSize() unit size}.
491
   * @return the new {@link IdeProgressBar} to use.
492
   */
493
  IdeProgressBar newProgressBar(String title, long size, String unitName, long unitSize);
494

495
  /**
496
   * @param title the {@link IdeProgressBar#getTitle() title}.
497
   * @param size the {@link IdeProgressBar#getMaxSize() expected maximum size} in bytes.
498
   * @return the new {@link IdeProgressBar} to use.
499
   */
500
  default IdeProgressBar newProgressBarInMib(String title, long size) {
501

502
    return newProgressBar(title, size, "MiB", 1048576);
7✔
503
  }
504

505
  /**
506
   * @param size the {@link IdeProgressBar#getMaxSize() expected maximum size} in bytes.
507
   * @return the new {@link IdeProgressBar} for copy.
508
   */
509
  default IdeProgressBar newProgressBarForDownload(long size) {
510

511
    return newProgressBarInMib(IdeProgressBar.TITLE_DOWNLOADING, size);
5✔
512
  }
513

514
  /**
515
   * @param size the {@link IdeProgressBar#getMaxSize() expected maximum size} in bytes.
516
   * @return the new {@link IdeProgressBar} for extracting.
517
   */
518
  default IdeProgressBar newProgressbarForExtracting(long size) {
519

520
    return newProgressBarInMib(IdeProgressBar.TITLE_EXTRACTING, size);
5✔
521
  }
522

523
  /**
524
   * @param size the {@link IdeProgressBar#getMaxSize() expected maximum size} in bytes.
525
   * @return the new {@link IdeProgressBar} for copy.
526
   */
527
  default IdeProgressBar newProgressbarForCopying(long size) {
528

529
    return newProgressBarInMib(IdeProgressBar.TITLE_COPYING, size);
5✔
530
  }
531

532
  /**
533
   * @return the {@link DirectoryMerger} used to configure and merge the workspace for an {@link com.devonfw.tools.ide.tool.ide.IdeToolCommandlet IDE}.
534
   */
535
  DirectoryMerger getWorkspaceMerger();
536

537
  /**
538
   * @return the {@link Path} to the working directory from where the command is executed.
539
   */
540
  Path getDefaultExecutionDirectory();
541

542
  /**
543
   * @return the {@link IdeSystem} instance wrapping {@link System}.
544
   */
545
  IdeSystem getSystem();
546

547
  /**
548
   * @return the {@link GitContext} used to run several git commands.
549
   */
550
  GitContext getGitContext();
551

552
  /**
553
   * @return the String value for the variable MAVEN_ARGS, or null if called outside an IDEasy installation.
554
   */
555
  default String getMavenArgs() {
556

557
    if (getIdeHome() == null) {
3!
558
      return null;
×
559
    }
560
    Mvn mvn = getCommandletManager().getCommandlet(Mvn.class);
6✔
561
    return mvn.getMavenArgs();
3✔
562
  }
563

564
  /**
565
   * @return the String value for the variable M2_REPO, or falls back to the default USER_HOME/.m2 location if called outside an IDEasy installation.
566
   */
567
  default Path getMavenRepository() {
568

569
    if (getIdeHome() != null) {
3!
570
      Path confPath = getConfPath();
3✔
571
      Path m2Folder = confPath.resolve(Mvn.MVN_CONFIG_FOLDER);
4✔
572
      if (!Files.isDirectory(m2Folder)) {
5✔
573
        Path m2LegacyFolder = confPath.resolve(Mvn.MVN_CONFIG_LEGACY_FOLDER);
4✔
574
        if (Files.isDirectory(m2LegacyFolder)) {
5!
575
          m2Folder = m2LegacyFolder;
×
576
        } else {
577
          // fallback to USER_HOME/.m2 folder
578
          m2Folder = getUserHome().resolve(Mvn.MVN_CONFIG_LEGACY_FOLDER);
5✔
579
        }
580
      }
581
      return m2Folder.resolve("repository");
4✔
582
    }
583
    return null;
×
584
  }
585

586
  /**
587
   * Updates the current working directory (CWD) and configures the environment paths according to the specified parameters. This method is central to changing
588
   * the IDE's notion of where it operates, affecting where configurations, workspaces, settings, and other resources are located or loaded from.
589
   *
590
   * @return the current {@link Step} of processing.
591
   */
592
  Step getCurrentStep();
593

594
  /**
595
   * @param name the {@link Step#getName() name} of the new {@link Step}.
596
   * @return the new {@link Step} that has been created and started.
597
   */
598
  default Step newStep(String name) {
599

600
    return newStep(name, Step.NO_PARAMS);
5✔
601
  }
602

603
  /**
604
   * @param name the {@link Step#getName() name} of the new {@link Step}.
605
   * @param parameters the {@link Step#getParameter(int) parameters} of the {@link Step}.
606
   * @return the new {@link Step} that has been created and started.
607
   */
608
  default Step newStep(String name, Object... parameters) {
609

610
    return newStep(false, name, parameters);
6✔
611
  }
612

613
  /**
614
   * @param silent the {@link Step#isSilent() silent flag}.
615
   * @param name the {@link Step#getName() name} of the new {@link Step}.
616
   * @param parameters the {@link Step#getParameter(int) parameters} of the {@link Step}.
617
   * @return the new {@link Step} that has been created and started.
618
   */
619
  Step newStep(boolean silent, String name, Object... parameters);
620

621
  /**
622
   * Updates the current working directory (CWD) and configures the environment paths according to the specified parameters. This method is central to changing
623
   * the IDE's notion of where it operates, affecting where configurations, workspaces, settings, and other resources are located or loaded from.
624
   *
625
   * @param ideHome The path to the IDE home directory.
626
   */
627
  default void setIdeHome(Path ideHome) {
628

629
    setCwd(ideHome, WORKSPACE_MAIN, ideHome);
5✔
630
  }
1✔
631

632
  /**
633
   * Updates the current working directory (CWD) and configures the environment paths according to the specified parameters. This method is central to changing
634
   * the IDE's notion of where it operates, affecting where configurations, workspaces, settings, and other resources are located or loaded from.
635
   *
636
   * @param userDir The path to set as the current working directory.
637
   * @param workspace The name of the workspace within the IDE's environment.
638
   * @param ideHome The path to the IDE home directory.
639
   */
640
  void setCwd(Path userDir, String workspace, Path ideHome);
641

642
  /**
643
   * Finds the path to the Bash executable.
644
   *
645
   * @return the {@link String} to the Bash executable, or {@code null} if Bash is not found
646
   */
647
  String findBash();
648

649
  /**
650
   * Finds the path to the Bash executable.
651
   *
652
   * @return the {@link String} to the Bash executable. Throws an {@link IllegalStateException} if no bash was found.
653
   */
654
  default String findBashRequired() {
655
    String bash = findBash();
3✔
656
    if (bash == null) {
2!
657
      String message = "Could not find bash what is a prerequisite of IDEasy.";
×
658
      if (getSystemInfo().isWindows()) {
×
659
        message = message + "\nPlease install Git for Windows and rerun.";
×
660
      }
661
      throw new IllegalStateException(message);
×
662
    }
663
    return bash;
2✔
664
  }
665

666
  /**
667
   * @return the {@link WindowsPathSyntax} used for {@link Path} conversion or {@code null} for no such conversion (typically if not on Windows).
668
   */
669
  WindowsPathSyntax getPathSyntax();
670

671
  /**
672
   * logs the status of {@link #getIdeHome() IDE_HOME} and {@link #getIdeRoot() IDE_ROOT}.
673
   */
674
  void logIdeHomeAndRootStatus();
675

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