in app/lib/tfcommand.ts [488:609]
public async getHelp(cmd: command.TFXCommand): Promise<string> {
const includeUndocumented = await this.commandArgs.includeUndocumented.val();
this.commandArgs.output.setValue("help");
let result = eol;
let continuedHierarchy: command.CommandHierarchy = cmd.commandHierarchy;
cmd.execPath.forEach(segment => {
continuedHierarchy = continuedHierarchy[segment];
});
if (continuedHierarchy === null) {
// Need help with a particular command
let singleArgData = (argName: string, maxArgLen: number) => {
// Lodash's kebab adds a dash between letters and numbers, so this is just a hack to avoid that.
let argKebab = argName === "json5" ? "json5" : _.kebabCase(argName);
const argObj = this.commandArgs[argName];
const shorthandArg = argObj.aliases.filter(a => a.length === 2 && a.substr(0, 1) === "-")[0];
if (shorthandArg) {
argKebab = `${argKebab}, ${shorthandArg}`;
}
if (argObj.undocumented && !includeUndocumented) {
return "";
}
return (
" --" +
argKebab +
" " +
repeatStr(" ", maxArgLen - argKebab.length) +
gray(argObj.description || argObj.friendlyName + ".") +
eol
);
};
let commandName = cmd.execPath[cmd.execPath.length - 1];
result +=
cyan("Syntax: ") +
eol +
cyan("tfx ") +
yellow(cmd.execPath.join(" ")) +
green(" --arg1 arg1val1 arg1val2[...]") +
gray(" --arg2 arg2val1 arg2val2[...]") +
eol +
eol;
return loader
.load(cmd.execPath, ["--service-url", "null"])
.then(tfCommand => {
result += cyan("Command: ") + commandName + eol;
result += tfCommand.description + eol + eol;
result += cyan("Arguments: ") + eol;
let uniqueArgs = this.getHelpArgs();
uniqueArgs = _.uniq(uniqueArgs);
let maxArgLen = uniqueArgs.map(a => _.kebabCase(a)).reduce((a, b) => Math.max(a, b.length), 0);
if (uniqueArgs.length === 0) {
result += "[No arguments for this command]" + eol;
}
uniqueArgs.forEach(arg => {
result += singleArgData(arg, maxArgLen);
});
if (this.serverCommand) {
result += eol + cyan("Global server command arguments:") + eol;
["authType", "username", "password", "token", "serviceUrl", "fiddler", "proxy"].forEach(arg => {
result += singleArgData(arg, 11);
});
}
result += eol + cyan("Global arguments:") + eol;
["help", "save", "noColor", "noPrompt", "output", "json", "traceLevel", "debugLogStream"].forEach(arg => {
result += singleArgData(arg, 9);
});
result +=
eol +
gray(
"To see more commands, type " +
resetColors("tfx " + cmd.execPath.slice(0, cmd.execPath.length - 1).join(" ") + " --help"),
);
})
.then(() => {
return result;
});
} else {
// Need help with a suite of commands
// There is a weird coloring bug when colors are nested, so we don't do that.
result +=
cyan("Available ") +
"commands" +
cyan(" and ") +
yellow("command groups") +
cyan(" in " + ["tfx"].concat(cmd.execPath).join(" / ") + ":") +
eol;
let commandDescriptionPromises: Promise<void>[] = [];
Object.keys(continuedHierarchy).forEach(command => {
if (command === "default") {
return;
}
let pr = loader.load(cmd.execPath.concat([command]), ["--service-url", "null"]).then(tfCommand => {
let coloredCommand = command;
if (continuedHierarchy[command] !== null) {
coloredCommand = yellow(command);
}
result += " - " + coloredCommand + gray(": " + tfCommand.description) + eol;
});
commandDescriptionPromises.push(pr);
});
return Promise.all(commandDescriptionPromises)
.then(() => {
result +=
eol +
eol +
gray("For help with an individual command, type ") +
resetColors("tfx " + cmd.execPath.join(" ") + " <command> --help") +
eol;
})
.then(() => {
return result;
});
}
}