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,71 @@ 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 ( ) ;
80
83
} catch ( err ) {
81
84
this . $fs . deleteDirectory ( projectDir ) . wait ( ) ;
82
85
throw err ;
83
86
}
84
-
85
87
this . $logger . out ( "Project %s was successfully created" , projectName ) ;
86
88
87
89
} ) . future < void > ( ) ( ) ;
88
90
}
89
91
92
+ private mergeProjectAndTemplateProperties ( projectDir : string , templatePath : string ) : IFuture < void > {
93
+ return ( ( ) => {
94
+ let projectPackageJsonPath = path . join ( projectDir , constants . PACKAGE_JSON_FILE_NAME ) ;
95
+ let projectPackageJsonData = this . $fs . readJson ( projectPackageJsonPath ) . wait ( ) ;
96
+ this . $logger . trace ( "Initial project package.json data: " , projectPackageJsonData ) ;
97
+ let templatePackageJsonData = this . $fs . readJson ( path . join ( templatePath , constants . PACKAGE_JSON_FILE_NAME ) ) . wait ( ) ;
98
+ if ( projectPackageJsonData . dependencies || templatePackageJsonData . dependencies ) {
99
+ projectPackageJsonData . dependencies = this . mergeDependencies ( projectPackageJsonData . dependencies , templatePackageJsonData . dependencies ) ;
100
+ }
101
+
102
+ if ( projectPackageJsonData . devDependencies || templatePackageJsonData . devDependencies ) {
103
+ projectPackageJsonData . devDependencies = this . mergeDependencies ( projectPackageJsonData . devDependencies , templatePackageJsonData . devDependencies ) ;
104
+ }
105
+
106
+ this . $logger . trace ( "New project package.json data: " , projectPackageJsonData ) ;
107
+ this . $fs . writeJson ( projectPackageJsonPath , projectPackageJsonData ) . wait ( ) ;
108
+ } ) . future < void > ( ) ( ) ;
109
+ }
110
+
111
+ private updateAppResourcesDir ( appDirectory : string ) : IFuture < void > {
112
+ return ( ( ) => {
113
+ let defaultAppResourcesDir = path . join ( this . $projectTemplatesService . defaultTemplatePath . wait ( ) , constants . APP_RESOURCES_FOLDER_NAME ) ;
114
+ let targetAppResourcesDir = path . join ( appDirectory , constants . APP_RESOURCES_FOLDER_NAME ) ;
115
+ this . $logger . trace ( `Updating AppResources values from ${ defaultAppResourcesDir } to ${ targetAppResourcesDir } ` ) ;
116
+ shelljs . cp ( "-R" , path . join ( defaultAppResourcesDir , "*" ) , targetAppResourcesDir ) ;
117
+ } ) . future < void > ( ) ( ) ;
118
+ }
119
+
120
+ private mergeDependencies ( projectDependencies : IStringDictionary , templateDependencies : IStringDictionary ) : IStringDictionary {
121
+ // Cast to any when logging as logger thinks it can print only string.
122
+ // Cannot use toString() because we want to print the whole objects, not [Object object]
123
+ this . $logger . trace ( "Merging dependencies, projectDependencies are: " , < any > projectDependencies , " templateDependencies are: " , < any > templateDependencies ) ;
124
+ projectDependencies = projectDependencies || { } ;
125
+ _ . extend ( projectDependencies , templateDependencies || { } ) ;
126
+ let sortedDeps : IStringDictionary = { } ;
127
+ let dependenciesNames = _ . keys ( projectDependencies ) . sort ( ) ;
128
+ _ . each ( dependenciesNames , ( key : string ) => {
129
+ sortedDeps [ key ] = projectDependencies [ key ] ;
130
+ } ) ;
131
+ this . $logger . trace ( "Sorted merged dependencies are: " , < any > sortedDeps ) ;
132
+ return sortedDeps ;
133
+ }
134
+
90
135
private createProjectCore ( projectDir : string , appSourcePath : string , projectId : string ) : IFuture < void > {
91
136
return ( ( ) => {
92
137
this . $fs . ensureDirectoryExists ( projectDir ) . wait ( ) ;
@@ -97,7 +142,7 @@ export class ProjectService implements IProjectService {
97
142
if ( this . $options . symlink ) {
98
143
this . $fs . symlink ( appSourcePath , appDestinationPath ) . wait ( ) ;
99
144
} else {
100
- shell . cp ( '-R' , path . join ( appSourcePath , "*" ) , appDestinationPath ) ;
145
+ shelljs . cp ( '-R' , path . join ( appSourcePath , "*" ) , appDestinationPath ) ;
101
146
}
102
147
103
148
this . createBasicProjectStructure ( projectDir , projectId ) . wait ( ) ;
0 commit comments