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

devonfw / IDEasy / 22303886886

23 Feb 2026 11:19AM UTC coverage: 70.647% (+0.2%) from 70.474%
22303886886

Pull #1714

github

web-flow
Merge f1f7e1e61 into 379acdc9d
Pull Request #1714: #404: #1713: advanced logging

4069 of 6360 branches covered (63.98%)

Branch coverage included in aggregate %.

10644 of 14466 relevant lines covered (73.58%)

3.1 hits per line

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

92.05
cli/src/main/java/com/devonfw/tools/ide/environment/VariableLine.java
1
package com.devonfw.tools.ide.environment;
2

3
import java.util.Arrays;
4
import java.util.List;
5

6
import org.slf4j.Logger;
7
import org.slf4j.LoggerFactory;
8

9
/**
10
 * Container that represents a line from a properties (ide.properties) file. We do not use {@link java.util.Properties} as we need support for exported
11
 * variables, lists/arrays, and saving changes without loosing comments, etc.
12
 */
13
public abstract class VariableLine {
3✔
14

15
  private static final Logger LOG = LoggerFactory.getLogger(VariableLine.class);
4✔
16

17
  /**
18
   * @return {@code true} if the variable is exported (e.g. "export MAVEN_OPTS=-Xmx20248m"), {@code false} otherwise.
19
   */
20
  public boolean isExport() {
21

22
    return false;
2✔
23
  }
24

25
  /**
26
   * @return the name of the variable. Will be {@code null} if not a regular variable line (e.g. a comment or empty line).
27
   */
28
  public String getName() {
29

30
    return null;
2✔
31
  }
32

33
  /**
34
   * @return the value of the variable. Will be {@code null} if not a regular variable line (e.g. a comment or empty line).
35
   */
36
  public String getValue() {
37

38
    return null;
2✔
39
  }
40

41
  /**
42
   * @return the comment line (including the '#' character). Will be {@code null} if not a comment line.
43
   */
44
  public String getComment() {
45

46
    return null;
2✔
47
  }
48

49
  /**
50
   * @return the {@link VariableSource} of the variable.
51
   */
52
  public VariableSource getSource() {
53

54
    return null;
×
55
  }
56

57
  /**
58
   * @param newName the new variable {@link #getName() name}.
59
   * @return the new {@link VariableLine} with the modified {@link #getName() name}.
60
   */
61
  public VariableLine withName(String newName) {
62

63
    throw new UnsupportedOperationException();
×
64
  }
65

66
  /**
67
   * @param newValue the new variable {@link #getValue() value}.
68
   * @return the new {@link VariableLine} with the modified {@link #getValue() value}.
69
   */
70
  public VariableLine withValue(String newValue) {
71

72
    throw new UnsupportedOperationException();
×
73
  }
74

75
  /**
76
   * @param newExport the new {@link #isExport() export} flag.
77
   * @return the new {@link VariableLine} with the modified {@link #isExport() export} flag.
78
   */
79
  public VariableLine withExport(boolean newExport) {
80

81
    throw new UnsupportedOperationException();
×
82
  }
83

84
  static final class Variable extends VariableLine {
85

86
    private final boolean export;
87

88
    private final String name;
89

90
    private final String value;
91

92
    private final String line;
93

94
    private final VariableSource source;
95

96
    Variable(boolean export, String name, String value) {
97

98
      this(export, name, value, null, null);
7✔
99
    }
1✔
100

101
    private Variable(boolean export, String name, String value, String line, VariableSource source) {
102

103
      super();
2✔
104
      this.export = export;
3✔
105
      this.name = name;
3✔
106
      this.value = value;
3✔
107
      if (line == null) {
2✔
108
        StringBuilder sb = new StringBuilder();
4✔
109
        if (export) {
2✔
110
          sb.append("export ");
4✔
111
        }
112
        sb.append(this.name);
5✔
113
        sb.append('=');
4✔
114
        sb.append(this.value);
5✔
115
        this.line = sb.toString();
4✔
116
      } else {
1✔
117
        this.line = line;
3✔
118
      }
119
      this.source = source;
3✔
120
    }
1✔
121

122
    @Override
123
    public boolean isExport() {
124

125
      return this.export;
3✔
126
    }
127

128
    @Override
129
    public String getName() {
130

131
      return this.name;
3✔
132
    }
133

134
    @Override
135
    public String getValue() {
136

137
      return this.value;
3✔
138
    }
139

140
    @Override
141
    public VariableSource getSource() {
142
      return source;
3✔
143
    }
144

145
    @Override
146
    public VariableLine withName(String newName) {
147

148
      if (newName.equals(this.name)) {
5!
149
        return this;
×
150
      }
151
      return new Variable(this.export, newName, this.value);
9✔
152
    }
153

154
    @Override
155
    public VariableLine withValue(String newValue) {
156

157
      if (newValue.equals(this.value)) {
5✔
158
        return this;
2✔
159
      }
160
      return new Variable(this.export, this.name, newValue);
9✔
161
    }
162

163
    @Override
164
    public VariableLine withExport(boolean newExport) {
165

166
      if (newExport == this.export) {
4!
167
        return this;
×
168
      }
169
      return new Variable(newExport, this.name, this.value);
9✔
170
    }
171

172
    @Override
173
    public String toString() {
174

175
      return this.line;
3✔
176
    }
177

178
  }
179

180
  static final class Comment extends VariableLine {
181

182
    private final String line;
183

184
    private Comment(String line) {
185

186
      super();
2✔
187
      this.line = line;
3✔
188
    }
1✔
189

190
    @Override
191
    public String getComment() {
192

193
      return this.line;
3✔
194
    }
195

196
    @Override
197
    public String toString() {
198

199
      return this.line;
3✔
200
    }
201

202
  }
203

204
  static final class Garbage extends VariableLine {
205

206
    private final String line;
207

208
    Garbage(String line) {
209

210
      super();
2✔
211
      this.line = line;
3✔
212
    }
1✔
213

214
    @Override
215
    public String toString() {
216

217
      return this.line;
3✔
218
    }
219

220
  }
221

222
  static final class Empty extends VariableLine {
223

224
    private final String line;
225

226
    Empty(String line) {
227

228
      super();
2✔
229
      this.line = line;
3✔
230
    }
1✔
231

232
    @Override
233
    public String toString() {
234

235
      return this.line;
3✔
236
    }
237

238
  }
239

240
  /**
241
   * Parses a {@link VariableLine} from {@link String}.
242
   *
243
   * @param line the {@link VariableLine} as {@link String} to parse.
244
   * @param source the source where the given {@link String} to parse is from (e.g. the file path).
245
   * @return the parsed {@link VariableLine}.
246
   */
247
  public static VariableLine of(String line, VariableSource source) {
248

249
    int len = line.length();
3✔
250
    int start = 0;
2✔
251
    while (start < len) {
3✔
252
      char c = line.charAt(start);
4✔
253
      if (c == ' ') {
3✔
254
        start++; // ignore leading spaces
2✔
255
      } else if (c == '#') {
3✔
256
        return new Comment(line);
5✔
257
      } else {
258
        break;
259
      }
260
    }
1✔
261
    if (start >= len) {
3✔
262
      return new Empty(line);
5✔
263
    }
264
    boolean export = false;
2✔
265
    int end = start;
2✔
266
    int space = -1;
2✔
267
    while (end < len) {
3✔
268
      char c = line.charAt(end);
4✔
269
      if (c == ' ') {
3✔
270
        if (space == -1) {
3✔
271
          space = end;
3✔
272
        }
273
      } else if (c == '=') {
3✔
274
        // .0123456789
275
        // "export ...="
276
        String name;
277
        if ((space == start + 6) && (end > start + 7) && line.substring(start, space).equals("export")) {
17!
278
          name = line.substring(space + 1, end).trim();
8✔
279
          if (name.isEmpty()) {
3✔
280
            name = line.substring(start, end).trim();
7✔
281
          } else {
282
            export = true;
3✔
283
          }
284
        } else {
285
          name = line.substring(start, end).trim();
6✔
286
        }
287
        String value = line.substring(end + 1).trim();
7✔
288
        if (value.startsWith("\"") && value.endsWith("\"")) {
8!
289
          value = value.substring(1, value.length() - 1);
8✔
290
        }
291
        return new Variable(export, name, value, line, source);
9✔
292
      }
293
      end++;
1✔
294
    }
1✔
295
    LOG.warn("Ignoring corrupted line '{}' in {}", line, source);
5✔
296
    return new Garbage(line);
5✔
297
  }
298

299
  /**
300
   * @param export the {@link #isExport() export flag}.
301
   * @param name the {@link #getName() name}.
302
   * @param value the {@link #getValue() value}.
303
   * @return the {@link VariableLine} for the given values.
304
   */
305
  public static VariableLine of(boolean export, String name, String value) {
306

307
    return new Variable(export, name, value);
7✔
308
  }
309

310
  /**
311
   * @param export the {@link #isExport() export flag}.
312
   * @param name the {@link #getName() name}.
313
   * @param value the {@link #getValue() value}.
314
   * @param source the {@link #getSource() source} of the variable.
315
   * @return the {@link VariableLine} for the given values.
316
   */
317
  public static VariableLine of(boolean export, String name, String value, VariableSource source) {
318

319
    return new Variable(export, name, value, null, source);
9✔
320
  }
321

322
  /**
323
   * @param value the {@link String} value to check.
324
   * @return {@code true} if the value is a bash array (starts with "(" and ends with ")"), {@code false} otherwise.
325
   */
326
  public static boolean isBashArray(String value) {
327

328
    return value.startsWith("(") && value.endsWith(")");
12!
329
  }
330

331
  /**
332
   * Returns a list of String Variables.
333
   *
334
   * @param value String to parse
335
   * @return List of variables.
336
   */
337
  public static List<String> parseArray(String value) {
338
    String csv = value;
2✔
339
    String separator = ",";
2✔
340
    if (isBashArray(value)) {
3✔
341
      csv = value.substring(1, value.length() - 1);
8✔
342
      separator = " ";
2✔
343
      // Support comma as separator in bash array syntax for convenience
344
      if (csv.contains(",")) {
4✔
345
        separator = ",";
2✔
346
      }
347
    }
348
    return Arrays.stream(csv.split(separator))
6✔
349
        .map(String::trim)
2✔
350
        .filter(s -> !s.isEmpty())
8✔
351
        .toList();
1✔
352
  }
353

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