Skip to content

Android releated commands - platform add, prepare, build and platform list #6

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 19 commits into from
Jul 17, 2014
Merged
Show file tree
Hide file tree
Changes from 18 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
9 changes: 9 additions & 0 deletions lib/bootstrap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,17 @@ require("./common/bootstrap");
$injector.require("nativescript-cli", "./nativescript-cli");

$injector.require("projectService", "./services/project-service");
$injector.require("androidProjectService", "./services/project-service");
$injector.require("iOSProjectService", "./services/project-service");
$injector.require("projectTemplatesService", "./services/project-templates-service");
$injector.require("platformService", "./services/platform-service");

$injector.requireCommand("create", "./commands/create-project-command");
$injector.requireCommand("platform|*list", "./commands/list-platforms-command");
$injector.requireCommand("platform|add", "./commands/add-platform-command");
$injector.requireCommand("run", "./commands/run-command");
$injector.requireCommand("prepare", "./commands/prepare-command");
$injector.requireCommand("build", "./commands/build-command");

$injector.require("npm", "./node-package-manager");
$injector.require("propertiesParser", "./properties-parser");
12 changes: 12 additions & 0 deletions lib/commands/add-platform-command.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
///<reference path="../.d.ts"/>

export class AddPlatformCommand implements ICommand {
constructor(private $platformService: IPlatformService) { }

execute(args: string[]): IFuture<void> {
return (() => {
this.$platformService.addPlatforms(args).wait();
}).future<void>()();
}
}
$injector.registerCommand("platform|add", AddPlatformCommand);
12 changes: 12 additions & 0 deletions lib/commands/build-command.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
///<reference path="../.d.ts"/>

export class BuildCommand implements ICommand {
constructor(private $platformService: IPlatformService) { }

execute(args: string[]): IFuture<void> {
return (() => {
this.$platformService.buildPlatform(args[0]).wait();
}).future<void>()();
}
}
$injector.registerCommand("build", BuildCommand);
20 changes: 20 additions & 0 deletions lib/commands/list-platforms-command.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
///<reference path="../.d.ts"/>
import helpers = require("./../common/helpers");

export class ListPlatformsCommand implements ICommand {
constructor(private $platformService: IPlatformService,
private $logger: ILogger) { }

execute(args: string[]): IFuture<void> {
return (() => {
var availablePlatforms = this.$platformService.getAvailablePlatforms().wait();
this.$logger.out("Available platforms: %s", helpers.formatListOfNames(availablePlatforms));

var installedPlatforms = this.$platformService.getInstalledPlatforms().wait();
this.$logger.out("Installed platforms %s", helpers.formatListOfNames(installedPlatforms));
}).future<void>()();
}
}
$injector.registerCommand("platform|*list", ListPlatformsCommand);


12 changes: 12 additions & 0 deletions lib/commands/prepare-command.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
///<reference path="../.d.ts"/>

export class PrepareCommand implements ICommand {
constructor(private $platformService: IPlatformService) { }

execute(args: string[]): IFuture<void> {
return (() => {
this.$platformService.preparePlatform(args[0]).wait();
}).future<void>()();
}
}
$injector.registerCommand("prepare", PrepareCommand);
12 changes: 12 additions & 0 deletions lib/commands/run-command.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
///<reference path="../.d.ts"/>

export class RunCommand implements ICommand {
constructor(private $platformService: IPlatformService) { }

execute(args: string[]): IFuture<void> {
return (() => {
this.$platformService.runPlatform(args[0]).wait();
}).future<void>()();
}
}
$injector.registerCommand("run", RunCommand);
2 changes: 1 addition & 1 deletion lib/common
10 changes: 7 additions & 3 deletions lib/declarations.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
interface INodePackageManager {
cache: string;
load(config?: any): IFuture<void>;
install(where: string, what: string): IFuture<any>;
cache: string;
load(config?: any): IFuture<void>;
install(where: string, what: string): IFuture<any>;
}

interface IPropertiesParser {
createEditor(filePath: string): IFuture<any>;
}
12 changes: 12 additions & 0 deletions lib/definitions/platform.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
interface IPlatformService {
addPlatforms(platforms: string[]): IFuture<void>;
getInstalledPlatforms(): IFuture<string[]>;
getAvailablePlatforms(): IFuture<string[]>;
runPlatform(platform: string): IFuture<void>;
preparePlatform(platform: string): IFuture<void>;
buildPlatform(platform: string): IFuture<void>;
}

interface IPlatformCapabilities {
targetedOS?: string[];
}
19 changes: 19 additions & 0 deletions lib/definitions/project.d.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,26 @@
interface IProjectService {
createProject(projectName: string, projectId: string): IFuture<void>;
createPlatformSpecificProject(platform: string): IFuture<void>;
prepareProject(normalizedPlatformName: string, platforms: string[]): IFuture<void>;
buildProject(platform: string): IFuture<void>;
ensureProject(): void;
projectData: IProjectData;
}

interface IPlatformProjectService {
createProject(projectData: IProjectData): IFuture<void>;
buildProject(projectData: IProjectData): IFuture<void>;
}

interface IProjectData {
projectDir: string;
platformsDir: string;
projectFilePath: string;
projectId?: string;
projectName?: string;
}

interface IProjectTemplatesService {
defaultTemplatePath: IFuture<string>;
getAndroidFrameworkPath(whereToInstall: string): IFuture<string>
}
3 changes: 3 additions & 0 deletions lib/definitions/properties-parser.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
declare module "properties-parser" {
function createEditor(path: string, callback: (err: IErrors, data: any) => void);
}
1 change: 1 addition & 0 deletions lib/definitions/shelljs.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ declare module "shelljs" {
function cp(arg: string, sourcePath: string, destinationPath: string): void;
function sed(arg: string, oldValue: any, newValue: string, filePath: string): void;
function mv(source: string[], destination: string);
function grep(what: any, where: string): any;
}
8 changes: 4 additions & 4 deletions lib/nativescript-cli.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
///<reference path=".d.ts"/>
"use strict";

import Fiber = require("fibers");
import Future = require("fibers/future");
import path = require("path");

require("./common/extensions");
require("./bootstrap");
require("./options");

import errors = require("./common/errors");
errors.installUncaughtExceptionListener();

$injector.register("config", {"CI_LOGGER": false});
$injector.register("config", {"CI_LOGGER": false, PROJECT_FILE_NAME: ".tnsproject", "DEBUG": process.env.NATIVESCRIPT_DEBUG});

var dispatcher = $injector.resolve("dispatcher");
dispatcher.runMainFiber();
dispatcher.runMainFiber();
2 changes: 1 addition & 1 deletion lib/node-package-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,4 @@ export class NodePackageManager implements INodePackageManager {
return future;
}
}
$injector.register("npm", NodePackageManager);
$injector.register("npm", NodePackageManager);
1 change: 1 addition & 0 deletions lib/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ var knownOpts:any = {
"path" : String,
"copy-from": String,
"link-to": String,
"release": String,
"version": Boolean,
"help": Boolean
},
Expand Down
20 changes: 20 additions & 0 deletions lib/properties-parser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
///<reference path=".d.ts"/>

import propertiesParser = require("properties-parser");
import Future = require("fibers/future");

export class PropertiesParser implements IPropertiesParser {
public createEditor(filePath: string) {
var future = new Future<any>();
propertiesParser.createEditor(filePath, (err, data) => {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This pattern seems repeated with the one in NodePackageManager. Consider adding a helper similar to the one in the Q library. https://github.com/kriskowal/q/wiki/API-Reference#qnfbindnodefunc-args

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a good idea, but I think it would be better to do it in another PR. Agree?

if(err) {
future.throw(err);
} else {
future.return(data);
}
});

return future;
}
}
$injector.register("propertiesParser", PropertiesParser);
146 changes: 146 additions & 0 deletions lib/services/platform-service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
///<reference path="../.d.ts"/>

import path = require("path");
import util = require("util");
import helpers = require("./../common/helpers");

export class PlatformService implements IPlatformService {
private platformCapabilities: { [key: string]: IPlatformCapabilities } = {
ios: {
targetedOS: ['darwin']
},
android: {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing OS'es?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

targetedOS is not obligatory property and when it is not specified that means that the platform is targeted for all supported os'es :)

}
};

private platformNames = [];

constructor(private $errors: IErrors,
private $fs: IFileSystem,
private $projectService: IProjectService) {
this.platformNames = Object.keys(this.platformCapabilities);
}

public getCapabilities(platform: string): IPlatformCapabilities {
return this.platformCapabilities[platform];
}

public addPlatforms(platforms: string[]): IFuture<void> {
return (() => {
this.$projectService.ensureProject();

if(!platforms || platforms.length === 0) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This check should be the first one to do in this function.

this.$errors.fail("No platform specified. Please specify a platform to add");
}

var platformsDir = this.$projectService.projectData.platformsDir;
this.$fs.ensureDirectoryExists(platformsDir).wait();

_.each(platforms, platform => {
this.addPlatform(platform.toLowerCase()).wait();
});

}).future<void>()();
}

private addPlatform(platform: string): IFuture<void> {
return(() => {
platform = platform.split("@")[0];
var platformPath = path.join(this.$projectService.projectData.platformsDir, platform);

// TODO: Check for version compatability if the platform is in format platform@version. This should be done in PR for semanting versioning

this.validatePlatform(platform);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This check can be done on the 2nd line of this method.


if (this.$fs.exists(platformPath).wait()) {
this.$errors.fail("Platform %s already added", platform);
}

// Copy platform specific files in platforms dir
this.$projectService.createPlatformSpecificProject(platform).wait();

}).future<void>()();
}

public getInstalledPlatforms(): IFuture<string[]> {
return(() => {
if(!this.$fs.exists(this.$projectService.projectData.platformsDir).wait()) {
return [];
}

var subDirs = this.$fs.readDirectory(this.$projectService.projectData.platformsDir).wait();
return _.filter(subDirs, p => { return this.platformNames.indexOf(p) > -1; });
}).future<string[]>()();
}

public getAvailablePlatforms(): IFuture<string[]> {
return (() => {
var installedPlatforms = this.getInstalledPlatforms().wait();
return _.filter(this.platformNames, p => {
return installedPlatforms.indexOf(p) < 0 && this.isPlatformSupportedForOS(p); // Only those not already installed
});
}).future<string[]>()();
}

public runPlatform(platform: string): IFuture<void> {
return (() => {

}).future<void>()();
}

public preparePlatform(platform: string): IFuture<void> {
return (() => {
platform = platform.toLowerCase();
this.validatePlatform(platform);
var normalizedPlatformName = this.normalizePlatformName(platform);

this.$projectService.prepareProject(normalizedPlatformName, this.platformNames).wait();
}).future<void>()();
}

public buildPlatform(platform: string): IFuture<void> {
return (() => {
platform = platform.toLocaleLowerCase();
this.validatePlatform(platform);

this.$projectService.buildProject(platform).wait();
}).future<void>()();
}

private validatePlatform(platform: string): void {
if (!this.isValidPlatform(platform)) {
this.$errors.fail("Invalid platform %s. Valid platforms are %s.", platform, helpers.formatListOfNames(this.platformNames));
}

if (!this.isPlatformSupportedForOS(platform)) {
this.$errors.fail("Applications for platform %s can not be built on this OS - %s", platform, process.platform);
}
}

private isValidPlatform(platform: string) {
return this.platformCapabilities[platform];
}

private isPlatformSupportedForOS(platform: string): boolean {
var platformCapabilities = this.getCapabilities(platform);
var targetedOS = platformCapabilities.targetedOS;

if(!targetedOS || targetedOS.indexOf("*") >= 0 || targetedOS.indexOf(process.platform) >= 0) {
return true;
}

return false;
}

private normalizePlatformName(platform: string): string {
switch(platform) {
case "android":
return "Android";
case "ios":
return "iOS";
}

return undefined;
}
}
$injector.register("platformService", PlatformService);
Loading