Skip to content

Commit 3fbf88b

Browse files
Fix isValidNativeScript project
The isValidNativeScript project method is used in Fusion. However the implementation is not correct. Fix it to have correct behavior. In order to fix it, modify projectData.initialize method - there's obsolete code for migration from .tnsproject to package.json - we do not need it anymore, so remove it. Also fix a case where failing builds do not fail the build process (incorrect argument passed to childProcess.spawnFromEvent). Update documentation for PublicAPI.
1 parent 7f5062f commit 3fbf88b

10 files changed

+101
-214
lines changed

PublicAPI.md

+26
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,32 @@ tns.projectService.createProject(projectSettings)
113113
</tr>
114114
</table>
115115

116+
* `isValidNativeScriptProject(projectDir: string): boolean` - Checks if the specified path is a valid NativeScript project. Returns `true` in case the directory is a valid project, `false` otherwise.
117+
118+
Sample usage:
119+
<table>
120+
<tr>
121+
<td>
122+
JavaScript
123+
</td>
124+
<td>
125+
TypeScript
126+
</td>
127+
</tr>
128+
<tr>
129+
<td>
130+
<pre lang="javascript">
131+
const isValidProject = tns.projectService.isValidNativeScriptProject("/tmp/myProject");
132+
</pre>
133+
</td>
134+
<td>
135+
<pre lang="typescript">
136+
const isValidProject = tns.projectService.isValidNativeScriptProject("/tmp/myProject");
137+
</pre>
138+
</td>
139+
</tr>
140+
</table>
141+
116142
## How to add a new method to Public API
117143
CLI is designed as command line tool and when it is used as a library, it does not give you access to all of the methods. This is mainly implementation detail. Most of the CLI's code is created to work in command line, not as a library, so before adding method to public API, most probably it will require some modification.
118144
For example the `$options` injected module contains information about all `--` options passed on the terminal. When the CLI is used as a library, the options are not populated. Before adding method to public API, make sure its implementation does not rely on `$options`.

lib/constants.ts

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export const TESTING_FRAMEWORKS = ['jasmine', 'mocha', 'qunit'];
1515
export const TEST_RUNNER_NAME = "nativescript-unit-test-runner";
1616
export const LIVESYNC_EXCLUDED_FILE_PATTERNS = ["**/*.js.map", "**/*.ts"];
1717
export const XML_FILE_EXTENSION = ".xml";
18+
export const PLATFORMS_DIR_NAME = "platforms";
1819

1920
export class PackageVersion {
2021
static NEXT = "next";

lib/project-data.ts

+18-61
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@ interface IProjectType {
99
}
1010

1111
export class ProjectData implements IProjectData {
12-
private static OLD_PROJECT_FILE_NAME = ".tnsproject";
13-
1412
/**
1513
* NOTE: Order of the elements is important as the TypeScript dependencies are commonly included in Angular project as well.
1614
*/
@@ -42,45 +40,48 @@ export class ProjectData implements IProjectData {
4240

4341
constructor(private $fs: IFileSystem,
4442
private $errors: IErrors,
45-
private $logger: ILogger,
4643
private $projectHelper: IProjectHelper,
4744
private $staticConfig: IStaticConfig,
4845
private $options: IOptions) { }
4946

50-
public initializeProjectData(projectDir? :string): void {
47+
public initializeProjectData(projectDir?: string): void {
5148
projectDir = projectDir || this.$projectHelper.projectDir;
5249
// If no project found, projectDir should be null
5350
if (projectDir) {
54-
this.initializeProjectDataCore(projectDir);
51+
const projectFilePath = path.join(projectDir, this.$staticConfig.PROJECT_FILE_NAME);
5552
let data: any = null;
5653

57-
if (this.$fs.exists(this.projectFilePath)) {
54+
if (projectFilePath) {
5855
let fileContent: any = null;
5956
try {
60-
fileContent = this.$fs.readJson(this.projectFilePath);
57+
fileContent = this.$fs.readJson(projectFilePath);
6158
data = fileContent[this.$staticConfig.CLIENT_NAME_KEY_IN_PROJECT_FILE];
6259
} catch (err) {
63-
this.$errors.fail({
64-
formatStr: "The project file %s is corrupted." + EOL +
60+
this.$errors.failWithoutHelp(
61+
`The project file ${this.projectFilePath} is corrupted.` + EOL +
6562
"Consider restoring an earlier version from your source control or backup." + EOL +
66-
"Additional technical info: %s",
67-
suppressCommandHelp: true
68-
},
69-
this.projectFilePath, err.toString());
63+
`Additional technical info: ${err.toString()}`);
7064
}
7165

7266
if (data) {
67+
this.projectDir = projectDir;
68+
this.projectName = this.$projectHelper.sanitizeName(path.basename(projectDir));
69+
this.platformsDir = path.join(projectDir, constants.PLATFORMS_DIR_NAME);
70+
this.projectFilePath = projectFilePath;
71+
this.appDirectoryPath = path.join(projectDir, constants.APP_FOLDER_NAME);
72+
this.appResourcesDirectoryPath = path.join(projectDir, constants.APP_FOLDER_NAME, constants.APP_RESOURCES_FOLDER_NAME);
7373
this.projectId = data.id;
7474
this.dependencies = fileContent.dependencies;
7575
this.devDependencies = fileContent.devDependencies;
7676
this.projectType = this.getProjectType();
77-
} else { // This is the case when we have package.json file but nativescipt key is not presented in it
78-
this.tryToUpgradeProject();
77+
78+
return;
7979
}
8080
}
81-
} else { // This is the case when no project file found
82-
this.tryToUpgradeProject();
8381
}
82+
83+
// This is the case when no project file found
84+
this.$errors.fail("No project found at or above '%s' and neither was a --path specified.", projectDir || this.$options.path || path.resolve("."));
8485
}
8586

8687
private getProjectType(): string {
@@ -97,49 +98,5 @@ export class ProjectData implements IProjectData {
9798

9899
return detectedProjectType;
99100
}
100-
101-
private throwNoProjectFoundError(): void {
102-
this.$errors.fail("No project found at or above '%s' and neither was a --path specified.", this.$options.path || path.resolve("."));
103-
}
104-
105-
private tryToUpgradeProject(): void {
106-
let projectDir = this.projectDir || path.resolve(this.$options.path || ".");
107-
let oldProjectFilePath = path.join(projectDir, ProjectData.OLD_PROJECT_FILE_NAME);
108-
if (this.$fs.exists(oldProjectFilePath)) {
109-
this.upgrade(projectDir, oldProjectFilePath);
110-
} else {
111-
this.throwNoProjectFoundError();
112-
}
113-
}
114-
115-
private upgrade(projectDir: string, oldProjectFilePath: string): void {
116-
try {
117-
let oldProjectData = this.$fs.readJson(oldProjectFilePath);
118-
119-
let newProjectFilePath = this.projectFilePath || path.join(projectDir, this.$staticConfig.PROJECT_FILE_NAME);
120-
let newProjectData = this.$fs.exists(newProjectFilePath) ? this.$fs.readJson(newProjectFilePath) : {};
121-
newProjectData[this.$staticConfig.CLIENT_NAME_KEY_IN_PROJECT_FILE] = oldProjectData;
122-
this.$fs.writeJson(newProjectFilePath, newProjectData);
123-
this.projectId = newProjectData[this.$staticConfig.CLIENT_NAME_KEY_IN_PROJECT_FILE].id;
124-
125-
this.$fs.deleteFile(oldProjectFilePath);
126-
} catch (err) {
127-
this.$logger.out("An error occurred while upgrading your project.");
128-
throw err;
129-
}
130-
131-
this.initializeProjectDataCore(projectDir);
132-
133-
this.$logger.out("Successfully upgraded your project file.");
134-
}
135-
136-
private initializeProjectDataCore(projectDir: string): void {
137-
this.projectDir = projectDir;
138-
this.projectName = this.$projectHelper.sanitizeName(path.basename(projectDir));
139-
this.platformsDir = path.join(projectDir, "platforms");
140-
this.projectFilePath = path.join(projectDir, this.$staticConfig.PROJECT_FILE_NAME);
141-
this.appDirectoryPath = path.join(projectDir, constants.APP_FOLDER_NAME);
142-
this.appResourcesDirectoryPath = path.join(projectDir, constants.APP_FOLDER_NAME, constants.APP_RESOURCES_FOLDER_NAME);
143-
}
144101
}
145102
$injector.register("projectData", ProjectData);

lib/services/android-project-service.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
262262
await this.spawn(gradleBin,
263263
buildOptions,
264264
{ stdio: buildConfig.buildOutputStdio || "inherit", cwd: this.getPlatformData(projectData).projectRoot },
265-
{ emitOptions: { eventName: constants.BUILD_OUTPUT_EVENT_NAME }, throwError: false });
265+
{ emitOptions: { eventName: constants.BUILD_OUTPUT_EVENT_NAME }, throwError: true });
266266
} else {
267267
this.$errors.failWithoutHelp("Cannot complete build because this project is ANT-based." + EOL +
268268
"Run `tns platform remove android && tns platform add android` to switch to Gradle and try again.");

lib/services/ios-project-service.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
339339
args,
340340
"exit",
341341
{ stdio: buildConfig.buildOutputStdio || "inherit", cwd: this.getPlatformData(projectData).projectRoot },
342-
{ emitOptions: { eventName: constants.BUILD_OUTPUT_EVENT_NAME }, throwError: false });
342+
{ emitOptions: { eventName: constants.BUILD_OUTPUT_EVENT_NAME }, throwError: true });
343343
// this.$logger.out("xcodebuild build succeded.");
344344

345345
await this.createIpa(projectRoot, projectData, buildConfig.buildOutputStdio);

lib/services/project-service.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,10 @@ export class ProjectService implements IProjectService {
7373
public isValidNativeScriptProject(pathToProject?: string): boolean {
7474
try {
7575
this.$projectData.initializeProjectData(pathToProject);
76+
return !!this.$projectData.projectDir && !!this.$projectData.projectId;
7677
} catch (e) {
7778
return false;
7879
}
79-
80-
return true;
8180
}
8281

8382
private getDataFromJson(templatePath: string): any {

test/nativescript-cli-lib.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ describe("nativescript-cli-lib", () => {
1414

1515
const publicApi: any = {
1616
deviceEmitter: null,
17-
projectService: ["createProject"],
17+
projectService: ["createProject", "isValidNativeScriptProject"],
1818
localBuildService: ["build"]
1919

2020
};

test/project-data.ts

-2
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@ describe("projectData", () => {
2525

2626
testInjector.register("errors", stubs.ErrorsStub);
2727

28-
testInjector.register("logger", stubs.LoggerStub);
29-
3028
testInjector.register("options", {});
3129

3230
testInjector.register("projectData", ProjectData);

0 commit comments

Comments
 (0)