Skip to content

tns-android/ios are installed as dev dependencies #2532

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

Closed
Closed
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
3 changes: 2 additions & 1 deletion lib/commands/install.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { EOL } from "os";
import * as constants from "../constants";

export class InstallCommand implements ICommand {
public enableHooks = false;
Expand Down Expand Up @@ -26,7 +27,7 @@ export class InstallCommand implements ICommand {
this.$projectDataService.initialize(this.$projectData.projectDir);
for (let platform of this.$platformsData.platformsNames) {
let platformData = this.$platformsData.getPlatformData(platform);
let frameworkPackageData = this.$projectDataService.getValue(platformData.frameworkPackageName);
let frameworkPackageData = this.$projectDataService.getValue(platformData.frameworkPackageName, constants.DEV_DEPENDENCIES);
if (frameworkPackageData && frameworkPackageData.version) {
try {
await this.$platformService.addPlatforms([`${platform}@${frameworkPackageData.version}`]);
Expand Down
5 changes: 3 additions & 2 deletions lib/commands/update.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as path from "path";
import * as shelljs from "shelljs";
import * as constants from "../constants";

export class UpdateCommand implements ICommand {
public allowedParameters: ICommandParameter[] = [];
Expand All @@ -13,7 +14,7 @@ export class UpdateCommand implements ICommand {
private $logger: ILogger) { }

public async execute(args: string[]): Promise<void> {
let folders = ["lib", "hooks", "platforms", "node_modules"];
let folders = ["hooks", "platforms", "node_modules"];
let tmpDir = path.join(this.$projectData.projectDir, ".tmp_backup");

try {
Expand Down Expand Up @@ -63,7 +64,7 @@ export class UpdateCommand implements ICommand {
this.$projectDataService.initialize(this.$projectData.projectDir);
for (let platform of availablePlatforms) {
let platformData = this.$platformsData.getPlatformData(platform);
let platformVersion = this.$projectDataService.getValue(platformData.frameworkPackageName);
let platformVersion = this.$projectDataService.getValue(platformData.frameworkPackageName, constants.DEV_DEPENDENCIES);
if (platformVersion) {
packagePlatforms.push(platform);
this.$projectDataService.removeProperty(platformData.frameworkPackageName);
Expand Down
5 changes: 5 additions & 0 deletions lib/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ 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 DEV_DEPENDENCIES = "devDependencies";
export const FRAMEWORK_TO_PACKAGE:IStringDictionary = {
"android": TNS_ANDROID_RUNTIME_NAME,
"ios": TNS_IOS_RUNTIME_NAME
};

export class PackageVersion {
static NEXT = "next";
Expand Down
1 change: 1 addition & 0 deletions lib/definitions/plugins.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ interface IPluginsService {
prepare(pluginData: IDependencyData, platform: string): Promise<void>;
getAllInstalledPlugins(): Promise<IPluginData[]>;
ensureAllDependenciesAreInstalled(): Promise<void>;
getInstalledFrameworkVersion(platform: string): string;

/**
* Returns all dependencies and devDependencies from pacakge.json file.
Expand Down
2 changes: 1 addition & 1 deletion lib/definitions/project.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ interface IProjectDataService {
* @param {string} propertyName The name of the property to be checked in `nativescript` key.
* @returns {any} The value of the property.
*/
getValue(propertyName: string): any;
getValue(propertyName: string, key?: string): any;

/**
* Sets a value in the `nativescript` key in a project's package.json.
Expand Down
2 changes: 1 addition & 1 deletion lib/services/android-project-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
if (!this._canUseGradle) {
if (!frameworkVersion) {
this.$projectDataService.initialize(this.$projectData.projectDir);
let frameworkInfoInProjectFile = this.$projectDataService.getValue(this.platformData.frameworkPackageName);
let frameworkInfoInProjectFile = this.$projectDataService.getValue(this.platformData.frameworkPackageName, constants.DEV_DEPENDENCIES);
frameworkVersion = frameworkInfoInProjectFile && frameworkInfoInProjectFile.version;
}

Expand Down
11 changes: 5 additions & 6 deletions lib/services/livesync/livesync-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class LiveSyncService implements ILiveSyncService {
private $platformsData: IPlatformsData,
private $platformService: IPlatformService,
private $projectData: IProjectData,
private $projectDataService: IProjectDataService,
private $pluginsService: IPluginsService,
private $prompter: IPrompter,
private $injector: IInjector,
private $mobileHelper: Mobile.IMobileHelper,
Expand All @@ -26,8 +26,7 @@ class LiveSyncService implements ILiveSyncService {
private $processService: IProcessService) { }

private async ensureAndroidFrameworkVersion(platformData: IPlatformData): Promise<void> { // TODO: this can be moved inside command or canExecute function
this.$projectDataService.initialize(this.$projectData.projectDir);
let frameworkVersion = this.$projectDataService.getValue(platformData.frameworkPackageName).version;
let frameworkVersion = this.$pluginsService.getInstalledFrameworkVersion(platformData.normalizedPlatformName);

if (platformData.normalizedPlatformName.toLowerCase() === this.$devicePlatformsConstants.Android.toLowerCase()) {
if (semver.lt(frameworkVersion, "1.2.1")) {
Expand All @@ -46,9 +45,9 @@ class LiveSyncService implements ILiveSyncService {
}

public async liveSync(platform: string, applicationReloadAction?: (deviceAppData: Mobile.IDeviceAppData) => Promise<void>): Promise<void> {
if (this.$options.justlaunch) {
this.$options.watch = false;
}
if (this.$options.justlaunch) {
this.$options.watch = false;
}
let liveSyncData: ILiveSyncData[] = [];

if (platform) {
Expand Down
4 changes: 3 additions & 1 deletion lib/services/platform-project-service-base.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import * as constants from "../constants";

export class PlatformProjectServiceBase implements IPlatformProjectServiceBase {
constructor(protected $fs: IFileSystem,
protected $projectData: IProjectData,
Expand All @@ -24,7 +26,7 @@ export class PlatformProjectServiceBase implements IPlatformProjectServiceBase {

protected getFrameworkVersion(runtimePackageName: string): string {
this.$projectDataService.initialize(this.$projectData.projectDir);
let frameworkVersion = this.$projectDataService.getValue(runtimePackageName).version;
let frameworkVersion = this.$projectDataService.getValue(runtimePackageName, constants.DEV_DEPENDENCIES).version;
return frameworkVersion;
}
}
12 changes: 5 additions & 7 deletions lib/services/platform-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export class PlatformService implements IPlatformService {
let packageToInstall = "";
let npmOptions: IStringDictionary = {
Copy link
Contributor

Choose a reason for hiding this comment

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

can we add --save-exact to npmOptions, as currently we are adding the framework package with ^, for example:

"tns-android": "^2.5.0"

This means that once we have tns-android 2.6.0, and I execute rm -rf node_modules && npm i I'll get the new framework.

pathToSave: path.join(this.$projectData.platformsDir, platform),
dependencyType: "save"
dependencyType: "save-dev"
};

if (!this.$options.frameworkPath) {
Expand All @@ -97,8 +97,7 @@ export class PlatformService implements IPlatformService {
let frameworkDir = path.join(downloadedPackagePath, constants.PROJECT_FRAMEWORK_FOLDER_NAME);
frameworkDir = path.resolve(frameworkDir);

let coreModuleName = await this.addPlatformCore(platformData, frameworkDir);
await this.$npm.uninstall(coreModuleName, { save: true }, this.$projectData.projectDir);
await this.addPlatformCore(platformData, frameworkDir);
} catch (err) {
this.$fs.deleteDirectory(platformPath);
throw err;
Expand Down Expand Up @@ -129,17 +128,15 @@ export class PlatformService implements IPlatformService {
if (customTemplateOptions) {
frameworkPackageNameData.template = customTemplateOptions.selectedTemplate;
}
this.$projectDataService.setValue(platformData.frameworkPackageName, frameworkPackageNameData);

return coreModuleName;

}

private async getPathToPlatformTemplate(selectedTemplate: string, frameworkPackageName: string): Promise<any> {
if (!selectedTemplate) {
// read data from package.json's nativescript key
// check the nativescript.tns-<platform>.template value
let nativescriptPlatformData = this.$projectDataService.getValue(frameworkPackageName);
let nativescriptPlatformData = this.$projectDataService.getValue(frameworkPackageName, constants.DEV_DEPENDENCIES);
selectedTemplate = nativescriptPlatformData && nativescriptPlatformData.template;
}

Expand Down Expand Up @@ -577,6 +574,7 @@ export class PlatformService implements IPlatformService {
let platformDir = path.join(this.$projectData.platformsDir, platform);
this.$fs.deleteDirectory(platformDir);
this.$projectDataService.removeProperty(platformData.frameworkPackageName);
this.$npm.uninstall(platformData.frameworkPackageName, {"save-dev": true});

this.$logger.out(`Platform ${platform} successfully removed.`);
});
Expand Down Expand Up @@ -709,7 +707,7 @@ export class PlatformService implements IPlatformService {
let platformData = this.$platformsData.getPlatformData(platform);

this.$projectDataService.initialize(this.$projectData.projectDir);
let data = this.$projectDataService.getValue(platformData.frameworkPackageName);
let data = this.$projectDataService.getValue(platformData.frameworkPackageName, constants.DEV_DEPENDENCIES);
let currentVersion = data && data.version ? data.version : "0.2.0";

let newVersion = version === constants.PackageVersion.NEXT ?
Expand Down
9 changes: 4 additions & 5 deletions lib/services/plugins-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -273,11 +273,10 @@ export class PluginsService implements IPluginsService {
};
}

private getInstalledFrameworkVersion(platform: string): string {
let platformData = this.$platformsData.getPlatformData(platform);
this.$projectDataService.initialize(this.$projectData.projectDir);
let frameworkData = this.$projectDataService.getValue(platformData.frameworkPackageName);
return frameworkData.version;
public getInstalledFrameworkVersion(platform: string): string {
let pathToInstalledFrameworkPackageJson = path.join(this.$projectData.projectDir, constants.NODE_MODULES_FOLDER_NAME, constants.FRAMEWORK_TO_PACKAGE[platform.toLowerCase()], constants.PACKAGE_JSON_FILE_NAME);
let jsonContent = this.$fs.readJson(pathToInstalledFrameworkPackageJson);
return jsonContent.version;
}

private isPluginDataValidForPlatform(pluginData: IPluginData, platform: string): boolean {
Expand Down
8 changes: 6 additions & 2 deletions lib/services/project-data-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,13 @@ export class ProjectDataService implements IProjectDataService {
}
}

public getValue(propertyName: string): any {
public getValue(propertyName: string, key?: string): any {
this.loadProjectFile();
return this.projectData ? this.projectData[this.$staticConfig.CLIENT_NAME_KEY_IN_PROJECT_FILE][propertyName] : null;
let rootKey: string = this.$staticConfig.CLIENT_NAME_KEY_IN_PROJECT_FILE;
if (key) {
rootKey = key;
}
return this.projectData ? this.projectData[rootKey][propertyName] : null;
}

public setValue(key: string, value: any): void {
Expand Down
8 changes: 8 additions & 0 deletions lib/tools/node-modules/node-modules-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,14 @@ export class NodeModulesBuilder implements INodeModulesBuilder {
let dependenciesBuilder = this.$injector.resolve(NodeModulesDependenciesBuilder, {});
let productionDependencies = dependenciesBuilder.getProductionDependencies(this.$projectData.projectDir);

let prodDependenciesArr = [];
Copy link
Contributor

Choose a reason for hiding this comment

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

The for below can be replaced with map:

const prodDependenciesArr = _.map(productionDependencies, prodDep => prodDep.name);

for (let i in productionDependencies) {
prodDependenciesArr.push(productionDependencies[i].name);
}

let prodDependenciesFilePath = path.join(this.$projectData.projectDir, "platforms", "android", "productionDependencies.json");
this.$fs.writeJson(prodDependenciesFilePath, prodDependenciesArr);
Copy link
Contributor

@rosen-vladimirov rosen-vladimirov Feb 26, 2017

Choose a reason for hiding this comment

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

what's the purpose of this file? Why should we write it to platforms dir? Can you add comment in the code, please.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll add comments to the code, but the basic idea is, we need to tell gradle what are the production dependencies, that CLI found, so we search for dependencies only in production modules, it saves time, and it's less error prone.

Copy link
Contributor

Choose a reason for hiding this comment

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

Why gradle needs to know which are the production dependencies? As far as I remember, CLI copies only production dependencies to platforms/android dir.
Also... this code is executed for iOS builds as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Because gradle needs to go through the node_modules folder and get all .aar so it can include them into the build. Currently we traverse all of the node_modules which is error prone and it's a waste of time, when we know which dependencies we should use.


if (!this.$options.bundle) {
const tnsModulesCopy = this.$injector.resolve(TnsModulesCopy, {
outputRoot: absoluteOutputPath
Expand Down
6 changes: 3 additions & 3 deletions test/plugins-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,9 @@ function createProjectFile(testInjector: IInjector): string {
"version": "0.1.0",
"nativescript": {
"id": "org.nativescript.Test",
"tns-android": {
"version": "1.4.0"
}
},
"devDependencies": {
"tns-android": "1.4.0"
}
};

Expand Down