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

Restructure error messaging #484

Merged
merged 6 commits into from
Nov 16, 2015
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
4 changes: 4 additions & 0 deletions bootstrap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ $injector.require("stringParameterBuilder", "./command-params");

$injector.require("commandsService", "./services/commands-service");

$injector.require("messagesService", "./services/messages-service");

$injector.require("cancellation", "./services/cancellation");
$injector.require("analyticsService", "./services/analytics-service");
$injector.require("hooksService", "./services/hooks-service");
Expand Down Expand Up @@ -95,7 +97,9 @@ $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("messageContractGenerator", "./services/message-contract-generator");
$injector.requireCommand("dev-preuninstall", "./commands/preuninstall");
$injector.requireCommand("dev-generate-messages", "./commands/generate-messages");
$injector.requireCommand("doctor", "./commands/doctor");

$injector.require("utils", "./utils");
Expand Down
57 changes: 57 additions & 0 deletions codeGeneration/code-entity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
///<reference path="../.d.ts"/>
"use strict";

export enum CodeEntityType {
Line,
Block
}

export class Line implements CodeGeneration.ILine {
public content: string;

constructor(content: string) {
this.content = content;
}

public get codeEntityType() {
return CodeEntityType.Line;
}

public static create(content: string): CodeGeneration.ILine {
return new Line(content);
}
}
$injector.register("swaggerLine", Line);

export class Block implements CodeGeneration.IBlock {
public opener: string;
public codeEntities: CodeGeneration.ICodeEntity[];
public endingCharacter: string;

constructor(opener?: string) {
this.opener = opener;
this.codeEntities = [];
}

public get codeEntityType() {
return CodeEntityType.Block;
}

public addBlock(block: CodeGeneration.IBlock): void {
this.codeEntities.push(block);
}

public addLine(line: CodeGeneration.ILine): void {
this.codeEntities.push(line);
}

public addBlocks(blocks: CodeGeneration.IBlock[]): void {
_.each(blocks, (block: CodeGeneration.IBlock) => this.addBlock(block));
}

public writeLine(content: string): void {
let line = Line.create(content);
this.codeEntities.push(line);
}
}
$injector.register("swaggerBlock", Block);
46 changes: 46 additions & 0 deletions codeGeneration/code-generation.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
declare module CodeGeneration {

interface IModel {
id: string;
properties: IDictionary<IModelProperty>;
}

interface IModelProperty {
type: string;
items: IModelPropertyItems;
allowableValues: IModelPropertyValue;
}

interface IModelPropertyItems {
$ref: string;
}

interface IModelPropertyValue {
valueType: string;
values: string[];
}

interface ICodeEntity {
opener?: string;
codeEntityType: any;
}

interface ILine extends ICodeEntity {
content: string;
}

interface IBlock extends ICodeEntity {
opener: string;
codeEntities: ICodeEntity[];
writeLine(content: string): void;
addLine(line: ILine): void;
addBlock(block: IBlock): void;
addBlocks(blocks: IBlock[]): void;
endingCharacter?: string;
}

interface IService {
serviceInterface: IBlock;
serviceImplementation: IBlock;
}
}
53 changes: 53 additions & 0 deletions codeGeneration/code-printer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
///<reference path="../.d.ts"/>
"use strict";

import {EOL} from "os";
import {CodeEntityType} from "./code-entity";

export class CodePrinter {
private static INDENT_CHAR = "\t";
private static NEW_LINE_CHAR = EOL;
private static START_BLOCK_CHAR = "{";
private static END_BLOCK_CHAR = "}";

public composeBlock(block: CodeGeneration.IBlock, indentSize: number = 0): string {
let content = this.getIndentation(indentSize);

if(block.opener) {
content += block.opener;
content += CodePrinter.START_BLOCK_CHAR;
content += CodePrinter.NEW_LINE_CHAR;
}

_.each(block.codeEntities, (codeEntity: CodeGeneration.ICodeEntity) => {
if(codeEntity.codeEntityType === CodeEntityType.Line) {
content += this.composeLine(<CodeGeneration.ILine>codeEntity, indentSize + 1);
} else if(codeEntity.codeEntityType === CodeEntityType.Block){
content += this.composeBlock(<CodeGeneration.IBlock>codeEntity, indentSize + 1);
}
});

if(block.opener) {
content += this.getIndentation(indentSize);
content += CodePrinter.END_BLOCK_CHAR;
content += block.endingCharacter || '';
}

content += CodePrinter.NEW_LINE_CHAR;

return content;
}

private getIndentation(indentSize: number): string {
return Array(indentSize).join(CodePrinter.INDENT_CHAR);
}

private composeLine(line: CodeGeneration.ILine, indentSize: number): string {
let content = this.getIndentation(indentSize);
content += line.content;
content += CodePrinter.NEW_LINE_CHAR;

return content;
}
}
$injector.register("swaggerCodePrinter", CodePrinter);
38 changes: 38 additions & 0 deletions commands/generate-messages.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
///<reference path="../.d.ts"/>
"use strict";
import * as path from "path";

export class GenerateMessages implements ICommand {
private static MESSAGES_DEFINITIONS_FILE_NAME = "messages.d.ts";
private static MESSAGES_IMPLEMENTATION_FILE_NAME = "messages.ts";

constructor(private $fs: IFileSystem,
private $messageContractGenerator: IServiceContractGenerator,
private $options: ICommonOptions) {
}

allowedParameters: ICommandParameter[] = [];

execute(args: string[]): IFuture<void> {
return (() => {
let definitionsPath = `"${this.$options.default ? "../" : ""}.d.ts"`,
result = this.$messageContractGenerator.generate(definitionsPath).wait(),
innerMessagesDirectory = path.join(__dirname, "../messages"),
outerMessagesDirectory = path.join(__dirname, "../.."),
interfaceFilePath: string,
implementationFilePath: string;

if (this.$options.default) {
interfaceFilePath = path.join(innerMessagesDirectory, GenerateMessages.MESSAGES_DEFINITIONS_FILE_NAME);
implementationFilePath = path.join(innerMessagesDirectory, GenerateMessages.MESSAGES_IMPLEMENTATION_FILE_NAME);
} else {
interfaceFilePath = path.join(outerMessagesDirectory, GenerateMessages.MESSAGES_DEFINITIONS_FILE_NAME);
implementationFilePath = path.join(outerMessagesDirectory, GenerateMessages.MESSAGES_IMPLEMENTATION_FILE_NAME);
}

this.$fs.writeFile(interfaceFilePath, result.interfaceFile).wait();
this.$fs.writeFile(implementationFilePath, result.implementationFile).wait();
}).future<void>()();
}
}
$injector.registerCommand("dev-generate-messages", GenerateMessages);
39 changes: 39 additions & 0 deletions declarations.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,7 @@ interface ICommonOptions {
emulator: boolean;
sdk: string;
var: Object;
default: Boolean;
}

interface IYargArgv extends IDictionary<any> {
Expand Down Expand Up @@ -558,3 +559,41 @@ interface IPluginVariablesHelper {
getPluginVariableFromVarOption(variableName: string, configuration?: string): any;
simplifyYargsObject(obj: any, configuration?: string): any;
}

/**
* Used for getting strings for informational/error messages.
*/
interface IMessagesService {
/**
* Array of the paths to the .json files containing all the messages.
* @type {string[]}
*/
pathsToMessageJsonFiles: string[];

/**
* @param {string} id Message's key in corresponding messages json file, could be complex (e.g. 'iOS.iTunes.ConnectError').
* @param {string[]} args Additional arguments used when the message's value is a string format.
* @return {string} The value found under the given id. If no value is found returns the id itself.
*/
getMessage(id: string, ...args: string[]): string;
}

/**
* Describes generated code parts.
*/
interface IServiceContractClientCode {
interfaceFile: string;
implementationFile: string;
}

/**
* Used for code generation.
*/
interface IServiceContractGenerator {
/**
* Generate code implementation along with interface
* @param {string} definitionsPath The path to the desired parent .d.ts file
* @return {IFuture<IServiceContractClientCode>} The generated code parts
*/
generate(definitionsPath?: string): IFuture<IServiceContractClientCode>;
}
8 changes: 4 additions & 4 deletions errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ export function installUncaughtExceptionListener(actionOnException?: () => void)
}

export class Errors implements IErrors {
constructor(private $injector: IInjector) {
}

public printCallStack: boolean = false;

Expand All @@ -102,15 +104,13 @@ export class Errors implements IErrors {
opts = { formatStr: opts };
}

args.unshift(opts.formatStr);

let exception: any = new (<any>Exception)();
exception.name = opts.name || "Exception";
exception.message = util.format.apply(null, args);
exception.message = this.$injector.resolve("messagesService").getMessage(opts.formatStr, ...args);
exception.stack = (new Error(exception.message)).stack;
exception.errorCode = opts.errorCode || ErrorCodes.UNKNOWN;
exception.suppressCommandHelp = opts.suppressCommandHelp;

this.$injector.resolve("logger").trace(opts.formatStr);
throw exception;
}

Expand Down
12 changes: 6 additions & 6 deletions file-system.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ import * as crypto from "crypto";

@injector.register("fs")
export class FileSystem implements IFileSystem {
constructor(private $injector: IInjector,
private $hostInfo: IHostInfo) { }
constructor(private $injector: IInjector) { }

//TODO: try 'archiver' module for zipping
public zipFiles(zipFile: string, files: string[], zipPathCallback: (path: string) => string): IFuture<void> {
Expand Down Expand Up @@ -60,15 +59,16 @@ export class FileSystem implements IFileSystem {
return (() => {
let shouldOverwriteFiles = !(options && options.overwriteExisitingFiles === false);
let isCaseSensitive = !(options && options.caseSensitive === false);
let $hostInfo = this.$injector.resolve("$hostInfo");

this.createDirectory(destinationDir).wait();

let proc: string;
if (this.$hostInfo.isWindows) {
if ($hostInfo.isWindows) {
proc = path.join(__dirname, "resources/platform-tools/unzip/win32/unzip");
} else if (this.$hostInfo.isDarwin) {
} else if ($hostInfo.isDarwin) {
proc = "unzip"; // darwin unzip is info-zip
} else if (this.$hostInfo.isLinux) {
} else if ($hostInfo.isLinux) {
proc = "unzip"; // linux unzip is info-zip
}

Expand Down Expand Up @@ -441,7 +441,7 @@ export class FileSystem implements IFileSystem {
return (() => {
let $childProcess = this.$injector.resolve("childProcess");

if(!this.$hostInfo.isWindows) {
if(!this.$injector.resolve("$hostInfo").isWindows) {
let chown = $childProcess.spawn("chown", ["-R", owner, path],
{ stdio: "ignore", detached: true });
this.futureFromEvent(chown, "close").wait();
Expand Down
13 changes: 13 additions & 0 deletions messages/messages.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
///<reference path="../.d.ts"/>
//
// automatically generated code; do not edit manually!
//
interface IMessages{
Devices : {
NotFoundDeviceByIdentifierErrorMessage: string;
NotFoundDeviceByIdentifierErrorMessageWithIdentifier: string;
NotFoundDeviceByIndexErrorMessage: string;
};

}

16 changes: 16 additions & 0 deletions messages/messages.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
///<reference path="../.d.ts"/>
"use strict";
//
// automatically generated code; do not edit manually!
//

export class Messages implements IMessages{
Devices = {
NotFoundDeviceByIdentifierErrorMessage: "Devices.NotFoundDeviceByIdentifierErrorMessage",
NotFoundDeviceByIdentifierErrorMessageWithIdentifier: "Devices.NotFoundDeviceByIdentifierErrorMessageWithIdentifier",
NotFoundDeviceByIndexErrorMessage: "Devices.NotFoundDeviceByIndexErrorMessage",
};

}
$injector.register('messages', Messages);

Loading