8000 Do not track help command when other command fails · telerik/mobile-cli-lib@c93c34b · GitHub
[go: up one dir, main page]

Skip to content
This repository was archived by the owner on Feb 2, 2021. It is now read-only.

Commit c93c34b

Browse files
Do not track help command when other command fails
In case any command fails, we execute help command in order to show the help content. This leads to multiple trackings, i.e. - user executes only one command, but in Analytics we see two commands. Instead of executing help command, introduce new method in htmlHelpService, that prints the help to the terminal and call it instead. Use the same method in the help command itself. Rename htmlHelpService to helpService - it has been incorrectly named from the beginning. Remove `helpTextPath` from staticConfig interface - this property is not used for more than 2 years. Introduce tests for `helpService` - get the tests from AppBuilder CLI.
1 parent 0812ce9 commit c93c34b

File tree

12 files changed

+498
-75
lines changed

12 files changed

+498
-75
lines changed

bootstrap.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ $injector.require("dynamicHelpService", "./services/dynamic-help-service");
9292
$injector.require("microTemplateService", "./services/micro-templating-service");
9393
$injector.require("mobileHelper", "./mobile/mobile-helper");
9494
$injector.require("devicePlatformsConstants", "./mobile/device-platforms-constants");
95-
$injector.require("htmlHelpService", "./services/html-help-service");
95+
$injector.require("helpService", "./services/html-help-service");
9696
$injector.require("messageContractGenerator", "./services/message-contract-generator");
9797
$injector.require("proxyService", "./services/proxy-service");
9898
$injector.require("credentialsService", "./services/credentials-service");

commands/help.ts

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
1-
import { EOL } from "os";
2-
31
export class HelpCommand implements ICommand {
4-
constructor(private $logger: ILogger,
5-
private $injector: IInjector,
6-
private $htmlHelpService: IHtmlHelpService,
7-
private $staticConfig: Config.IStaticConfig,
2+
constructor(private $injector: IInjector,
3+
private $helpService: IHelpService,
84
private $options: ICommonOptions) { }
95

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

2420
if (this.$options.help) {
25-
const help = await this.$htmlHelpService.getCommandLineHelpForCommand(topic);
26-
if (this.$staticConfig.FULL_CLIENT_NAME) {
27-
this.$logger.info(this.$staticConfig.FULL_CLIENT_NAME.green.bold + EOL);
28-
}
29-
30-
this.$logger.printMarkdown(help);
21+
await this.$helpService.showCommandLineHelp(topic);
3122
} else {
32-
await this.$htmlHelpService.openHelpForCommandInBrowser(topic);
23+
await this.$helpService.openHelpForCommandInBrowser(topic);
3324
}
3425
}
3526
}

commands/post-install.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ export class PostInstallCommand implements ICommand {
22
constructor(private $fs: IFileSystem,
33
private $staticConfig: Config.IStaticConfig,
44
private $commandsService: ICommandsService,
5-
private $htmlHelpService: IHtmlHelpService,
5+
private $helpService: IHelpService,
66
private $options: ICommonOptions,
77
private $doctorService: IDoctorService,
88
private $analyticsService: IAnalyticsService,
@@ -22,7 +22,7 @@ export class PostInstallCommand implements ICommand {
2222
}
2323
}
2424

25-
await this.$htmlHelpService.generateHtmlPages();
25+
await this.$helpService.generateHtmlPages();
2626

2727
const doctorResult = await this.$doctorService.printWarnings({ trackResult: false });
2828
// Explicitly ask for confirmation of usage-reporting:

declarations.d.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -540,7 +540,7 @@ interface IErrors {
540540
fail(formatStr: string, ...args: any[]): never;
541541
fail(opts: { formatStr?: string; errorCode?: number; suppressCommandHelp?: boolean }, ...args: any[]): never;
542542
failWithoutHelp(message: string, ...args: any[]): never;
543-
beginCommand(action: () => Promise<boolean>, printCommandHelp: () => Promise<boolean>): Promise<boolean>;
543+
beginCommand(action: () => Promise<boolean>, printCommandHelp: () => Promise<void>): Promise<boolean>;
544544
verifyHeap(message: string): void;
545545
printCallStack: boolean;
546546
}
@@ -955,7 +955,7 @@ interface IMicroTemplateService {
955955
parseContent(data: string, options: { isHtml: boolean }): Promise<string>;
956956
}
957957

958-
interface IHtmlHelpService {
958+
interface IHelpService {
959959
generateHtmlPages(): Promise<void>;
960960

961961
/**
@@ -966,6 +966,13 @@ interface IHtmlHelpService {
966966
getCommandLineHelpForCommand(commandName: string): Promise<string>;
967967

968968
openHelpForCommandInBrowser(commandName: string): Promise<void>;
969+
970+
/**
971+
* Shows command line help for specified command.
972+
* @param {string} commandName The name of the command for which to show the help.
973+
* @returns {Promise<void>}
974+
*/
975+
showCommandLineHelp(commandName: string): Promise<void>;
969976
}
970977

971978
/**

definitions/config.d.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ declare module Config {
1313
ERROR_REPORT_SETTING_NAME: string;
1414
SYS_REQUIREMENTS_LINK: string;
1515
version: string;
16-
helpTextPath: string;
1716
getAdbFilePath(): Promise<string>;
1817
disableAnalytics?: boolean;
1918
disableCommandHooks?: boolean;

errors.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ export class Errors implements IErrors {
151151
return this.fail({ formatStr: util.format.apply(null, args), suppressCommandHelp: true });
152152
}
153153

154-
public async beginCommand(action: () => Promise<boolean>, printCommandHelp: () => Promise<boolean>): Promise<boolean> {
154+
public async beginCommand(action: () => Promise<boolean>, printCommandHelp: () => Promise<void>): Promise<boolean> {
155155
try {
156156
return await action();
157157
} catch (ex) {

services/commands-service.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ export class CommandsService implements ICommandsService {
2424
private $logger: ILogger,
2525
private $options: ICommonOptions,
2626
private $resources: IResourceLoader,
27-
private $staticConfig: Config.IStaticConfig) {
27+
private $staticConfig: Config.IStaticConfig,
28+
private $helpService: IHelpService) {
2829
}
2930

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

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

8585
private async executeCommandAction(commandName: string, commandArguments: string[], action: (_commandName: string, _commandArguments: string[]) => Promise<boolean>): Promise<boolean> {

services/dynamic-help-service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export class DynamicHelpService implements IDynamicHelpService {
1515

1616
public getLocalVariables(options: { isHtml: boolean }): IDictionary<any> {
1717
const isHtml = options.isHtml;
18-
//in html help we want to show all help. Only CONSOLE specific help(wrapped in if(isConsole) ) must be omitted
18+
// in html help we want to show all help. Only CONSOLE specific help(wrapped in if(isConsole) ) must be omitted
1919
const localVariables = this.$dynamicHelpProvider.getLocalVariables(options);
2020
localVariables["isLinux"] = isHtml || this.isPlatform("linux");
2121
localVariables["isWindows"] = isHtml || this.isPlatform("win32");

services/html-help-service.ts

Lines changed: 49 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as path from "path";
22
import { EOL } from "os";
33
import marked = require("marked");
44

5-
export class HtmlHelpService implements IHtmlHelpService {
5+
export class HelpService implements IHelpService {
66
private static MARKDOWN_FILE_EXTENSION = ".md";
77
private static HTML_FILE_EXTENSION = ".html";
88
private static MAN_PAGE_NAME_REGEX = /@MAN_PAGE_NAME@/g;
@@ -38,23 +38,59 @@ export class HtmlHelpService implements IHtmlHelpService {
3838
private $fs: IFileSystem,
3939
private $staticConfig: Config.IStaticConfig,
4040
private $microTemplateService: IMicroTemplateService,
41-
private $opener: IOpener,
42-
private $commandsServiceProvider: ICommandsServiceProvider) {
41+
private $opener: IOpener) {
4342
this.pathToHtmlPages = this.$staticConfig.HTML_PAGES_DIR;
4443
this.pathToManPages = this.$staticConfig.MAN_PAGES_DIR;
4544
}
4645

46+
public async openHelpForCommandInBrowser(commandName: string): Promise<void> {
47+
const htmlPage = await this.convertCommandNameToFileName(commandName) + HelpService.HTML_FILE_EXTENSION;
48+
this.$logger.trace("Opening help for command '%s'. FileName is '%s'.", commandName, htmlPage);
49+
50+
this.$fs.ensureDirectoryExists(this.pathToHtmlPages);
51+
if (!this.tryOpeningSelectedPage(htmlPage)) {
52+
// HTML pages may have been skipped on post-install, lets generate them.
53+
this.$logger.trace("Required HTML file '%s' is missing. Let's try generating HTML files and see if we'll find it.", htmlPage);
54+
await this.generateHtmlPages();
55+
if (!this.tryOpeningSelectedPage(htmlPage)) {
56+
this.$errors.failWithoutHelp("Unable to find help for '%s'", commandName);
57+
}
58+
}
59+
}
60+
4761
public async generateHtmlPages(): Promise<void> {
4862
const mdFiles = this.$fs.enumerateFilesInDirectorySync(this.pathToManPages);
4963
const basicHtmlPage = this.$fs.readText(this.pathToBasicPage);
5064
await Promise.all(_.map(mdFiles, markdownFile => this.createHtmlPage(basicHtmlPage, markdownFile)));
5165
this.$logger.trace("Finished generating HTML files.");
5266
}
5367

68+
public async showCommandLineHelp(commandName: string): Promise<void> {
69+
const help = await this.getCommandLineHelpForCommand(commandName);
70+
if (this.$staticConfig.FULL_CLIENT_NAME) {
71+
this.$logger.info(this.$staticConfig.FULL_CLIENT_NAME.green.bold + EOL);
72+
}
73+
74+
this.$logger.printMarkdown(help);
75+
}
76+
77+
public async getCommandLineHelpForCommand(commandName: string): Promise<string> {
78+
const helpText = await this.readMdFileForCommand(commandName);
79+
const commandLineHelp = (await this.$microTemplateService.parseContent(helpText, { isHtml: false }))
80+
.replace(/&nbsp;/g, " ")
81+
.replace(HelpService.MARKDOWN_LINK_REGEX, "$1")
82+
.replace(HelpService.SPAN_REGEX, (matchingSubstring: string, textBeforeSpan: string, textInsideSpan: string, index: number, fullString: string): string => {
83+
return textBeforeSpan + textInsideSpan.replace(this.newLineRegex, "");
84+
})
85+
.replace(HelpService.NEW_LINE_REGEX, EOL);
86+
87+
return commandLineHelp;
88+
}
89+
5490
// This method should return Promise in order to generate all html pages simultaneously.
5591
private async createHtmlPage(basicHtmlPage: string, pathToMdFile: string): Promise<void> {
5692
const mdFileName = path.basename(pathToMdFile);
57-
const htmlFileName = mdFileName.replace(HtmlHelpService.MARKDOWN_FILE_EXTENSION, HtmlHelpService.HTML_FILE_EXTENSION);
93+
const htmlFileName = mdFileName.replace(HelpService.MARKDOWN_FILE_EXTENSION, HelpService.HTML_FILE_EXTENSION);
5894
this.$logger.trace("Generating '%s' help topic.", htmlFileName);
5995

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

69105
const outputHtml = basicHtmlPage
70-
.replace(HtmlHelpService.MAN_PAGE_NAME_REGEX, mdFileName.replace(HtmlHelpService.MARKDOWN_FILE_EXTENSION, ""))
71-
.replace(HtmlHelpService.HTML_COMMAND_HELP_REGEX, htmlText)
72-
.replace(HtmlHelpService.RELATIVE_PATH_TO_STYLES_CSS_REGEX, path.relative(path.dirname(filePath), this.pathToStylesCss))
73-
.replace(HtmlHelpService.RELATIVE_PATH_TO_IMAGES_REGEX, path.relative(path.dirname(filePath), this.pathToImages))
74-
.replace(HtmlHelpService.RELATIVE_PATH_TO_INDEX_REGEX, path.relative(path.dirname(filePath), this.pathToIndexHtml));
106+
.replace(HelpService.MAN_PAGE_NAME_REGEX, mdFileName.replace(HelpService.MARKDOWN_FILE_EXTENSION, ""))
107+
.replace(HelpService.HTML_COMMAND_HELP_REGEX, htmlText)
108+
.replace(HelpService.RELATIVE_PATH_TO_STYLES_CSS_REGEX, path.relative(path.dirname(filePath), this.pathToStylesCss))
109+
.replace(HelpService.RELATIVE_PATH_TO_IMAGES_REGEX, path.relative(path.dirname(filePath), this.pathToImages))
110+
.replace(HelpService.RELATIVE_PATH_TO_INDEX_REGEX, path.relative(path.dirname(filePath), this.pathToIndexHtml));
75111

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

80-
public async openHelpForCommandInBrowser(commandName: string): Promise<void> {
81-
const htmlPage = await this.convertCommandNameToFileName(commandName) + HtmlHelpService.HTML_FILE_EXTENSION;
82-
this.$logger.trace("Opening help for command '%s'. FileName is '%s'.", commandName, htmlPage);
83-
84-
this.$fs.ensureDirectoryExists(this.pathToHtmlPages);
85-
if (!this.tryOpeningSelectedPage(htmlPage)) {
86-
// HTML pages may have been skipped on post-install, lets generate them.
87-
this.$logger.trace("Required HTML file '%s' is missing. Let's try generating HTML files and see if we'll find it.", htmlPage);
88-
await this.generateHtmlPages();
89-
if (!this.tryOpeningSelectedPage(htmlPage)) {
90-
this.$errors.failWithoutHelp("Unable to find help for '%s'", commandName);
91-
}
92-
}
93-
}
94-
95116
private async convertCommandNameToFileName(commandName: string): Promise<string> {
96117
const defaultCommandMatch = commandName.match(/(\w+?)\|\*/);
97118
if (defaultCommandMatch) {
@@ -101,11 +122,8 @@ export class HtmlHelpService implements IHtmlHelpService {
101122

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

111129
return commandName.replace(/\|/g, "-") || "index";
@@ -127,7 +145,7 @@ export class HtmlHelpService implements IHtmlHelpService {
127145
}
128146

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

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

138156
this.$errors.failWithoutHelp("Unknown command '%s'. Try '$ %s help' for a full list of supported commands.", mdFileName.replace(".md", ""), this.$staticConfig.CLIENT_NAME.toLowerCase());
139157
}
140-
141-
public async getCommandLineHelpForCommand(commandName: string): Promise<string> {
142-
const helpText = await this.readMdFileForCommand(commandName);
143-
const commandLineHelp = (await this.$microTemplateService.parseContent(helpText, { isHtml: false }))
144-
.replace(/&nbsp;/g, " ")
145-
.replace(HtmlHelpService.MARKDOWN_LINK_REGEX, "$1")
146-
.replace(HtmlHelpService.SPAN_REGEX, (matchingSubstring: string, textBeforeSpan: string, textInsideSpan: string, index: number, fullString: string): string => {
147-
return textBeforeSpan + textInsideSpan.replace(this.newLineRegex, "");
148-
})
149-
.replace(HtmlHelpService.NEW_LINE_REGEX, EOL);
150-
151-
return commandLineHelp;
152-
}
153158
}
154159

155-
$injector.register("htmlHelpService", HtmlHelpService);
160+
$injector.register("helpService", HelpService);

static-config-base.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,6 @@ export abstract class StaticConfigBase implements Config.IStaticConfig {
3636

3737
constructor(protected $injector: IInjector) { }
3838

39-
public get helpTextPath(): string {
40-
return null;
41-
}
42-
4339
public async getAdbFilePath(): Promise<string> {
4440
if (!this._adbFilePath) {
4541
this._adbFilePath = await this.getAdbFilePathCore();

0 commit comments

Comments
 (0)
0