Skip to content

Commit 3bc89ae

Browse files
Fatme HavaluovaFatme Havaluova
Fatme Havaluova
authored and
Fatme Havaluova
committed
Fix PR comments
1 parent 3eef986 commit 3bc89ae

File tree

10 files changed

+120
-88
lines changed

10 files changed

+120
-88
lines changed

.vscode/launch.json

-42
This file was deleted.

lib/definitions/plugins.d.ts

+24-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ interface IPluginsService {
99

1010
interface IPluginData extends INodeModuleData {
1111
platformsData: IPluginPlatformsData;
12+
/* Gets all plugin variables from plugin */
1213
pluginVariables: IDictionary<IPluginVariableData>;
1314
pluginPlatformsFolderPath(platform: string): string;
1415
}
@@ -27,13 +28,35 @@ interface IPluginPlatformsData {
2728
}
2829

2930
interface IPluginVariablesService {
31+
/**
32+
* Saves plugin variables in project package.json file.
33+
* @param {IPluginData} pluginData for the plugin.
34+
* @return {IFuture<void>}
35+
*/
3036
savePluginVariablesInProjectFile(pluginData: IPluginData): IFuture<void>;
37+
/**
38+
* Removes plugin variables from project package.json file.
39+
* @param {IPluginData} pluginData for the plugin.
40+
* @return {IFuture<void>}
41+
*/
3142
removePluginVariablesFromProjectFile(pluginData: IPluginData): IFuture<void>;
43+
/**
44+
* Replaces all plugin variables with their corresponding values.
45+
* @param {IPluginData} pluginData for the plugin.
46+
* @param {pluginConfigurationFileContent} pluginConfigurationFileContent for the plugin.
47+
* @return {IFuture<string>} returns the changed plugin configuration file content.
48+
*/
3249
interpolatePluginVariables(pluginData: IPluginData, pluginConfigurationFileContent: string): IFuture<string>;
50+
/**
51+
* Returns the
52+
* @param {IPluginData} pluginData for the plugin.
53+
* @return {IFuture<string>} returns the changed plugin configuration file content.
54+
*/
55+
getPluginVariablePropertyName(pluginData: IPluginData): string;
3356
}
3457

3558
interface IPluginVariableData {
36-
default?: string;
59+
defaultValue?: string;
3760
name?: string;
3861
value?: string;
3962
}

lib/definitions/project.d.ts

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ interface IProjectDataService {
1616
getValue(propertyName: string): IFuture<any>;
1717
setValue(key: string, value: any): IFuture<void>;
1818
removeProperty(propertyName: string): IFuture<void>;
19+
removeDependency(dependencyName: string): IFuture<void>;
1920
}
2021

2122
interface IProjectTemplatesService {

lib/services/plugin-variables-service.ts

+10-11
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,20 @@
11
///<reference path="../.d.ts"/>
22
"use strict";
33

4-
import helpers = require("./../common/helpers");
4+
import * as helpers from "./../common/helpers";
55

66
export class PluginVariablesService implements IPluginVariablesService {
77
private static PLUGIN_VARIABLES_KEY = "variables";
88

99
constructor(private $errors: IErrors,
10-
private $fs: IFileSystem,
1110
private $pluginVariablesHelper: IPluginVariablesHelper,
1211
private $projectData: IProjectData,
1312
private $projectDataService: IProjectDataService,
14-
private $prompter: IPrompter,
15-
private $staticConfig: IStaticConfig) { }
13+
private $prompter: IPrompter) { }
14+
15+
public getPluginVariablePropertyName(pluginData: IPluginData): string {
16+
return `${pluginData.name}-${PluginVariablesService.PLUGIN_VARIABLES_KEY}`;
17+
}
1618

1719
public savePluginVariablesInProjectFile(pluginData: IPluginData): IFuture<void> {
1820
return (() => {
@@ -44,7 +46,7 @@ export class PluginVariablesService implements IPluginVariablesService {
4446
this.$errors.failWithoutHelp(`Unable to find the value for ${pluginVariableData.name} plugin variable into project package.json file. Verify that your package.json file is correct and try again.`);
4547
}
4648

47-
pluginConfigurationFileContent = pluginConfigurationFileContent.replace(new RegExp(pluginVariableData.name, "gi"), pluginVariableData.value);
49+
pluginConfigurationFileContent = pluginConfigurationFileContent.replace(new RegExp(`{${pluginVariableData.name}}`, "gi"), pluginVariableData.value);
4850
}).future<void>()()).wait();
4951
return pluginConfigurationFileContent;
5052
}).future<string>()();
@@ -57,12 +59,13 @@ export class PluginVariablesService implements IPluginVariablesService {
5759
if(value) {
5860
value = value[pluginVariableName];
5961
} else {
60-
value = pluginVariableData.default;
62+
value = pluginVariableData.defaultValue;
6163
if(!value && helpers.isInteractive()) {
6264
let promptSchema = {
6365
name: pluginVariableName,
6466
type: "input",
65-
message: `Enter value for ${pluginVariableName} variable: `
67+
message: `Enter value for ${pluginVariableName} variable:`,
68+
validate: (val: string) => !!val ? true : 'Please enter a value!'
6669
};
6770
let promptData = this.$prompter.get([promptSchema]).wait();
6871
value = promptData[pluginVariableName];
@@ -94,10 +97,6 @@ export class PluginVariablesService implements IPluginVariablesService {
9497
return variableData;
9598
}).future<IPluginVariableData>()();
9699
}
97-
98-
private getPluginVariablePropertyName(pluginData: IPluginData): string {
99-
return `${pluginData.name}-${PluginVariablesService.PLUGIN_VARIABLES_KEY}`;
100-
}
101100
}
102101
$injector.register("pluginVariablesService", PluginVariablesService);
103102

lib/services/plugins-service.ts

+62-23
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,20 @@ export class PluginsService implements IPluginsService {
3434
this.ensure().wait();
3535
let dependencyData = this.$npm.cache(plugin, undefined, PluginsService.NPM_CONFIG).wait();
3636
if(dependencyData.nativescript) {
37-
this.executeNpmCommand(PluginsService.INSTALL_COMMAND_NAME, plugin).wait();
38-
3937
let pluginData = this.convertToPluginData(dependencyData);
40-
this.$pluginVariablesService.savePluginVariablesInProjectFile(pluginData).wait();
38+
this.validate(pluginData).wait();
39+
40+
try {
41+
this.$pluginVariablesService.savePluginVariablesInProjectFile(pluginData).wait();
42+
this.executeNpmCommand(PluginsService.INSTALL_COMMAND_NAME, plugin).wait();
43+
} catch(err) {
44+
// Revert package.json
45+
this.$projectDataService.initialize(this.$projectData.projectDir);
46+
this.$projectDataService.removeProperty(this.$pluginVariablesService.getPluginVariablePropertyName(pluginData)).wait();
47+
this.$projectDataService.removeDependency(pluginData.name).wait();
48+
49+
throw err;
50+
}
4151

4252
this.$logger.out(`Successfully installed plugin ${dependencyData.name}.`);
4353
} else {
@@ -49,6 +59,17 @@ export class PluginsService implements IPluginsService {
4959

5060
public remove(pluginName: string): IFuture<void> {
5161
return (() => {
62+
let isUninstallCommandExecuted = false;
63+
64+
let executeUninstallCommand = () => {
65+
return (() => {
66+
if(!isUninstallCommandExecuted) {
67+
this.executeNpmCommand(PluginsService.UNINSTALL_COMMAND_NAME, pluginName).wait();
68+
isUninstallCommandExecuted = true;
69+
}
70+
}).future<void>()();
71+
};
72+
5273
let removePluginNativeCodeAction = (modulesDestinationPath: string, platform: string, platformData: IPlatformData) => {
5374
return (() => {
5475
let pluginData = this.convertToPluginData(this.getNodeModuleData(pluginName).wait());
@@ -60,10 +81,13 @@ export class PluginsService implements IPluginsService {
6081
if(this.$fs.exists(pluginConfigurationFilePath).wait()) {
6182
let tnsModulesDestinationPath = path.join(platformData.appDestinationDirectoryPath, constants.APP_FOLDER_NAME, constants.TNS_MODULES_FOLDER_NAME);
6283
let nodeModules = this.$broccoliBuilder.getChangedNodeModules(tnsModulesDestinationPath, platform).wait();
63-
_.each(nodeModules, (index, nodeModule) => {
64-
let data = this.convertToPluginData(this.getNodeModuleData(pluginName).wait());
84+
let plugins = _.map(_.keys(nodeModules), nodeModule => this.convertToPluginData(this.getNodeModuleData(pluginName).wait()));
85+
86+
_.forEach(plugins, (data, index) => {
6587
if(data.isPlugin) {
6688
if(this.$fs.exists(this.getPluginConfigurationFilePath(data, platformData)).wait()) {
89+
executeUninstallCommand().wait();
90+
6791
if(index === 0) {
6892
this.$projectDataService.initialize(this.$projectData.projectDir);
6993
let frameworkVersion = this.$projectDataService.getValue(platformData.frameworkPackageName).wait().version;
@@ -73,9 +97,12 @@ export class PluginsService implements IPluginsService {
7397
let cachedPackagePath = this.$injector.resolve("npmInstallationManager").getCachedPackagePath(platformData.frameworkPackageName, frameworkVersion);
7498
let cachedConfigurationFilePath = path.join(cachedPackagePath, constants.PROJECT_FRAMEWORK_FOLDER_NAME, relativeConfigurationFilePath);
7599

76-
shelljs.cp("-f", cachedConfigurationFilePath, platformData.configurationFilePath);
100+
shelljs.cp("-f", cachedConfigurationFilePath, path.dirname(platformData.configurationFilePath));
101+
}
102+
103+
if(data.name !== pluginName) {
104+
this.merge(data, platformData).wait();
77105
}
78-
this.merge(data, platformData).wait();
79106
}
80107
}
81108
});
@@ -88,7 +115,7 @@ export class PluginsService implements IPluginsService {
88115
};
89116
this.executeForAllInstalledPlatforms(removePluginNativeCodeAction).wait();
90117

91-
this.executeNpmCommand(PluginsService.UNINSTALL_COMMAND_NAME, pluginName).wait();
118+
executeUninstallCommand().wait();
92119

93120
let showMessage = true;
94121
let action = (modulesDestinationPath: string, platform: string, platformData: IPlatformData) => {
@@ -111,23 +138,10 @@ export class PluginsService implements IPluginsService {
111138
return (() => {
112139
let pluginData = this.convertToPluginData(dependencyData);
113140

141+
this.validate(pluginData).wait();
142+
114143
let action = (pluginDestinationPath: string, platform: string, platformData: IPlatformData) => {
115144
return (() => {
116-
let installedFrameworkVersion = this.getInstalledFrameworkVersion(platform).wait();
117-
let pluginPlatformsData = pluginData.platformsData;
118-
if(pluginPlatformsData) {
119-
let pluginVersion = (<any>pluginPlatformsData)[platform];
120-
if(!pluginVersion) {
121-
this.$logger.warn(`${pluginData.name} is not supported for ${platform}.`);
122-
return;
123-
}
124-
125-
if(semver.gt(pluginVersion, installedFrameworkVersion)) {
126-
this.$logger.warn(`${pluginData.name} ${pluginVersion} for ${platform} is not compatible with the currently installed framework version ${installedFrameworkVersion}.`);
127-
return;
128-
}
129-
}
130-
131145
if(this.$fs.exists(path.join(platformData.appDestinationDirectoryPath, constants.APP_FOLDER_NAME)).wait()) {
132146
this.$fs.ensureDirectoryExists(pluginDestinationPath).wait();
133147
shelljs.cp("-Rf", pluginData.fullPath, pluginDestinationPath);
@@ -342,5 +356,30 @@ export class PluginsService implements IPluginsService {
342356
let pluginConfigurationFilePath = path.join(pluginPlatformsFolderPath, platformData.configurationFileName);
343357
return pluginConfigurationFilePath;
344358
}
359+
360+
private validate(pluginData: IPluginData): IFuture<void> {
361+
return (() => {
362+
let action = (pluginDestinationPath: string, platform: string, platformData: IPlatformData) => {
363+
return (() => {
364+
let installedFrameworkVersion = this.getInstalledFrameworkVersion(platform).wait();
365+
let pluginPlatformsData = pluginData.platformsData;
366+
if(pluginPlatformsData) {
367+
let pluginVersion = (<any>pluginPlatformsData)[platform];
368+
if(!pluginVersion) {
369+
this.$logger.warn(`${pluginData.name} is not supported for ${platform}.`);
370+
return;
371+
}
372+
373+
if(semver.gt(pluginVersion, installedFrameworkVersion)) {
374+
this.$logger.warn(`${pluginData.name} ${pluginVersion} for ${platform} is not compatible with the currently installed framework version ${installedFrameworkVersion}.`);
375+
return;
376+
}
377+
}
378+
}).future<void>()();
379+
};
380+
381+
this.executeForAllInstalledPlatforms(action).wait();
382+
}).future<void>()();
383+
}
345384
}
346385
$injector.register("pluginsService", PluginsService);

lib/services/project-data-service.ts

+11-3
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,15 @@ import * as path from "path";
55
import * as assert from "assert";
66

77
export class ProjectDataService implements IProjectDataService {
8+
private static DEPENDENCIES_KEY_NAME = "dependencies";
9+
810
private projectFilePath: string;
911
private projectData: IDictionary<any>;
1012

1113
constructor(private $fs: IFileSystem,
1214
private $staticConfig: IStaticConfig,
1315
private $errors: IErrors,
14-
private $logger: ILogger,
15-
private $injector: IInjector) {
16+
private $logger: ILogger) {
1617
}
1718

1819
public initialize(projectDir: string): void {
@@ -47,9 +48,16 @@ export class ProjectDataService implements IProjectDataService {
4748
}).future<void>()();
4849
}
4950

51+
public removeDependency(dependencyName: string): IFuture<void> {
52+
return (() => {
53+
this.loadProjectFile().wait();
54+
delete this.projectData[ProjectDataService.DEPENDENCIES_KEY_NAME][dependencyName];
55+
this.$fs.writeJson(this.projectFilePath, this.projectData, "\t").wait();
56+
}).future<void>()();
57+
}
58+
5059
private loadProjectFile(): IFuture<void> {
5160
return (() => {
52-
//this.initialize(this.$injector.resolve("projectData").projectDir);
5361
assert.ok(this.projectFilePath, "Initialize method of projectDataService is not called.");
5462

5563
if(!this.projectData) {

lib/tools/broccoli/builder.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ export class Builder implements IBroccoliBuilder {
4545

4646
let future = new Future<void>();
4747

48-
pipeline.on('end', (err: any, data: any) => {
48+
pipeline.on('end', (err: Error, data: any) => {
4949
if(err) {
5050
future.throw(err);
5151
} else {

test/plugin-variables-service.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ describe("Plugin Variables service", () => {
124124
createProjectFile(testInjector).wait();
125125

126126
let defaultPluginValue = "myDefaultValue";
127-
let pluginVariables = { "MY_TEST_PLUGIN_VARIABLE": { default: defaultPluginValue } };
127+
let pluginVariables = { "MY_TEST_PLUGIN_VARIABLE": { defaultValue: defaultPluginValue } };
128128
let pluginData = createPluginData(pluginVariables);
129129
let pluginVariablesService = testInjector.resolve("pluginVariablesService");
130130
pluginVariablesService.savePluginVariablesInProjectFile(pluginData).wait();
@@ -168,7 +168,7 @@ describe("Plugin Variables service", () => {
168168
createProjectFile(testInjector).wait();
169169

170170
let defaultPluginValue = "myAppNAme";
171-
let pluginVariables = { "APP_NAME": { default: defaultPluginValue } };
171+
let pluginVariables = { "APP_NAME": { defaultValue: defaultPluginValue } };
172172
let pluginData = createPluginData(pluginVariables);
173173
let pluginVariablesService = testInjector.resolve("pluginVariablesService");
174174
pluginVariablesService.savePluginVariablesInProjectFile(pluginData).wait();
@@ -242,7 +242,7 @@ describe("Plugin Variables service", () => {
242242
let pluginConfigurationFileContent = '<?xml version="1.0" encoding="UTF-8"?>' +
243243
'<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.android.basiccontactables" android:versionCode="1" android:versionName="1.0" >' +
244244
'<application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/Theme.Sample" >' +
245-
'<activity android:label="@string/FB_APP_NAME" android:name="com.facebook.LoginActivity" android:theme="@android:style/Theme.Translucent.NoTitleBar"/>' +
245+
'<activity android:label="@string/{FB_APP_NAME}" android:name="com.facebook.LoginActivity" android:theme="@android:style/Theme.Translucent.NoTitleBar"/>' +
246246
'</application>' +
247247
'</manifest>';
248248
let result = pluginVariablesService.interpolatePluginVariables(pluginData, pluginConfigurationFileContent).wait();
@@ -277,7 +277,7 @@ describe("Plugin Variables service", () => {
277277
let pluginConfigurationFileContent = '<?xml version="1.0" encoding="UTF-8"?>' +
278278
'<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.android.basiccontactables" android:versionCode="1" android:versionName="1.0" >' +
279279
'<application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/Theme.Sample" >' +
280-
'<activity android:label="@string/Fb_App_NaMe" android:name="com.facebook.LoginActivity" android:theme="@android:style/Theme.Translucent.NoTitleBar"/>' +
280+
'<activity android:label="@string/{Fb_App_NaMe}" android:name="com.facebook.LoginActivity" android:theme="@android:style/Theme.Translucent.NoTitleBar"/>' +
281281
'</application>' +
282282
'</manifest>';
283283
let result = pluginVariablesService.interpolatePluginVariables(pluginData, pluginConfigurationFileContent).wait();
@@ -312,8 +312,8 @@ describe("Plugin Variables service", () => {
312312
let pluginConfigurationFileContent = '<?xml version="1.0" encoding="UTF-8"?>' +
313313
'<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.android.basiccontactables" android:versionCode="1" android:versionName="1.0" >' +
314314
'<application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/Theme.Sample" >' +
315-
'<activity android:label="@string/Fb_App_NaMe" android:name="com.facebook.LoginActivity" android:theme="@android:style/Theme.Translucent.NoTitleBar"/>' +
316-
'<activity android:label="@string/FB_APP_url" />' +
315+
'<activity android:label="@string/{Fb_App_NaMe}" android:name="com.facebook.LoginActivity" android:theme="@android:style/Theme.Translucent.NoTitleBar"/>' +
316+
'<activity android:label="@string/{FB_APP_url}" />' +
317317
'</application>' +
318318
'</manifest>';
319319

0 commit comments

Comments
 (0)