Skip to content

Commit d8e02ca

Browse files
feat: Expose paths to project configuration files in projectData
Expose new properties in `projectData` with paths to specific configuration files. This allows all tools that require CLI to get these paths and will not require changes in them when the structure of project is modified. Introduce additional constants and use them in the code
1 parent 7ff8a54 commit d8e02ca

14 files changed

+74
-24
lines changed

lib/constants.ts

+3
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,10 @@ export const SRC_DIR = "src";
2424
export const MAIN_DIR = "main";
2525
export const ASSETS_DIR = "assets";
2626
export const MANIFEST_FILE_NAME = "AndroidManifest.xml";
27+
export const APP_GRADLE_FILE_NAME = "app.gradle";
28+
export const INFO_PLIST_FILE_NAME = "Info.plist";
2729
export const INCLUDE_GRADLE_NAME = "include.gradle";
30+
export const BUILD_XCCONFIG_FILE_NAME = "build.xcconfig";
2831
export const BUILD_DIR = "build";
2932
export const OUTPUTS_DIR = "outputs";
3033
export const APK_DIR = "apk";

lib/definitions/project.d.ts

+6
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,12 @@ interface IProjectData extends IProjectDir {
6969
appResourcesDirectoryPath: string;
7070
projectType: string;
7171
nsConfig: INsConfig;
72+
androidManifestPath: string;
73+
appGradlePath: string;
74+
gradleFilesDirectoryPath: string;
75+
infoPlistPath: string;
76+
buildXcconfigPath: string;
77+
7278
/**
7379
* Initializes project data with the given project directory. If none supplied defaults to --path option or cwd.
7480
* @param {string} projectDir Project root directory.

lib/project-data.ts

+22-1
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,20 @@ export class ProjectData implements IProjectData {
4343
public dependencies: any;
4444
public devDependencies: IStringDictionary;
4545
public projectType: string;
46+
public androidManifestPath: string;
47+
public infoPlistPath: string;
48+
public appGradlePath: string;
49+
public gradleFilesDirectoryPath: string;
50+
public buildXcconfigPath: string;
4651

4752
constructor(private $fs: IFileSystem,
4853
private $errors: IErrors,
4954
private $projectHelper: IProjectHelper,
5055
private $staticConfig: IStaticConfig,
5156
private $options: IOptions,
52-
private $logger: ILogger) { }
57+
private $logger: ILogger,
58+
private $androidResourcesMigrationService: IAndroidResourcesMigrationService,
59+
private $devicePlatformsConstants: Mobile.IDevicePlatformsConstants) { }
5360

5461
public initializeProjectData(projectDir?: string): void {
5562
projectDir = projectDir || this.$projectHelper.projectDir;
@@ -108,13 +115,27 @@ export class ProjectData implements IProjectData {
108115
this.nsConfig = nsConfig;
109116
this.appDirectoryPath = this.getAppDirectoryPath();
110117
this.appResourcesDirectoryPath = this.getAppResourcesDirectoryPath();
118+
this.androidManifestPath = this.getPathToAndroidManifest(this.appResourcesDirectoryPath);
119+
this.gradleFilesDirectoryPath = path.join(this.appResourcesDirectoryPath, this.$devicePlatformsConstants.Android);
120+
this.appGradlePath = path.join(this.gradleFilesDirectoryPath, constants.APP_GRADLE_FILE_NAME);
121+
this.infoPlistPath = path.join(this.appResourcesDirectoryPath, this.$devicePlatformsConstants.iOS, constants.INFO_PLIST_FILE_NAME);
122+
this.buildXcconfigPath = path.join(this.appResourcesDirectoryPath, this.$devicePlatformsConstants.iOS, constants.BUILD_XCCONFIG_FILE_NAME);
111123

112124
return;
113125
}
114126

115127
this.errorInvalidProject(projectDir);
116128
}
117129

130+
private getPathToAndroidManifest(appResourcesDir: string): string {
131+
const androidDirPath = path.join(appResourcesDir, this.$devicePlatformsConstants.Android);
132+
const androidManifestDir = this.$androidResourcesMigrationService.hasMigrated(appResourcesDir) ?
133+
path.join(androidDirPath, constants.SRC_DIR, constants.MAIN_DIR) :
134+
androidDirPath;
135+
136+
return path.join(androidManifestDir, constants.MANIFEST_FILE_NAME);
137+
}
138+
118139
private errorInvalidProject(projectDir: string): void {
119140
const currentDir = path.resolve(".");
120141
this.$logger.trace(`Unable to find project. projectDir: ${projectDir}, options.path: ${this.$options.path}, ${currentDir}`);

lib/services/android-project-service.ts

+3-5
Original file line numberDiff line numberDiff line change
@@ -256,11 +256,9 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
256256
const gradleSettingsFilePath = path.join(this.getPlatformData(projectData).projectRoot, "settings.gradle");
257257
shell.sed('-i', /__PROJECT_NAME__/, this.getProjectNameFromId(projectData), gradleSettingsFilePath);
258258

259-
// will replace applicationId in app/App_Resources/Android/app.gradle if it has not been edited by the user
260-
const userAppGradleFilePath = path.join(projectData.appResourcesDirectoryPath, this.$devicePlatformsConstants.Android, "app.gradle");
261-
262259
try {
263-
shell.sed('-i', /__PACKAGE__/, projectData.projectId, userAppGradleFilePath);
260+
// will replace applicationId in app/App_Resources/Android/app.gradle if it has not been edited by the user
261+
shell.sed('-i', /__PACKAGE__/, projectData.projectId, projectData.appGradlePath);
264262
} catch (e) {
265263
this.$logger.warn(`\n${e}.\nCheck if you're using an outdated template and update it.`);
266264
}
@@ -520,7 +518,7 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
520518
}
521519

522520
// Copy include.gradle file
523-
const includeGradleFilePath = path.join(pluginPlatformsFolderPath, "include.gradle");
521+
const includeGradleFilePath = path.join(pluginPlatformsFolderPath, constants.INCLUDE_GRADLE_NAME);
524522
if (this.$fs.exists(includeGradleFilePath)) {
525523
shell.cp("-f", includeGradleFilePath, pluginConfigurationDirectoryPath);
526524
}

lib/services/android-resources-migration-service.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ export class AndroidResourcesMigrationService implements IAndroidResourcesMigrat
3737
const getDirectories = (files: string[]) => files.filter(isDirectory);
3838
const getFiles = (files: string[]) => files.filter((file: string) => !isDirectory(file));
3939

40-
this.$fs.copyFile(path.join(originalAppResources, "app.gradle"), path.join(appResourcesDestination, "app.gradle"));
40+
this.$fs.copyFile(path.join(originalAppResources, constants.APP_GRADLE_FILE_NAME), path.join(appResourcesDestination, constants.APP_GRADLE_FILE_NAME));
4141

4242
const appResourcesFiles = getAllFiles(originalAppResources);
4343
const resourceDirectories = getDirectories(appResourcesFiles);

lib/services/ios-project-service.ts

+9-8
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { XCConfigService } from "./xcconfig-service";
1616
import * as simplePlist from "simple-plist";
1717
import * as mobileprovision from "ios-mobileprovision-finder";
1818
import { SpawnOptions } from "child_process";
19+
import { BUILD_XCCONFIG_FILE_NAME } from "../constants";
1920

2021
export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServiceBase implements IPlatformProjectService {
2122
private static XCODE_PROJECT_EXT_NAME = ".xcodeproj";
@@ -89,8 +90,8 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
8990
frameworkDirectoriesExtensions: [".framework"],
9091
frameworkDirectoriesNames: ["Metadata", "metadataGenerator", "NativeScript", "internal"],
9192
targetedOS: ['darwin'],
92-
configurationFileName: "Info.plist",
93-
configurationFilePath: path.join(projectRoot, projectData.projectName, projectData.projectName + "-Info.plist"),
93+
configurationFileName: constants.INFO_PLIST_FILE_NAME,
94+
configurationFilePath: path.join(projectRoot, projectData.projectName, projectData.projectName + `-${constants.INFO_PLIST_FILE_NAME}`),
9495
relativeToFrameworkConfigurationFilePath: path.join("__PROJECT_NAME__", "__PROJECT_NAME__-Info.plist"),
9596
fastLivesyncFileExtensions: [".tiff", ".tif", ".jpg", "jpeg", "gif", ".png", ".bmp", ".BMPf", ".ico", ".cur", ".xbm"] // https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIImage_Class/
9697
};
@@ -338,7 +339,7 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
338339
// Starting from tns-ios 1.4 the xcconfig file is referenced in the project template
339340
const frameworkVersion = this.getFrameworkVersion(this.getPlatformData(projectData).frameworkPackageName, projectData.projectDir);
340341
if (semver.lt(frameworkVersion, "1.4.0")) {
341-
basicArgs.push("-xcconfig", path.join(projectRoot, projectData.projectName, "build.xcconfig"));
342+
basicArgs.push("-xcconfig", path.join(projectRoot, projectData.projectName, BUILD_XCCONFIG_FILE_NAME));
342343
}
343344

344345
// if (this.$logger.getLevel() === "INFO") {
@@ -1039,7 +1040,7 @@ We will now place an empty obsolete compatability white screen LauncScreen.xib f
10391040
}
10401041

10411042
private validateFramework(libraryPath: string): void {
1042-
const infoPlistPath = path.join(libraryPath, "Info.plist");
1043+
const infoPlistPath = path.join(libraryPath, constants.INFO_PLIST_FILE_NAME);
10431044
if (!this.$fs.exists(infoPlistPath)) {
10441045
this.$errors.failWithoutHelp("The bundle at %s does not contain an Info.plist file.", libraryPath);
10451046
}
@@ -1227,13 +1228,13 @@ We will now place an empty obsolete compatability white screen LauncScreen.xib f
12271228
const allPlugins: IPluginData[] = await (<IPluginsService>this.$injector.resolve("pluginsService")).getAllInstalledPlugins(projectData);
12281229
for (const plugin of allPlugins) {
12291230
const pluginPlatformsFolderPath = plugin.pluginPlatformsFolderPath(IOSProjectService.IOS_PLATFORM_NAME);
1230-
const pluginXcconfigFilePath = path.join(pluginPlatformsFolderPath, "build.xcconfig");
1231+
const pluginXcconfigFilePath = path.join(pluginPlatformsFolderPath, BUILD_XCCONFIG_FILE_NAME);
12311232
if (this.$fs.exists(pluginXcconfigFilePath)) {
12321233
await this.mergeXcconfigFiles(pluginXcconfigFilePath, pluginsXcconfigFilePath);
12331234
}
12341235
}
12351236

1236-
const appResourcesXcconfigPath = path.join(projectData.appResourcesDirectoryPath, this.getPlatformData(projectData).normalizedPlatformName, "build.xcconfig");
1237+
const appResourcesXcconfigPath = path.join(projectData.appResourcesDirectoryPath, this.getPlatformData(projectData).normalizedPlatformName, BUILD_XCCONFIG_FILE_NAME);
12371238
if (this.$fs.exists(appResourcesXcconfigPath)) {
12381239
await this.mergeXcconfigFiles(appResourcesXcconfigPath, pluginsXcconfigFilePath);
12391240
}
@@ -1289,7 +1290,7 @@ We will now place an empty obsolete compatability white screen LauncScreen.xib f
12891290

12901291
private getBuildXCConfigFilePath(projectData: IProjectData): string {
12911292
const buildXCConfig = path.join(projectData.appResourcesDirectoryPath,
1292-
this.getPlatformData(projectData).normalizedPlatformName, "build.xcconfig");
1293+
this.getPlatformData(projectData).normalizedPlatformName, BUILD_XCCONFIG_FILE_NAME);
12931294
return buildXCConfig;
12941295
}
12951296

@@ -1350,7 +1351,7 @@ We will now place an empty obsolete compatability white screen LauncScreen.xib f
13501351
const choicePersist = await this.$prompter.promptForChoice("Do you want to make teamId: " + teamId + " a persistent choice for your app?", choicesPersist);
13511352
switch (choicesPersist.indexOf(choicePersist)) {
13521353
case 0:
1353-
const xcconfigFile = path.join(projectData.appResourcesDirectoryPath, this.getPlatformData(projectData).normalizedPlatformName, "build.xcconfig");
1354+
const xcconfigFile = path.join(projectData.appResourcesDirectoryPath, this.getPlatformData(projectData).normalizedPlatformName, BUILD_XCCONFIG_FILE_NAME);
13541355
this.$fs.appendFile(xcconfigFile, "\nDEVELOPMENT_TEAM = " + teamId + "\n");
13551356
break;
13561357
case 1:

lib/services/itmstransporter-service.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as path from "path";
22
import * as temp from "temp";
33
import { EOL } from "os";
4-
import { ITMSConstants } from "../constants";
4+
import { ITMSConstants, INFO_PLIST_FILE_NAME } from "../constants";
55
import { ItunesConnectApplicationTypes } from "../constants";
66
import { quoteString, versionCompare } from "../common/helpers";
77

@@ -135,7 +135,7 @@ export class ITMSTransporterService implements IITMSTransporterService {
135135
}
136136
const appFile = path.join(payloadDir, allApps[0]);
137137

138-
const plistObject = await this.$bplistParser.parseFile(path.join(appFile, "Info.plist"));
138+
const plistObject = await this.$bplistParser.parseFile(path.join(appFile, INFO_PLIST_FILE_NAME));
139139
const bundleId = plistObject && plistObject[0] && plistObject[0].CFBundleIdentifier;
140140
if (!bundleId) {
141141
this.$errors.failWithoutHelp(`Unable to determine bundle identifier from ${ipaFileFullPath}.`);

lib/services/project-changes-service.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import * as path from "path";
2-
import { NODE_MODULES_FOLDER_NAME, NativePlatformStatus, PACKAGE_JSON_FILE_NAME } from "../constants";
2+
import { NODE_MODULES_FOLDER_NAME, NativePlatformStatus, PACKAGE_JSON_FILE_NAME, APP_GRADLE_FILE_NAME, BUILD_XCCONFIG_FILE_NAME } from "../constants";
33
import { getHash } from "../common/helpers";
44

55
const prepareInfoFileName = ".nsprepareinfo";
@@ -77,12 +77,12 @@ export class ProjectChangesService implements IProjectChangesService {
7777
if (platform === this.$devicePlatformsConstants.iOS.toLowerCase()) {
7878
this._changesInfo.configChanged = this.filesChanged([path.join(platformResourcesDir, platformData.configurationFileName),
7979
path.join(platformResourcesDir, "LaunchScreen.storyboard"),
80-
path.join(platformResourcesDir, "build.xcconfig")
80+
path.join(platformResourcesDir, BUILD_XCCONFIG_FILE_NAME)
8181
]);
8282
} else {
8383
this._changesInfo.configChanged = this.filesChanged([
8484
path.join(platformResourcesDir, platformData.configurationFileName),
85-
path.join(platformResourcesDir, "app.gradle")
85+
path.join(platformResourcesDir, APP_GRADLE_FILE_NAME)
8686
]);
8787
}
8888
}

test/ios-project-service.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import { NodePackageManager } from "../lib/node-package-manager";
3333
import { assert } from "chai";
3434
import { IOSProvisionService } from "../lib/services/ios-provision-service";
3535
import { SettingsService } from "../lib/common/test/unit-tests/stubs";
36+
import { BUILD_XCCONFIG_FILE_NAME } from "../lib/constants";
3637
import { ProjectDataStub } from "./stubs";
3738
import temp = require("temp");
3839

@@ -800,7 +801,7 @@ describe("Merge Project XCConfig files", () => {
800801

801802
iOSEntitlementsService = testInjector.resolve("iOSEntitlementsService");
802803

803-
appResourcesXcconfigPath = path.join(projectData.appResourcesDirectoryPath, "iOS", "build.xcconfig");
804+
appResourcesXcconfigPath = path.join(projectData.appResourcesDirectoryPath, "iOS", BUILD_XCCONFIG_FILE_NAME);
804805
appResourceXCConfigContent = `CODE_SIGN_IDENTITY = iPhone Distribution
805806
// To build for device with XCode 8 you need to specify your development team. More info: https://developer.apple.com/library/prerelease/content/releasenotes/DeveloperTools/RN-Xcode/Introduction.html
806807
// DEVELOPMENT_TEAM = YOUR_TEAM_ID;

test/platform-service.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import * as ChildProcessLib from "../lib/common/child-process";
2222
import ProjectChangesLib = require("../lib/services/project-changes-service");
2323
import { Messages } from "../lib/common/messages/messages";
2424
import { SettingsService } from "../lib/common/test/unit-tests/stubs";
25+
import { INFO_PLIST_FILE_NAME, MANIFEST_FILE_NAME } from "../lib/constants";
2526

2627
require("should");
2728
const temp = require("temp");
@@ -425,7 +426,7 @@ describe('Platform Service Tests', () => {
425426
appDestinationDirectoryPath: testDirData.appDestFolderPath,
426427
appResourcesDestinationDirectoryPath: testDirData.appResourcesFolderPath,
427428
normalizedPlatformName: platformToTest,
428-
configurationFileName: platformToTest === "ios" ? "Info.plist" : "AndroidManifest.xml",
429+
configurationFileName: platformToTest === "ios" ? INFO_PLIST_FILE_NAME : MANIFEST_FILE_NAME,
429430
projectRoot: testDirData.tempFolder,
430431
platformProjectService: {
431432
prepareProject: (): any => null,

test/plugin-variables-service.ts

+5
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { StaticConfig } from "../lib/config";
1212
import { MessagesService } from "../lib/common/services/messages-service";
1313
import { Yok } from '../lib/common/yok';
1414
import { SettingsService } from "../lib/common/test/unit-tests/stubs";
15+
import { DevicePlatformsConstants } from "../lib/common/mobile/device-platforms-constants";
1516
import * as stubs from './stubs';
1617
import * as path from "path";
1718
import * as temp from "temp";
@@ -39,6 +40,10 @@ function createTestInjector(): IInjector {
3940
});
4041
testInjector.register("staticConfig", StaticConfig);
4142
testInjector.register("settingsService", SettingsService);
43+
testInjector.register("devicePlatformsConstants", DevicePlatformsConstants);
44+
testInjector.register("androidResourcesMigrationService", {
45+
hasMigrated: () => true
46+
});
4247

4348
return testInjector;
4449
}

test/project-data.ts

+7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { ProjectData } from "../lib/project-data";
22
import { Yok } from "../lib/common/yok";
3+
import { DevicePlatformsConstants } from "../lib/common/mobile/device-platforms-constants";
34
import { assert } from "chai";
45
import * as stubs from "./stubs";
56
import * as path from "path";
@@ -30,6 +31,12 @@ describe("projectData", () => {
3031

3132
testInjector.register("options", {});
3233

34+
testInjector.register("devicePlatformsConstants", DevicePlatformsConstants);
35+
36+
testInjector.register("androidResourcesMigrationService", {
37+
hasMigrated: () => true
38+
});
39+
3340
testInjector.register("projectData", ProjectData);
3441

3542
return testInjector;

test/services/android-plugin-build-service.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { HostInfo } from "../../lib/common/host-info";
77
import { Logger } from "../../lib/common/logger";
88
import * as ErrorsLib from "../../lib/common/errors";
99
import temp = require("temp");
10+
import { INCLUDE_GRADLE_NAME } from "../../lib/constants";
1011
temp.track();
1112

1213
describe('androiPluginBuildService', () => {
@@ -65,7 +66,7 @@ dependencies {
6566
compile "com.android.support:design:$supportVersion"
6667
}`;
6768

68-
fs.writeFile(path.join(pluginFolder, "include.gradle"), validIncludeGradleContent);
69+
fs.writeFile(path.join(pluginFolder, INCLUDE_GRADLE_NAME), validIncludeGradleContent);
6970
}
7071

7172
function setUpPluginNativeFolder(manifestFile: boolean, resFolder: boolean, assetsFolder: boolean) {
@@ -196,7 +197,7 @@ dependencies {
196197
tempPluginDirPath: pluginFolder
197198
};
198199

199-
const includeGradleName = "include.gradle";
200+
const includeGradleName = INCLUDE_GRADLE_NAME;
200201
await androidBuildPluginService.migrateIncludeGradle(config);
201202
const includeGradleContent = fs.readText(path.join(pluginFolder, includeGradleName).toString());
202203
const productFlavorsAreRemoved = includeGradleContent.indexOf("productFlavors") === -1;

test/stubs.ts

+6
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,12 @@ export class ProjectDataStub implements IProjectData {
258258
devDependencies: IStringDictionary;
259259
projectType: string;
260260
appResourcesDirectoryPath: string;
261+
public androidManifestPath: string;
262+
public infoPlistPath: string;
263+
public appGradlePath: string;
264+
public gradleFilesDirectoryPath: string;
265+
public buildXcconfigPath: string;
266+
261267
public initializeProjectData(projectDir?: string): void {
262268
this.projectDir = this.projectDir || projectDir;
263269
}

0 commit comments

Comments
 (0)