diff --git a/PublicAPI.md b/PublicAPI.md
index 3832969abb..e29610ab9a 100644
--- a/PublicAPI.md
+++ b/PublicAPI.md
@@ -113,6 +113,32 @@ tns.projectService.createProject(projectSettings)
+* `isValidNativeScriptProject(projectDir: string): boolean` - Checks if the specified path is a valid NativeScript project. Returns `true` in case the directory is a valid project, `false` otherwise.
+
+Sample usage:
+
+
+
+ JavaScript
+ |
+
+ TypeScript
+ |
+
+
+
+
+const isValidProject = tns.projectService.isValidNativeScriptProject("/tmp/myProject");
+
+ |
+
+
+const isValidProject = tns.projectService.isValidNativeScriptProject("/tmp/myProject");
+
+ |
+
+
+
## How to add a new method to Public API
CLI is designed as command line tool and when it is used as a library, it does not give you access to all of the methods. This is mainly implementation detail. Most of the CLI's code is created to work in command line, not as a library, so before adding method to public API, most probably it will require some modification.
For example the `$options` injected module contains information about all `--` options passed on the terminal. When the CLI is used as a library, the options are not populated. Before adding method to public API, make sure its implementation does not rely on `$options`.
diff --git a/lib/commands/appstore-upload.ts b/lib/commands/appstore-upload.ts
index 33736455a2..89fa327030 100644
--- a/lib/commands/appstore-upload.ts
+++ b/lib/commands/appstore-upload.ts
@@ -73,7 +73,7 @@ export class PublishIOS implements ICommand {
// This is not very correct as if we build multiple targets we will try to sign all of them using the signing identity here.
await this.$platformService.preparePlatform(platform, appFilesUpdaterOptions, this.$options.platformTemplate, this.$projectData, { provision: this.$options.provision, sdk: this.$options.sdk });
await this.$platformService.buildPlatform(platform, iOSBuildConfig, this.$projectData);
- ipaFilePath = this.$platformService.lastOutputPath(platform, { isForDevice: iOSBuildConfig.buildForDevice }, this.$projectData);
+ ipaFilePath = this.$platformService.lastOutputPath(platform, iOSBuildConfig, this.$projectData);
} else {
this.$logger.info("No .ipa, mobile provision or certificate set. Perfect! Now we'll build .xcarchive and let Xcode pick the distribution certificate and provisioning profile for you when exporting .ipa for AppStore submission.");
await this.$platformService.preparePlatform(platform, appFilesUpdaterOptions, this.$options.platformTemplate, this.$projectData, { provision: this.$options.provision, sdk: this.$options.sdk });
diff --git a/lib/commands/build.ts b/lib/commands/build.ts
index 524656a0bc..d8107e9cb7 100644
--- a/lib/commands/build.ts
+++ b/lib/commands/build.ts
@@ -26,7 +26,7 @@ export class BuildCommandBase {
};
await this.$platformService.buildPlatform(platform, buildConfig, this.$projectData);
if (this.$options.copyTo) {
- this.$platformService.copyLastOutput(platform, this.$options.copyTo, { isForDevice: this.$options.forDevice }, this.$projectData);
+ this.$platformService.copyLastOutput(platform, this.$options.copyTo, buildConfig, this.$projectData);
}
}
}
diff --git a/lib/commands/debug.ts b/lib/commands/debug.ts
index d9388f8b77..a51b3af5ab 100644
--- a/lib/commands/debug.ts
+++ b/lib/commands/debug.ts
@@ -16,11 +16,6 @@
}
public async execute(args: string[]): Promise {
- if (this.$options.start) {
- return this.debugService.debug(this.$projectData);
- }
-
- const appFilesUpdaterOptions: IAppFilesUpdaterOptions = { bundle: this.$options.bundle, release: this.$options.release };
const deployOptions: IDeployPlatformOptions = {
clean: this.$options.clean,
device: this.$options.device,
@@ -31,6 +26,15 @@
provision: this.$options.provision,
teamId: this.$options.teamId
};
+
+ const buildConfig: IBuildConfig = _.merge({ buildForDevice: this.$options.forDevice }, deployOptions);
+
+ if (this.$options.start) {
+ return this.debugService.debug(this.$projectData, buildConfig);
+ }
+
+ const appFilesUpdaterOptions: IAppFilesUpdaterOptions = { bundle: this.$options.bundle, release: this.$options.release };
+
await this.$platformService.deployPlatform(this.$devicesService.platform, appFilesUpdaterOptions, deployOptions, this.$projectData, { provision: this.$options.provision, sdk: this.$options.sdk });
this.$config.debugLivesync = true;
let applicationReloadAction = async (deviceAppData: Mobile.IDeviceAppData): Promise => {
@@ -45,7 +49,7 @@
await deviceAppData.device.applicationManager.stopApplication(applicationId);
- await this.debugService.debug(this.$projectData);
+ await this.debugService.debug(this.$projectData, buildConfig);
};
return this.$usbLiveSyncService.liveSync(this.$devicesService.platform, this.$projectData, applicationReloadAction);
}
diff --git a/lib/common b/lib/common
index 137dc3cd5c..f0fec92382 160000
--- a/lib/common
+++ b/lib/common
@@ -1 +1 @@
-Subproject commit 137dc3cd5c9fcc8870ce484026ed90f3191cddd6
+Subproject commit f0fec923825f23c6ed85acfd8de3eff5c860560c
diff --git a/lib/constants.ts b/lib/constants.ts
index 93b1aa85b1..c3fa4e4904 100644
--- a/lib/constants.ts
+++ b/lib/constants.ts
@@ -15,6 +15,7 @@ export const TESTING_FRAMEWORKS = ['jasmine', 'mocha', 'qunit'];
export const TEST_RUNNER_NAME = "nativescript-unit-test-runner";
export const LIVESYNC_EXCLUDED_FILE_PATTERNS = ["**/*.js.map", "**/*.ts"];
export const XML_FILE_EXTENSION = ".xml";
+export const PLATFORMS_DIR_NAME = "platforms";
export class PackageVersion {
static NEXT = "next";
diff --git a/lib/definitions/debug.d.ts b/lib/definitions/debug.d.ts
index 9d3026e655..e424594783 100644
--- a/lib/definitions/debug.d.ts
+++ b/lib/definitions/debug.d.ts
@@ -1,6 +1,6 @@
interface IDebugService {
- debug(projectData: IProjectData): Promise;
- debugStart(projectData: IProjectData): Promise;
+ debug(projectData: IProjectData, buildConfig: IBuildConfig): Promise;
+ debugStart(projectData: IProjectData, buildConfig: IBuildConfig): Promise;
debugStop(): Promise
platform: string;
}
\ No newline at end of file
diff --git a/lib/definitions/platform.d.ts b/lib/definitions/platform.d.ts
index 193bd93866..223fc2bfb1 100644
--- a/lib/definitions/platform.d.ts
+++ b/lib/definitions/platform.d.ts
@@ -1,6 +1,6 @@
interface IPlatformService extends NodeJS.EventEmitter {
cleanPlatforms(platforms: string[], platformTemplate: string, projectData: IProjectData, platformSpecificData: IPlatformSpecificData, framework?: string): Promise;
-
+
addPlatforms(platforms: string[], platformTemplate: string, projectData: IProjectData, platformSpecificData: IPlatformSpecificData, frameworkPath?: string): Promise;
/**
@@ -143,28 +143,37 @@ interface IPlatformService extends NodeJS.EventEmitter {
/**
* Returns information about the latest built application for device in the current project.
* @param {IPlatformData} platformData Data describing the current platform.
+ * @param {IBuildConfig} buildConfig Defines if the build is for release configuration.
* @returns {IApplicationPackage} Information about latest built application.
*/
- getLatestApplicationPackageForDevice(platformData: IPlatformData): IApplicationPackage;
+ getLatestApplicationPackageForDevice(platformData: IPlatformData, buildConfig: IBuildConfig): IApplicationPackage;
/**
* Returns information about the latest built application for simulator in the current project.
* @param {IPlatformData} platformData Data describing the current platform.
+ * @param {IBuildConfig} buildConfig Defines if the build is for release configuration.
* @returns {IApplicationPackage} Information about latest built application.
*/
- getLatestApplicationPackageForEmulator(platformData: IPlatformData): IApplicationPackage;
+ getLatestApplicationPackageForEmulator(platformData: IPlatformData, buildConfig: IBuildConfig): IApplicationPackage;
/**
* Copies latest build output to a specified location.
* @param {string} platform Mobile platform - Android, iOS.
* @param {string} targetPath Destination where the build artifact should be copied.
- * @param {{isForDevice: boolean}} settings Defines if the searched artifact should be for simulator.
+ * @param {IBuildConfig} buildConfig Defines if the searched artifact should be for simulator and is it built for release.
* @param {IProjectData} projectData DTO with information about the project.
* @returns {void}
*/
- copyLastOutput(platform: string, targetPath: string, settings: {isForDevice: boolean}, projectData: IProjectData): void;
+ copyLastOutput(platform: string, targetPath: string, buildConfig: IBuildConfig, projectData: IProjectData): void;
- lastOutputPath(platform: string, settings: { isForDevice: boolean }, projectData: IProjectData): string;
+ /**
+ * Gets the latest build output.
+ * @param {string} platform Mobile platform - Android, iOS.
+ * @param {IBuildConfig} buildConfig Defines if the searched artifact should be for simulator and is it built for release.
+ * @param {IProjectData} projectData DTO with information about the project.
+ * @returns {string} The path to latest built artifact.
+ */
+ lastOutputPath(platform: string, buildConfig: IBuildConfig, projectData: IProjectData): string;
/**
* Reads contents of a file on device.
@@ -209,8 +218,7 @@ interface IPlatformData {
appDestinationDirectoryPath: string;
deviceBuildOutputPath: string;
emulatorBuildOutputPath?: string;
- validPackageNamesForDevice: string[];
- validPackageNamesForEmulator?: string[];
+ getValidPackageNames(buildOptions: { isReleaseBuild?: boolean, isForDevice?: boolean }): string[];
frameworkFilesExtensions: string[];
frameworkDirectoriesExtensions?: string[];
frameworkDirectoriesNames?: string[];
diff --git a/lib/definitions/project-changes.d.ts b/lib/definitions/project-changes.d.ts
index b394fb92e8..cd5bae3cfa 100644
--- a/lib/definitions/project-changes.d.ts
+++ b/lib/definitions/project-changes.d.ts
@@ -19,8 +19,10 @@ interface IProjectChangesInfo {
changesRequireBuild: boolean;
}
+interface IProjectChangesOptions extends IAppFilesUpdaterOptions, IProvision {}
+
interface IProjectChangesService {
- checkForChanges(platform: string, projectData: IProjectData): IProjectChangesInfo;
+ checkForChanges(platform: string, projectData: IProjectData, buildOptions: IProjectChangesOptions): IProjectChangesInfo;
getPrepareInfo(platform: string, projectData: IProjectData): IPrepareInfo;
savePrepareInfo(platform: string, projectData: IProjectData): void;
getPrepareInfoFilePath(platform: string, projectData: IProjectData): string;
diff --git a/lib/definitions/project.d.ts b/lib/definitions/project.d.ts
index bb180a357c..c08a61ab42 100644
--- a/lib/definitions/project.d.ts
+++ b/lib/definitions/project.d.ts
@@ -254,11 +254,10 @@ interface IPlatformProjectService extends NodeJS.EventEmitter {
/**
* Removes build artifacts specific to the platform
* @param {string} projectRoot The root directory of the native project.
- * @param {string[]} options Options that can be passed to clean command.
* @param {IProjectData} projectData DTO with information about the project.
* @returns {void}
*/
- cleanProject(projectRoot: string, options: string[], projectData: IProjectData): Promise
+ cleanProject(projectRoot: string, projectData: IProjectData): Promise
}
interface IAndroidProjectPropertiesManager {
diff --git a/lib/project-data.ts b/lib/project-data.ts
index dc4ee0b10e..da438d88cc 100644
--- a/lib/project-data.ts
+++ b/lib/project-data.ts
@@ -9,8 +9,6 @@ interface IProjectType {
}
export class ProjectData implements IProjectData {
- private static OLD_PROJECT_FILE_NAME = ".tnsproject";
-
/**
* NOTE: Order of the elements is important as the TypeScript dependencies are commonly included in Angular project as well.
*/
@@ -42,45 +40,51 @@ export class ProjectData implements IProjectData {
constructor(private $fs: IFileSystem,
private $errors: IErrors,
- private $logger: ILogger,
private $projectHelper: IProjectHelper,
private $staticConfig: IStaticConfig,
- private $options: IOptions) { }
+ private $options: IOptions,
+ private $logger: ILogger) { }
- public initializeProjectData(projectDir? :string): void {
+ public initializeProjectData(projectDir?: string): void {
projectDir = projectDir || this.$projectHelper.projectDir;
// If no project found, projectDir should be null
if (projectDir) {
- this.initializeProjectDataCore(projectDir);
+ const projectFilePath = path.join(projectDir, this.$staticConfig.PROJECT_FILE_NAME);
let data: any = null;
- if (this.$fs.exists(this.projectFilePath)) {
+ if (this.$fs.exists(projectFilePath)) {
let fileContent: any = null;
try {
- fileContent = this.$fs.readJson(this.projectFilePath);
+ fileContent = this.$fs.readJson(projectFilePath);
data = fileContent[this.$staticConfig.CLIENT_NAME_KEY_IN_PROJECT_FILE];
} catch (err) {
- this.$errors.fail({
- formatStr: "The project file %s is corrupted." + EOL +
- "Consider restoring an earlier version from your source control or backup." + EOL +
- "Additional technical info: %s",
- suppressCommandHelp: true
- },
- this.projectFilePath, err.toString());
+ this.$errors.failWithoutHelp(`The project file ${this.projectFilePath} is corrupted. ${EOL}` +
+ `Consider restoring an earlier version from your source control or backup.${EOL}` +
+ `Additional technical info: ${err.toString()}`);
}
if (data) {
+ this.projectDir = projectDir;
+ this.projectName = this.$projectHelper.sanitizeName(path.basename(projectDir));
+ this.platformsDir = path.join(projectDir, constants.PLATFORMS_DIR_NAME);
+ this.projectFilePath = projectFilePath;
+ this.appDirectoryPath = path.join(projectDir, constants.APP_FOLDER_NAME);
+ this.appResourcesDirectoryPath = path.join(projectDir, constants.APP_FOLDER_NAME, constants.APP_RESOURCES_FOLDER_NAME);
this.projectId = data.id;
this.dependencies = fileContent.dependencies;
this.devDependencies = fileContent.devDependencies;
this.projectType = this.getProjectType();
- } else { // This is the case when we have package.json file but nativescipt key is not presented in it
- this.tryToUpgradeProject();
+
+ return;
}
}
- } else { // This is the case when no project file found
- this.tryToUpgradeProject();
}
+
+ const currentDir = path.resolve(".");
+ this.$logger.trace(`Unable to find project. projectDir: ${projectDir}, options.path: ${this.$options.path}, ${currentDir}`);
+
+ // This is the case when no project file found
+ this.$errors.fail("No project found at or above '%s' and neither was a --path specified.", projectDir || this.$options.path || currentDir);
}
private getProjectType(): string {
@@ -97,49 +101,5 @@ export class ProjectData implements IProjectData {
return detectedProjectType;
}
-
- private throwNoProjectFoundError(): void {
- this.$errors.fail("No project found at or above '%s' and neither was a --path specified.", this.$options.path || path.resolve("."));
- }
-
- private tryToUpgradeProject(): void {
- let projectDir = this.projectDir || path.resolve(this.$options.path || ".");
- let oldProjectFilePath = path.join(projectDir, ProjectData.OLD_PROJECT_FILE_NAME);
- if (this.$fs.exists(oldProjectFilePath)) {
- this.upgrade(projectDir, oldProjectFilePath);
- } else {
- this.throwNoProjectFoundError();
- }
- }
-
- private upgrade(projectDir: string, oldProjectFilePath: string): void {
- try {
- let oldProjectData = this.$fs.readJson(oldProjectFilePath);
-
- let newProjectFilePath = this.projectFilePath || path.join(projectDir, this.$staticConfig.PROJECT_FILE_NAME);
- let newProjectData = this.$fs.exists(newProjectFilePath) ? this.$fs.readJson(newProjectFilePath) : {};
- newProjectData[this.$staticConfig.CLIENT_NAME_KEY_IN_PROJECT_FILE] = oldProjectData;
- this.$fs.writeJson(newProjectFilePath, newProjectData);
- this.projectId = newProjectData[this.$staticConfig.CLIENT_NAME_KEY_IN_PROJECT_FILE].id;
-
- this.$fs.deleteFile(oldProjectFilePath);
- } catch (err) {
- this.$logger.out("An error occurred while upgrading your project.");
- throw err;
- }
-
- this.initializeProjectDataCore(projectDir);
-
- this.$logger.out("Successfully upgraded your project file.");
- }
-
- private initializeProjectDataCore(projectDir: string): void {
- this.projectDir = projectDir;
- this.projectName = this.$projectHelper.sanitizeName(path.basename(projectDir));
- this.platformsDir = path.join(projectDir, "platforms");
- this.projectFilePath = path.join(projectDir, this.$staticConfig.PROJECT_FILE_NAME);
- this.appDirectoryPath = path.join(projectDir, constants.APP_FOLDER_NAME);
- this.appResourcesDirectoryPath = path.join(projectDir, constants.APP_FOLDER_NAME, constants.APP_RESOURCES_FOLDER_NAME);
- }
}
$injector.register("projectData", ProjectData);
diff --git a/lib/providers/livesync-provider.ts b/lib/providers/livesync-provider.ts
index 747cf03a8b..a175688275 100644
--- a/lib/providers/livesync-provider.ts
+++ b/lib/providers/livesync-provider.ts
@@ -45,10 +45,10 @@ export class LiveSyncProvider implements ILiveSyncProvider {
await this.$platformService.buildPlatform(device.deviceInfo.platform, buildConfig, projectData);
let platformData = this.$platformsData.getPlatformData(device.deviceInfo.platform, projectData);
if (device.isEmulator) {
- return this.$platformService.getLatestApplicationPackageForEmulator(platformData).packageName;
+ return this.$platformService.getLatestApplicationPackageForEmulator(platformData, buildConfig).packageName;
}
- return this.$platformService.getLatestApplicationPackageForDevice(platformData).packageName;
+ return this.$platformService.getLatestApplicationPackageForDevice(platformData, buildConfig).packageName;
}
public async preparePlatformForSync(platform: string, provision: any, projectData: IProjectData): Promise {
diff --git a/lib/services/android-debug-service.ts b/lib/services/android-debug-service.ts
index 5f22534ea0..24ba6c0e1a 100644
--- a/lib/services/android-debug-service.ts
+++ b/lib/services/android-debug-service.ts
@@ -28,18 +28,18 @@ class AndroidDebugService implements IDebugService {
this._device = newDevice;
}
- public async debug(projectData: IProjectData): Promise {
+ public async debug(projectData: IProjectData, buildConfig: IBuildConfig): Promise {
return this.$options.emulator
- ? this.debugOnEmulator(projectData)
- : this.debugOnDevice(projectData);
+ ? this.debugOnEmulator(projectData, buildConfig)
+ : this.debugOnDevice(projectData, buildConfig);
}
- private async debugOnEmulator(projectData: IProjectData): Promise {
+ private async debugOnEmulator(projectData: IProjectData, buildConfig: IBuildConfig): Promise {
// Assure we've detected the emulator as device
// For example in case deployOnEmulator had stated new emulator instance
// we need some time to detect it. Let's force detection.
await this.$androidDeviceDiscovery.startLookingForDevices();
- await this.debugOnDevice(projectData);
+ await this.debugOnDevice(projectData, buildConfig);
}
private isPortAvailable(candidatePort: number): Promise {
@@ -108,7 +108,7 @@ class AndroidDebugService implements IDebugService {
return this.device.adb.executeCommand(["forward", `tcp:${local}`, `localabstract:${remote}`]);
}
- private async debugOnDevice(projectData: IProjectData): Promise {
+ private async debugOnDevice(projectData: IProjectData, buildConfig: IBuildConfig): Promise {
let packageFile = "";
if (!this.$options.start && !this.$options.emulator) {
@@ -117,7 +117,7 @@ class AndroidDebugService implements IDebugService {
this.$options.forDevice = !!cachedDeviceOption;
let platformData = this.$platformsData.getPlatformData(this.platform, projectData);
- packageFile = this.$platformService.getLatestApplicationPackageForDevice(platformData).packageName;
+ packageFile = this.$platformService.getLatestApplicationPackageForDevice(platformData, buildConfig).packageName;
this.$logger.out("Using ", packageFile);
}
@@ -170,7 +170,7 @@ class AndroidDebugService implements IDebugService {
await this.debugStartCore(packageName);
}
- public async debugStart(projectData: IProjectData): Promise {
+ public async debugStart(projectData: IProjectData, buildConfig: IBuildConfig): Promise {
await this.$devicesService.initialize({ platform: this.platform, deviceId: this.$options.device });
let action = (device: Mobile.IAndroidDevice): Promise => {
this.device = device;
diff --git a/lib/services/android-project-service.ts b/lib/services/android-project-service.ts
index 500d4831e6..8baaa94d97 100644
--- a/lib/services/android-project-service.ts
+++ b/lib/services/android-project-service.ts
@@ -5,6 +5,7 @@ import * as semver from "semver";
import * as projectServiceBaseLib from "./platform-project-service-base";
import { DeviceAndroidDebugBridge } from "../common/mobile/android/device-android-debug-bridge";
import { EOL } from "os";
+import { Configurations } from "../common/constants";
export class AndroidProjectService extends projectServiceBaseLib.PlatformProjectServiceBase implements IPlatformProjectService {
private static VALUES_DIRNAME = "values";
@@ -57,12 +58,14 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
emulatorServices: this.$androidEmulatorServices,
projectRoot: projectRoot,
deviceBuildOutputPath: path.join(projectRoot, "build", "outputs", "apk"),
- validPackageNamesForDevice: [
- `${packageName}-debug.apk`,
- `${packageName}-release.apk`,
- `${projectData.projectName}-debug.apk`,
- `${projectData.projectName}-release.apk`
- ],
+ getValidPackageNames: (buildOptions: { isReleaseBuild?: boolean, isForDevice?: boolean }): string[] => {
+ const buildMode = buildOptions.isReleaseBuild ? Configurations.Release.toLowerCase() : Configurations.Debug.toLowerCase();
+
+ return [
+ `${packageName}-${buildMode}.apk`,
+ `${projectData.projectName}-${buildMode}.apk`
+ ];
+ },
frameworkFilesExtensions: [".jar", ".dat", ".so"],
configurationFileName: "AndroidManifest.xml",
configurationFilePath: path.join(projectRoot, "src", "main", "AndroidManifest.xml"),
@@ -262,7 +265,7 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
await this.spawn(gradleBin,
buildOptions,
{ stdio: buildConfig.buildOutputStdio || "inherit", cwd: this.getPlatformData(projectData).projectRoot },
- { emitOptions: { eventName: constants.BUILD_OUTPUT_EVENT_NAME }, throwError: false });
+ { emitOptions: { eventName: constants.BUILD_OUTPUT_EVENT_NAME }, throwError: true });
} else {
this.$errors.failWithoutHelp("Cannot complete build because this project is ANT-based." + EOL +
"Run `tns platform remove android && tns platform add android` to switch to Gradle and try again.");
@@ -376,7 +379,7 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
// check whether the dependency that's being removed has native code
let pluginConfigDir = path.join(this.getPlatformData(projectData).projectRoot, "configurations", pluginData.name);
if (this.$fs.exists(pluginConfigDir)) {
- await this.cleanProject(this.getPlatformData(projectData).projectRoot, [], projectData);
+ await this.cleanProject(this.getPlatformData(projectData).projectRoot, projectData);
}
} catch (e) {
if (e.code === "ENOENT") {
@@ -407,12 +410,9 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
}
}
- // We don't need release options here
- let buildOptions = this.getBuildOptions({ release: false }, projectData);
-
let projectRoot = this.getPlatformData(projectData).projectRoot;
- await this.cleanProject(projectRoot, buildOptions, projectData);
+ await this.cleanProject(projectRoot, projectData);
}
}
@@ -425,15 +425,16 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
return this.$childProcess.spawnFromEvent(gradleBin, ["--stop", "--quiet"], "close", { stdio: "inherit", cwd: projectRoot });
}
- public async cleanProject(projectRoot: string, options: string[], projectData: IProjectData): Promise {
- options.unshift("clean");
+ public async cleanProject(projectRoot: string, projectData: IProjectData): Promise {
+ const buildOptions = this.getBuildOptions({ release: false }, projectData);
+ buildOptions.unshift("clean");
let gradleBin = path.join(projectRoot, "gradlew");
if (this.$hostInfo.isWindows) {
gradleBin += ".bat";
}
- await this.spawn(gradleBin, options, { stdio: "inherit", cwd: this.getPlatformData(projectData).projectRoot });
+ await this.spawn(gradleBin, buildOptions, { stdio: "inherit", cwd: this.getPlatformData(projectData).projectRoot });
}
public async cleanDeviceTempFolder(deviceIdentifier: string, projectData: IProjectData): Promise {
diff --git a/lib/services/ios-debug-service.ts b/lib/services/ios-debug-service.ts
index 6f81637e98..6ef796bec8 100644
--- a/lib/services/ios-debug-service.ts
+++ b/lib/services/ios-debug-service.ts
@@ -39,7 +39,7 @@ class IOSDebugService implements IDebugService {
return "ios";
}
- public async debug(projectData: IProjectData): Promise {
+ public async debug(projectData: IProjectData, buildConfig: IBuildConfig): Promise {
if (this.$options.debugBrk && this.$options.start) {
this.$errors.failWithoutHelp("Expected exactly one of the --debug-brk or --start options.");
}
@@ -50,26 +50,26 @@ class IOSDebugService implements IDebugService {
if (this.$options.emulator) {
if (this.$options.debugBrk) {
- return this.emulatorDebugBrk(projectData, true);
+ return this.emulatorDebugBrk(projectData, buildConfig, true);
} else if (this.$options.start) {
return this.emulatorStart(projectData);
} else {
- return this.emulatorDebugBrk(projectData);
+ return this.emulatorDebugBrk(projectData, buildConfig);
}
} else {
if (this.$options.debugBrk) {
- return this.deviceDebugBrk(projectData, true);
+ return this.deviceDebugBrk(projectData, buildConfig, true);
} else if (this.$options.start) {
return this.deviceStart(projectData);
} else {
- return this.deviceDebugBrk(projectData, false);
+ return this.deviceDebugBrk(projectData, buildConfig, false);
}
}
}
- public async debugStart(projectData: IProjectData): Promise {
+ public async debugStart(projectData: IProjectData, buildConfig: IBuildConfig): Promise {
await this.$devicesService.initialize({ platform: this.platform, deviceId: this.$options.device });
- this.$devicesService.execute(async (device: Mobile.IiOSDevice) => await device.isEmulator ? this.emulatorDebugBrk(projectData) : this.debugBrkCore(device, projectData));
+ this.$devicesService.execute(async (device: Mobile.IiOSDevice) => await device.isEmulator ? this.emulatorDebugBrk(projectData, buildConfig) : this.debugBrkCore(device, projectData));
}
public async debugStop(): Promise {
@@ -93,10 +93,10 @@ class IOSDebugService implements IDebugService {
}
}
- private async emulatorDebugBrk(projectData: IProjectData, shouldBreak?: boolean): Promise {
+ private async emulatorDebugBrk(projectData: IProjectData, buildConfig: IBuildConfig, shouldBreak?: boolean): Promise {
let platformData = this.$platformsData.getPlatformData(this.platform, projectData);
- let emulatorPackage = this.$platformService.getLatestApplicationPackageForEmulator(platformData);
+ let emulatorPackage = this.$platformService.getLatestApplicationPackageForEmulator(platformData, buildConfig);
let args = shouldBreak ? "--nativescript-debug-brk" : "--nativescript-debug-start";
let child_process = await this.$iOSEmulatorServices.runApplicationOnEmulator(emulatorPackage.packageName, {
@@ -135,11 +135,11 @@ class IOSDebugService implements IDebugService {
await iOSEmulator.postDarwinNotification(attachRequestMessage);
}
- private async deviceDebugBrk(projectData: IProjectData, shouldBreak?: boolean): Promise {
+ private async deviceDebugBrk(projectData: IProjectData, buildConfig: IBuildConfig, shouldBreak?: boolean): Promise {
await this.$devicesService.initialize({ platform: this.platform, deviceId: this.$options.device });
this.$devicesService.execute(async (device: iOSDevice.IOSDevice) => {
if (device.isEmulator) {
- return await this.emulatorDebugBrk(projectData, shouldBreak);
+ return await this.emulatorDebugBrk(projectData, buildConfig, shouldBreak);
}
const runOptions: IRunPlatformOptions = {
diff --git a/lib/services/ios-project-service.ts b/lib/services/ios-project-service.ts
index bbdb69932b..48a16f9762 100644
--- a/lib/services/ios-project-service.ts
+++ b/lib/services/ios-project-service.ts
@@ -64,12 +64,13 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
projectRoot: projectRoot,
deviceBuildOutputPath: path.join(projectRoot, "build", "device"),
emulatorBuildOutputPath: path.join(projectRoot, "build", "emulator"),
- validPackageNamesForDevice: [
- projectData.projectName + ".ipa"
- ],
- validPackageNamesForEmulator: [
- projectData.projectName + ".app"
- ],
+ getValidPackageNames: (buildOptions: { isReleaseBuild?: boolean, isForDevice?: boolean }): string[] => {
+ if (buildOptions.isForDevice) {
+ return [projectData.projectName + ".ipa"];
+ }
+
+ return [projectData.projectName + ".app"];
+ },
frameworkFilesExtensions: [".a", ".framework", ".bin"],
frameworkDirectoriesExtensions: [".framework"],
frameworkDirectoriesNames: ["Metadata", "metadataGenerator", "NativeScript", "internal"],
@@ -339,7 +340,7 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
args,
"exit",
{ stdio: buildConfig.buildOutputStdio || "inherit", cwd: this.getPlatformData(projectData).projectRoot },
- { emitOptions: { eventName: constants.BUILD_OUTPUT_EVENT_NAME }, throwError: false });
+ { emitOptions: { eventName: constants.BUILD_OUTPUT_EVENT_NAME }, throwError: true });
// this.$logger.out("xcodebuild build succeded.");
await this.createIpa(projectRoot, projectData, buildConfig.buildOutputStdio);
@@ -665,7 +666,7 @@ We will now place an empty obsolete compatability white screen LauncScreen.xib f
return { stderr: "", stdout: "", exitCode: 0 };
}
- public async cleanProject(projectRoot: string, options: string[]): Promise {
+ public async cleanProject(projectRoot: string): Promise {
return Promise.resolve();
}
@@ -1170,6 +1171,10 @@ We will now place an empty obsolete compatability white screen LauncScreen.xib f
teamId = teams[0].id;
this.$logger.warn("Found and using the following development team installed on your system: " + teams[0].name + " (" + teams[0].id + ")");
} else if (teams.length > 0) {
+ if (!helpers.isInteractive()) {
+ this.$errors.failWithoutHelp(`Unable to determine default development team. Available development teams are: ${_.map(teams, team => team.id)}. Specify team in app/App_Resources/iOS/build.xcconfig file in the following way: DEVELOPMENT_TEAM = `);
+ }
+
let choices: string[] = [];
for (let team of teams) {
choices.push(team.name + " (" + team.id + ")");
diff --git a/lib/services/local-build-service.ts b/lib/services/local-build-service.ts
index cea0053505..fedaeb1ce9 100644
--- a/lib/services/local-build-service.ts
+++ b/lib/services/local-build-service.ts
@@ -9,14 +9,14 @@ export class LocalBuildService extends EventEmitter {
public async build(platform: string, platformBuildOptions: IPlatformBuildData, platformTemplate?: string): Promise {
this.$projectData.initializeProjectData(platformBuildOptions.projectDir);
- await this.$platformService.preparePlatform(platform, platformBuildOptions, platformTemplate, this.$projectData, undefined);
+ await this.$platformService.preparePlatform(platform, platformBuildOptions, platformTemplate, this.$projectData, { provision: platformBuildOptions.provision, sdk: null });
this.$platformService.on(BUILD_OUTPUT_EVENT_NAME, (data: any) => {
data.projectDir = platformBuildOptions.projectDir;
this.emit(BUILD_OUTPUT_EVENT_NAME, data);
});
platformBuildOptions.buildOutputStdio = "pipe";
await this.$platformService.buildPlatform(platform, platformBuildOptions, this.$projectData);
- return this.$platformService.lastOutputPath(platform, { isForDevice: platformBuildOptions.buildForDevice }, this.$projectData);
+ return this.$platformService.lastOutputPath(platform, platformBuildOptions, this.$projectData);
}
}
diff --git a/lib/services/platform-service.ts b/lib/services/platform-service.ts
index 1880b754e7..841175a125 100644
--- a/lib/services/platform-service.ts
+++ b/lib/services/platform-service.ts
@@ -233,7 +233,7 @@ export class PlatformService extends EventEmitter implements IPlatformService {
await this.$pluginsService.validate(platformData, projectData);
await this.ensurePlatformInstalled(platform, platformTemplate, projectData, platformSpecificData);
- let changesInfo = this.$projectChangesService.checkForChanges(platform, projectData);
+ let changesInfo = this.$projectChangesService.checkForChanges(platform, projectData, { bundle: appFilesUpdaterOptions.bundle, release: appFilesUpdaterOptions.release, provision: platformSpecificData.provision });
this.$logger.trace("Changes info in prepare platform:", changesInfo);
@@ -243,7 +243,7 @@ export class PlatformService extends EventEmitter implements IPlatformService {
let previousPrepareInfo = this.$projectChangesService.getPrepareInfo(platform, projectData);
// clean up prepared plugins when not building for release
if (previousPrepareInfo && previousPrepareInfo.release !== appFilesUpdaterOptions.release) {
- await platformData.platformProjectService.cleanProject(platformData.projectRoot, [], projectData);
+ await platformData.platformProjectService.cleanProject(platformData.projectRoot, projectData);
}
}
@@ -364,7 +364,7 @@ export class PlatformService extends EventEmitter implements IPlatformService {
if (!this.$fs.exists(outputPath)) {
return true;
}
- let packageNames = forDevice ? platformData.validPackageNamesForDevice : platformData.validPackageNamesForEmulator;
+ let packageNames = platformData.getValidPackageNames({ isForDevice: forDevice });
let packages = this.getApplicationPackages(outputPath, packageNames);
if (packages.length === 0) {
return true;
@@ -425,21 +425,21 @@ export class PlatformService extends EventEmitter implements IPlatformService {
return !localBuildInfo || !deviceBuildInfo || deviceBuildInfo.buildTime !== localBuildInfo.buildTime;
}
- public async installApplication(device: Mobile.IDevice, options: IRelease, projectData: IProjectData): Promise {
+ public async installApplication(device: Mobile.IDevice, buildConfig: IBuildConfig, projectData: IProjectData): Promise {
this.$logger.out("Installing...");
let platformData = this.$platformsData.getPlatformData(device.deviceInfo.platform, projectData);
let packageFile = "";
if (this.$devicesService.isiOSSimulator(device)) {
- packageFile = this.getLatestApplicationPackageForEmulator(platformData).packageName;
+ packageFile = this.getLatestApplicationPackageForEmulator(platformData, buildConfig).packageName;
} else {
- packageFile = this.getLatestApplicationPackageForDevice(platformData).packageName;
+ packageFile = this.getLatestApplicationPackageForDevice(platformData, buildConfig).packageName;
}
await platformData.platformProjectService.cleanDeviceTempFolder(device.deviceInfo.identifier, projectData);
await device.applicationManager.reinstallApplication(projectData.projectId, packageFile);
- if (!options.release) {
+ if (!buildConfig.release) {
let deviceFilePath = await this.getDeviceBuildInfoFilePath(device, projectData);
let buildInfoFilePath = this.getBuildOutputPath(device.deviceInfo.platform, platformData, { buildForDevice: !device.isEmulator });
let appIdentifier = projectData.projectId;
@@ -475,7 +475,7 @@ export class PlatformService extends EventEmitter implements IPlatformService {
}
if (deployOptions.forceInstall || shouldBuild || (await this.shouldInstall(device, projectData))) {
- await this.installApplication(device, deployOptions, projectData);
+ await this.installApplication(device, buildConfig, projectData);
} else {
this.$logger.out("Skipping install.");
}
@@ -581,13 +581,13 @@ export class PlatformService extends EventEmitter implements IPlatformService {
appUpdater.cleanDestinationApp();
}
- public lastOutputPath(platform: string, settings: { isForDevice: boolean }, projectData: IProjectData): string {
+ public lastOutputPath(platform: string, buildConfig: IBuildConfig, projectData: IProjectData): string {
let packageFile: string;
let platformData = this.$platformsData.getPlatformData(platform, projectData);
- if (settings.isForDevice) {
- packageFile = this.getLatestApplicationPackageForDevice(platformData).packageName;
+ if (buildConfig.buildForDevice) {
+ packageFile = this.getLatestApplicationPackageForDevice(platformData, buildConfig).packageName;
} else {
- packageFile = this.getLatestApplicationPackageForEmulator(platformData).packageName;
+ packageFile = this.getLatestApplicationPackageForEmulator(platformData, buildConfig).packageName;
}
if (!packageFile || !this.$fs.exists(packageFile)) {
this.$errors.failWithoutHelp("Unable to find built application. Try 'tns build %s'.", platform);
@@ -595,11 +595,11 @@ export class PlatformService extends EventEmitter implements IPlatformService {
return packageFile;
}
- public copyLastOutput(platform: string, targetPath: string, settings: { isForDevice: boolean }, projectData: IProjectData): void {
+ public copyLastOutput(platform: string, targetPath: string, buildConfig: IBuildConfig, projectData: IProjectData): void {
platform = platform.toLowerCase();
targetPath = path.resolve(targetPath);
- let packageFile = this.lastOutputPath(platform, settings, projectData);
+ let packageFile = this.lastOutputPath(platform, buildConfig, projectData);
this.$fs.ensureDirectoryExists(path.dirname(targetPath));
@@ -742,12 +742,12 @@ export class PlatformService extends EventEmitter implements IPlatformService {
return packages[0];
}
- public getLatestApplicationPackageForDevice(platformData: IPlatformData): IApplicationPackage {
- return this.getLatestApplicationPackage(platformData.deviceBuildOutputPath, platformData.validPackageNamesForDevice);
+ public getLatestApplicationPackageForDevice(platformData: IPlatformData, buildConfig: IBuildConfig): IApplicationPackage {
+ return this.getLatestApplicationPackage(platformData.deviceBuildOutputPath, platformData.getValidPackageNames({ isForDevice: true, isReleaseBuild: buildConfig.release }));
}
- public getLatestApplicationPackageForEmulator(platformData: IPlatformData): IApplicationPackage {
- return this.getLatestApplicationPackage(platformData.emulatorBuildOutputPath || platformData.deviceBuildOutputPath, platformData.validPackageNamesForEmulator || platformData.validPackageNamesForDevice);
+ public getLatestApplicationPackageForEmulator(platformData: IPlatformData, buildConfig: IBuildConfig): IApplicationPackage {
+ return this.getLatestApplicationPackage(platformData.emulatorBuildOutputPath || platformData.deviceBuildOutputPath, platformData.getValidPackageNames({ isForDevice: false, isReleaseBuild: buildConfig.release }));
}
private async updatePlatform(platform: string, version: string, platformTemplate: string, projectData: IProjectData, platformSpecificData: IPlatformSpecificData): Promise {
diff --git a/lib/services/project-changes-service.ts b/lib/services/project-changes-service.ts
index 1c454ffbf2..befe87b170 100644
--- a/lib/services/project-changes-service.ts
+++ b/lib/services/project-changes-service.ts
@@ -38,7 +38,6 @@ export class ProjectChangesService implements IProjectChangesService {
constructor(
private $platformsData: IPlatformsData,
private $devicePlatformsConstants: Mobile.IDevicePlatformsConstants,
- private $options: IOptions,
private $fs: IFileSystem) {
}
@@ -46,10 +45,10 @@ export class ProjectChangesService implements IProjectChangesService {
return this._changesInfo;
}
- public checkForChanges(platform: string, projectData: IProjectData): IProjectChangesInfo {
+ public checkForChanges(platform: string, projectData: IProjectData, projectChangesOptions: IProjectChangesOptions): IProjectChangesInfo {
let platformData = this.$platformsData.getPlatformData(platform, projectData);
this._changesInfo = new ProjectChangesInfo();
- if (!this.ensurePrepareInfo(platform, projectData)) {
+ if (!this.ensurePrepareInfo(platform, projectData, projectChangesOptions)) {
this._newFiles = 0;
this._changesInfo.appFilesChanged = this.containsNewerFiles(projectData.appDirectoryPath, projectData.appResourcesDirectoryPath, projectData);
this._changesInfo.packageChanged = this.filesChanged([path.join(projectData.projectDir, "package.json")]);
@@ -77,7 +76,7 @@ export class ProjectChangesService implements IProjectChangesService {
}
}
if (platform.toLowerCase() === this.$devicePlatformsConstants.iOS.toLowerCase()) {
- const nextCommandProvisionUUID = this.$options.provision;
+ const nextCommandProvisionUUID = projectChangesOptions.provision;
// We should consider reading here the provisioning profile UUID from the xcodeproj and xcconfig.
const prevProvisionUUID = this._prepareInfo.iOSProvisioningProfileUUID;
if (nextCommandProvisionUUID !== prevProvisionUUID) {
@@ -86,13 +85,13 @@ export class ProjectChangesService implements IProjectChangesService {
this._prepareInfo.iOSProvisioningProfileUUID = nextCommandProvisionUUID;
}
}
- if (this.$options.bundle !== this._prepareInfo.bundle || this.$options.release !== this._prepareInfo.release) {
+ if (projectChangesOptions.bundle !== this._prepareInfo.bundle || projectChangesOptions.release !== this._prepareInfo.release) {
this._changesInfo.appFilesChanged = true;
this._changesInfo.appResourcesChanged = true;
this._changesInfo.modulesChanged = true;
this._changesInfo.configChanged = true;
- this._prepareInfo.release = this.$options.release;
- this._prepareInfo.bundle = this.$options.bundle;
+ this._prepareInfo.release = projectChangesOptions.release;
+ this._prepareInfo.bundle = projectChangesOptions.bundle;
}
if (this._changesInfo.packageChanged) {
this._changesInfo.modulesChanged = true;
@@ -134,7 +133,7 @@ export class ProjectChangesService implements IProjectChangesService {
this.$fs.writeJson(prepareInfoFilePath, this._prepareInfo);
}
- private ensurePrepareInfo(platform: string, projectData: IProjectData): boolean {
+ private ensurePrepareInfo(platform: string, projectData: IProjectData, projectChangesOptions: IProjectChangesOptions): boolean {
this._prepareInfo = this.getPrepareInfo(platform, projectData);
if (this._prepareInfo) {
let platformData = this.$platformsData.getPlatformData(platform, projectData);
@@ -145,8 +144,8 @@ export class ProjectChangesService implements IProjectChangesService {
}
this._prepareInfo = {
time: "",
- bundle: this.$options.bundle,
- release: this.$options.release,
+ bundle: projectChangesOptions.bundle,
+ release: projectChangesOptions.release,
changesRequireBuild: true,
changesRequireBuildTime: null
};
diff --git a/lib/services/project-service.ts b/lib/services/project-service.ts
index 5054616043..150430e873 100644
--- a/lib/services/project-service.ts
+++ b/lib/services/project-service.ts
@@ -73,11 +73,10 @@ export class ProjectService implements IProjectService {
public isValidNativeScriptProject(pathToProject?: string): boolean {
try {
this.$projectData.initializeProjectData(pathToProject);
+ return !!this.$projectData.projectDir && !!this.$projectData.projectId;
} catch (e) {
return false;
}
-
- return true;
}
private getDataFromJson(templatePath: string): any {
diff --git a/lib/services/test-execution-service.ts b/lib/services/test-execution-service.ts
index 40593cb418..099ec6343c 100644
--- a/lib/services/test-execution-service.ts
+++ b/lib/services/test-execution-service.ts
@@ -73,9 +73,10 @@ class TestExecutionService implements ITestExecutionService {
await this.$usbLiveSyncService.liveSync(platform, projectData);
if (this.$options.debugBrk) {
+ const buildConfig: IBuildConfig = _.merge({ buildForDevice: this.$options.forDevice }, deployOptions);
this.$logger.info('Starting debugger...');
let debugService: IDebugService = this.$injector.resolve(`${platform}DebugService`);
- await debugService.debugStart(projectData);
+ await debugService.debugStart(projectData, buildConfig);
}
resolve();
} catch (err) {
@@ -127,20 +128,22 @@ class TestExecutionService implements ITestExecutionService {
this.$errors.failWithoutHelp("Verify that listed files are well-formed and try again the operation.");
}
+ const deployOptions: IDeployPlatformOptions = {
+ clean: this.$options.clean,
+ device: this.$options.device,
+ emulator: this.$options.emulator,
+ projectDir: this.$options.path,
+ platformTemplate: this.$options.platformTemplate,
+ release: this.$options.release,
+ provision: this.$options.provision,
+ teamId: this.$options.teamId
+ };
+
+ const buildConfig: IBuildConfig = _.merge({ buildForDevice: this.$options.forDevice }, deployOptions);
+
if (this.$options.debugBrk) {
- await this.getDebugService(platform).debug(projectData);
+ await this.getDebugService(platform).debug(projectData, buildConfig);
} else {
- const deployOptions: IDeployPlatformOptions = {
- clean: this.$options.clean,
- device: this.$options.device,
- emulator: this.$options.emulator,
- projectDir: this.$options.path,
- platformTemplate: this.$options.platformTemplate,
- release: this.$options.release,
- provision: this.$options.provision,
- teamId: this.$options.teamId
- };
-
await this.$platformService.deployPlatform(platform, appFilesUpdaterOptions, deployOptions, projectData, { provision: this.$options.provision, sdk: this.$options.sdk });
await this.$usbLiveSyncService.liveSync(platform, projectData);
}
diff --git a/test/nativescript-cli-lib.ts b/test/nativescript-cli-lib.ts
index fc2162d217..f4fe159e97 100644
--- a/test/nativescript-cli-lib.ts
+++ b/test/nativescript-cli-lib.ts
@@ -14,9 +14,9 @@ describe("nativescript-cli-lib", () => {
const publicApi: any = {
deviceEmitter: null,
- projectService: ["createProject"],
- localBuildService: ["build"]
-
+ projectService: ["createProject", "isValidNativeScriptProject"],
+ localBuildService: ["build"],
+ deviceLogProvider: null
};
const pathToEntryPoint = path.join(__dirname, "..", "lib", "nativescript-cli-lib.js").replace(/\\/g, "\\\\");
diff --git a/test/npm-support.ts b/test/npm-support.ts
index 3b5ab60f3d..261cfe9ad0 100644
--- a/test/npm-support.ts
+++ b/test/npm-support.ts
@@ -187,11 +187,12 @@ async function addDependencies(testInjector: IInjector, projectFolder: string, d
}
async function preparePlatform(testInjector: IInjector): Promise {
- let platformService: IPlatformService = testInjector.resolve("platformService");
- let projectData: IProjectData = testInjector.resolve("projectData");
+ const platformService: IPlatformService = testInjector.resolve("platformService");
+ const projectData: IProjectData = testInjector.resolve("projectData");
projectData.initializeProjectData();
+ const options: IOptions = testInjector.resolve("options");
- await platformService.preparePlatform("android", { bundle: false, release: false }, "", projectData, undefined);
+ await platformService.preparePlatform("android", { bundle: options.bundle, release: options.release }, "", projectData, { provision: options.provision, sdk: options.sdk });
}
describe("Npm support tests", () => {
diff --git a/test/platform-commands.ts b/test/platform-commands.ts
index af5eec1d26..202f0d8c45 100644
--- a/test/platform-commands.ts
+++ b/test/platform-commands.ts
@@ -32,6 +32,7 @@ class PlatformData implements IPlatformData {
emulatorServices: Mobile.IEmulatorPlatformServices = null;
projectRoot = "";
deviceBuildOutputPath = "";
+ getValidPackageNames = (buildOptions: {isForDevice?: boolean, isReleaseBuild?: boolean}) => [""];
validPackageNamesForDevice: string[] = [];
frameworkFilesExtensions = [".jar", ".dat"];
appDestinationDirectoryPath = "";
diff --git a/test/platform-service.ts b/test/platform-service.ts
index cd524e3a3c..7d7216d184 100644
--- a/test/platform-service.ts
+++ b/test/platform-service.ts
@@ -369,7 +369,7 @@ describe('Platform Service Tests', () => {
platformService = testInjector.resolve("platformService");
const appFilesUpdaterOptions: IAppFilesUpdaterOptions = { bundle: false, release: release };
- await platformService.preparePlatform(platformToTest, appFilesUpdaterOptions, "", projectData, undefined);
+ await platformService.preparePlatform(platformToTest, appFilesUpdaterOptions, "", projectData, { provision: null, sdk: null });
let test1FileName = platformToTest.toLowerCase() === "ios" ? "test1.js" : "test2.js";
let test2FileName = platformToTest.toLowerCase() === "ios" ? "test2.js" : "test1.js";
@@ -446,7 +446,7 @@ describe('Platform Service Tests', () => {
try {
testInjector.resolve("$logger").warn = (text: string) => warnings += text;
const appFilesUpdaterOptions: IAppFilesUpdaterOptions = { bundle: false, release: false };
- await platformService.preparePlatform("android", appFilesUpdaterOptions, "", projectData, undefined);
+ await platformService.preparePlatform("android", appFilesUpdaterOptions, "", projectData, { provision: null, sdk: null });
} finally {
testInjector.resolve("$logger").warn = oldLoggerWarner;
}
diff --git a/test/project-service.ts b/test/project-service.ts
index bb2421bfc6..a4bac957e1 100644
--- a/test/project-service.ts
+++ b/test/project-service.ts
@@ -5,7 +5,6 @@ import { ChildProcess } from "../lib/common/child-process";
import * as ProjectServiceLib from "../lib/services/project-service";
import { ProjectNameService } from "../lib/services/project-name-service";
import * as ProjectDataServiceLib from "../lib/services/project-data-service";
-import * as ProjectDataLib from "../lib/project-data";
import * as ProjectHelperLib from "../lib/common/project-helper";
import { StaticConfig } from "../lib/config";
import * as NpmLib from "../lib/node-package-manager";
@@ -72,7 +71,7 @@ class ProjectIntegrationTest {
let sourceDir = projectSourceDirectory;
// Hidden files (starting with dots ".") are not copied.
- let expectedFiles = fs.enumerateFilesInDirectorySync(sourceDir, (file, stat) => stat.isDirectory() || !_.startsWith(path.basename(file), ".") );
+ let expectedFiles = fs.enumerateFilesInDirectorySync(sourceDir, (file, stat) => stat.isDirectory() || !_.startsWith(path.basename(file), "."));
let actualFiles = fs.enumerateFilesInDirectorySync(appDirectoryPath);
assert.isTrue(actualFiles.length >= expectedFiles.length, "Files in created project must be at least as files in app dir.");
@@ -459,158 +458,65 @@ describe("Project Service Tests", () => {
});
});
-});
-
-function createTestInjector() {
- let testInjector = new yok.Yok();
-
- testInjector.register("errors", stubs.ErrorsStub);
- testInjector.register('logger', stubs.LoggerStub);
- testInjector.register("projectService", ProjectServiceLib.ProjectService);
- testInjector.register("projectHelper", ProjectHelperLib.ProjectHelper);
- testInjector.register("projectTemplatesService", stubs.ProjectTemplatesService);
- testInjector.register("projectNameValidator", mockProjectNameValidator);
-
- testInjector.register("fs", FileSystem);
- testInjector.register("projectDataService", ProjectDataServiceLib.ProjectDataService);
-
- testInjector.register("staticConfig", StaticConfig);
- testInjector.register("analyticsService", { track: async () => undefined });
-
- testInjector.register("npmInstallationManager", NpmInstallationManager);
- testInjector.register("httpClient", HttpClientLib.HttpClient);
- testInjector.register("lockfile", stubs.LockFile);
-
- testInjector.register("childProcess", ChildProcess);
-
- testInjector.register('projectData', ProjectDataLib.ProjectData);
- testInjector.register("options", Options);
- testInjector.register("hostInfo", HostInfo);
-
- return testInjector;
-}
-
-describe("project upgrade procedure tests", () => {
- it("should throw error when no nativescript project folder specified", () => {
- let testInjector = createTestInjector();
- let tempFolder = temp.mkdirSync("project upgrade");
- let options = testInjector.resolve("options");
- options.path = tempFolder;
- let isErrorThrown = false;
-
- try {
- let projectData: IProjectData = testInjector.resolve("projectData");
- projectData.initializeProjectData(); // This should trigger upgrade procedure
- } catch (err) {
- isErrorThrown = true;
- let expectedErrorMessage = "No project found at or above '%s' and neither was a --path specified.," + tempFolder;
- assert.equal(expectedErrorMessage, err.toString());
- }
-
- assert.isTrue(isErrorThrown);
- });
- it("should upgrade project when .tnsproject file exists but package.json file doesn't exist", () => {
- let testInjector = createTestInjector();
- let fs: IFileSystem = testInjector.resolve("fs");
-
- let tempFolder = temp.mkdirSync("projectUpgradeTest2");
- let options = testInjector.resolve("options");
- options.path = tempFolder;
- let tnsProjectData = {
- "id": "org.nativescript.Test",
- "tns-ios": {
- "version": "1.0.0"
- },
- "description": "dummy",
- "license": "MIT",
- "readme": "dummy",
- "repository": "dummy"
- };
- let tnsProjectFilePath = path.join(tempFolder, ".tnsproject");
- fs.writeJson(tnsProjectFilePath, tnsProjectData);
- let projectData: IProjectData = testInjector.resolve("projectData");
- projectData.initializeProjectData(); // This should trigger upgrade procedure
-
- let packageJsonFilePath = path.join(tempFolder, "package.json");
- let packageJsonFileContent = require(packageJsonFilePath);
- assert.isTrue(fs.exists(packageJsonFilePath));
- assert.isFalse(fs.exists(tnsProjectFilePath));
- assert.deepEqual(tnsProjectData, packageJsonFileContent["nativescript"]);
- });
- it("should upgrade project when .tnsproject and package.json exist but nativescript key is not presented in package.json file", () => {
- let testInjector = createTestInjector();
- let fs: IFileSystem = testInjector.resolve("fs");
-
- let tempFolder = temp.mkdirSync("projectUpgradeTest3");
- let options = testInjector.resolve("options");
- options.path = tempFolder;
- let tnsProjectData = {
- "id": "org.nativescript.Test",
- "tns-ios": {
- "version": "1.0.1"
- }
- };
- let packageJsonData = {
- "name": "testModuleName",
- "version": "0.0.0",
- "dependencies": {
- "myFirstDep": "0.0.1"
- },
- "description": "dummy",
- "license": "MIT",
- "readme": "dummy",
- "repository": "dummy"
+ describe("isValidNativeScriptProject", () => {
+ const getTestInjector = (): IInjector => {
+ const testInjector = new yok.Yok();
+ testInjector.register("npm", {});
+ testInjector.register("errors", {});
+ testInjector.register("fs", {});
+ testInjector.register("logger", {});
+ testInjector.register("projectDataService", {});
+ testInjector.register("projectNameService", {});
+ testInjector.register("projectTemplatesService", {});
+ testInjector.register("staticConfig", {});
+ testInjector.register("projectHelper", {});
+
+ return testInjector;
};
- let tnsProjectFilePath = path.join(tempFolder, ".tnsproject");
- fs.writeJson(tnsProjectFilePath, tnsProjectData);
- let packageJsonFilePath = path.join(tempFolder, "package.json");
- fs.writeJson(packageJsonFilePath, packageJsonData);
+ it("returns true when initialize project data does not throw, projectDir and projectId are valid", () => {
+ const testInjector = getTestInjector();
+ testInjector.register("projectData", {
+ projectDir: "projectDir",
+ projectId: "projectId",
+ initializeProjectData: (): void => undefined
+ });
- let projectData: IProjectData = testInjector.resolve("projectData");
- projectData.initializeProjectData(); // This should trigger upgrade procedure
+ const projectService: IProjectService = testInjector.resolve(ProjectServiceLib.ProjectService);
+ assert.isTrue(projectService.isValidNativeScriptProject("some-dir"));
+ });
- let packageJsonFileContent = require(packageJsonFilePath);
- let expectedPackageJsonContent: any = packageJsonData;
- expectedPackageJsonContent["nativescript"] = tnsProjectData;
- assert.deepEqual(expectedPackageJsonContent, packageJsonFileContent);
- });
- it("shouldn't upgrade project when .tnsproject and package.json exist and nativescript key is presented in package.json file", () => {
- let testInjector = createTestInjector();
- let fs: IFileSystem = testInjector.resolve("fs");
+ it("returns false when initialize project data throws", () => {
+ const testInjector = getTestInjector();
+ testInjector.register("projectData", {
+ initializeProjectData: (): void => { throw new Error("err"); }
+ });
- let tempFolder = temp.mkdirSync("projectUpgradeTest4");
- let options = testInjector.resolve("options");
- options.path = tempFolder;
- let tnsProjectData = {
+ const projectService: IProjectService = testInjector.resolve(ProjectServiceLib.ProjectService);
+ assert.isFalse(projectService.isValidNativeScriptProject("some-dir"));
+ });
- };
- let packageJsonData = {
- "name": "testModuleName",
- "version": "0.0.0",
- "dependencies": {
- "myFirstDep": "0.0.2"
- },
- "nativescript": {
- "id": "org.nativescript.Test",
- "tns-ios": {
- "version": "1.0.2"
- }
- },
- "description": "dummy",
- "license": "MIT",
- "readme": "dummy",
- "repository": "dummy"
- };
+ it("returns false when initializeProjectData does not throw, but there's no projectDir set", () => {
+ const testInjector = getTestInjector();
+ testInjector.register("projectData", {
+ projectId: "projectId",
+ initializeProjectData: (): void => undefined
+ });
- fs.writeJson(path.join(tempFolder, ".tnsproject"), tnsProjectData);
- fs.writeJson(path.join(tempFolder, "package.json"), packageJsonData);
- testInjector.resolve("projectData"); // This should trigger upgrade procedure
+ const projectService: IProjectService = testInjector.resolve(ProjectServiceLib.ProjectService);
+ assert.isFalse(projectService.isValidNativeScriptProject("some-dir"));
+ });
- let packageJsonFilePath = path.join(tempFolder, "package.json");
- let packageJsonFileContent = require(packageJsonFilePath);
+ it("returns false when initializeProjectData does not throw, but there's no projectId set", () => {
+ const testInjector = getTestInjector();
+ testInjector.register("projectData", {
+ projectDir: "projectDir",
+ initializeProjectData: (): void => undefined
+ });
- assert.deepEqual(packageJsonData, packageJsonFileContent);
+ const projectService: IProjectService = testInjector.resolve(ProjectServiceLib.ProjectService);
+ assert.isFalse(projectService.isValidNativeScriptProject("some-dir"));
+ });
});
});
diff --git a/test/stubs.ts b/test/stubs.ts
index 010f78b230..46585c861c 100644
--- a/test/stubs.ts
+++ b/test/stubs.ts
@@ -255,7 +255,7 @@ export class PlatformsDataStub extends EventEmitter implements IPlatformsData {
normalizedPlatformName: "",
appDestinationDirectoryPath: "",
deviceBuildOutputPath: "",
- validPackageNamesForDevice: [],
+ getValidPackageNames: (buildOptions: {isForDevice?: boolean, isReleaseBuild?: boolean}) => [],
frameworkFilesExtensions: [],
relativeToFrameworkConfigurationFilePath: "",
fastLivesyncFileExtensions: []
@@ -276,7 +276,7 @@ export class PlatformProjectServiceStub extends EventEmitter implements IPlatfor
emulatorServices: undefined,
projectRoot: "",
deviceBuildOutputPath: "",
- validPackageNamesForDevice: [],
+ getValidPackageNames: (buildOptions: {isForDevice?: boolean, isReleaseBuild?: boolean}) => [],
frameworkFilesExtensions: [],
appDestinationDirectoryPath: "",
relativeToFrameworkConfigurationFilePath: "",
@@ -352,7 +352,7 @@ export class PlatformProjectServiceStub extends EventEmitter implements IPlatfor
async stopServices(): Promise {
return Promise.resolve({stderr: "", stdout: "", exitCode: 0});
}
- async cleanProject(projectRoot: string, options: string[]): Promise {
+ async cleanProject(projectRoot: string, projectData: IProjectData): Promise {
return Promise.resolve();
}
}
@@ -664,14 +664,14 @@ export class PlatformServiceStub extends EventEmitter implements IPlatformServic
return null;
}
- public getLatestApplicationPackageForEmulator(platformData: IPlatformData): IApplicationPackage {
+ public getLatestApplicationPackageForEmulator(platformData: IPlatformData, buildConfig: IBuildConfig): IApplicationPackage {
return null;
}
- public copyLastOutput(platform: string, targetPath: string, settings: { isForDevice: boolean }): void {
+ public copyLastOutput(platform: string, targetPath: string, buildConfig: IBuildConfig): void {
}
- public lastOutputPath(platform: string, settings: { isForDevice: boolean }): string {
+ public lastOutputPath(platform: string, buildConfig: IBuildConfig): string {
return "";
}