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

devonfw / IDEasy / 12073943517

28 Nov 2024 06:24PM UTC coverage: 67.417% (+0.03%) from 67.39%
12073943517

push

github

web-flow
#778: add icd #779: use functions instead of alias #810: setup in current shell #782: fix IDE_ROOT on linux/mac #774: fixed HTTP proxy support (#811)

2500 of 4050 branches covered (61.73%)

Branch coverage included in aggregate %.

6511 of 9316 relevant lines covered (69.89%)

3.09 hits per line

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

58.9
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.io.FileAccess;
15
import com.devonfw.tools.ide.io.IdeProgressBar;
16
import com.devonfw.tools.ide.merge.DirectoryMerger;
17
import com.devonfw.tools.ide.os.SystemInfo;
18
import com.devonfw.tools.ide.os.WindowsPathSyntax;
19
import com.devonfw.tools.ide.process.ProcessContext;
20
import com.devonfw.tools.ide.repo.CustomToolRepository;
21
import com.devonfw.tools.ide.repo.ToolRepository;
22
import com.devonfw.tools.ide.step.Step;
23
import com.devonfw.tools.ide.tool.mvn.Mvn;
24
import com.devonfw.tools.ide.url.model.UrlMetadata;
25
import com.devonfw.tools.ide.variable.IdeVariables;
26

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

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

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

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

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

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

51
  /**
52
   * 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
53
   * filtering, .gitignore, etc.).
54
   */
55
  String FOLDER_IDE = "_ide";
56

57
  /** The name of the updates folder for temporary data and backup. */
58
  String FOLDER_UPDATES = "updates";
59

60
  /** The name of the volume folder for mounting archives like *.dmg. */
61
  String FOLDER_VOLUME = "volume";
62

63
  /** The name of the backups folder for backup. */
64
  String FOLDER_BACKUPS = "backups";
65

66
  /** The name of the downloads folder. */
67
  String FOLDER_DOWNLOADS = "Downloads";
68

69
  /** The name of the bin folder where executable files are found by default. */
70
  String FOLDER_BIN = "bin";
71

72
  /** The name of the repositories folder where properties files are stores for each repository */
73
  String FOLDER_REPOSITORIES = "repositories";
74

75
  /** The name of the repositories folder where properties files are stores for each repository */
76
  String FOLDER_LEGACY_REPOSITORIES = "projects";
77

78
  /** The name of the Contents folder inside a MacOS app. */
79
  String FOLDER_CONTENTS = "Contents";
80

81
  /** The name of the Resources folder inside a MacOS app. */
82
  String FOLDER_RESOURCES = "Resources";
83

84
  /** The name of the app folder inside a MacOS app. */
85
  String FOLDER_APP = "app";
86

87
  /** The name of the extra folder inside the software folder */
88
  String FOLDER_EXTRA = "extra";
89

90
  /**
91
   * The name of the {@link #getPluginsPath() plugins folder} and also the plugins folder inside the IDE folders of {@link #getSettingsPath() settings} (e.g.
92
   * settings/eclipse/plugins).
93
   */
94
  String FOLDER_PLUGINS = "plugins";
95

96
  /**
97
   * The name of the workspace folder inside the IDE specific {@link #FOLDER_SETTINGS settings} containing the configuration templates in #FOLDER_SETUP
98
   * #FOLDER_UPDATE.
99
   */
100
  String FOLDER_WORKSPACE = "workspace";
101

102
  /**
103
   * The name of the setup folder inside the {@link #FOLDER_WORKSPACE workspace} folder containing the templates for the configuration templates for the initial
104
   * setup of a workspace. This is closely related with the {@link #FOLDER_UPDATE update} folder.
105
   */
106
  String FOLDER_SETUP = "setup";
107

108
  /**
109
   * The name of the update folder inside the {@link #FOLDER_WORKSPACE workspace} folder containing the templates for the configuration templates for the update
110
   * 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
111
   * 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
112
   * for indentation and other code-formatting settings. If all developers in a project team use the same formatter settings, this will actively prevent
113
   * 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
114
   * 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
115
   * 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
116
   * user as needed.
117
   */
118
  String FOLDER_UPDATE = "update";
119

120
  /** The file where the installed software version is written to as plain text. */
121
  String FILE_SOFTWARE_VERSION = ".ide.software.version";
122

123
  /** The file where the installed software version is written to as plain text. */
124
  String FILE_LEGACY_SOFTWARE_VERSION = ".devon.software.version";
125

126
  /** The file extension for a {@link java.util.Properties} file. */
127
  String EXT_PROPERTIES = ".properties";
128

129
  /** The default for {@link #getWorkspaceName()}. */
130
  String WORKSPACE_MAIN = "main";
131

132
  /** The folder with the configuration template files from the settings. */
133
  String FOLDER_TEMPLATES = "templates";
134

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

138
  /**
139
   * @return {@code true} if {@link #isOfflineMode() offline mode} is active or we are NOT {@link #isOnline() online}, {@code false} otherwise.
140
   */
141
  default boolean isOffline() {
142

143
    return isOfflineMode() || !isOnline();
10✔
144
  }
145

146
  /**
147
   * @return {@code true} if we are currently online (Internet access is available), {@code false} otherwise.
148
   */
149
  boolean isOnline();
150

151
  /**
152
   * Asks the user for a single string input.
153
   *
154
   * @param message The information message to display.
155
   * @param defaultValue The default value to return when no input is provided.
156
   * @return The string input from the user, or the default value if no input is provided.
157
   */
158
  String askForInput(String message, String defaultValue);
159

160
  /**
161
   * Asks the user for a single string input.
162
   *
163
   * @param message The information message to display.
164
   * @return The string input from the user, or the default value if no input is provided.
165
   */
166
  String askForInput(String message);
167

168
  /**
169
   * @param question the question to ask.
170
   * @return {@code true} if the user answered with "yes", {@code false} otherwise ("no").
171
   */
172
  default boolean question(String question) {
173

174
    String yes = "yes";
×
175
    String option = question(question, yes, "no");
×
176
    if (yes.equals(option)) {
×
177
      return true;
×
178
    }
179
    return false;
×
180
  }
181

182
  /**
183
   * @param <O> type of the option. E.g. {@link String}.
184
   * @param question the question to ask.
185
   * @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.
186
   * @return the option selected by the user as answer.
187
   */
188
  @SuppressWarnings("unchecked")
189
  <O> O question(String question, O... options);
190

191
  /**
192
   * 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
193
   * exception is thrown to abort further processing.
194
   *
195
   * @param question the yes/no question to {@link #question(String) ask}.
196
   * @throws CliAbortException if the user answered with "no" and further processing shall be aborted.
197
   */
198
  default void askToContinue(String question) {
199

200
    boolean yesContinue = question(question);
×
201
    if (!yesContinue) {
×
202
      throw new CliAbortException();
×
203
    }
204
  }
×
205

206
  /**
207
   * @param purpose the purpose why Internet connection is required.
208
   * @throws CliException if you are {@link #isOffline() offline}.
209
   */
210
  default void requireOnline(String purpose) {
211

212
    if (isOfflineMode()) {
3!
213
      throw CliOfflineException.ofPurpose(purpose);
×
214
    }
215
  }
1✔
216

217
  /**
218
   * @return the {@link SystemInfo}.
219
   */
220
  SystemInfo getSystemInfo();
221

222
  /**
223
   * @return the {@link EnvironmentVariables} with full inheritance.
224
   */
225
  EnvironmentVariables getVariables();
226

227
  /**
228
   * @return the {@link FileAccess}.
229
   */
230
  FileAccess getFileAccess();
231

232
  /**
233
   * @return the {@link CommandletManager}.
234
   */
235
  CommandletManager getCommandletManager();
236

237
  /**
238
   * @return the default {@link ToolRepository}.
239
   */
240
  ToolRepository getDefaultToolRepository();
241

242
  /**
243
   * @return the {@link CustomToolRepository}.
244
   */
245
  CustomToolRepository getCustomToolRepository();
246

247
  /**
248
   * @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
249
   *     isolated projects.
250
   * @see com.devonfw.tools.ide.variable.IdeVariables#IDE_HOME
251
   */
252
  Path getIdeHome();
253

254
  /**
255
   * @return the name of the current project.
256
   * @see com.devonfw.tools.ide.variable.IdeVariables#PROJECT_NAME
257
   */
258
  String getProjectName();
259

260
  /**
261
   * @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
262
   *     sub-folder. There is a reserved ".ide" folder where central IDE data is stored such as the {@link #getUrlsPath() download metadata} and the central
263
   *     software repository.
264
   * @see com.devonfw.tools.ide.variable.IdeVariables#IDE_ROOT
265
   */
266
  Path getIdeRoot();
267

268
  /**
269
   * @return the current working directory ("user.dir"). This is the directory where the user's shell was located when the IDE CLI was invoked.
270
   */
271
  Path getCwd();
272

273
  /**
274
   * @return the {@link Path} for the temporary directory to use. Will be different from the OS specific temporary directory (java.io.tmpDir).
275
   */
276
  Path getTempPath();
277

278
  /**
279
   * @return the {@link Path} for the temporary download directory to use.
280
   */
281
  Path getTempDownloadPath();
282

283
  /**
284
   * @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
285
   *     download tools.
286
   * @see com.devonfw.tools.ide.url.model.folder.UrlRepository
287
   */
288
  Path getUrlsPath();
289

290
  /**
291
   * @return the {@link UrlMetadata}. Will be lazily instantiated and thereby automatically be cloned or pulled (by default).
292
   */
293
  UrlMetadata getUrls();
294

295
  /**
296
   * @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
297
   *     the same artifact is requested again it will be taken from the cache to avoid downloading it again.
298
   */
299
  Path getDownloadPath();
300

301
  /**
302
   * @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
303
   *     {@link #getSoftwareRepositoryPath() software repository} as sub-folder named after the according tool.
304
   */
305
  Path getSoftwarePath();
306

307
  /**
308
   * @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
309
   *     here from the {@link #getSoftwareRepositoryPath() software repository} as sub-folder named after the according tool.
310
   */
311
  Path getSoftwareExtraPath();
312

313
  /**
314
   * @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
315
   *     are shared among all IDE instances (see {@link #getIdeHome() IDE_HOME}) via symbolic links (see {@link #getSoftwarePath()}). Therefore this repository
316
   *     follows the sub-folder structure {@code «repository»/«tool»/«edition»/«version»/}. So multiple versions of the same tool exist here as different
317
   *     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
318
   *     of the scope of this folders.
319
   */
320
  Path getSoftwareRepositoryPath();
321

322
  /**
323
   * @return the {@link Path} to the {@link #FOLDER_PLUGINS plugins folder} inside {@link #getIdeHome() IDE_HOME}. All plugins of the IDE instance will be
324
   *     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.
325
   */
326
  Path getPluginsPath();
327

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

337
  /**
338
   * @return the {@link Path} to the users home directory. Typically initialized via the {@link System#getProperty(String) system property} "user.home".
339
   * @see com.devonfw.tools.ide.variable.IdeVariables#HOME
340
   */
341
  Path getUserHome();
342

343
  /**
344
   * @return the {@link Path} to the ".ide" subfolder in the {@link #getUserHome() users home directory}.
345
   */
346
  Path getUserHomeIde();
347

348
  /**
349
   * @return the {@link Path} to the {@code settings} folder with the cloned git repository containing the project configuration.
350
   */
351
  Path getSettingsPath();
352

353
  /**
354
   * @return the {@link Path} to the templates folder inside the {@link #getSettingsPath() settings}. The relative directory structure in this templates folder
355
   *     is to be applied to {@link #getIdeHome() IDE_HOME} when the project is set up.
356
   */
357
  default Path getSettingsTemplatePath() {
358
    Path settingsFolder = getSettingsPath();
3✔
359
    Path templatesFolder = settingsFolder.resolve(IdeContext.FOLDER_TEMPLATES);
4✔
360
    if (!Files.isDirectory(templatesFolder)) {
5✔
361
      Path templatesFolderLegacy = settingsFolder.resolve(IdeContext.FOLDER_LEGACY_TEMPLATES);
4✔
362
      if (Files.isDirectory(templatesFolderLegacy)) {
5!
363
        templatesFolder = templatesFolderLegacy;
×
364
      } else {
365
        warning("No templates found in settings git repo neither in {} nor in {} - configuration broken", templatesFolder, templatesFolderLegacy);
13✔
366
        return null;
2✔
367
      }
368
    }
369
    return templatesFolder;
2✔
370
  }
371

372
  /**
373
   * @return the {@link Path} to the {@code conf} folder with instance specific tool configurations and the
374
   *     {@link EnvironmentVariablesType#CONF user specific project configuration}.
375
   */
376
  Path getConfPath();
377

378
  /**
379
   * @return the {@link Path} to the workspace.
380
   * @see #getWorkspaceName()
381
   */
382
  Path getWorkspacePath();
383

384
  /**
385
   * @return the name of the workspace. Defaults to {@link #WORKSPACE_MAIN}.
386
   */
387
  String getWorkspaceName();
388

389
  /**
390
   * @return the value of the system {@link IdeVariables#PATH PATH} variable. It is automatically extended according to the tools available in
391
   *     {@link #getSoftwarePath() software path} unless {@link #getIdeHome() IDE_HOME} was not found.
392
   */
393
  SystemPath getPath();
394

395
  /**
396
   * @return a new {@link ProcessContext} to {@link ProcessContext#run() run} external commands.
397
   */
398
  ProcessContext newProcess();
399

400
  /**
401
   * Prepares the {@link IdeProgressBar} initializes task name and maximum size as well as the behaviour and style.
402
   *
403
   * @param taskName name of the task.
404
   * @param size of the content.
405
   * @return {@link IdeProgressBar} to use.
406
   */
407
  IdeProgressBar prepareProgressBar(String taskName, long size);
408

409
  /**
410
   * @return the {@link DirectoryMerger} used to configure and merge the workspace for an {@link com.devonfw.tools.ide.tool.ide.IdeToolCommandlet IDE}.
411
   */
412
  DirectoryMerger getWorkspaceMerger();
413

414
  /**
415
   * @return the {@link Path} to the working directory from where the command is executed.
416
   */
417
  Path getDefaultExecutionDirectory();
418

419
  /**
420
   * @return the {@link IdeSystem} instance wrapping {@link System}.
421
   */
422
  IdeSystem getSystem();
423

424
  /**
425
   * @return the {@link GitContext} used to run several git commands.
426
   */
427
  GitContext getGitContext();
428

429
  /**
430
   * @return the String value for the variable MAVEN_ARGS, or null if called outside an IDEasy installation.
431
   */
432
  default String getMavenArgs() {
433

434
    if (getIdeHome() == null) {
3!
435
      return null;
×
436
    }
437
    Mvn mvn = getCommandletManager().getCommandlet(Mvn.class);
6✔
438
    return mvn.getMavenArgs();
3✔
439
  }
440

441
  /**
442
   * @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.
443
   */
444
  default Path getMavenRepository() {
445

446
    if (getIdeHome() != null) {
3!
447
      Path confPath = getConfPath();
3✔
448
      Path m2Folder = confPath.resolve(Mvn.MVN_CONFIG_FOLDER);
4✔
449
      if (!Files.isDirectory(m2Folder)) {
5✔
450
        Path m2LegacyFolder = confPath.resolve(Mvn.MVN_CONFIG_LEGACY_FOLDER);
4✔
451
        if (Files.isDirectory(m2LegacyFolder)) {
5!
452
          m2Folder = m2LegacyFolder;
×
453
        } else {
454
          // fallback to USER_HOME/.m2 folder
455
          m2Folder = getUserHome().resolve(Mvn.MVN_CONFIG_LEGACY_FOLDER);
5✔
456
        }
457
      }
458
      return m2Folder.resolve("repository");
4✔
459
    }
460
    return null;
×
461
  }
462

463
  /**
464
   * Updates the current working directory (CWD) and configures the environment paths according to the specified parameters. This method is central to changing
465
   * the IDE's notion of where it operates, affecting where configurations, workspaces, settings, and other resources are located or loaded from.
466
   *
467
   * @return the current {@link Step} of processing.
468
   */
469
  Step getCurrentStep();
470

471
  /**
472
   * @param name the {@link Step#getName() name} of the new {@link Step}.
473
   * @return the new {@link Step} that has been created and started.
474
   */
475
  default Step newStep(String name) {
476

477
    return newStep(name, Step.NO_PARAMS);
5✔
478
  }
479

480
  /**
481
   * @param name the {@link Step#getName() name} of the new {@link Step}.
482
   * @param parameters the {@link Step#getParameter(int) parameters} of the {@link Step}.
483
   * @return the new {@link Step} that has been created and started.
484
   */
485
  default Step newStep(String name, Object... parameters) {
486

487
    return newStep(false, name, parameters);
6✔
488
  }
489

490
  /**
491
   * @param silent the {@link Step#isSilent() silent flag}.
492
   * @param name the {@link Step#getName() name} of the new {@link Step}.
493
   * @param parameters the {@link Step#getParameter(int) parameters} of the {@link Step}.
494
   * @return the new {@link Step} that has been created and started.
495
   */
496
  Step newStep(boolean silent, String name, Object... parameters);
497

498
  /**
499
   * Updates the current working directory (CWD) and configures the environment paths according to the specified parameters. This method is central to changing
500
   * the IDE's notion of where it operates, affecting where configurations, workspaces, settings, and other resources are located or loaded from.
501
   *
502
   * @param ideHome The path to the IDE home directory.
503
   */
504
  default void setIdeHome(Path ideHome) {
505

506
    setCwd(ideHome, WORKSPACE_MAIN, ideHome);
5✔
507
  }
1✔
508

509
  /**
510
   * Updates the current working directory (CWD) and configures the environment paths according to the specified parameters. This method is central to changing
511
   * the IDE's notion of where it operates, affecting where configurations, workspaces, settings, and other resources are located or loaded from.
512
   *
513
   * @param userDir The path to set as the current working directory.
514
   * @param workspace The name of the workspace within the IDE's environment.
515
   * @param ideHome The path to the IDE home directory.
516
   */
517
  void setCwd(Path userDir, String workspace, Path ideHome);
518

519
  /**
520
   * Finds the path to the Bash executable.
521
   *
522
   * @return the {@link String} to the Bash executable, or {@code null} if Bash is not found
523
   */
524
  String findBash();
525

526
  /**
527
   * Finds the path to the Bash executable.
528
   *
529
   * @return the {@link String} to the Bash executable. Throws an {@link IllegalStateException} if no bash was found.
530
   */
531
  default String findBashRequired() {
532
    String bash = findBash();
3✔
533
    if (bash == null) {
2!
534
      String message = "Could not find bash what is a prerequisite of IDEasy.";
×
535
      if (getSystemInfo().isWindows()) {
×
536
        message = message + "\nPlease install Git for Windows and rerun.";
×
537
      }
538
      throw new IllegalStateException(message);
×
539
    }
540
    return bash;
2✔
541
  }
542

543
  /**
544
   * @return the {@link WindowsPathSyntax} used for {@link Path} conversion or {@code null} for no such conversion (typically if not on Windows).
545
   */
546
  WindowsPathSyntax getPathSyntax();
547

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