4
4
import * as constants from "../constants" ;
5
5
import * as osenv from "osenv" ;
6
6
import * as path from "path" ;
7
- import * as shell from "shelljs" ;
7
+ import * as shelljs from "shelljs" ;
8
8
9
9
export class ProjectService implements IProjectService {
10
10
@@ -18,7 +18,7 @@ export class ProjectService implements IProjectService {
18
18
private $projectTemplatesService : IProjectTemplatesService ,
19
19
private $options : IOptions ) { }
20
20
21
- public createProject ( projectName : string ) : IFuture < void > {
21
+ public createProject ( projectName : string , selectedTemplate ?: string ) : IFuture < void > {
22
22
return ( ( ) => {
23
23
if ( ! projectName ) {
24
24
this . $errors . fail ( "You must specify <App name> when creating a new project." ) ;
@@ -51,7 +51,6 @@ export class ProjectService implements IProjectService {
51
51
52
52
let appDirectory = path . join ( projectDir , constants . APP_FOLDER_NAME ) ;
53
53
let appPath : string = null ;
54
-
55
54
if ( customAppPath ) {
56
55
this . $logger . trace ( "Using custom app from %s" , customAppPath ) ;
57
56
@@ -68,25 +67,77 @@ export class ProjectService implements IProjectService {
68
67
this . $logger . trace ( "Copying custom app into %s" , appDirectory ) ;
69
68
appPath = customAppPath ;
70
69
} else {
71
- // No custom app - use nativescript hello world application
72
- this . $logger . trace ( "Using NativeScript hello world application" ) ;
73
- let defaultTemplatePath = this . $projectTemplatesService . defaultTemplatePath . wait ( ) ;
74
- this . $logger . trace ( "Copying NativeScript hello world application into %s" , appDirectory ) ;
70
+ let defaultTemplatePath = this . $projectTemplatesService . prepareTemplate ( selectedTemplate ) . wait ( ) ;
71
+ this . $logger . trace ( `Copying application from '${ defaultTemplatePath } ' into '${ appDirectory } '.` ) ;
75
72
appPath = defaultTemplatePath ;
76
73
}
77
74
78
75
try {
79
76
this . createProjectCore ( projectDir , appPath , projectId ) . wait ( ) ;
77
+ //update dependencies and devDependencies of newly created project with data from template
78
+ this . mergeProjectAndTemplateProperties ( projectDir , appPath ) . wait ( ) ;
79
+ this . updateAppResourcesDir ( appDirectory ) . wait ( ) ;
80
+ // Delete app/package.json file, its just causing confusion.
81
+ // Also its dependencies and devDependencies are already merged in project's package.json.
82
+ this . $fs . deleteFile ( path . join ( projectDir , constants . APP_FOLDER_NAME , constants . PACKAGE_JSON_FILE_NAME ) ) . wait ( ) ;
83
+ this . $npm . install ( projectDir , projectDir , { "ignore-scripts" : this . $options . ignoreScripts } ) . wait ( ) ;
80
84
} catch ( err ) {
81
85
this . $fs . deleteDirectory ( projectDir ) . wait ( ) ;
82
86
throw err ;
83
87
}
84
-
85
88
this . $logger . out ( "Project %s was successfully created" , projectName ) ;
86
89
87
90
} ) . future < void > ( ) ( ) ;
88
91
}
89
92
93
+ private mergeProjectAndTemplateProperties ( projectDir : string , templatePath : string ) : IFuture < void > {
94
+ return ( ( ) => {
95
+ let templatePackageJsonPath = path . join ( templatePath , constants . PACKAGE_JSON_FILE_NAME ) ;
96
+ if ( this . $fs . exists ( templatePackageJsonPath ) . wait ( ) ) {
97
+ let projectPackageJsonPath = path . join ( projectDir , constants . PACKAGE_JSON_FILE_NAME ) ;
98
+ let projectPackageJsonData = this . $fs . readJson ( projectPackageJsonPath ) . wait ( ) ;
99
+ this . $logger . trace ( "Initial project package.json data: " , projectPackageJsonData ) ;
100
+ let templatePackageJsonData = this . $fs . readJson ( templatePackageJsonPath ) . wait ( ) ;
101
+ if ( projectPackageJsonData . dependencies || templatePackageJsonData . dependencies ) {
102
+ projectPackageJsonData . dependencies = this . mergeDependencies ( projectPackageJsonData . dependencies , templatePackageJsonData . dependencies ) ;
103
+ }
104
+
105
+ if ( projectPackageJsonData . devDependencies || templatePackageJsonData . devDependencies ) {
106
+ projectPackageJsonData . devDependencies = this . mergeDependencies ( projectPackageJsonData . devDependencies , templatePackageJsonData . devDependencies ) ;
107
+ }
108
+
109
+ this . $logger . trace ( "New project package.json data: " , projectPackageJsonData ) ;
110
+ this . $fs . writeJson ( projectPackageJsonPath , projectPackageJsonData ) . wait ( ) ;
111
+ } else {
112
+ this . $logger . trace ( `Template ${ templatePath } does not have ${ constants . PACKAGE_JSON_FILE_NAME } file.` ) ;
113
+ }
114
+ } ) . future < void > ( ) ( ) ;
115
+ }
116
+
117
+ private updateAppResourcesDir ( appDirectory : string ) : IFuture < void > {
118
+ return ( ( ) => {
119
+ let defaultAppResourcesDir = path . join ( this . $projectTemplatesService . defaultTemplatePath . wait ( ) , constants . APP_RESOURCES_FOLDER_NAME ) ;
120
+ let targetAppResourcesDir = path . join ( appDirectory , constants . APP_RESOURCES_FOLDER_NAME ) ;
121
+ this . $logger . trace ( `Updating AppResources values from ${ defaultAppResourcesDir } to ${ targetAppResourcesDir } ` ) ;
122
+ shelljs . cp ( "-R" , path . join ( defaultAppResourcesDir , "*" ) , targetAppResourcesDir ) ;
123
+ } ) . future < void > ( ) ( ) ;
124
+ }
125
+
126
+ private mergeDependencies ( projectDependencies : IStringDictionary , templateDependencies : IStringDictionary ) : IStringDictionary {
127
+ // Cast to any when logging as logger thinks it can print only string.
128
+ // Cannot use toString() because we want to print the whole objects, not [Object object]
129
+ this . $logger . trace ( "Merging dependencies, projectDependencies are: " , < any > projectDependencies , " templateDependencies are: " , < any > templateDependencies ) ;
130
+ projectDependencies = projectDependencies || { } ;
131
+ _ . extend ( projectDependencies , templateDependencies || { } ) ;
132
+ let sortedDeps : IStringDictionary = { } ;
133
+ let dependenciesNames = _ . keys ( projectDependencies ) . sort ( ) ;
134
+ _ . each ( dependenciesNames , ( key : string ) => {
135
+ sortedDeps [ key ] = projectDependencies [ key ] ;
136
+ } ) ;
137
+ this . $logger . trace ( "Sorted merged dependencies are: " , < any > sortedDeps ) ;
138
+ return sortedDeps ;
139
+ }
140
+
90
141
private createProjectCore ( projectDir : string , appSourcePath : string , projectId : string ) : IFuture < void > {
91
142
return ( ( ) => {
92
143
this . $fs . ensureDirectoryExists ( projectDir ) . wait ( ) ;
@@ -97,7 +148,7 @@ export class ProjectService implements IProjectService {
97
148
if ( this . $options . symlink ) {
98
149
this . $fs . symlink ( appSourcePath , appDestinationPath ) . wait ( ) ;
99
150
} else {
100
- shell . cp ( '-R' , path . join ( appSourcePath , "*" ) , appDestinationPath ) ;
151
+ shelljs . cp ( '-R' , path . join ( appSourcePath , "*" ) , appDestinationPath ) ;
101
152
}
102
153
103
154
this . createBasicProjectStructure ( projectDir , projectId ) . wait ( ) ;
0 commit comments