valepakh commented on code in PR #953: URL: https://github.com/apache/ignite-3/pull/953#discussion_r937773748
########## modules/cli/src/main/java/org/apache/ignite/cli/core/repl/executor/IgnitePicocliCommands.java: ########## @@ -0,0 +1,234 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.cli.core.repl.executor; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; +import org.apache.ignite.cli.core.repl.completer.CompleterFilter; +import org.apache.ignite.cli.core.repl.completer.DynamicCompleter; +import org.apache.ignite.cli.core.repl.completer.DynamicCompleterRegistry; +import org.jetbrains.annotations.NotNull; +import org.jline.builtins.Options.HelpException; +import org.jline.console.ArgDesc; +import org.jline.console.CmdDesc; +import org.jline.console.CommandRegistry; +import org.jline.reader.Candidate; +import org.jline.reader.Completer; +import org.jline.reader.LineReader; +import org.jline.reader.ParsedLine; +import org.jline.reader.impl.completer.ArgumentCompleter; +import org.jline.reader.impl.completer.NullCompleter; +import org.jline.reader.impl.completer.SystemCompleter; +import org.jline.utils.AttributedString; +import picocli.AutoComplete; +import picocli.CommandLine; +import picocli.CommandLine.Help; +import picocli.CommandLine.Model.CommandSpec; +import picocli.CommandLine.Model.OptionSpec; +import picocli.shell.jline3.PicocliCommands; + +/** + * Inspired by {@link PicocliCommands} but with custom dynamic completer and completer filtering. + */ +public class IgnitePicocliCommands implements CommandRegistry { + + private final CommandLine cmd; + private final Set<String> commands; + private final Map<String, String> aliasCommand = new HashMap<>(); + private final DynamicCompleterRegistry completerRegistry; + private final List<CompleterFilter> completerFilters; + + /** Default constructor. */ + public IgnitePicocliCommands(CommandLine cmd, DynamicCompleterRegistry completerRegistry, List<CompleterFilter> completerFilters) { + this.cmd = cmd; + this.completerFilters = completerFilters; + this.completerRegistry = completerRegistry; + this.commands = cmd.getCommandSpec().subcommands().keySet(); + putAliases(cmd); + } + + private void putAliases(CommandLine cmd) { + for (String c : commands) { + for (String a : cmd.getSubcommands().get(c).getCommandSpec().aliases()) { + aliasCommand.put(a, c); + } + } + } + + /** {@inheritDoc} */ + @Override + public boolean hasCommand(String command) { + return commands.contains(command) || aliasCommand.containsKey(command); + } + + /** {@inheritDoc} */ + @Override + public SystemCompleter compileCompleters() { + SystemCompleter out = new SystemCompleter(); + List<String> all = new ArrayList<>(); + all.addAll(commands); + all.addAll(aliasCommand.keySet()); + out.add(all, new IgnitePicocliCompleter()); + return out; + } + + private CommandLine findSubcommandLine(List<String> args, int lastIdx) { + CommandLine out = cmd; + for (int i = 0; i < lastIdx; i++) { + if (!args.get(i).startsWith("-")) { + out = findSubcommandLine(out, args.get(i)); + if (out == null) { + break; + } + } + } + return out; + } + + private CommandLine findSubcommandLine(CommandLine cmdline, String command) { + for (CommandLine s : cmdline.getSubcommands().values()) { + if (s.getCommandName().equals(command) || Arrays.asList(s.getCommandSpec().aliases()).contains(command)) { + return s; + } + } + return null; + } + + /** {@inheritDoc} */ + @Override + public CmdDesc commandDescription(List<String> args) { + CommandLine sub = findSubcommandLine(args, args.size()); + if (sub == null) { + return null; + } + CommandSpec spec = sub.getCommandSpec(); + Help cmdhelp = new picocli.CommandLine.Help(spec); + List<AttributedString> main = new ArrayList<>(); + Map<String, List<AttributedString>> options = new HashMap<>(); + String synopsis = AttributedString.stripAnsi(spec.usageMessage().sectionMap().get("synopsis").render(cmdhelp)); + main.add(HelpException.highlightSyntax(synopsis.trim(), HelpException.defaultStyle())); + // using JLine help highlight because the statement below does not work well... + // main.add(new AttributedString(spec.usageMessage().sectionMap().get("synopsis").render(cmdhelp).toString())); + for (OptionSpec o : spec.options()) { + String key = Arrays.stream(o.names()).collect(Collectors.joining(" ")); + List<AttributedString> val = new ArrayList<>(); + for (String d : o.description()) { + val.add(new AttributedString(d)); + } + if (o.arity().max() > 0) { + key += "=" + o.paramLabel(); + } + options.put(key, val); + } + return new CmdDesc(main, ArgDesc.doArgNames(List.of("")), options); + } + + /** {@inheritDoc} */ + @Override + public List<String> commandInfo(String command) { + List<String> out = new ArrayList<>(); + CommandSpec spec = cmd.getSubcommands().get(command).getCommandSpec(); + Help cmdhelp = new picocli.CommandLine.Help(spec); + String description = AttributedString.stripAnsi(spec.usageMessage().sectionMap().get("description").render(cmdhelp)); + out.addAll(Arrays.asList(description.split("\\r?\\n"))); + return out; + } + + @Override + public Object invoke(CommandRegistry.CommandSession session, String command, Object[] args) throws Exception { + List<String> arguments = new ArrayList<>(); + arguments.add(command); + arguments.addAll(Arrays.stream(args).map(Object::toString).collect(Collectors.toList())); Review Comment: ```suggestion Arrays.stream(args).map(Object::toString).forEach(arguments::add); ``` ########## modules/cli/src/main/java/org/apache/ignite/cli/core/repl/executor/IgnitePicocliCommands.java: ########## @@ -0,0 +1,234 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.cli.core.repl.executor; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; +import org.apache.ignite.cli.core.repl.completer.CompleterFilter; +import org.apache.ignite.cli.core.repl.completer.DynamicCompleter; +import org.apache.ignite.cli.core.repl.completer.DynamicCompleterRegistry; +import org.jetbrains.annotations.NotNull; +import org.jline.builtins.Options.HelpException; +import org.jline.console.ArgDesc; +import org.jline.console.CmdDesc; +import org.jline.console.CommandRegistry; +import org.jline.reader.Candidate; +import org.jline.reader.Completer; +import org.jline.reader.LineReader; +import org.jline.reader.ParsedLine; +import org.jline.reader.impl.completer.ArgumentCompleter; +import org.jline.reader.impl.completer.NullCompleter; +import org.jline.reader.impl.completer.SystemCompleter; +import org.jline.utils.AttributedString; +import picocli.AutoComplete; +import picocli.CommandLine; +import picocli.CommandLine.Help; +import picocli.CommandLine.Model.CommandSpec; +import picocli.CommandLine.Model.OptionSpec; +import picocli.shell.jline3.PicocliCommands; + +/** + * Inspired by {@link PicocliCommands} but with custom dynamic completer and completer filtering. + */ +public class IgnitePicocliCommands implements CommandRegistry { + + private final CommandLine cmd; + private final Set<String> commands; + private final Map<String, String> aliasCommand = new HashMap<>(); + private final DynamicCompleterRegistry completerRegistry; + private final List<CompleterFilter> completerFilters; + + /** Default constructor. */ + public IgnitePicocliCommands(CommandLine cmd, DynamicCompleterRegistry completerRegistry, List<CompleterFilter> completerFilters) { + this.cmd = cmd; + this.completerFilters = completerFilters; + this.completerRegistry = completerRegistry; + this.commands = cmd.getCommandSpec().subcommands().keySet(); + putAliases(cmd); + } + + private void putAliases(CommandLine cmd) { + for (String c : commands) { + for (String a : cmd.getSubcommands().get(c).getCommandSpec().aliases()) { + aliasCommand.put(a, c); + } + } + } + + /** {@inheritDoc} */ + @Override + public boolean hasCommand(String command) { + return commands.contains(command) || aliasCommand.containsKey(command); + } + + /** {@inheritDoc} */ + @Override + public SystemCompleter compileCompleters() { + SystemCompleter out = new SystemCompleter(); + List<String> all = new ArrayList<>(); + all.addAll(commands); + all.addAll(aliasCommand.keySet()); + out.add(all, new IgnitePicocliCompleter()); + return out; + } + + private CommandLine findSubcommandLine(List<String> args, int lastIdx) { + CommandLine out = cmd; + for (int i = 0; i < lastIdx; i++) { + if (!args.get(i).startsWith("-")) { + out = findSubcommandLine(out, args.get(i)); + if (out == null) { + break; + } + } + } + return out; + } + + private CommandLine findSubcommandLine(CommandLine cmdline, String command) { + for (CommandLine s : cmdline.getSubcommands().values()) { + if (s.getCommandName().equals(command) || Arrays.asList(s.getCommandSpec().aliases()).contains(command)) { + return s; + } + } + return null; + } + + /** {@inheritDoc} */ + @Override + public CmdDesc commandDescription(List<String> args) { + CommandLine sub = findSubcommandLine(args, args.size()); + if (sub == null) { + return null; + } + CommandSpec spec = sub.getCommandSpec(); + Help cmdhelp = new picocli.CommandLine.Help(spec); + List<AttributedString> main = new ArrayList<>(); + Map<String, List<AttributedString>> options = new HashMap<>(); + String synopsis = AttributedString.stripAnsi(spec.usageMessage().sectionMap().get("synopsis").render(cmdhelp)); + main.add(HelpException.highlightSyntax(synopsis.trim(), HelpException.defaultStyle())); + // using JLine help highlight because the statement below does not work well... + // main.add(new AttributedString(spec.usageMessage().sectionMap().get("synopsis").render(cmdhelp).toString())); + for (OptionSpec o : spec.options()) { + String key = Arrays.stream(o.names()).collect(Collectors.joining(" ")); + List<AttributedString> val = new ArrayList<>(); + for (String d : o.description()) { + val.add(new AttributedString(d)); + } + if (o.arity().max() > 0) { + key += "=" + o.paramLabel(); + } + options.put(key, val); + } + return new CmdDesc(main, ArgDesc.doArgNames(List.of("")), options); + } + + /** {@inheritDoc} */ + @Override + public List<String> commandInfo(String command) { + List<String> out = new ArrayList<>(); + CommandSpec spec = cmd.getSubcommands().get(command).getCommandSpec(); + Help cmdhelp = new picocli.CommandLine.Help(spec); + String description = AttributedString.stripAnsi(spec.usageMessage().sectionMap().get("description").render(cmdhelp)); + out.addAll(Arrays.asList(description.split("\\r?\\n"))); + return out; Review Comment: Or at least ```suggestion return new ArrayList<>(Arrays.asList(description.split("\\r?\\n"))); ``` ########## modules/cli/src/main/java/org/apache/ignite/cli/core/repl/executor/IgnitePicocliCommands.java: ########## @@ -0,0 +1,234 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.cli.core.repl.executor; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; +import org.apache.ignite.cli.core.repl.completer.CompleterFilter; +import org.apache.ignite.cli.core.repl.completer.DynamicCompleter; +import org.apache.ignite.cli.core.repl.completer.DynamicCompleterRegistry; +import org.jetbrains.annotations.NotNull; +import org.jline.builtins.Options.HelpException; +import org.jline.console.ArgDesc; +import org.jline.console.CmdDesc; +import org.jline.console.CommandRegistry; +import org.jline.reader.Candidate; +import org.jline.reader.Completer; +import org.jline.reader.LineReader; +import org.jline.reader.ParsedLine; +import org.jline.reader.impl.completer.ArgumentCompleter; +import org.jline.reader.impl.completer.NullCompleter; +import org.jline.reader.impl.completer.SystemCompleter; +import org.jline.utils.AttributedString; +import picocli.AutoComplete; +import picocli.CommandLine; +import picocli.CommandLine.Help; +import picocli.CommandLine.Model.CommandSpec; +import picocli.CommandLine.Model.OptionSpec; +import picocli.shell.jline3.PicocliCommands; + +/** + * Inspired by {@link PicocliCommands} but with custom dynamic completer and completer filtering. + */ +public class IgnitePicocliCommands implements CommandRegistry { + + private final CommandLine cmd; + private final Set<String> commands; + private final Map<String, String> aliasCommand = new HashMap<>(); + private final DynamicCompleterRegistry completerRegistry; + private final List<CompleterFilter> completerFilters; + + /** Default constructor. */ + public IgnitePicocliCommands(CommandLine cmd, DynamicCompleterRegistry completerRegistry, List<CompleterFilter> completerFilters) { + this.cmd = cmd; + this.completerFilters = completerFilters; + this.completerRegistry = completerRegistry; + this.commands = cmd.getCommandSpec().subcommands().keySet(); + putAliases(cmd); + } + + private void putAliases(CommandLine cmd) { + for (String c : commands) { + for (String a : cmd.getSubcommands().get(c).getCommandSpec().aliases()) { + aliasCommand.put(a, c); + } + } + } + + /** {@inheritDoc} */ + @Override + public boolean hasCommand(String command) { + return commands.contains(command) || aliasCommand.containsKey(command); + } + + /** {@inheritDoc} */ + @Override + public SystemCompleter compileCompleters() { + SystemCompleter out = new SystemCompleter(); + List<String> all = new ArrayList<>(); + all.addAll(commands); + all.addAll(aliasCommand.keySet()); + out.add(all, new IgnitePicocliCompleter()); + return out; + } + + private CommandLine findSubcommandLine(List<String> args, int lastIdx) { + CommandLine out = cmd; + for (int i = 0; i < lastIdx; i++) { + if (!args.get(i).startsWith("-")) { + out = findSubcommandLine(out, args.get(i)); + if (out == null) { + break; + } + } + } + return out; + } + + private CommandLine findSubcommandLine(CommandLine cmdline, String command) { + for (CommandLine s : cmdline.getSubcommands().values()) { + if (s.getCommandName().equals(command) || Arrays.asList(s.getCommandSpec().aliases()).contains(command)) { + return s; + } + } + return null; + } + + /** {@inheritDoc} */ + @Override + public CmdDesc commandDescription(List<String> args) { + CommandLine sub = findSubcommandLine(args, args.size()); + if (sub == null) { + return null; + } + CommandSpec spec = sub.getCommandSpec(); + Help cmdhelp = new picocli.CommandLine.Help(spec); + List<AttributedString> main = new ArrayList<>(); + Map<String, List<AttributedString>> options = new HashMap<>(); + String synopsis = AttributedString.stripAnsi(spec.usageMessage().sectionMap().get("synopsis").render(cmdhelp)); + main.add(HelpException.highlightSyntax(synopsis.trim(), HelpException.defaultStyle())); + // using JLine help highlight because the statement below does not work well... + // main.add(new AttributedString(spec.usageMessage().sectionMap().get("synopsis").render(cmdhelp).toString())); + for (OptionSpec o : spec.options()) { + String key = Arrays.stream(o.names()).collect(Collectors.joining(" ")); Review Comment: IDEA suggests replacing this with `String.join` ########## modules/cli/src/main/java/org/apache/ignite/cli/core/repl/executor/IgnitePicocliCommands.java: ########## @@ -0,0 +1,234 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.cli.core.repl.executor; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; +import org.apache.ignite.cli.core.repl.completer.CompleterFilter; +import org.apache.ignite.cli.core.repl.completer.DynamicCompleter; +import org.apache.ignite.cli.core.repl.completer.DynamicCompleterRegistry; +import org.jetbrains.annotations.NotNull; +import org.jline.builtins.Options.HelpException; +import org.jline.console.ArgDesc; +import org.jline.console.CmdDesc; +import org.jline.console.CommandRegistry; +import org.jline.reader.Candidate; +import org.jline.reader.Completer; +import org.jline.reader.LineReader; +import org.jline.reader.ParsedLine; +import org.jline.reader.impl.completer.ArgumentCompleter; +import org.jline.reader.impl.completer.NullCompleter; +import org.jline.reader.impl.completer.SystemCompleter; +import org.jline.utils.AttributedString; +import picocli.AutoComplete; +import picocli.CommandLine; +import picocli.CommandLine.Help; +import picocli.CommandLine.Model.CommandSpec; +import picocli.CommandLine.Model.OptionSpec; +import picocli.shell.jline3.PicocliCommands; + +/** + * Inspired by {@link PicocliCommands} but with custom dynamic completer and completer filtering. + */ +public class IgnitePicocliCommands implements CommandRegistry { + + private final CommandLine cmd; + private final Set<String> commands; + private final Map<String, String> aliasCommand = new HashMap<>(); + private final DynamicCompleterRegistry completerRegistry; + private final List<CompleterFilter> completerFilters; + + /** Default constructor. */ + public IgnitePicocliCommands(CommandLine cmd, DynamicCompleterRegistry completerRegistry, List<CompleterFilter> completerFilters) { + this.cmd = cmd; + this.completerFilters = completerFilters; + this.completerRegistry = completerRegistry; + this.commands = cmd.getCommandSpec().subcommands().keySet(); + putAliases(cmd); + } + + private void putAliases(CommandLine cmd) { + for (String c : commands) { + for (String a : cmd.getSubcommands().get(c).getCommandSpec().aliases()) { + aliasCommand.put(a, c); + } + } + } + + /** {@inheritDoc} */ + @Override + public boolean hasCommand(String command) { + return commands.contains(command) || aliasCommand.containsKey(command); + } + + /** {@inheritDoc} */ + @Override + public SystemCompleter compileCompleters() { + SystemCompleter out = new SystemCompleter(); + List<String> all = new ArrayList<>(); + all.addAll(commands); + all.addAll(aliasCommand.keySet()); + out.add(all, new IgnitePicocliCompleter()); + return out; + } + + private CommandLine findSubcommandLine(List<String> args, int lastIdx) { + CommandLine out = cmd; + for (int i = 0; i < lastIdx; i++) { + if (!args.get(i).startsWith("-")) { + out = findSubcommandLine(out, args.get(i)); + if (out == null) { + break; + } + } + } + return out; + } + + private CommandLine findSubcommandLine(CommandLine cmdline, String command) { + for (CommandLine s : cmdline.getSubcommands().values()) { + if (s.getCommandName().equals(command) || Arrays.asList(s.getCommandSpec().aliases()).contains(command)) { + return s; + } + } + return null; + } + + /** {@inheritDoc} */ + @Override + public CmdDesc commandDescription(List<String> args) { + CommandLine sub = findSubcommandLine(args, args.size()); + if (sub == null) { + return null; + } + CommandSpec spec = sub.getCommandSpec(); + Help cmdhelp = new picocli.CommandLine.Help(spec); + List<AttributedString> main = new ArrayList<>(); + Map<String, List<AttributedString>> options = new HashMap<>(); + String synopsis = AttributedString.stripAnsi(spec.usageMessage().sectionMap().get("synopsis").render(cmdhelp)); + main.add(HelpException.highlightSyntax(synopsis.trim(), HelpException.defaultStyle())); + // using JLine help highlight because the statement below does not work well... + // main.add(new AttributedString(spec.usageMessage().sectionMap().get("synopsis").render(cmdhelp).toString())); + for (OptionSpec o : spec.options()) { + String key = Arrays.stream(o.names()).collect(Collectors.joining(" ")); + List<AttributedString> val = new ArrayList<>(); + for (String d : o.description()) { + val.add(new AttributedString(d)); + } + if (o.arity().max() > 0) { + key += "=" + o.paramLabel(); + } + options.put(key, val); + } + return new CmdDesc(main, ArgDesc.doArgNames(List.of("")), options); + } + + /** {@inheritDoc} */ + @Override + public List<String> commandInfo(String command) { + List<String> out = new ArrayList<>(); + CommandSpec spec = cmd.getSubcommands().get(command).getCommandSpec(); + Help cmdhelp = new picocli.CommandLine.Help(spec); + String description = AttributedString.stripAnsi(spec.usageMessage().sectionMap().get("description").render(cmdhelp)); + out.addAll(Arrays.asList(description.split("\\r?\\n"))); + return out; Review Comment: ```suggestion return Arrays.asList(description.split("\\r?\\n")); ``` -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
