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

devonfw / IDEasy / 20021384931

08 Dec 2025 08:20AM UTC coverage: 69.924% (-0.08%) from 70.003%
20021384931

push

github

web-flow
#1640: remove post-install hook from terraform (#1641)

3924 of 6173 branches covered (63.57%)

Branch coverage included in aggregate %.

10049 of 13810 relevant lines covered (72.77%)

3.15 hits per line

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

69.91
cli/src/main/java/com/devonfw/tools/ide/tool/ToolInstallRequest.java
1
package com.devonfw.tools.ide.tool;
2

3
import com.devonfw.tools.ide.log.IdeLogger;
4
import com.devonfw.tools.ide.process.ProcessContext;
5
import com.devonfw.tools.ide.step.Step;
6
import com.devonfw.tools.ide.version.GenericVersionRange;
7
import com.devonfw.tools.ide.version.VersionIdentifier;
8
import com.devonfw.tools.ide.version.VersionRange;
9

10
/**
11
 * Container for data related to a tool installation.
12
 */
13
public final class ToolInstallRequest {
1✔
14

15
  private final ToolInstallRequest parent;
16

17
  private final boolean silent;
18

19
  private final boolean direct;
20

21
  private boolean cveCheckDone;
22

23
  private ToolEditionAndVersion requested;
24

25
  private ToolEditionAndVersion installed;
26

27
  private ProcessContext processContext;
28

29
  private Step step;
30

31
  /**
32
   * The constructor.
33
   *
34
   * @param silent the {@link #isSilent() silent} flag.
35
   */
36
  public ToolInstallRequest(boolean silent) {
37
    this(null, silent, false);
5✔
38
  }
1✔
39

40
  /**
41
   * The constructor.
42
   *
43
   * @param parent the parent {@link ToolInstallRequest} (in case of a dependency).
44
   */
45
  public ToolInstallRequest(ToolInstallRequest parent) {
46
    this(parent, parent.silent, false);
6✔
47
  }
1✔
48

49
  /**
50
   * The constructor.
51
   *
52
   * @param silent the {@link #isSilent() silent} flag.
53
   * @param direct the {@link #isDirect() direct} flag.
54
   */
55
  private ToolInstallRequest(ToolInstallRequest parent, boolean silent, boolean direct) {
56
    super();
2✔
57
    this.parent = parent;
3✔
58
    this.silent = silent;
3✔
59
    this.direct = direct;
3✔
60
    if (parent != null) {
2✔
61
      this.processContext = parent.processContext;
4✔
62
    }
63
  }
1✔
64

65
  /**
66
   * @param logger the {@link IdeLogger} used to log an installation loop if found.
67
   * @return {@code true} if an installation loop was found and logged, {@code false} otherwise.
68
   */
69
  public boolean isInstallLoop(IdeLogger logger) {
70

71
    if ((this.requested == null) || (this.requested.getEdition() == null)) {
7!
72
      throw new IllegalStateException(); // this method was called too early
×
73
    }
74
    StringBuilder sb = new StringBuilder();
4✔
75
    boolean loopFound = detectInstallLoopRecursively(this.requested, sb);
6✔
76
    if (loopFound) {
2!
77
      logger.warning("Found installation loop:\n"
×
78
              + "{}\n"
79
              + "This typically indicates an internal bug in IDEasy.\n"
80
              + "Please report this bug, when you see this and include this entire warning message.\n"
81
              + "We are now trying to prevent an infinity loop and abort the recursive installation.",
82
          sb);
83
    }
84
    return loopFound;
2✔
85
  }
86

87
  private boolean detectInstallLoopRecursively(ToolEditionAndVersion toolEditionAndVersion, StringBuilder sb) {
88

89
    if (this.requested != toolEditionAndVersion) {
4✔
90
      if (this.requested.getEdition().equals(toolEditionAndVersion.getEdition())) {
7!
91
        if (this.requested.getResolvedVersion().equals(toolEditionAndVersion.getResolvedVersion())) {
×
92
          sb.append(this.requested);
×
93
          return true;
×
94
        }
95
      }
96
    }
97
    if (this.parent == null) {
3✔
98
      return false;
2✔
99
    }
100
    boolean loopFound = this.parent.detectInstallLoopRecursively(toolEditionAndVersion, sb);
6✔
101
    if (loopFound && (sb != null)) {
2!
102
      sb.append("-->");
×
103
      sb.append(this.requested);
×
104
    }
105
    return loopFound;
2✔
106
  }
107

108
  /**
109
   * @return {@code true} if this installation should be silent and log information like "tool already installed" only on debug level to avoid spam,
110
   *     {@code false} otherwise. A {@link #isDirect() direct} installation should never be silent.
111
   */
112
  public boolean isSilent() {
113

114
    return this.silent;
3✔
115
  }
116

117
  /**
118
   * @return {@code true} if the user directly triggered this tool installation (via "ide install tool"), {@code false} otherwise (indirect installation e.g. as
119
   *     dependency or via "ide create" or "ide update").
120
   */
121
  public boolean isDirect() {
122

123
    return this.direct;
×
124
  }
125

126
  /**
127
   * @return {@code true} if CVEs have already been checked, {@code false} otherwise.
128
   */
129
  public boolean isCveCheckDone() {
130

131
    return this.cveCheckDone;
3✔
132
  }
133

134
  void setCveCheckDone() {
135

136
    assert !this.cveCheckDone;
4!
137
    this.cveCheckDone = true;
3✔
138
  }
1✔
139

140
  /**
141
   * @return the {@link ToolEditionAndVersion} that is requested to be installed.
142
   */
143
  public ToolEditionAndVersion getRequested() {
144

145
    return this.requested;
3✔
146
  }
147

148
  /**
149
   * @param requested new value of {@link #getRequested()}.
150
   */
151
  public void setRequested(ToolEditionAndVersion requested) {
152
    if (this.requested != null) {
3!
153
      throw new IllegalStateException();
×
154
    }
155
    this.requested = requested;
3✔
156
  }
1✔
157

158
  /**
159
   * @return the {@link ToolEditionAndVersion} that is currently installed or {@code null} if the tool is not installed yet.
160
   */
161
  public ToolEditionAndVersion getInstalled() {
162

163
    return this.installed;
3✔
164
  }
165

166
  /**
167
   * @param installed new value of {@link #getInstalled()}.
168
   */
169
  public void setInstalled(ToolEditionAndVersion installed) {
170

171
    if (this.installed != null) {
3!
172
      throw new IllegalStateException();
×
173
    }
174
    this.installed = installed;
3✔
175
  }
1✔
176

177
  /**
178
   * @return the {@link ProcessContext} to use for executing the tool. Will also be configured during the installation (variables set, PATH extended).
179
   */
180
  public ProcessContext getProcessContext() {
181
    return this.processContext;
3✔
182
  }
183

184
  /**
185
   * @param processContext new value of {@link #getProcessContext()}.
186
   */
187
  public void setProcessContext(ProcessContext processContext) {
188

189
    if (this.processContext != null) {
3!
190
      throw new IllegalStateException();
×
191
    }
192
    this.processContext = processContext;
3✔
193
  }
1✔
194

195
  /**
196
   * @return the {@link Step} for the installation.
197
   */
198
  public Step getStep() {
199

200
    return this.step;
3✔
201
  }
202

203
  /**
204
   * @param step new value of {@link #getStep()}.
205
   */
206
  public void setStep(Step step) {
207

208
    if (this.step != null) {
×
209
      throw new IllegalStateException();
×
210
    }
211
    this.step = step;
×
212
  }
×
213

214
  /**
215
   * @return {@code true} if an additional installation is required not linked to the project's software folder (e.g. because of a transitive installation from
216
   *     a dependency that is incompatible with the project version), {@code false} otherwise.
217
   */
218
  public boolean isAdditionalInstallation() {
219
    if (this.requested != null) {
3!
220
      GenericVersionRange versionToInstall = this.requested.getVersion();
4✔
221
      return (versionToInstall instanceof VersionRange);
3✔
222
    }
223
    return false;
×
224
  }
225

226
  /**
227
   * @return {@code true} if the {@link #getRequested() requested edition and version} matches the {@link #getInstalled() installed edition and version}
228
   */
229
  public boolean isAlreadyInstalled() {
230

231
    if (this.installed == null) {
3✔
232
      return false;
2✔
233
    }
234
    VersionIdentifier installedVersion = this.installed.getResolvedVersion();
4✔
235
    if (installedVersion == null) {
2✔
236
      return false;
2✔
237
    }
238
    ToolEdition installedEdition = this.installed.getEdition();
4✔
239
    if (installedEdition == null) {
2!
240
      return false; // should actually never happen
×
241
    }
242
    if (!this.requested.getEdition().equals(installedEdition)) {
6✔
243
      return false;
2✔
244
    }
245
    return installedVersion.equals(this.requested.getResolvedVersion());
6✔
246
  }
247

248
  /**
249
   * @return a new {@link #isDirect() direct} {@link ToolInstallRequest}.
250
   */
251
  public static ToolInstallRequest ofDirect() {
252

253
    return new ToolInstallRequest(null, false, true);
7✔
254
  }
255
}
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