Skip to content
This repository was archived by the owner on Feb 2, 2021. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion bootstrap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ $injector.require("dynamicHelpService", "./services/dynamic-help-service");
$injector.require("microTemplateService", "./services/micro-templating-service");
$injector.require("mobileHelper", "./mobile/mobile-helper");
$injector.require("devicePlatformsConstants", "./mobile/device-platforms-constants");
$injector.require("htmlHelpService", "./services/html-help-service");
$injector.require("helpService", "./services/help-service");
$injector.require("messageContractGenerator", "./services/message-contract-generator");
$injector.require("proxyService", "./services/proxy-service");
$injector.require("credentialsService", "./services/credentials-service");
Expand Down
17 changes: 4 additions & 13 deletions commands/help.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
import { EOL } from "os";

export class HelpCommand implements ICommand {
constructor(private $logger: ILogger,
private $injector: IInjector,
private $htmlHelpService: IHtmlHelpService,
private $staticConfig: Config.IStaticConfig,
constructor(private $injector: IInjector,
private $helpService: IHelpService,
private $options: ICommonOptions) { }

public enableHooks = false;
Expand All @@ -22,14 +18,9 @@ export class HelpCommand implements ICommand {
}

if (this.$options.help) {
const help = await this.$htmlHelpService.getCommandLineHelpForCommand(topic);
if (this.$staticConfig.FULL_CLIENT_NAME) {
this.$logger.info(this.$staticConfig.FULL_CLIENT_NAME.green.bold + EOL);
}

this.$logger.printMarkdown(help);
await this.$helpService.showCommandLineHelp(topic);
} else {
await this.$htmlHelpService.openHelpForCommandInBrowser(topic);
await this.$helpService.openHelpForCommandInBrowser(topic);
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions commands/post-install.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ export class PostInstallCommand implements ICommand {
constructor(private $fs: IFileSystem,
private $staticConfig: Config.IStaticConfig,
private $commandsService: ICommandsService,
private $htmlHelpService: IHtmlHelpService,
private $helpService: IHelpService,
private $options: ICommonOptions,
private $doctorService: IDoctorService,
private $analyticsService: IAnalyticsService,
Expand All @@ -22,7 +22,7 @@ export class PostInstallCommand implements ICommand {
}
}

await this.$htmlHelpService.generateHtmlPages();
await this.$helpService.generateHtmlPages();

const doctorResult = await this.$doctorService.printWarnings({ trackResult: false });
// Explicitly ask for confirmation of usage-reporting:
Expand Down
16 changes: 8 additions & 8 deletions declarations.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -540,7 +540,7 @@ interface IErrors {
fail(formatStr: string, ...args: any[]): never;
fail(opts: { formatStr?: string; errorCode?: number; suppressCommandHelp?: boolean }, ...args: any[]): never;
failWithoutHelp(message: string, ...args: any[]): never;
beginCommand(action: () => Promise<boolean>, printCommandHelp: () => Promise<boolean>): Promise<boolean>;
beginCommand(action: () => Promise<boolean>, printCommandHelp: () => Promise<void>): Promise<boolean>;
verifyHeap(message: string): void;
printCallStack: boolean;
}
Expand Down Expand Up @@ -955,17 +955,17 @@ interface IMicroTemplateService {
parseContent(data: string, options: { isHtml: boolean }): Promise<string>;
}

interface IHtmlHelpService {
interface IHelpService {
generateHtmlPages(): Promise<void>;

openHelpForCommandInBrowser(commandName: string): Promise<void>;

/**
* Gets the help content for a specific command that should be shown on the terminal.
* @param {string} commandName Name of the command for which to read the help.
* @returns {Promise<string>} Help content of the command parsed with all terminal rules applied (stripped content that should be shown only for html help).
* Shows command line help for specified command.
* @param {string} commandName The name of the command for which to show the help.
* @returns {Promise<void>}
*/
getCommandLineHelpForCommand(commandName: string): Promise<string>;

openHelpForCommandInBrowser(commandName: string): Promise<void>;
showCommandLineHelp(commandName: string): Promise<void>;
}

/**
Expand Down
1 change: 0 additions & 1 deletion definitions/config.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ declare module Config {
ERROR_REPORT_SETTING_NAME: string;
SYS_REQUIREMENTS_LINK: string;
version: string;
helpTextPath: string;
getAdbFilePath(): Promise<string>;
disableAnalytics?: boolean;
disableCommandHooks?: boolean;
Expand Down
2 changes: 1 addition & 1 deletion errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ export class Errors implements IErrors {
return this.fail({ formatStr: util.format.apply(null, args), suppressCommandHelp: true });
}

public async beginCommand(action: () => Promise<boolean>, printCommandHelp: () => Promise<boolean>): Promise<boolean> {
public async beginCommand(action: () => Promise<boolean>, printCommandHelp: () => Promise<void>): Promise<boolean> {
try {
return await action();
} catch (ex) {
Expand Down
8 changes: 4 additions & 4 deletions services/commands-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ export class CommandsService implements ICommandsService {
private $logger: ILogger,
private $options: ICommonOptions,
private $resources: IResourceLoader,
private $staticConfig: Config.IStaticConfig) {
private $staticConfig: Config.IStaticConfig,
private $helpService: IHelpService) {
}

public allCommands(opts: { includeDevCommands: boolean }): string[] {
Expand Down Expand Up @@ -77,9 +78,8 @@ export class CommandsService implements ICommandsService {
return false;
}

private async printHelp(commandName: string): Promise<boolean> {
this.$options.help = true;
return this.executeCommandUnchecked("help", [this.beautifyCommandName(commandName)]);
private printHelp(commandName: string): Promise<void> {
return this.$helpService.showCommandLineHelp(this.beautifyCommandName(commandName));
}

private async executeCommandAction(commandName: string, commandArguments: string[], action: (_commandName: string, _commandArguments: string[]) => Promise<boolean>): Promise<boolean> {
Expand Down
2 changes: 1 addition & 1 deletion services/dynamic-help-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export class DynamicHelpService implements IDynamicHelpService {

public getLocalVariables(options: { isHtml: boolean }): IDictionary<any> {
const isHtml = options.isHtml;
//in html help we want to show all help. Only CONSOLE specific help(wrapped in if(isConsole) ) must be omitted
// in html help we want to show all help. Only CONSOLE specific help(wrapped in if(isConsole) ) must be omitted
const localVariables = this.$dynamicHelpProvider.getLocalVariables(options);
localVariables["isLinux"] = isHtml || this.isPlatform("linux");
localVariables["isWindows"] = isHtml || this.isPlatform("win32");
Expand Down
98 changes: 54 additions & 44 deletions services/html-help-service.ts → services/help-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as path from "path";
import { EOL } from "os";
import marked = require("marked");

export class HtmlHelpService implements IHtmlHelpService {
export class HelpService implements IHelpService {
private static MARKDOWN_FILE_EXTENSION = ".md";
private static HTML_FILE_EXTENSION = ".html";
private static MAN_PAGE_NAME_REGEX = /@MAN_PAGE_NAME@/g;
Expand Down Expand Up @@ -38,23 +38,64 @@ export class HtmlHelpService implements IHtmlHelpService {
private $fs: IFileSystem,
private $staticConfig: Config.IStaticConfig,
private $microTemplateService: IMicroTemplateService,
private $opener: IOpener,
private $commandsServiceProvider: ICommandsServiceProvider) {
private $opener: IOpener) {
this.pathToHtmlPages = this.$staticConfig.HTML_PAGES_DIR;
this.pathToManPages = this.$staticConfig.MAN_PAGES_DIR;
}

public async openHelpForCommandInBrowser(commandName: string): Promise<void> {
const htmlPage = await this.convertCommandNameToFileName(commandName) + HelpService.HTML_FILE_EXTENSION;
this.$logger.trace("Opening help for command '%s'. FileName is '%s'.", commandName, htmlPage);

this.$fs.ensureDirectoryExists(this.pathToHtmlPages);
if (!this.tryOpeningSelectedPage(htmlPage)) {
// HTML pages may have been skipped on post-install, lets generate them.
this.$logger.trace("Required HTML file '%s' is missing. Let's try generating HTML files and see if we'll find it.", htmlPage);
await this.generateHtmlPages();
if (!this.tryOpeningSelectedPage(htmlPage)) {
this.$errors.failWithoutHelp("Unable to find help for '%s'", commandName);
}
}
}

public async generateHtmlPages(): Promise<void> {
const mdFiles = this.$fs.enumerateFilesInDirectorySync(this.pathToManPages);
const basicHtmlPage = this.$fs.readText(this.pathToBasicPage);
await Promise.all(_.map(mdFiles, markdownFile => this.createHtmlPage(basicHtmlPage, markdownFile)));
this.$logger.trace("Finished generating HTML files.");
}

public async showCommandLineHelp(commandName: string): Promise<void> {
const help = await this.getCommandLineHelpForCommand(commandName);
if (this.$staticConfig.FULL_CLIENT_NAME) {
this.$logger.info(this.$staticConfig.FULL_CLIENT_NAME.green.bold + EOL);
}

this.$logger.printMarkdown(help);
}

/**
* Gets the help content for a specific command that should be shown on the terminal.
* @param {string} commandName Name of the command for which to read the help.
* @returns {Promise<string>} Help content of the command parsed with all terminal rules applied (stripped content that should be shown only for html help).
*/
private async getCommandLineHelpForCommand(commandName: string): Promise<string> {
const helpText = await this.readMdFileForCommand(commandName);
const commandLineHelp = (await this.$microTemplateService.parseContent(helpText, { isHtml: false }))
.replace(/&nbsp;/g, " ")
.replace(HelpService.MARKDOWN_LINK_REGEX, "$1")
.replace(HelpService.SPAN_REGEX, (matchingSubstring: string, textBeforeSpan: string, textInsideSpan: string, index: number, fullString: string): string => {
return textBeforeSpan + textInsideSpan.replace(this.newLineRegex, "");
})
.replace(HelpService.NEW_LINE_REGEX, EOL);

return commandLineHelp;
}

// This method should return Promise in order to generate all html pages simultaneously.
private async createHtmlPage(basicHtmlPage: string, pathToMdFile: string): Promise<void> {
const mdFileName = path.basename(pathToMdFile);
const htmlFileName = mdFileName.replace(HtmlHelpService.MARKDOWN_FILE_EXTENSION, HtmlHelpService.HTML_FILE_EXTENSION);
const htmlFileName = mdFileName.replace(HelpService.MARKDOWN_FILE_EXTENSION, HelpService.HTML_FILE_EXTENSION);
this.$logger.trace("Generating '%s' help topic.", htmlFileName);

const helpText = this.$fs.readText(pathToMdFile);
Expand All @@ -67,31 +108,16 @@ export class HtmlHelpService implements IHtmlHelpService {
this.$logger.trace("HTML file path for '%s' man page is: '%s'.", mdFileName, filePath);

const outputHtml = basicHtmlPage
.replace(HtmlHelpService.MAN_PAGE_NAME_REGEX, mdFileName.replace(HtmlHelpService.MARKDOWN_FILE_EXTENSION, ""))
.replace(HtmlHelpService.HTML_COMMAND_HELP_REGEX, htmlText)
.replace(HtmlHelpService.RELATIVE_PATH_TO_STYLES_CSS_REGEX, path.relative(path.dirname(filePath), this.pathToStylesCss))
.replace(HtmlHelpService.RELATIVE_PATH_TO_IMAGES_REGEX, path.relative(path.dirname(filePath), this.pathToImages))
.replace(HtmlHelpService.RELATIVE_PATH_TO_INDEX_REGEX, path.relative(path.dirname(filePath), this.pathToIndexHtml));
.replace(HelpService.MAN_PAGE_NAME_REGEX, mdFileName.replace(HelpService.MARKDOWN_FILE_EXTENSION, ""))
.replace(HelpService.HTML_COMMAND_HELP_REGEX, htmlText)
.replace(HelpService.RELATIVE_PATH_TO_STYLES_CSS_REGEX, path.relative(path.dirname(filePath), this.pathToStylesCss))
.replace(HelpService.RELATIVE_PATH_TO_IMAGES_REGEX, path.relative(path.dirname(filePath), this.pathToImages))
.replace(HelpService.RELATIVE_PATH_TO_INDEX_REGEX, path.relative(path.dirname(filePath), this.pathToIndexHtml));

this.$fs.writeFile(filePath, outputHtml);
this.$logger.trace("Finished writing file '%s'.", filePath);
}

public async openHelpForCommandInBrowser(commandName: string): Promise<void> {
const htmlPage = await this.convertCommandNameToFileName(commandName) + HtmlHelpService.HTML_FILE_EXTENSION;
this.$logger.trace("Opening help for command '%s'. FileName is '%s'.", commandName, htmlPage);

this.$fs.ensureDirectoryExists(this.pathToHtmlPages);
if (!this.tryOpeningSelectedPage(htmlPage)) {
// HTML pages may have been skipped on post-install, lets generate them.
this.$logger.trace("Required HTML file '%s' is missing. Let's try generating HTML files and see if we'll find it.", htmlPage);
await this.generateHtmlPages();
if (!this.tryOpeningSelectedPage(htmlPage)) {
this.$errors.failWithoutHelp("Unable to find help for '%s'", commandName);
}
}
}

private async convertCommandNameToFileName(commandName: string): Promise<string> {
const defaultCommandMatch = commandName.match(/(\w+?)\|\*/);
if (defaultCommandMatch) {
Expand All @@ -101,11 +127,8 @@ export class HtmlHelpService implements IHtmlHelpService {

const availableCommands = this.$injector.getRegisteredCommandsNames(true).sort();
this.$logger.trace("List of registered commands: %s", availableCommands.join(", "));
if (commandName && _.startsWith(commandName, this.$commandsServiceProvider.dynamicCommandsPrefix) && !_.includes(availableCommands, commandName)) {
const dynamicCommands = await this.$commandsServiceProvider.getDynamicCommands();
if (!_.includes(dynamicCommands, commandName)) {
this.$errors.failWithoutHelp("Unknown command '%s'. Try '$ %s help' for a full list of supported commands.", commandName, this.$staticConfig.CLIENT_NAME.toLowerCase());
}
if (!_.includes(availableCommands, commandName)) {
this.$errors.failWithoutHelp("Unknown command '%s'. Try '$ %s help' for a full list of supported commands.", commandName, this.$staticConfig.CLIENT_NAME.toLowerCase());
}

return commandName.replace(/\|/g, "-") || "index";
Expand All @@ -127,7 +150,7 @@ export class HtmlHelpService implements IHtmlHelpService {
}

private async readMdFileForCommand(commandName: string): Promise<string> {
const mdFileName = await this.convertCommandNameToFileName(commandName) + HtmlHelpService.MARKDOWN_FILE_EXTENSION;
const mdFileName = await this.convertCommandNameToFileName(commandName) + HelpService.MARKDOWN_FILE_EXTENSION;
this.$logger.trace("Reading help for command '%s'. FileName is '%s'.", commandName, mdFileName);

const markdownFile = _.find(this.$fs.enumerateFilesInDirectorySync(this.pathToManPages), file => path.basename(file) === mdFileName);
Expand All @@ -137,19 +160,6 @@ export class HtmlHelpService implements IHtmlHelpService {

this.$errors.failWithoutHelp("Unknown command '%s'. Try '$ %s help' for a full list of supported commands.", mdFileName.replace(".md", ""), this.$staticConfig.CLIENT_NAME.toLowerCase());
}

public async getCommandLineHelpForCommand(commandName: string): Promise<string> {
const helpText = await this.readMdFileForCommand(commandName);
const commandLineHelp = (await this.$microTemplateService.parseContent(helpText, { isHtml: false }))
.replace(/&nbsp;/g, " ")
.replace(HtmlHelpService.MARKDOWN_LINK_REGEX, "$1")
.replace(HtmlHelpService.SPAN_REGEX, (matchingSubstring: string, textBeforeSpan: string, textInsideSpan: string, index: number, fullString: string): string => {
return textBeforeSpan + textInsideSpan.replace(this.newLineRegex, "");
})
.replace(HtmlHelpService.NEW_LINE_REGEX, EOL);

return commandLineHelp;
}
}

$injector.register("htmlHelpService", HtmlHelpService);
$injector.register("helpService", HelpService);
4 changes: 0 additions & 4 deletions static-config-base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,6 @@ export abstract class StaticConfigBase implements Config.IStaticConfig {

constructor(protected $injector: IInjector) { }

public get helpTextPath(): string {
return null;
}

public async getAdbFilePath(): Promise<string> {
if (!this._adbFilePath) {
this._adbFilePath = await this.getAdbFilePathCore();
Expand Down
Loading