Skip to content

Commit 8c302a3

Browse files
committed
feat(nsconfig): read app folder path from nsconfig
1 parent b9890bf commit 8c302a3

17 files changed

+156
-61
lines changed

lib/bootstrap.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ $injector.require("options", "./options");
66
$injector.require("nativescript-cli", "./nativescript-cli");
77

88
$injector.require("projectData", "./project-data");
9-
$injector.require("projectDataService", "./services/project-data-service");
9+
$injector.requirePublic("projectDataService", "./services/project-data-service");
1010
$injector.requirePublic("projectService", "./services/project-service");
1111
$injector.require("androidProjectService", "./services/android-project-service");
1212
$injector.require("iOSEntitlementsService", "./services/ios-entitlements-service");

lib/commands/test-init.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ class TestInitCommand implements ICommand {
6868

6969
await this.$pluginsService.add('nativescript-unit-test-runner', this.$projectData);
7070

71-
const testsDir = path.join(projectDir, 'app/tests');
71+
const testsDir = path.join(this.$projectData.appDirectoryPath, 'tests');
7272
let shouldCreateSampleTests = true;
7373
if (this.$fs.exists(testsDir)) {
7474
this.$logger.info('app/tests/ directory already exists, will not create an example test project.');

lib/common

lib/constants.ts

+1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ export const APK_DIR = "apk";
3030
export const RESOURCES_DIR = "res";
3131
export const CONFIG_NS_FILE_NAME = "nsconfig.json";
3232
export const CONFIG_NS_APP_RESOURCES_ENTRY = "appResourcesPath";
33+
export const CONFIG_NS_APP_ENTRY = "appPath";
3334

3435
export class PackageVersion {
3536
static NEXT = "next";

lib/definitions/project.d.ts

+5
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,18 @@ interface IProjectData extends IProjectDir {
6363
appDirectoryPath: string;
6464
appResourcesDirectoryPath: string;
6565
projectType: string;
66+
nsConfig: any;
6667
/**
6768
* Initializes project data with the given project directory. If none supplied defaults to --path option or cwd.
6869
* @param {string} projectDir Project root directory.
6970
* @returns {void}
7071
*/
7172
initializeProjectData(projectDir?: string): void;
73+
initializeProjectDataFromContent(packageJsonContent: string, nsconfigContent: string, projectDir?: string): void;
74+
getAppDirectoryPath(projectDir?: string): string;
75+
getAppDirectoryRelativePath(): string;
7276
getAppResourcesDirectoryPath(projectDir?: string): string;
77+
getAppResourcesRelativeDirectoryPath(): string;
7378
}
7479

7580
interface IProjectDataService {

lib/project-data.ts

+97-39
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import * as constants from "./constants";
22
import * as path from "path";
3+
import { parseJson } from "./common/helpers";
34
import { EOL } from "os";
45

56
interface IProjectType {
@@ -32,10 +33,9 @@ export class ProjectData implements IProjectData {
3233
public projectFilePath: string;
3334
public projectId: string;
3435
public projectName: string;
36+
public nsConfig: any;
3537
public appDirectoryPath: string;
36-
get appResourcesDirectoryPath(): string {
37-
return this.getAppResourcesDirectoryPath();
38-
}
38+
public appResourcesDirectoryPath: string;
3939
public dependencies: any;
4040
public devDependencies: IStringDictionary;
4141
public projectType: string;
@@ -49,45 +49,81 @@ export class ProjectData implements IProjectData {
4949

5050
public initializeProjectData(projectDir?: string): void {
5151
projectDir = projectDir || this.$projectHelper.projectDir;
52+
5253
// If no project found, projectDir should be null
5354
if (projectDir) {
54-
const projectFilePath = path.join(projectDir, this.$staticConfig.PROJECT_FILE_NAME);
55-
let data: any = null;
55+
const projectFilePath = this.getProjectFilePath(projectDir);
5656

5757
if (this.$fs.exists(projectFilePath)) {
58-
let fileContent: any = null;
59-
try {
60-
fileContent = this.$fs.readJson(projectFilePath);
61-
data = fileContent[this.$staticConfig.CLIENT_NAME_KEY_IN_PROJECT_FILE];
62-
} catch (err) {
63-
this.$errors.failWithoutHelp(`The project file ${this.projectFilePath} is corrupted. ${EOL}` +
64-
`Consider restoring an earlier version from your source control or backup.${EOL}` +
65-
`Additional technical info: ${err.toString()}`);
66-
}
67-
68-
if (data) {
69-
this.projectDir = projectDir;
70-
this.projectName = this.$projectHelper.sanitizeName(path.basename(projectDir));
71-
this.platformsDir = path.join(projectDir, constants.PLATFORMS_DIR_NAME);
72-
this.projectFilePath = projectFilePath;
73-
this.appDirectoryPath = path.join(projectDir, constants.APP_FOLDER_NAME);
74-
this.projectId = data.id;
75-
this.dependencies = fileContent.dependencies;
76-
this.devDependencies = fileContent.devDependencies;
77-
this.projectType = this.getProjectType();
78-
79-
return;
80-
}
58+
let packageJsonContent: any = null;
59+
packageJsonContent = this.$fs.readText(projectFilePath);
60+
const nsConfigContent: any = this.getNsConfigContent(projectDir);
61+
62+
this.initializeProjectDataFromContent(packageJsonContent, nsConfigContent, projectDir);
8163
}
64+
65+
return;
66+
}
67+
68+
this.errorInvalidProject(projectDir);
69+
}
70+
71+
public initializeProjectDataFromContent(packageJsonContent: string, nsconfigContent: string, projectDir?: string): void {
72+
projectDir = projectDir || this.$projectHelper.projectDir || "";
73+
const projectFilePath = this.getProjectFilePath(projectDir);
74+
// If no project found, projectDir should be null
75+
let nsData: any = null;
76+
let nsConfig: any = null;
77+
let packageJsonData: any = null;
78+
79+
try {
80+
packageJsonData = parseJson(packageJsonContent);
81+
nsData = packageJsonData[this.$staticConfig.CLIENT_NAME_KEY_IN_PROJECT_FILE];
82+
} catch (err) {
83+
this.$errors.failWithoutHelp(`The project file ${this.projectFilePath} is corrupted. ${EOL}` +
84+
`Consider restoring an earlier version from your source control or backup.${EOL}` +
85+
`Additional technical info: ${err.toString()}`);
8286
}
8387

88+
try {
89+
nsConfig = nsconfigContent ? parseJson(nsconfigContent) : null;
90+
} catch (err) {
91+
this.$errors.failWithoutHelp(`The NativeScript configuration file ${constants.CONFIG_NS_FILE_NAME} is corrupted. ${EOL}` +
92+
`Consider restoring an earlier version from your source control or backup.${EOL}` +
93+
`Additional technical info: ${err.toString()}`);
94+
}
95+
96+
if (nsData) {
97+
this.projectDir = projectDir;
98+
this.projectName = this.$projectHelper.sanitizeName(path.basename(projectDir));
99+
this.platformsDir = path.join(projectDir, constants.PLATFORMS_DIR_NAME);
100+
this.projectFilePath = projectFilePath;
101+
this.projectId = nsData.id;
102+
this.dependencies = packageJsonData.dependencies;
103+
this.devDependencies = packageJsonData.devDependencies;
104+
this.projectType = this.getProjectType();
105+
this.nsConfig = nsConfig;
106+
this.appDirectoryPath = this.getAppDirectoryPath();
107+
this.appResourcesDirectoryPath = this.getAppResourcesDirectoryPath();
108+
109+
return;
110+
}
111+
112+
this.errorInvalidProject(projectDir);
113+
}
114+
115+
private errorInvalidProject(projectDir: string): void {
84116
const currentDir = path.resolve(".");
85117
this.$logger.trace(`Unable to find project. projectDir: ${projectDir}, options.path: ${this.$options.path}, ${currentDir}`);
86118

87119
// This is the case when no project file found
88120
this.$errors.fail("No project found at or above '%s' and neither was a --path specified.", projectDir || this.$options.path || currentDir);
89121
}
90122

123+
private getProjectFilePath(projectDir: string): string {
124+
return path.join(projectDir, this.$staticConfig.PROJECT_FILE_NAME);
125+
}
126+
91127
public getAppResourcesDirectoryPath(projectDir?: string): string {
92128
if (!projectDir) {
93129
projectDir = this.projectDir;
@@ -97,23 +133,45 @@ export class ProjectData implements IProjectData {
97133
return null;
98134
}
99135

100-
const configNSFilePath = path.join(projectDir, constants.CONFIG_NS_FILE_NAME);
101-
let absoluteAppResourcesDirPath: string;
136+
return path.resolve(projectDir, this.getAppResourcesRelativeDirectoryPath());
137+
}
102138

103-
if (this.$fs.exists(configNSFilePath)) {
104-
const configNS = this.$fs.readJson(configNSFilePath);
139+
public getAppResourcesRelativeDirectoryPath(): string {
140+
if (this.nsConfig && this.nsConfig[constants.CONFIG_NS_APP_RESOURCES_ENTRY]) {
141+
return this.nsConfig[constants.CONFIG_NS_APP_RESOURCES_ENTRY];
142+
}
143+
144+
return path.join(this.getAppDirectoryRelativePath(), constants.APP_RESOURCES_FOLDER_NAME);
145+
}
105146

106-
if (configNS && configNS[constants.CONFIG_NS_APP_RESOURCES_ENTRY]) {
107-
const appResourcesDirPath = configNS[constants.CONFIG_NS_APP_RESOURCES_ENTRY];
147+
public getAppDirectoryPath(projectDir?: string): string {
148+
if (!projectDir) {
149+
projectDir = this.projectDir;
150+
}
108151

109-
absoluteAppResourcesDirPath = path.resolve(projectDir, appResourcesDirPath);
152+
if (!projectDir) {
153+
return null;
154+
}
110155

111-
return absoluteAppResourcesDirPath;
112-
}
156+
return path.resolve(projectDir, this.getAppDirectoryRelativePath());
157+
}
158+
159+
public getAppDirectoryRelativePath(): string {
160+
if (this.nsConfig && this.nsConfig[constants.CONFIG_NS_APP_ENTRY]) {
161+
return this.nsConfig[constants.CONFIG_NS_APP_ENTRY];
162+
}
163+
164+
return constants.APP_FOLDER_NAME;
165+
}
166+
167+
private getNsConfigContent(projectDir: string): string {
168+
const configNSFilePath = path.join(projectDir, constants.CONFIG_NS_FILE_NAME);
169+
170+
if (!this.$fs.exists(configNSFilePath)) {
171+
return null;
113172
}
114173

115-
// if no nsconfig is present default to app/App_Resources
116-
return path.join(projectDir, constants.APP_FOLDER_NAME, constants.APP_RESOURCES_FOLDER_NAME);
174+
return this.$fs.readText(configNSFilePath);
117175
}
118176

119177
private getProjectType(): string {

lib/providers/project-files-provider.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,13 @@ export class ProjectFilesProvider extends ProjectFilesProviderBase {
1616
const platformData = this.$platformsData.getPlatformData(platform.toLowerCase(), projectData);
1717
const parsedFilePath = this.getPreparedFilePath(filePath, projectFilesConfig);
1818
let mappedFilePath = "";
19+
let relativePath;
1920
if (parsedFilePath.indexOf(constants.NODE_MODULES_FOLDER_NAME) > -1) {
20-
const relativePath = path.relative(path.join(projectData.projectDir, constants.NODE_MODULES_FOLDER_NAME), parsedFilePath);
21+
relativePath = path.relative(path.join(projectData.projectDir, constants.NODE_MODULES_FOLDER_NAME), parsedFilePath);
2122
mappedFilePath = path.join(platformData.appDestinationDirectoryPath, constants.APP_FOLDER_NAME, constants.TNS_MODULES_FOLDER_NAME, relativePath);
2223
} else {
23-
mappedFilePath = path.join(platformData.appDestinationDirectoryPath, path.relative(projectData.projectDir, parsedFilePath));
24+
relativePath = path.relative(projectData.appDirectoryPath, parsedFilePath);
25+
mappedFilePath = path.join(platformData.appDestinationDirectoryPath, constants.APP_FOLDER_NAME, relativePath);
2426
}
2527

2628
const appResourcesDirectoryPath = projectData.appResourcesDirectoryPath;

lib/services/livesync/livesync-service.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import * as choki from "chokidar";
33
import { EOL } from "os";
44
import { EventEmitter } from "events";
55
import { hook } from "../../common/helpers";
6-
import { APP_FOLDER_NAME, PACKAGE_JSON_FILE_NAME, LiveSyncTrackActionNames, USER_INTERACTION_NEEDED_EVENT_NAME, DEBUGGER_ATTACHED_EVENT_NAME, DEBUGGER_DETACHED_EVENT_NAME, TrackActionNames } from "../../constants";
6+
import { PACKAGE_JSON_FILE_NAME, LiveSyncTrackActionNames, USER_INTERACTION_NEEDED_EVENT_NAME, DEBUGGER_ATTACHED_EVENT_NAME, DEBUGGER_DETACHED_EVENT_NAME, TrackActionNames } from "../../constants";
77
import { FileExtensions, DeviceTypes, DeviceDiscoveryEventNames } from "../../common/constants";
88
import { cache } from "../../common/decorators";
99

@@ -515,7 +515,7 @@ export class LiveSyncService extends EventEmitter implements IDebugLiveSyncServi
515515
}
516516

517517
private async startWatcher(projectData: IProjectData, liveSyncData: ILiveSyncInfo): Promise<void> {
518-
const patterns = [APP_FOLDER_NAME];
518+
const patterns = [path.relative(projectData.projectDir, projectData.appDirectoryPath)];
519519

520520
if (liveSyncData.watchAllFiles) {
521521
const productionDependencies = this.$nodeModulesDependenciesBuilder.getProductionDependencies(projectData.projectDir);

lib/services/platform-service.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -571,10 +571,9 @@ export class PlatformService extends EventEmitter implements IPlatformService {
571571
public async cleanDestinationApp(platformInfo: IPreparePlatformInfo): Promise<void> {
572572
await this.ensurePlatformInstalled(platformInfo.platform, platformInfo.platformTemplate, platformInfo.projectData, platformInfo.config);
573573

574-
const appSourceDirectoryPath = path.join(platformInfo.projectData.projectDir, constants.APP_FOLDER_NAME);
575574
const platformData = this.$platformsData.getPlatformData(platformInfo.platform, platformInfo.projectData);
576575
const appDestinationDirectoryPath = path.join(platformData.appDestinationDirectoryPath, constants.APP_FOLDER_NAME);
577-
const appUpdater = new AppFilesUpdater(appSourceDirectoryPath, appDestinationDirectoryPath, platformInfo.appFilesUpdaterOptions, this.$fs);
576+
const appUpdater = new AppFilesUpdater(platformInfo.projectData.appDirectoryPath, appDestinationDirectoryPath, platformInfo.appFilesUpdaterOptions, this.$fs);
578577
appUpdater.cleanDestinationApp();
579578
}
580579

lib/services/prepare-platform-service.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,8 @@ export class PreparePlatformService {
2020

2121
// Copy app folder to native project
2222
this.$fs.ensureDirectoryExists(appDestinationDirectoryPath);
23-
const appSourceDirectoryPath = path.join(copyAppFilesData.projectData.projectDir, constants.APP_FOLDER_NAME);
2423

25-
const appUpdater = new AppFilesUpdater(appSourceDirectoryPath, appDestinationDirectoryPath, copyAppFilesData.appFilesUpdaterOptions, this.$fs);
24+
const appUpdater = new AppFilesUpdater(copyAppFilesData.projectData.appDirectoryPath, appDestinationDirectoryPath, copyAppFilesData.appFilesUpdaterOptions, this.$fs);
2625
appUpdater.updateApp(sourceFiles => {
2726
this.$xmlValidator.validateXmlFiles(sourceFiles);
2827
}, copyAppFilesData.projectData, copyAppFilesData.filesToSync);

lib/services/project-data-service.ts

+8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import * as path from "path";
22
import { ProjectData } from "../project-data";
3+
import { exported } from "../common/decorators";
34

45
interface IProjectFileData {
56
projectData: any;
@@ -41,6 +42,13 @@ export class ProjectDataService implements IProjectDataService {
4142
return projectDataInstance;
4243
}
4344

45+
@exported("projectDataService")
46+
public getProjectDataFromContent(packageJsonContent: string, nsconfigContent: string, projectDir?: string): IProjectData {
47+
const projectDataInstance = this.$injector.resolve<IProjectData>(ProjectData);
48+
projectDataInstance.initializeProjectDataFromContent(packageJsonContent, nsconfigContent, projectDir);
49+
return projectDataInstance;
50+
}
51+
4452
private getValue(projectDir: string, propertyName: string): any {
4553
const projectData = this.getProjectFileData(projectDir).projectData;
4654

lib/services/project-service.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ export class ProjectService implements IProjectService {
101101
private async extractTemplate(projectDir: string, realTemplatePath: string): Promise<void> {
102102
this.$fs.ensureDirectoryExists(projectDir);
103103

104-
const appDestinationPath = path.join(projectDir, constants.APP_FOLDER_NAME);
104+
const appDestinationPath = this.$projectData.getAppDirectoryPath(projectDir);
105105
this.$fs.createDirectory(appDestinationPath);
106106

107107
this.$logger.trace(`Copying application from '${realTemplatePath}' into '${appDestinationPath}'.`);
@@ -111,7 +111,7 @@ export class ProjectService implements IProjectService {
111111
}
112112

113113
private async ensureAppResourcesExist(projectDir: string): Promise<void> {
114-
const appPath = path.join(projectDir, constants.APP_FOLDER_NAME),
114+
const appPath = this.$projectData.getAppDirectoryPath(projectDir),
115115
appResourcesDestinationPath = this.$projectData.getAppResourcesDirectoryPath(projectDir);
116116

117117
if (!this.$fs.exists(appResourcesDestinationPath)) {
@@ -138,7 +138,7 @@ export class ProjectService implements IProjectService {
138138
}
139139

140140
private removeMergedDependencies(projectDir: string, templatePackageJsonData: any): void {
141-
const extractedTemplatePackageJsonPath = path.join(projectDir, constants.APP_FOLDER_NAME, constants.PACKAGE_JSON_FILE_NAME);
141+
const extractedTemplatePackageJsonPath = path.join(this.$projectData.getAppDirectoryPath(projectDir), constants.PACKAGE_JSON_FILE_NAME);
142142
for (const key in templatePackageJsonData) {
143143
if (constants.PackageJsonKeysToKeep.indexOf(key) === -1) {
144144
delete templatePackageJsonData[key];

test/ios-entitlements-service.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,13 @@ describe("IOSEntitlements Service Tests", () => {
4747
injector = createTestInjector();
4848

4949
platformsData = injector.resolve("platformsData");
50-
projectData = $injector.resolve<IProjectData>("projectData");
50+
projectData = injector.resolve("projectData");
5151
projectData.projectName = 'testApp';
5252

5353
projectData.platformsDir = temp.mkdirSync("platformsDir");
5454
projectData.projectDir = temp.mkdirSync("projectDir");
55+
projectData.appDirectoryPath = projectData.getAppDirectoryPath();
56+
projectData.appResourcesDirectoryPath = projectData.getAppResourcesDirectoryPath();
5557

5658
fs = injector.resolve("$fs");
5759

test/platform-service.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -454,8 +454,9 @@ describe('Platform Service Tests', () => {
454454

455455
const projectData = testInjector.resolve("projectData");
456456
projectData.projectDir = testDirData.tempFolder;
457-
projectData.appDirectoryPath = testDirData.appFolderPath;
458457
projectData.projectName = "app";
458+
projectData.appDirectoryPath = testDirData.appFolderPath;
459+
projectData.appResourcesDirectoryPath = path.join(testDirData.appFolderPath, "App_Resources");
459460

460461
platformService = testInjector.resolve("platformService");
461462
const appFilesUpdaterOptions: IAppFilesUpdaterOptions = { bundle: false, release: release };
@@ -887,6 +888,8 @@ describe('Platform Service Tests', () => {
887888

888889
const projectData = testInjector.resolve("projectData");
889890
projectData.projectDir = testDirData.tempFolder;
891+
projectData.appDirectoryPath = projectData.getAppDirectoryPath();
892+
projectData.appResourcesDirectoryPath = projectData.getAppResourcesDirectoryPath();
890893

891894
platformService = testInjector.resolve("platformService");
892895
const oldLoggerWarner = testInjector.resolve("$logger").warn;

test/project-data.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ describe("projectData", () => {
1515

1616
testInjector.register("fs", {
1717
exists: () => true,
18-
readJson: (): any => null
18+
readJson: (): any => null,
19+
readText: (): any => null
1920
});
2021

2122
testInjector.register("staticConfig", {
@@ -41,11 +42,11 @@ describe("projectData", () => {
4142
const fs = testInjector.resolve("fs");
4243
fs.exists = (filePath: string) => filePath && path.basename(filePath) === "package.json";
4344

44-
fs.readJson = () => ({
45+
fs.readText = () => (JSON.stringify({
4546
nativescript: {},
4647
dependencies: dependencies,
4748
devDependencies: devDependencies
48-
});
49+
}));
4950

5051
const projectHelper: IProjectHelper = testInjector.resolve("projectHelper");
5152
projectHelper.projectDir = "projectDir";

0 commit comments

Comments
 (0)