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

devonfw / IDEasy / 23022412641

12 Mar 2026 08:29PM UTC coverage: 70.411% (-0.07%) from 70.479%
23022412641

Pull #1740

github

web-flow
Merge 5ab0935dc into 94a01cec9
Pull Request #1740: #1642: improved help #404: fix loghandling npe

4140 of 6476 branches covered (63.93%)

Branch coverage included in aggregate %.

10730 of 14643 relevant lines covered (73.28%)

3.08 hits per line

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

85.79
cli/src/main/java/com/devonfw/tools/ide/commandlet/HelpCommandlet.java
1
package com.devonfw.tools.ide.commandlet;
2

3
import java.util.ArrayList;
4
import java.util.Collections;
5
import java.util.List;
6

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

10
import com.devonfw.tools.ide.context.AbstractIdeContext;
11
import com.devonfw.tools.ide.context.IdeContext;
12
import com.devonfw.tools.ide.log.IdeLogLevel;
13
import com.devonfw.tools.ide.nls.NlsBundle;
14
import com.devonfw.tools.ide.property.CommandletProperty;
15
import com.devonfw.tools.ide.property.KeywordProperty;
16
import com.devonfw.tools.ide.property.Property;
17
import com.devonfw.tools.ide.tool.ToolCommandlet;
18
import com.devonfw.tools.ide.version.IdeVersion;
19

20
/**
21
 * {@link Commandlet} to print the environment variables.
22
 */
23
public final class HelpCommandlet extends Commandlet {
24

25
  private static final Logger LOG = LoggerFactory.getLogger(HelpCommandlet.class);
4✔
26

27
  /** The optional commandlet to get help about. */
28
  public final CommandletProperty commandlet;
29

30
  /**
31
   * The constructor.
32
   *
33
   * @param context the {@link IdeContext}.
34
   */
35
  public HelpCommandlet(IdeContext context) {
36

37
    super(context);
3✔
38
    addKeyword("--help", "-h");
4✔
39
    this.commandlet = add(new CommandletProperty("", false, "commandlet"));
11✔
40
  }
1✔
41

42
  @Override
43
  public String getName() {
44

45
    return "help";
2✔
46
  }
47

48
  @Override
49
  public boolean isIdeRootRequired() {
50

51
    return false;
2✔
52
  }
53

54
  @Override
55
  public boolean isWriteLogFile() {
56

57
    return false;
×
58
  }
59

60
  @Override
61
  protected void doRun() {
62

63
    this.context.printLogo();
3✔
64
    NlsBundle bundle = NlsBundle.of(this.context);
4✔
65
    IdeLogLevel.SUCCESS.log(LOG, bundle.get("version-banner"), IdeVersion.getVersionString());
12✔
66
    Commandlet cmd = this.commandlet.getValue();
5✔
67
    printCommandletHelp(bundle, cmd);
4✔
68
    if (cmd == null) {
2✔
69
      LOG.info("");
3✔
70
      LOG.info(bundle.getDetail(this.context.getCommandletManager().getCommandlet(HelpCommandlet.class)));
9✔
71
    }
72

73
    LOG.info("");
3✔
74
    LOG.info(bundle.get("icd-hint"));
5✔
75
  }
1✔
76

77
  private void printCommandletHelp(NlsBundle bundle, Commandlet cmd) {
78

79
    Args values = null;
2✔
80
    Args options = null;
2✔
81
    StringBuilder usage = new StringBuilder();
4✔
82
    usage.append(bundle.get("usage"));
6✔
83
    usage.append(" ide [global-option]*");
4✔
84
    if (cmd == null) {
2✔
85
      usage.append(" [[commandlet] [local-option]* [arg]*]");
5✔
86
    } else {
87
      values = new Args();
5✔
88
      options = new Args();
5✔
89
      for (Property<?> property : cmd.getProperties()) {
11✔
90
        if (property.isValue() || property.isRequired()) {
3!
91
          usage.append(" ");
4✔
92
          if (!property.isRequired()) {
3✔
93
            usage.append('[');
4✔
94
          }
95
          String name = property.getName();
3✔
96
          if (name.isEmpty()) {
3✔
97
            assert !(property instanceof KeywordProperty);
4!
98
            String key = "<" + property.getAlias() + ">";
4✔
99
            usage.append(key);
4✔
100
            values.add(key, bundle.get(cmd, property));
7✔
101
          } else {
1✔
102
            usage.append(name);
4✔
103
          }
104
          if (property.isMultiValued()) {
3✔
105
            usage.append('*');
4✔
106
          }
107
          if (!property.isRequired()) {
3✔
108
            usage.append(']');
4✔
109
          }
110
        } else if (property.isOption() && !property.isRequired()) {
1!
111
          String id = property.getAlias();
×
112
          String name = property.getName();
×
113
          if (id == null) {
×
114
            id = name;
×
115
          } else {
116
            id = id + " | " + name;
×
117
          }
118
          String description = bundle.get(cmd, property);
×
119
          options.add(id, description);
×
120
          usage.append(" [");
×
121
          usage.append(id);
×
122
          usage.append(']');
×
123
        }
124
      }
1✔
125
    }
126
    LOG.info(usage.toString());
4✔
127
    if (cmd == null) {
2✔
128
      printCommandlets(bundle);
4✔
129
    } else {
130
      LOG.info(bundle.get(cmd));
5✔
131
      LOG.info(bundle.getDetail(cmd));
5✔
132
      printArgs(options, bundle, "options.local");
5✔
133
      printArgs(values, bundle, "values");
5✔
134
    }
135
    options = new Args();
5✔
136
    ContextCommandlet cxtCmd = new ContextCommandlet(((AbstractIdeContext) this.context).getStartContext());
8✔
137
    collectOptions(options, cxtCmd, bundle);
5✔
138
    printArgs(options, bundle, "options.global");
5✔
139
    if (cmd != null) {
2✔
140
      cmd.printHelp(bundle);
3✔
141
    }
142
  }
1✔
143

144
  private void printArgs(Args args, NlsBundle bundle, String bundleKey) {
145
    if (!args.get().isEmpty()) {
4✔
146
      LOG.info("");
3✔
147
      LOG.info(bundle.get(bundleKey));
5✔
148
      args.print();
2✔
149
    }
150

151
  }
1✔
152

153
  private void printCommandlets(NlsBundle bundle) {
154

155
    Args commandlets = new Args();
5✔
156
    Args toolcommandlets = new Args();
5✔
157
    for (Commandlet cmd : this.context.getCommandletManager().getCommandlets()) {
13✔
158
      String key = cmd.getName();
3✔
159
      KeywordProperty keyword = cmd.getFirstKeyword();
3✔
160
      if (keyword != null) {
2!
161
        String name = keyword.getName();
3✔
162
        if (!name.equals(key)) {
4!
163
          key = key + "(" + keyword + ")";
×
164
        }
165
      }
166
      if (cmd instanceof ToolCommandlet) {
3✔
167
        toolcommandlets.add(key, bundle.get(cmd));
7✔
168
      } else {
169
        commandlets.add(key, bundle.get(cmd));
6✔
170
      }
171
    }
1✔
172

173
    LOG.info(bundle.get("commandlets"));
5✔
174
    commandlets.print(IdeLogLevel.INTERACTION);
3✔
175
    LOG.info("");
3✔
176
    LOG.info(bundle.get("toolcommandlets"));
5✔
177
    toolcommandlets.print(IdeLogLevel.INTERACTION);
3✔
178
  }
1✔
179

180
  private void collectOptions(Args options, Commandlet cmd, NlsBundle bundle) {
181

182
    for (Property<?> property : cmd.getProperties()) {
11✔
183
      if (property.isOption() && !property.isRequired()) {
6!
184
        String id = property.getAlias();
3✔
185
        String name = property.getName();
3✔
186
        if (id == null) {
2✔
187
          id = name;
3✔
188
        } else {
189
          id = id + " | " + name;
4✔
190
        }
191
        String description = bundle.get(cmd, property);
5✔
192
        options.add(id, description);
4✔
193
      }
194
    }
1✔
195
  }
1✔
196

197
  private static class Arg implements Comparable<Arg> {
198

199
    private final String key;
200

201
    private final String description;
202

203
    private Arg(String key, String description) {
204

205
      super();
2✔
206
      this.key = key;
3✔
207
      this.description = description;
3✔
208
    }
1✔
209

210
    @Override
211
    public int compareTo(Arg arg) {
212

213
      if (arg == null) {
2!
214
        return 1;
×
215
      }
216
      return this.key.compareTo(arg.key);
6✔
217
    }
218
  }
219

220
  private class Args {
221

222
    private final List<Arg> args;
223

224
    private int maxKeyLength;
225

226
    private Args() {
227

228
      super();
2✔
229
      this.args = new ArrayList<>();
5✔
230
    }
1✔
231

232
    private void add(String key, String description) {
233

234
      add(new Arg(key, description));
7✔
235
    }
1✔
236

237
    private void add(Arg arg) {
238

239
      this.args.add(arg);
5✔
240
      int keyLength = arg.key.length();
4✔
241
      if (keyLength > this.maxKeyLength) {
4✔
242
        this.maxKeyLength = keyLength;
3✔
243
      }
244
    }
1✔
245

246
    String format(Arg arg) {
247

248
      StringBuilder sb = new StringBuilder(this.maxKeyLength + 2 + arg.description.length());
12✔
249
      sb.append(arg.key);
5✔
250
      int delta = this.maxKeyLength - arg.key.length();
7✔
251
      while (delta > 0) {
2✔
252
        sb.append(' ');
4✔
253
        delta--;
2✔
254
      }
255
      sb.append("  ");
4✔
256
      sb.append(arg.description);
5✔
257
      return sb.toString();
3✔
258
    }
259

260
    void print() {
261

262
      print(IdeLogLevel.INFO);
3✔
263
    }
1✔
264

265
    void print(IdeLogLevel level) {
266

267
      for (Arg arg : get()) {
11✔
268
        String message = format(arg);
4✔
269
        level.log(LOG, message);
4✔
270
      }
1✔
271
    }
1✔
272

273
    public List<Arg> get() {
274

275
      Collections.sort(this.args);
3✔
276
      return this.args;
3✔
277
    }
278
  }
279
}
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