diff --git a/lib/definitions/project.d.ts b/lib/definitions/project.d.ts index db203277d2..df3d0022ab 100644 --- a/lib/definitions/project.d.ts +++ b/lib/definitions/project.d.ts @@ -10,6 +10,8 @@ interface IProjectData { projectFilePath: string; projectId?: string; dependencies: any; + appDirectoryPath: string; + appResourcesDirectoryPath: string; } interface IProjectDataService { @@ -55,6 +57,7 @@ interface IPlatformProjectService { afterPrepareAllPlugins(): IFuture; getAppResourcesDestinationDirectoryPath(): IFuture; deploy(deviceIdentifier: string): IFuture; + processConfigurationFilesFromAppResources(): IFuture; } interface IAndroidProjectPropertiesManager { diff --git a/lib/project-data.ts b/lib/project-data.ts index e0696062d9..4114ab3fff 100644 --- a/lib/project-data.ts +++ b/lib/project-data.ts @@ -1,8 +1,9 @@ /// "use strict"; +import * as constants from "./constants"; import * as path from "path"; -import * as os from "os"; +import {EOL} from "os"; export class ProjectData implements IProjectData { private static OLD_PROJECT_FILE_NAME = ".tnsproject"; @@ -12,6 +13,8 @@ export class ProjectData implements IProjectData { public projectFilePath: string; public projectId: string; public projectName: string; + public appDirectoryPath: string; + public appResourcesDirectoryPath: string; public dependencies: any; constructor(private $fs: IFileSystem, @@ -37,8 +40,8 @@ export class ProjectData implements IProjectData { fileContent = this.$fs.readJson(this.projectFilePath).wait(); data = fileContent[this.$staticConfig.CLIENT_NAME_KEY_IN_PROJECT_FILE]; } catch (err) { - this.$errors.fail({formatStr: "The project file %s is corrupted." + os.EOL + - "Consider restoring an earlier version from your source control or backup." + os.EOL + + 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()); @@ -101,6 +104,8 @@ export class ProjectData implements IProjectData { 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/services/android-project-service.ts b/lib/services/android-project-service.ts index d98592360e..8868de0dc4 100644 --- a/lib/services/android-project-service.ts +++ b/lib/services/android-project-service.ts @@ -12,7 +12,6 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject private static VALUES_DIRNAME = "values"; private static VALUES_VERSION_DIRNAME_PREFIX = AndroidProjectService.VALUES_DIRNAME + "-v"; private static ANDROID_PLATFORM_NAME = "android"; - private static LIBS_FOLDER_NAME = "libs"; private static MIN_RUNTIME_VERSION_WITH_GRADLE = "1.3.0"; private _androidProjectPropertiesManagers: IDictionary; @@ -252,9 +251,6 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject this.$fs.ensureDirectoryExists(targetPath).wait(); shell.cp("-f", path.join(libraryPath, "*.jar"), targetPath); - let projectLibsDir = path.join(this.platformData.projectRoot, "libs"); - this.$fs.ensureDirectoryExists(projectLibsDir).wait(); - shell.cp("-f", path.join(libraryPath, "*.jar"), projectLibsDir); }).future()(); } @@ -280,25 +276,46 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject public preparePluginNativeCode(pluginData: IPluginData): IFuture { return (() => { let pluginPlatformsFolderPath = this.getPluginPlatformsFolderPath(pluginData, AndroidProjectService.ANDROID_PLATFORM_NAME); + this.processResourcesFromPlugin(pluginData.name, pluginPlatformsFolderPath).wait(); + }).future()(); + } - // Handle *.jars inside libs folder - let libsFolderPath = path.join(pluginPlatformsFolderPath, AndroidProjectService.LIBS_FOLDER_NAME); - if(this.$fs.exists(libsFolderPath).wait()) { - this.addLibrary(libsFolderPath).wait(); + public processConfigurationFilesFromAppResources(): IFuture { + return (() => { + // Process androidManifest.xml from App_Resources + let manifestFilePath = path.join(this.$projectData.appResourcesDirectoryPath, this.platformData.normalizedPlatformName, this.platformData.configurationFileName); + if (this.$fs.exists(manifestFilePath).wait()) { + this.processResourcesFromPlugin("NativescriptAppResources", path.dirname(manifestFilePath)).wait(); } }).future()(); } + private processResourcesFromPlugin(pluginName: string, pluginPlatformsFolderPath: string): IFuture { + return (() => { + let configurationsDirectoryPath = path.join(this.platformData.projectRoot, "configurations"); + this.$fs.ensureDirectoryExists(configurationsDirectoryPath).wait(); + + let pluginConfigurationDirectoryPath = path.join(configurationsDirectoryPath, pluginName); + this.$fs.ensureDirectoryExists(pluginConfigurationDirectoryPath).wait(); + + // Copy include.gradle file + let includeGradleFilePath = path.join(pluginPlatformsFolderPath, "include.gradle"); + if(this.$fs.exists(includeGradleFilePath).wait()) { + shell.cp("-f", includeGradleFilePath, pluginConfigurationDirectoryPath); + } + + // Copy all resources from plugin + let resourcesDestinationDirectoryPath = path.join(this.platformData.projectRoot, "src", pluginName); + this.$fs.ensureDirectoryExists(resourcesDestinationDirectoryPath).wait(); + shell.cp("-Rf", path.join(pluginPlatformsFolderPath, "*"), resourcesDestinationDirectoryPath); + }).future()(); + } + public removePluginNativeCode(pluginData: IPluginData): IFuture { return (() => { try { - let pluginPlatformsFolderPath = this.getPluginPlatformsFolderPath(pluginData, AndroidProjectService.ANDROID_PLATFORM_NAME); - let libsFolderPath = path.join(pluginPlatformsFolderPath, AndroidProjectService.LIBS_FOLDER_NAME); - - if(this.$fs.exists(libsFolderPath).wait()) { - let pluginJars = this.$fs.enumerateFilesInDirectorySync(libsFolderPath); - _.each(pluginJars, jarName => this.$fs.deleteFile(path.join(libsFolderPath, jarName)).wait()); - } + this.$fs.deleteDirectory(path.join(this.platformData.projectRoot, "configurations", pluginData.name)).wait(); + this.$fs.deleteDirectory(path.join(this.platformData.projectRoot, "src", pluginData.name)).wait(); } catch(e) { if (e.code === "ENOENT") { this.$logger.debug("No native code jars found: " + e.message); diff --git a/lib/services/ios-project-service.ts b/lib/services/ios-project-service.ts index a6936d384f..dc0fa20f18 100644 --- a/lib/services/ios-project-service.ts +++ b/lib/services/ios-project-service.ts @@ -354,6 +354,10 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ }).future()(); } + public processConfigurationFilesFromAppResources(): IFuture { + return Future.fromResult(); + } + private get projectPodFilePath(): string { return path.join(this.platformData.projectRoot, "Podfile"); } diff --git a/lib/services/platform-service.ts b/lib/services/platform-service.ts index 59c0f388ce..7acd9b8852 100644 --- a/lib/services/platform-service.ts +++ b/lib/services/platform-service.ts @@ -217,6 +217,9 @@ export class PlatformService implements IPlatformService { let excludedDirs = [constants.APP_RESOURCES_FOLDER_NAME]; this.$projectFilesManager.processPlatformSpecificFiles(directoryPath, platform, excludedDirs).wait(); + // Process configurations files from App_Resources + platformData.platformProjectService.processConfigurationFilesFromAppResources().wait(); + this.$logger.out("Project successfully prepared"); }).future()(); } diff --git a/test/npm-support.ts b/test/npm-support.ts index d32135ce3f..5a2f1ef907 100644 --- a/test/npm-support.ts +++ b/test/npm-support.ts @@ -123,7 +123,8 @@ function setupProject(): IFuture { prepareProject: () => Future.fromResult(), prepareAppResources: () => Future.fromResult(), afterPrepareAllPlugins: () => Future.fromResult(), - getAppResourcesDestinationDirectoryPath: () => Future.fromResult("") + getAppResourcesDestinationDirectoryPath: () => Future.fromResult(""), + processConfigurationFilesFromAppResources: () => Future.fromResult() } }; }; diff --git a/test/platform-service.ts b/test/platform-service.ts index d8a0831d3f..a4a766ecb5 100644 --- a/test/platform-service.ts +++ b/test/platform-service.ts @@ -220,7 +220,8 @@ describe('Platform Service Tests', () => { createProject: (projectRoot: string, frameworkDir: string) => Future.fromResult(), interpolateData: (projectRoot: string) => Future.fromResult(), afterCreateProject: (projectRoot: string) => Future.fromResult(), - getAppResourcesDestinationDirectoryPath: () => Future.fromResult("") + getAppResourcesDestinationDirectoryPath: () => Future.fromResult(""), + processConfigurationFilesFromAppResources: () => Future.fromResult() } }; }; @@ -279,7 +280,8 @@ describe('Platform Service Tests', () => { createProject: (projectRoot: string, frameworkDir: string) => Future.fromResult(), interpolateData: (projectRoot: string) => Future.fromResult(), afterCreateProject: (projectRoot: string) => Future.fromResult(), - getAppResourcesDestinationDirectoryPath: () => Future.fromResult("") + getAppResourcesDestinationDirectoryPath: () => Future.fromResult(""), + processConfigurationFilesFromAppResources: () => Future.fromResult() } }; }; diff --git a/test/stubs.ts b/test/stubs.ts index 66a86c304d..638cc44c96 100644 --- a/test/stubs.ts +++ b/test/stubs.ts @@ -249,6 +249,8 @@ export class ProjectDataStub implements IProjectData { projectFilePath: string; projectId: string; dependencies: any; + appDirectoryPath: string; + appResourcesDirectoryPath: string; } export class PlatformsDataStub implements IPlatformsData { @@ -265,7 +267,7 @@ export class PlatformsDataStub implements IPlatformsData { deviceBuildOutputPath: "", validPackageNamesForDevice: [], frameworkFilesExtensions: [], - relativeToFrameworkConfigurationFilePath: "", + relativeToFrameworkConfigurationFilePath: "" }; } @@ -340,6 +342,9 @@ export class PlatformProjectServiceStub implements IPlatformProjectService { deploy(deviceIdentifier: string): IFuture { return Future.fromResult(); } + processConfigurationFilesFromAppResources(): IFuture { + return Future.fromResult(); + } } export class ProjectDataService implements IProjectDataService {