nativescript
Version:
Command-line interface for building NativeScript projects
195 lines • 9.69 kB
JavaScript
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ProjectService = void 0;
const constants = require("../constants");
const path = require("path");
const simple_git_1 = require("simple-git");
const decorators_1 = require("../common/decorators");
const constants_1 = require("../constants");
const decorators_2 = require("../common/decorators");
const yok_1 = require("../common/yok");
class ProjectService {
constructor($options, $hooksService, $packageManager, $errors, $fs, $logger, $pacoteService, $projectDataService, $projectConfigService, $projectHelper, $projectNameService, $projectTemplatesService, $tempService, $staticConfig, $childProcess) {
this.$options = $options;
this.$hooksService = $hooksService;
this.$packageManager = $packageManager;
this.$errors = $errors;
this.$fs = $fs;
this.$logger = $logger;
this.$pacoteService = $pacoteService;
this.$projectDataService = $projectDataService;
this.$projectConfigService = $projectConfigService;
this.$projectHelper = $projectHelper;
this.$projectNameService = $projectNameService;
this.$projectTemplatesService = $projectTemplatesService;
this.$tempService = $tempService;
this.$staticConfig = $staticConfig;
this.$childProcess = $childProcess;
}
async validateProjectName(opts) {
let projectName = opts.projectName;
if (!projectName) {
this.$errors.failWithHelp("You must specify <App name> when creating a new project.");
}
projectName = await this.$projectNameService.ensureValidName(projectName, {
force: opts.force,
});
const projectDir = this.getValidProjectDir(opts.pathToProject, projectName);
if (this.$fs.exists(projectDir) && !this.$fs.isEmptyDir(projectDir)) {
this.$errors.fail("Path already exists and is not empty %s", projectDir);
}
return projectName;
}
async createProject(projectOptions) {
const projectName = await this.validateProjectName({
projectName: projectOptions.projectName,
force: projectOptions.force,
pathToProject: projectOptions.pathToProject,
});
const projectDir = this.getValidProjectDir(projectOptions.pathToProject, projectName);
this.$fs.createDirectory(projectDir);
const appId = projectOptions.appId ||
this.$projectHelper.generateDefaultAppId(projectName, constants.DEFAULT_APP_IDENTIFIER_PREFIX);
this.$logger.trace(`Creating a new NativeScript project with name ${projectName} and id ${appId} at location ${projectDir}`);
const projectCreationData = await this.createProjectCore({
template: projectOptions.template,
projectDir,
ignoreScripts: projectOptions.ignoreScripts,
appId: appId,
projectName,
});
// can pass --no-git to skip creating a git repo
// useful in monorepos where we're creating
// sub projects in an existing git repo.
if (this.$options.git) {
try {
if (!this.$options.force) {
const git = (0, simple_git_1.default)(projectDir);
if (await git.checkIsRepo()) {
// throwing here since we're catching below.
throw new Error("Already part of a git repository.");
}
}
await this.$childProcess.exec(`git init ${projectDir}`);
await this.$childProcess.exec(`git -C ${projectDir} add --all`);
await this.$childProcess.exec(`git -C ${projectDir} commit --no-verify -m "init"`);
}
catch (err) {
this.$logger.trace("Unable to initialize git repository. Error is: ", err);
}
}
this.$logger.trace(`Project ${projectName} was successfully created.`);
return projectCreationData;
}
isValidNativeScriptProject(pathToProject) {
try {
const projectData = this.$projectDataService.getProjectData(pathToProject);
return (!!projectData &&
!!projectData.projectDir &&
!!(projectData.projectIdentifiers.ios &&
projectData.projectIdentifiers.android));
}
catch (e) {
return false;
}
}
getValidProjectDir(pathToProject, projectName) {
const selectedPath = path.resolve(pathToProject || ".");
const projectDir = path.join(selectedPath, projectName);
return projectDir;
}
async createProjectCore(projectCreationSettings) {
const { template, projectDir, appId, projectName, ignoreScripts, } = projectCreationSettings;
try {
const templateData = await this.$projectTemplatesService.prepareTemplate(template, projectDir);
await this.extractTemplate(projectDir, templateData);
this.alterPackageJsonData(projectCreationSettings);
this.$projectConfigService.writeDefaultConfig(projectDir, appId);
await this.ensureAppResourcesExist(projectDir);
// Install devDependencies and execute all scripts:
await this.$packageManager.install(projectDir, projectDir, {
disableNpmInstall: false,
frameworkPath: null,
ignoreScripts,
});
}
catch (err) {
this.$fs.deleteDirectory(projectDir);
throw err;
}
await this.$hooksService.executeAfterHooks(constants_1.Hooks.createProject, {
hookArgs: projectCreationSettings,
});
return { projectName, projectDir };
}
async extractTemplate(projectDir, templateData) {
this.$fs.ensureDirectoryExists(projectDir);
const fullTemplateName = templateData.version
? `${templateData.templateName}@${templateData.version}`
: templateData.templateName;
await this.$pacoteService.extractPackage(fullTemplateName, projectDir);
}
async ensureAppResourcesExist(projectDir) {
const projectData = this.$projectDataService.getProjectData(projectDir);
const appResourcesDestinationPath = projectData.getAppResourcesDirectoryPath(projectDir);
if (!this.$fs.exists(appResourcesDestinationPath)) {
this.$logger.trace("Project does not have App_Resources - fetching from default template.");
this.$fs.createDirectory(appResourcesDestinationPath);
const tempDir = await this.$tempService.mkdirSync("ns-default-template");
// the template installed doesn't have App_Resources -> get from a default template
await this.$pacoteService.extractPackage(constants.RESERVED_TEMPLATE_NAMES["default"], tempDir);
const templateProjectData = this.$projectDataService.getProjectData(tempDir);
const templateAppResourcesDir = templateProjectData.getAppResourcesDirectoryPath(tempDir);
this.$fs.copyFile(path.join(templateAppResourcesDir, "*"), appResourcesDestinationPath);
}
}
alterPackageJsonData(projectCreationSettings) {
const { projectDir, projectName } = projectCreationSettings;
const projectFilePath = path.join(projectDir, this.$staticConfig.PROJECT_FILE_NAME);
let packageJsonData = this.$fs.readJson(projectFilePath);
// clean up keys from the template package.json that we don't care about.
Object.keys(packageJsonData).forEach((key) => {
if (key.startsWith("_") ||
constants.TemplatesV2PackageJsonKeysToRemove.includes(key)) {
delete packageJsonData[key];
}
});
// this is used to ensure the order of keys is consistent, the blanks are filled in from the template
const packageJsonSchema = {
name: projectName,
main: "",
version: "1.0.0",
private: true,
dependencies: {},
devDependencies: {},
// anythign else would go below
};
packageJsonData = Object.assign(packageJsonSchema, packageJsonData);
this.$fs.writeJson(projectFilePath, packageJsonData);
}
}
exports.ProjectService = ProjectService;
__decorate([
(0, decorators_1.exported)("projectService"),
(0, decorators_2.performanceLog)()
], ProjectService.prototype, "createProject", null);
__decorate([
(0, decorators_1.exported)("projectService")
], ProjectService.prototype, "isValidNativeScriptProject", null);
__decorate([
(0, decorators_2.performanceLog)()
], ProjectService.prototype, "extractTemplate", null);
__decorate([
(0, decorators_2.performanceLog)()
], ProjectService.prototype, "ensureAppResourcesExist", null);
__decorate([
(0, decorators_2.performanceLog)()
], ProjectService.prototype, "alterPackageJsonData", null);
yok_1.injector.register("projectService", ProjectService);
//# sourceMappingURL=project-service.js.map