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

Commit 52e8914

Browse files
FatmeFatme
Fatme
authored and
Fatme
committed
Merge pull request #306 from telerik/fatme/ns-release-1.0.0
TNS release 1.0.0
2 parents 55c8fcc + f3c23be commit 52e8914

28 files changed

+213
-79
lines changed

commands/post-install.ts

-8
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ export class PostInstallCommand implements ICommand {
1313

1414
constructor(private $fs: IFileSystem,
1515
private $staticConfig: Config.IStaticConfig,
16-
private $childProcess: IChildProcess,
1716
private $commandsService: ICommandsService,
1817
private $htmlHelpService: IHtmlHelpService,
1918
private $sysInfo: ISysInfo,
@@ -43,8 +42,6 @@ export class PostInstallCommand implements ICommand {
4342
this.printAppBuilderWarnings(sysInfo);
4443
}
4544

46-
this.checkSevenZip().wait();
47-
4845
this.$commandsService.tryExecuteCommand("autocomplete", []).wait();
4946
}).future<void>()();
5047
}
@@ -139,10 +136,5 @@ export class PostInstallCommand implements ICommand {
139136
+ "or http://docs.oracle.com/javase/7/docs/webnotes/install/ (for JDK 7)." + os.EOL);
140137
}
141138
}
142-
143-
private checkSevenZip(): IFuture<void> {
144-
var sevenZipErrorMessage = util.format(PostInstallCommand.SEVEN_ZIP_ERROR_MESSAGE, this.$staticConfig.SYS_REQUIREMENTS_LINK);
145-
return this.$childProcess.tryExecuteApplication(this.$staticConfig.sevenZipFilePath, ["-h"], "exit", sevenZipErrorMessage);
146-
}
147139
}
148140
$injector.registerCommand("dev-post-install", PostInstallCommand);

commands/preuninstall.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export class PreUninstallCommand implements ICommand {
2121
var adbPath = path.join(__dirname, relativeAdbPath);
2222

2323
var killAdbServerCommand = util.format("\"%s\" kill-server", adbPath);
24-
this.$logger.warn("Trying to kill adb server. Some running andorid related operations may fail.");
24+
this.$logger.warn("Trying to kill adb server. Some running Android related operations may fail.");
2525

2626
try {
2727
this.$childProcess.exec(killAdbServerCommand).wait();

declarations.d.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -183,8 +183,6 @@ interface IDictionary<T> {
183183
[key: string]: T
184184
}
185185

186-
interface IStringDictionary extends IDictionary<string> { }
187-
188186
interface IAnalyticsService {
189187
checkConsent(featureName: string): IFuture<void>;
190188
trackFeature(featureName: string): IFuture<void>;
@@ -198,6 +196,8 @@ interface IAnalyticsService {
198196
interface IPrompter extends IDisposable {
199197
get(schema: IPromptSchema[]): IFuture<any>;
200198
getPassword(prompt: string, options?: {allowEmpty?: boolean}): IFuture<string>;
199+
getString(prompt: string): IFuture<string>;
200+
promptForChoice(promptMessage: string, choices: any[]): IFuture<string>;
201201
confirm(prompt: string, defaultAction?: () => boolean): IFuture<boolean>;
202202
}
203203

definitions/commands-service.d.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
interface ICommandsService {
2-
allCommands(includeDev: boolean): string[];
2+
allCommands(opts: {includeDevCommands: boolean}): string[];
33
tryExecuteCommand(commandName: string, commandArguments: string[]): IFuture<void>;
44
executeCommandUnchecked(commandName: string, commandArguments: string[]): IFuture<boolean>;
55
completeCommand(): IFuture<boolean>;
66
}
77

88
interface ICommandsServiceProvider {
9+
dynamicCommandsPrefix: string;
910
getDynamicCommands(): IFuture<string[]>;
1011
generateDynamicCommands(): IFuture<void>;
1112
registerDynamicSubCommands(): void;

definitions/commands.d.ts

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ interface ICommandArgument { }
2222

2323
interface ICommandParameter {
2424
mandatory: boolean;
25+
errorMessage?: string
2526
validate(value: string, errorMessage?: string): IFuture<boolean>;
2627
}
2728

definitions/config.d.ts

-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ declare module Config {
1111
version: string;
1212
helpTextPath: string;
1313
adbFilePath: string;
14-
sevenZipFilePath: string;
1514
disableAnalytics?: boolean;
1615
disableHooks?: boolean;
1716
enableDeviceRunCommandOnWindows?: boolean;

definitions/logger.d.ts

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
interface ILogger {
22
setLevel(level: string): void;
33
getLevel(): string;
4-
fatal(formatStr: any, ...args: string[]): void;
5-
error(formatStr: any, ...args: string[]): void;
6-
warn(formatStr: any, ...args: string[]): void;
7-
info(formatStr: any, ...args: string[]): void;
8-
debug(formatStr: any, ...args: string[]): void;
9-
trace(formatStr: any, ...args: string[]): void;
4+
fatal(formatStr?: any, ...args: string[]): void;
5+
error(formatStr?: any, ...args: string[]): void;
6+
warn(formatStr?: any, ...args: string[]): void;
7+
info(formatStr?: any, ...args: string[]): void;
8+
debug(formatStr?: any, ...args: string[]): void;
9+
trace(formatStr?: any, ...args: string[]): void;
1010

11-
out(formatStr: any, ...args: string[]): void;
11+
out(formatStr?: any, ...args: string[]): void;
1212
write(...args: string[]): void;
1313

1414
prepare(item: any): string;

definitions/minimatch.d.ts

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
///<reference path="./node.d.ts"/>
2+
3+
declare module minimatch {
4+
export interface Options {
5+
debug?: boolean;
6+
nobrace?: boolean;
7+
noglobstar?: boolean;
8+
dot?: boolean;
9+
noext?: boolean;
10+
nonull?: boolean;
11+
nocase?: boolean;
12+
matchBase?: boolean;
13+
nocomment?: boolean;
14+
nonegate?: boolean;
15+
flipNegate?: boolean;
16+
}
17+
18+
export interface Minimatch {
19+
constructor(pattern: string, options: Options): Minimatch;
20+
pattern: string;
21+
options: Options;
22+
regexp: RegExp;
23+
set: any[][];
24+
negate: boolean;
25+
comment: boolean;
26+
empty: boolean;
27+
makeRe(): RegExp;
28+
match(path: string): boolean;
29+
}
30+
31+
export interface IMinimatch {
32+
(path: string, pattern: string, options?: Options): boolean;
33+
filter(pattern: string, options?: Options): (path: string) => boolean;
34+
match(fileList: string[], pattern: string, options?: Options): string[];
35+
makeRe(pattern: string, options?: Options): RegExp;
36+
37+
Minimatch: minimatch.Minimatch;
38+
}
39+
}
40+
41+
declare var minimatch: minimatch.IMinimatch;
42+
43+
declare module "minimatch" {
44+
export = minimatch;
45+
}

definitions/mobile.d.ts

-1
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,6 @@ declare module Mobile {
165165
}
166166

167167
interface IHouseArrestClient {
168-
getAfcClientForAppDocuments(applicationIdentifier: string): Mobile.IAfcClient;
169168
getAfcClientForAppContainer(applicationIdentifier: string): Mobile.IAfcClient;
170169
closeSocket(): void;
171170
}

definitions/options-service.d.ts

-3
This file was deleted.

docs/helpers/styles.css

+1
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ ul {
186186
}
187187

188188
ol {
189+
margin: 10px 10px 10px 20px;
189190
list-style-type: decimal;
190191
}
191192

file-system.ts

+26-7
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import Future = require("fibers/future");
66
import path = require("path");
77
import util = require("util");
88
import rimraf = require("rimraf");
9+
import minimatch = require("minimatch");
910
import hostInfo = require("./host-info");
1011

1112
export class FileSystem implements IFileSystem {
@@ -55,20 +56,38 @@ export class FileSystem implements IFileSystem {
5556
return (() => {
5657
var shouldOverwriteFiles = !(options && options.overwriteExisitingFiles === false);
5758
var isCaseSensitive = !(options && options.caseSensitive === false);
58-
59-
//the wild card symbol at the end is required in order for the -ssc- switch of 7zip to behave properly
60-
zipFile = isCaseSensitive ? zipFile : zipFile + '*';
6159

6260
this.createDirectory(destinationDir).wait();
63-
var args = <string[]>(_.flatten(['x', shouldOverwriteFiles ? "-y" : "-aos", '-o' + destinationDir, isCaseSensitive ? '-ssc' : '-ssc-', zipFile, fileFilters || []]));
6461

65-
var $childProcess = this.$injector.resolve("childProcess");
66-
var $staticConfig = this.$injector.resolve("staticConfig");
62+
var proc: string;
63+
if (hostInfo.isWindows()) {
64+
proc = path.join(__dirname, "resources/platform-tools/unzip/win32/unzip");
65+
} else if (hostInfo.isDarwin()) {
66+
proc = "unzip"; // darwin unzip is info-zip
67+
} else if (hostInfo.isLinux()) {
68+
proc = "unzip"; // linux unzip is info-zip
69+
}
70+
71+
if (!isCaseSensitive) {
72+
zipFile = this.findFileCaseInsensitive(zipFile);
73+
}
74+
75+
var args = <string[]>(_.flatten(['-b', shouldOverwriteFiles ? "-o" : "-n", isCaseSensitive ? [] : '-C', zipFile, fileFilters || [], '-d', destinationDir]));
6776

68-
$childProcess.spawnFromEvent($staticConfig.sevenZipFilePath, args, "close", { stdio: "ignore", detached: true }).wait();
77+
var $childProcess = this.$injector.resolve("childProcess");
78+
$childProcess.spawnFromEvent(proc, args, "close", { stdio: "ignore", detached: true }).wait();
6979
}).future<void>()();
7080
}
7181

82+
private findFileCaseInsensitive(file: string): string {
83+
var dir = path.dirname(file);
84+
var basename = path.basename(file);
85+
var entries = this.readDirectory(dir).wait();
86+
var match = minimatch.match(entries, basename, {nocase:true, nonegate: true, nonull: true})[0];
87+
var result = path.join(dir, match);
88+
return result;
89+
}
90+
7291
public exists(path: string): IFuture<boolean> {
7392
var future = new Future<boolean>();
7493
fs.exists(path, (exists: boolean) => future.return(exists));

helpers.ts

+10
Original file line numberDiff line numberDiff line change
@@ -140,3 +140,13 @@ export function createTable(headers: string[], data: string[][]): any {
140140
_.forEach(data, row => table.push(row));
141141
return table;
142142
}
143+
144+
export function remove<T>(array: T[], predicate: (element: T) => boolean, numberOfElements?: number): T[] {
145+
numberOfElements = numberOfElements || 1;
146+
var index = _.findIndex(array, predicate);
147+
if (index === -1) {
148+
return new Array<T>();
149+
}
150+
151+
return <T[]>array.splice(index, numberOfElements);
152+
}

mobile/ios/ios-device.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -378,8 +378,8 @@ export class IOSDevice implements Mobile.IIOSDevice {
378378
return(() => {
379379
//TODO: CloseSocket must be part of afcClient. Refactor it.
380380
var houseArrestClient: Mobile.IHouseArrestClient = this.$injector.resolve(iOSProxyServices.HouseArrestClient, {device: this});
381-
var afcClientForAppDocuments = houseArrestClient.getAfcClientForAppDocuments(appIdentifier.appIdentifier);
382-
afcClientForAppDocuments.transferCollection(localToDevicePaths).wait();
381+
var afcClientForContainer = houseArrestClient.getAfcClientForAppContainer(appIdentifier.appIdentifier);
382+
afcClientForContainer.transferCollection(localToDevicePaths).wait();
383383
houseArrestClient.closeSocket();
384384

385385
if (!options.skipRefresh) {

mobile/ios/ios-proxy-services.ts

+9-6
Original file line numberDiff line numberDiff line change
@@ -349,9 +349,13 @@ export class NotificationProxyClient implements Mobile.INotificationProxyClient
349349

350350
export class HouseArrestClient implements Mobile.IHouseArrestClient {
351351
private plistService: Mobile.IiOSDeviceSocket = null;
352+
private static PREDEFINED_ERRORS: IStringDictionary = {
353+
ApplicationLookupFailed: "Unable to find the application on a connected device. Ensure that the application is installed and try again."
354+
}
352355

353356
constructor(private device: Mobile.IIOSDevice,
354-
private $injector: IInjector) {
357+
private $injector: IInjector,
358+
private $errors: IErrors) {
355359
}
356360

357361
private getAfcClientCore(command: string, applicationIdentifier: string): Mobile.IAfcClient {
@@ -363,15 +367,14 @@ export class HouseArrestClient implements Mobile.IHouseArrestClient {
363367
"Identifier": applicationIdentifier
364368
});
365369

366-
this.plistService.receiveMessage().wait();
370+
var response = this.plistService.receiveMessage().wait();
371+
if(response.Error) {
372+
this.$errors.failWithoutHelp(HouseArrestClient.PREDEFINED_ERRORS[response.Error] || response.Error);
373+
}
367374

368375
return this.$injector.resolve(AfcClient, {service: service});
369376
}
370377

371-
public getAfcClientForAppDocuments(applicationIdentifier: string): Mobile.IAfcClient {
372-
return this.getAfcClientCore("VendDocuments", applicationIdentifier);
373-
}
374-
375378
public getAfcClientForAppContainer(applicationIdentifier: string): Mobile.IAfcClient {
376379
return this.getAfcClientCore("VendContainer", applicationIdentifier);
377380
}

mobile/wp8/wp8-emulator-services.ts

+6-2
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,15 @@ class Wp8EmulatorServices implements Mobile.IEmulatorPlatformServices {
3232
startEmulator(app: string, emulatorOptions?: Mobile.IEmulatorOptions) : IFuture<void> {
3333
return (() => {
3434
this.$logger.info("Starting Windows Phone Emulator");
35-
var emulatorStarter = path.join(process.env.ProgramFiles, Wp8EmulatorServices.WP8_LAUNCHER_PATH, Wp8EmulatorServices.WP8_LAUNCHER);
36-
this.$childProcess.spawn(emulatorStarter, ["/installlaunch", app, "/targetdevice:xd"], { stdio: ["ignore", "ignore", "ignore"], detached: true }).unref();
35+
var emulatorStarter = path.join(Wp8EmulatorServices.programFilesPath, Wp8EmulatorServices.WP8_LAUNCHER_PATH, Wp8EmulatorServices.WP8_LAUNCHER);
36+
this.$childProcess.spawn(emulatorStarter, ["/installlaunch", app, "/targetdevice:xd"], { stdio: "ignore", detached: true }).unref();
3737
}).future<void>()();
3838
}
3939

40+
private static get programFilesPath(): string {
41+
return (process.arch === "x64") ? process.env["PROGRAMFILES(X86)"] : process.env.ProgramFiles;
42+
}
43+
4044
private static WP8_LAUNCHER = "XapDeployCmd.exe";
4145
private static WP8_LAUNCHER_PATH = "Microsoft SDKs\\Windows Phone\\v8.0\\Tools\\XAP Deployment";
4246
}

prompter.ts

+27
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,33 @@ export class Prompter implements IPrompter {
6868
}).future<string>()();
6969
}
7070

71+
public getString(prompt: string): IFuture<string> {
72+
return (() => {
73+
var schema: IPromptSchema = {
74+
message: prompt,
75+
type: "input",
76+
name: "inputString"
77+
};
78+
79+
var result = this.get([schema]).wait();
80+
return result.inputString;
81+
}).future<string>()();
82+
}
83+
84+
public promptForChoice(promptMessage: string, choices: any[]): IFuture<string> {
85+
return (() => {
86+
var schema: IPromptSchema = {
87+
message: promptMessage,
88+
type: "list",
89+
name: "userAnswer",
90+
choices: choices
91+
};
92+
93+
var result = this.get([schema]).wait();
94+
return result.userAnswer;
95+
}).future<string>()();
96+
}
97+
7198
public confirm(prompt: string, defaultAction?: () => boolean): IFuture<boolean> {
7299
return ((): boolean => {
73100
var schema = {
-1.38 MB
Binary file not shown.
-1.37 MB
Binary file not shown.
-220 KB
Binary file not shown.
-590 KB
Binary file not shown.
-126 KB
Binary file not shown.
258 KB
Binary file not shown.

0 commit comments

Comments
 (0)