diff -r 3d1cd23f88f7 -r 79eeb33c738f src/main/java/de/unixwork/uwproj/Feature.java --- a/src/main/java/de/unixwork/uwproj/Feature.java Thu Nov 13 18:46:08 2025 +0100 +++ b/src/main/java/de/unixwork/uwproj/Feature.java Fri Nov 14 15:09:37 2025 +0100 @@ -6,17 +6,15 @@ import static de.unixwork.uwproj.Util.shId; -public final class Feature { +public final class Feature extends AbstractOption { private final String name; - private final String arg; private final boolean auto; private final TargetData targetData; private final TargetData disabled = new TargetData(); - private String desc = ""; public Feature(Element e) { + super(Util.getAttrOrDefault(e, "arg", e.getAttribute("name"))); name = e.getAttribute("name"); - arg = Util.getAttrOrDefault(e, "arg", name); auto = Boolean.parseBoolean(e.getAttribute("default")); targetData = new TargetData(e); @@ -68,102 +66,8 @@ return auto; } - /** - * Generates help text for the feature option. - *
- * If {@link #isAuto()} returns true, the option name will be --disable-${@link #getArg()}, otherwise - * it will be --enable-${@link #getArg()}, preceded by two spaces, respectively. - *
- * If no description is available via {@link #getDesc()}, only the option name is generated. Otherwise, - * description is added according to the following rules: - *
- * When the option name does not consume more than 25 characters, the description starts in the same line. - * Otherwise, a line break is added, first. The description will be placed in a block starting from column - * 27 to 80 and automatically break when necessary. The description must not contain a single word - * that is longer than 54 characters, or it will break the layout. - * - * @return a help text for terminal output - */ - public String getHelpText() { - final var builder = new StringBuilder(); - - // Compute option name - final var opt = (auto ? " --disable-" : " --enable-")+arg; - - // Add option name - builder.append(opt); - - // Stop, if there is no description - if (desc.isBlank()) return builder.toString(); - - // Prepare the description by replacing some unwanted spaces - final var hdesc = desc.trim() - .replaceAll("\\r", "") - .replaceAll("\\t", " "); - - // Declare our frame where the description shall be placed - final int startx = 26; - final int endx = 80; - - // Move to startx (break, if we already past that) - if (opt.length() >= startx) { - builder.append("\n"); - builder.append(" ".repeat(startx)); - } else { - builder.append(" ".repeat(startx-opt.length())); - } - - // Append the description keeping the layout intact - int x = startx; - for (int i = 0 ; i < hdesc.length() ;) { - // get the next word and see where we would end - int s = hdesc.indexOf(' ', i); - if (s < 0) s = hdesc.length(); - int n = hdesc.indexOf('\n', i); - if (n < 0) n = hdesc.length(); - s = Math.min(s, n); - int l = s-i; - if (x + l > endx) { - // does not fit, break into next line - builder.append('\n'); - builder.append(" ".repeat(startx)); - x = startx; - } - // append the word - builder.append(hdesc, i, s); - x += l; - i += l; - // append the next spaces - while (i < hdesc.length()) { - int c = hdesc.charAt(i); - if (c == ' ') { - // as long as we don't need to break, add the spaces - i++; - x++; - if (x < endx) builder.append(' '); - } else if (c == '\n') { - // if user wants us to break, comply - i++; - // if we have still space, just move to the end of the line - if (x < endx) { - x = endx; - } else { - // otherwise, we need to add an extra blank line - builder.append('\n'); - } - } else { - // we have found the next word, so continue with the outer loop - break; - } - } - // break to new line, when spaces moved us outside the frame - if (x > endx) { - builder.append('\n'); - builder.append(" ".repeat(startx)); - x = startx; - } - } - - return builder.toString(); + @Override + public String getHelpTextArg() { + return (auto ? "--disable-" : "--enable-")+arg; } }