mirror of
https://github.com/alibaba/arthas.git
synced 2024-04-21 10:21:39 +00:00
transform command: help
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
package com.taobao.arthas.core.command.basic1000;
|
||||
|
||||
import com.taobao.arthas.core.command.model.*;
|
||||
import com.taobao.arthas.core.shell.cli.Completion;
|
||||
import com.taobao.arthas.core.shell.cli.CompletionUtils;
|
||||
import com.taobao.arthas.core.shell.command.AnnotatedCommand;
|
||||
@@ -9,24 +10,15 @@ import com.taobao.arthas.core.shell.command.CommandResolver;
|
||||
import com.taobao.arthas.core.shell.session.Session;
|
||||
import com.taobao.arthas.core.util.usage.StyledUsageFormatter;
|
||||
import com.taobao.middleware.cli.CLI;
|
||||
import com.taobao.middleware.cli.Option;
|
||||
import com.taobao.middleware.cli.annotations.Argument;
|
||||
import com.taobao.middleware.cli.annotations.Description;
|
||||
import com.taobao.middleware.cli.annotations.Name;
|
||||
import com.taobao.middleware.cli.annotations.Summary;
|
||||
import com.taobao.text.Color;
|
||||
import com.taobao.text.Decoration;
|
||||
import com.taobao.text.Style;
|
||||
import com.taobao.text.ui.Element;
|
||||
import com.taobao.text.ui.LabelElement;
|
||||
import com.taobao.text.ui.TableElement;
|
||||
import com.taobao.text.util.RenderUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static com.taobao.text.ui.Element.label;
|
||||
import static com.taobao.text.ui.Element.row;
|
||||
|
||||
/**
|
||||
* @author vlinux on 14/10/26.
|
||||
*/
|
||||
@@ -47,16 +39,91 @@ public class HelpCommand extends AnnotatedCommand {
|
||||
public void process(CommandProcess process) {
|
||||
List<Command> commands = allCommands(process.session());
|
||||
Command targetCmd = findCommand(commands);
|
||||
String message;
|
||||
if (targetCmd == null) {
|
||||
message = RenderUtil.render(mainHelp(commands), process.width());
|
||||
process.appendResult(createHelpModel(commands));
|
||||
} else {
|
||||
message = commandHelp(targetCmd, process.width());
|
||||
process.appendResult(createHelpDetailModel(targetCmd));
|
||||
}
|
||||
process.write(message);
|
||||
process.end();
|
||||
}
|
||||
|
||||
public HelpModel createHelpDetailModel(Command targetCmd) {
|
||||
return new HelpModel(createCommandVO(targetCmd, true));
|
||||
}
|
||||
|
||||
private HelpModel createHelpModel(List<Command> commands) {
|
||||
HelpModel helpModel = new HelpModel();
|
||||
for (Command command : commands) {
|
||||
if(command.cli() == null || command.cli().isHidden()){
|
||||
continue;
|
||||
}
|
||||
helpModel.addCommandVO(createCommandVO(command, false));
|
||||
}
|
||||
return helpModel;
|
||||
}
|
||||
|
||||
private CommandVO createCommandVO(Command command, boolean withDetail) {
|
||||
CLI cli = command.cli();
|
||||
CommandVO commandVO = new CommandVO();
|
||||
commandVO.setName(command.name());
|
||||
if (cli!=null){
|
||||
commandVO.setSummary(cli.getSummary());
|
||||
if (withDetail){
|
||||
commandVO.setCli(cli);
|
||||
StyledUsageFormatter usageFormatter = new StyledUsageFormatter(null);
|
||||
String usageLine = usageFormatter.computeUsageLine(null, cli);
|
||||
commandVO.setUsage(usageLine);
|
||||
commandVO.setDescription(cli.getDescription());
|
||||
|
||||
//以线程安全的方式遍历options
|
||||
List<Option> options = cli.getOptions();
|
||||
for (int i = 0; i < options.size(); i++) {
|
||||
Option option = options.get(i);
|
||||
if (option.isHidden()){
|
||||
continue;
|
||||
}
|
||||
commandVO.addOption(createOptionVO(option));
|
||||
}
|
||||
|
||||
//arguments
|
||||
List<com.taobao.middleware.cli.Argument> arguments = cli.getArguments();
|
||||
for (int i = 0; i < arguments.size(); i++) {
|
||||
com.taobao.middleware.cli.Argument argument = arguments.get(i);
|
||||
if (argument.isHidden()){
|
||||
continue;
|
||||
}
|
||||
commandVO.addArgument(createArgumentVO(argument));
|
||||
}
|
||||
}
|
||||
}
|
||||
return commandVO;
|
||||
}
|
||||
|
||||
private ArgumentVO createArgumentVO(com.taobao.middleware.cli.Argument argument) {
|
||||
ArgumentVO argumentVO = new ArgumentVO();
|
||||
argumentVO.setArgName(argument.getArgName());
|
||||
argumentVO.setMultiValued(argument.isMultiValued());
|
||||
argumentVO.setRequired(argument.isRequired());
|
||||
return argumentVO;
|
||||
}
|
||||
|
||||
private CommandOptionVO createOptionVO(Option option) {
|
||||
CommandOptionVO optionVO = new CommandOptionVO();
|
||||
if (!isEmptyName(option.getLongName())) {
|
||||
optionVO.setLongName(option.getLongName());
|
||||
}
|
||||
if (!isEmptyName(option.getShortName())) {
|
||||
optionVO.setShortName(option.getShortName());
|
||||
}
|
||||
optionVO.setDescription(option.getDescription());
|
||||
optionVO.setAcceptValue(option.acceptValue());
|
||||
return optionVO;
|
||||
}
|
||||
|
||||
private boolean isEmptyName(String name) {
|
||||
return name == null || name.equals(Option.NO_NAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void complete(Completion completion) {
|
||||
List<Command> commands = allCommands(completion.session());
|
||||
@@ -72,24 +139,6 @@ public class HelpCommand extends AnnotatedCommand {
|
||||
CompletionUtils.complete(completion, names);
|
||||
}
|
||||
|
||||
private static String commandHelp(Command command, int width) {
|
||||
return StyledUsageFormatter.styledUsage(command.cli(), width);
|
||||
}
|
||||
|
||||
private static Element mainHelp(List<Command> commands) {
|
||||
TableElement table = new TableElement().leftCellPadding(1).rightCellPadding(1);
|
||||
table.row(new LabelElement("NAME").style(Style.style(Decoration.bold)), new LabelElement("DESCRIPTION"));
|
||||
for (Command command : commands) {
|
||||
CLI cli = command.cli();
|
||||
// com.taobao.arthas.core.shell.impl.BuiltinCommandResolver doesn't have CLI instance
|
||||
if (cli == null || cli.isHidden()) {
|
||||
continue;
|
||||
}
|
||||
table.add(row().add(label(cli.getName()).style(Style.style(Color.green))).add(label(cli.getSummary())));
|
||||
}
|
||||
return table;
|
||||
}
|
||||
|
||||
private List<Command> allCommands(Session session) {
|
||||
List<CommandResolver> commandResolvers = session.getCommandResolvers();
|
||||
List<Command> commands = new ArrayList<Command>();
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.taobao.arthas.core.command.model;
|
||||
|
||||
/**
|
||||
* @author gongdewei 2020/4/3
|
||||
*/
|
||||
public class ArgumentVO {
|
||||
private String argName;
|
||||
private boolean required;
|
||||
private boolean multiValued;
|
||||
|
||||
public ArgumentVO() {
|
||||
}
|
||||
|
||||
public ArgumentVO(String argName, boolean required, boolean multiValued) {
|
||||
this.argName = argName;
|
||||
this.required = required;
|
||||
this.multiValued = multiValued;
|
||||
}
|
||||
|
||||
public String getArgName() {
|
||||
return argName;
|
||||
}
|
||||
|
||||
public void setArgName(String argName) {
|
||||
this.argName = argName;
|
||||
}
|
||||
|
||||
public boolean isRequired() {
|
||||
return required;
|
||||
}
|
||||
|
||||
public void setRequired(boolean required) {
|
||||
this.required = required;
|
||||
}
|
||||
|
||||
public boolean isMultiValued() {
|
||||
return multiValued;
|
||||
}
|
||||
|
||||
public void setMultiValued(boolean multiValued) {
|
||||
this.multiValued = multiValued;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package com.taobao.arthas.core.command.model;
|
||||
|
||||
|
||||
/**
|
||||
* @author gongdewei 2020/4/3
|
||||
*/
|
||||
public class CommandOptionVO {
|
||||
/**
|
||||
* the option long name.
|
||||
*/
|
||||
private String longName;
|
||||
|
||||
/**
|
||||
* the option short name.
|
||||
*/
|
||||
private String shortName;
|
||||
|
||||
/**
|
||||
* The option description.
|
||||
*/
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* whether or not the option receives a single value or multiple values.
|
||||
*/
|
||||
private boolean acceptValue;
|
||||
|
||||
public CommandOptionVO() {
|
||||
}
|
||||
|
||||
public String getLongName() {
|
||||
return longName;
|
||||
}
|
||||
|
||||
public void setLongName(String longName) {
|
||||
this.longName = longName;
|
||||
}
|
||||
|
||||
public String getShortName() {
|
||||
return shortName;
|
||||
}
|
||||
|
||||
public void setShortName(String shortName) {
|
||||
this.shortName = shortName;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public boolean isAcceptValue() {
|
||||
return acceptValue;
|
||||
}
|
||||
|
||||
public void setAcceptValue(boolean acceptValue) {
|
||||
this.acceptValue = acceptValue;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package com.taobao.arthas.core.command.model;
|
||||
|
||||
import com.taobao.middleware.cli.CLI;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author gongdewei 2020/4/3
|
||||
*/
|
||||
public class CommandVO {
|
||||
//TODO remove cli
|
||||
private transient CLI cli;
|
||||
private String name;
|
||||
private String description;
|
||||
private String usage;
|
||||
private String summary;
|
||||
private List<CommandOptionVO> options = new ArrayList<CommandOptionVO>();
|
||||
private List<ArgumentVO> arguments = new ArrayList<ArgumentVO>();
|
||||
|
||||
public CommandVO() {
|
||||
}
|
||||
|
||||
public CommandVO(String name, String description) {
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public CommandVO addOption(CommandOptionVO optionVO){
|
||||
this.options.add(optionVO);
|
||||
return this;
|
||||
}
|
||||
|
||||
public CommandVO addArgument(ArgumentVO argumentVO){
|
||||
this.arguments.add(argumentVO);
|
||||
return this;
|
||||
}
|
||||
|
||||
public CLI cli() {
|
||||
return cli;
|
||||
}
|
||||
|
||||
public void setCli(CLI cli) {
|
||||
this.cli = cli;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public String getUsage() {
|
||||
return usage;
|
||||
}
|
||||
|
||||
public void setUsage(String usage) {
|
||||
this.usage = usage;
|
||||
}
|
||||
|
||||
public String getSummary() {
|
||||
return summary;
|
||||
}
|
||||
|
||||
public void setSummary(String summary) {
|
||||
this.summary = summary;
|
||||
}
|
||||
|
||||
public List<CommandOptionVO> getOptions() {
|
||||
return options;
|
||||
}
|
||||
|
||||
public void setOptions(List<CommandOptionVO> options) {
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
public List<ArgumentVO> getArguments() {
|
||||
return arguments;
|
||||
}
|
||||
|
||||
public void setArguments(List<ArgumentVO> arguments) {
|
||||
this.arguments = arguments;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.taobao.arthas.core.command.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author gongdewei 2020/4/3
|
||||
*/
|
||||
public class HelpModel extends ResultModel {
|
||||
|
||||
//list
|
||||
private List<CommandVO> commands;
|
||||
|
||||
//details
|
||||
private CommandVO detailCommand;
|
||||
|
||||
public HelpModel() {
|
||||
}
|
||||
|
||||
public HelpModel(List<CommandVO> commands) {
|
||||
this.commands = commands;
|
||||
}
|
||||
|
||||
public HelpModel(CommandVO command) {
|
||||
this.detailCommand = command;
|
||||
}
|
||||
|
||||
public void addCommandVO(CommandVO commandVO){
|
||||
if (commands == null) {
|
||||
commands = new ArrayList<CommandVO>();
|
||||
}
|
||||
this.commands.add(commandVO);
|
||||
}
|
||||
|
||||
public List<CommandVO> getCommands() {
|
||||
return commands;
|
||||
}
|
||||
|
||||
public void setCommands(List<CommandVO> commands) {
|
||||
this.commands = commands;
|
||||
}
|
||||
|
||||
public CommandVO getDetailCommand() {
|
||||
return detailCommand;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return "help";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.taobao.arthas.core.command.view;
|
||||
|
||||
import com.taobao.arthas.core.command.model.CommandVO;
|
||||
import com.taobao.arthas.core.command.model.HelpModel;
|
||||
import com.taobao.arthas.core.shell.command.CommandProcess;
|
||||
import com.taobao.arthas.core.util.usage.StyledUsageFormatter;
|
||||
import com.taobao.middleware.cli.CLI;
|
||||
import com.taobao.text.Color;
|
||||
import com.taobao.text.Decoration;
|
||||
import com.taobao.text.Style;
|
||||
import com.taobao.text.ui.Element;
|
||||
import com.taobao.text.ui.LabelElement;
|
||||
import com.taobao.text.ui.TableElement;
|
||||
import com.taobao.text.util.RenderUtil;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static com.taobao.text.ui.Element.label;
|
||||
import static com.taobao.text.ui.Element.row;
|
||||
|
||||
/**
|
||||
* @author gongdewei 2020/4/3
|
||||
*/
|
||||
public class HelpView extends ResultView<HelpModel> {
|
||||
|
||||
@Override
|
||||
public void draw(CommandProcess process, HelpModel result) {
|
||||
if (result.getCommands() != null) {
|
||||
String message = RenderUtil.render(mainHelp(result.getCommands()), process.width());
|
||||
process.write(message);
|
||||
} else if (result.getDetailCommand() != null) {
|
||||
process.write(commandHelp(result.getDetailCommand().cli(), process.width()));
|
||||
}
|
||||
}
|
||||
|
||||
private static Element mainHelp(List<CommandVO> commands) {
|
||||
TableElement table = new TableElement().leftCellPadding(1).rightCellPadding(1);
|
||||
table.row(new LabelElement("NAME").style(Style.style(Decoration.bold)), new LabelElement("DESCRIPTION"));
|
||||
for (CommandVO commandVO : commands) {
|
||||
table.add(row().add(label(commandVO.getName()).style(Style.style(Color.green))).add(label(commandVO.getSummary())));
|
||||
}
|
||||
return table;
|
||||
}
|
||||
|
||||
private static String commandHelp(CLI command, int width) {
|
||||
return StyledUsageFormatter.styledUsage(command, width);
|
||||
}
|
||||
}
|
||||
@@ -103,7 +103,7 @@ public class StyledUsageFormatter extends UsageMessageFormatter {
|
||||
return Style.style(Decoration.bold, fontColor);
|
||||
}
|
||||
|
||||
private String computeUsageLine(String prefix, CLI cli) {
|
||||
public String computeUsageLine(String prefix, CLI cli) {
|
||||
// initialise the string buffer
|
||||
StringBuilder buff;
|
||||
if (prefix == null) {
|
||||
|
||||
Reference in New Issue
Block a user