1- /*jshint -W108*/
1+ /*jshint -W108,-W069 */
22'use strict' ;
33
44var pkg = require ( __dirname + '/../../package.json' ) ;
55var semver = require ( 'semver' ) ;
6- var fs = require ( 'extfs' ) ;
6+ var fs = require ( 'fs' ) ;
7+ var extfs = require ( 'extfs' ) ;
8+ var xml2js = require ( "xml2js" ) ;
9+ var parser = new xml2js . Parser ( ) ;
710var yeoman = require ( 'yeoman-generator' ) ;
811var chalk = require ( 'chalk' ) ;
912
1013var boilerPlatePath = '/AppStoreWidgetBoilerplate/' ;
11-
1214var banner = [
1315 '' ,
1416 chalk . bold . cyan ( ' __ ____ __' ) + ' _ _ _ ' ,
@@ -27,10 +29,41 @@ var banner = [
2729module . exports = yeoman . generators . Base . extend ( {
2830 constructor : function ( ) {
2931 yeoman . generators . Base . apply ( this , arguments ) ;
30- if ( ! fs . isEmptySync ( this . destinationRoot ( ) ) ) {
31- this . log ( banner ) ;
32- this . log ( chalk . red ( 'Error: Current folder does not seem to be empty, the generator needs to be run in an empty folder. Please create an empty folder first.\n' ) ) ;
33- process . exit ( 0 ) ;
32+ var done = this . async ( ) ;
33+ this . isNew = true ;
34+
35+ this . folders = extfs . getDirsSync ( this . destinationRoot ( ) ) ;
36+ this . current = { } ;
37+ this . current . version = '1.0.0' ;
38+ this . current . name = 'CurrentWidget' ;
39+
40+ if ( this . folders . indexOf ( 'src' ) !== - 1 ) {
41+ var srcFolderContent = extfs . getDirsSync ( this . destinationPath ( 'src' ) ) ;
42+ if ( srcFolderContent . length === 1 ) {
43+ this . current . name = srcFolderContent [ 0 ] ;
44+ }
45+ if ( ! extfs . isEmptySync ( this . destinationPath ( 'src/package.xml' ) ) ) {
46+ var pkgXml = fs . readFileSync ( this . destinationPath ( 'src/package.xml' ) ) . toString ( ) ;
47+ parser . parseString ( pkgXml , function ( err , result ) {
48+ this . isNew = false ;
49+ if ( err ) {
50+ this . log ( 'Error: ' + err ) ;
51+ process . exit ( 0 ) ;
52+ }
53+ if ( result . package . clientModule [ 0 ] [ "$" ] [ "version" ] ) {
54+ this . current . version = result . package . clientModule [ 0 ] [ "$" ] [ "version" ] ;
55+ }
56+ done ( ) ;
57+ } . bind ( this ) ) ;
58+ } else {
59+ this . isNew = false ;
60+ done ( ) ;
61+ }
62+ } else if ( ! extfs . isEmptySync ( this . destinationRoot ( ) ) ) {
63+ this . isNew = false ;
64+ done ( ) ;
65+ } else {
66+ done ( ) ;
3467 }
3568 } ,
3669 prompting : function ( ) {
@@ -39,7 +72,7 @@ module.exports = yeoman.generators.Base.extend({
3972 // Have Yeoman greet the user.
4073 this . log ( banner ) ;
4174
42- var prompts = [
75+ var promptsNew = [
4376 {
4477 type : 'input' ,
4578 name : 'widgetName' ,
@@ -92,12 +125,58 @@ module.exports = yeoman.generators.Base.extend({
92125 }
93126 ] ;
94127
95- this . prompt ( prompts , function ( props ) {
96- this . props = props ;
97- // To access props later use this.props.someOption;
128+ var promptsUpgrade = [
129+ {
130+ type : 'confirm' ,
131+ name : 'upgrade' ,
132+ message : 'Are you upgrading a custom widget? (Need \'src\' folder to work)' ,
133+ default : false
134+ } , {
135+ type : 'input' ,
136+ name : 'widgetName' ,
137+ validate : function ( input ) {
138+ if ( / ^ ( [ a - z A - Z ] * ) $ / . test ( input ) ) { return true ; }
139+ return 'Your widget can only contain letters (a-z & A-Z). Please provide a valid name' ;
140+ } ,
141+ message : 'What is name of your widget? (Please make it the same as your current MPK file, e.g. "CustomWidget.mpk", name is "CustomWidget")' ,
142+ default : this . current . name ,
143+ when : function ( props ) {
144+ return props . upgrade ;
145+ }
146+ } , {
147+ type : 'input' ,
148+ name : 'version' ,
149+ validate : function ( input ) {
150+ if ( semver . valid ( input ) && semver . satisfies ( input , '>=1.0.0' ) ) {
151+ return true ;
152+ }
153+ return 'Your version needs to be formatted as x.x.x and starts at 1.0.0. Using 1.0.0' ;
154+ } ,
155+ message : 'Enter your current version (package.xml) or the default version' ,
156+ default : this . current . version ,
157+ when : function ( props ) {
158+ return props . upgrade ;
159+ }
160+ }
161+ ] ;
98162
99- done ( ) ;
100- } . bind ( this ) ) ;
163+ if ( this . isNew ) {
164+ this . prompt ( promptsNew , function ( props ) {
165+ this . props = props ;
166+ // To access props later use this.props.someOption;
167+ done ( ) ;
168+ } . bind ( this ) ) ;
169+ } else {
170+ this . log ( chalk . bold . red ( ' The directory is not empty. If you are creating a new widget, please open the generator in an empty folder (Press Ctrl+C to abort)\n\n' ) ) ;
171+ this . prompt ( promptsUpgrade , function ( props ) {
172+ this . props = props ;
173+ if ( ! props . upgrade ) {
174+ process . exit ( 0 ) ;
175+ } else {
176+ done ( ) ;
177+ }
178+ } . bind ( this ) ) ;
179+ }
101180
102181 } ,
103182
@@ -119,83 +198,85 @@ module.exports = yeoman.generators.Base.extend({
119198 // Using grunt (future version will include Gulp)
120199 this . widget . builder = 'grunt' ;
121200
122- // Copy generic files
123- this . fs . copy ( this . templatePath ( boilerPlatePath + '.jshintrc' ) , this . destinationPath ( '.jshintrc' ) ) ;
124- this . fs . copy ( this . templatePath ( '_gitignore' ) , this . destinationPath ( '.gitignore' ) ) ;
125- this . fs . copy ( this . templatePath ( 'icon.png' ) , this . destinationPath ( 'icon.png' ) ) ;
126- this . fs . copy ( this . templatePath ( boilerPlatePath + 'assets/app_store_banner.png' ) , this . destinationPath ( 'assets/app_store_banner.png' ) ) ;
127- this . fs . copy ( this . templatePath ( boilerPlatePath + 'assets/app_store_icon.png' ) , this . destinationPath ( 'assets/app_store_icon.png' ) ) ;
128- this . fs . copy ( this . templatePath ( boilerPlatePath + 'LICENSE' ) , this . destinationPath ( 'LICENSE' ) ) ;
129- this . fs . copy ( this . templatePath ( boilerPlatePath + 'README.md' ) , this . destinationPath ( 'README.md' ) ) ;
130- this . fs . copy ( this . templatePath ( boilerPlatePath + 'test/Test.mpr' ) , this . destinationPath ( 'test/Test.mpr' ) ) ;
131- this . fs . copy ( this . templatePath ( boilerPlatePath + 'xsd/widget.xsd' ) , this . destinationPath ( 'xsd/widget.xsd' ) ) ;
132-
133- // Copy files based on WidgetName
134- this . fs . copy (
135- this . templatePath ( boilerPlatePath + 'src/WidgetName/lib/jquery-1.11.2.js' ) ,
136- this . destinationPath ( 'src/' + this . widget . widgetName + '/lib/jquery-1.11.2.js' )
137- ) ;
201+ if ( this . isNew ) {
202+ // Copy generic files
203+ this . fs . copy ( this . templatePath ( boilerPlatePath + '.jshintrc' ) , this . destinationPath ( '.jshintrc' ) ) ;
204+ this . fs . copy ( this . templatePath ( '_gitignore' ) , this . destinationPath ( '.gitignore' ) ) ;
205+ this . fs . copy ( this . templatePath ( 'icon.png' ) , this . destinationPath ( 'icon.png' ) ) ;
206+ this . fs . copy ( this . templatePath ( boilerPlatePath + 'assets/app_store_banner.png' ) , this . destinationPath ( 'assets/app_store_banner.png' ) ) ;
207+ this . fs . copy ( this . templatePath ( boilerPlatePath + 'assets/app_store_icon.png' ) , this . destinationPath ( 'assets/app_store_icon.png' ) ) ;
208+ this . fs . copy ( this . templatePath ( boilerPlatePath + 'LICENSE' ) , this . destinationPath ( 'LICENSE' ) ) ;
209+ this . fs . copy ( this . templatePath ( boilerPlatePath + 'README.md' ) , this . destinationPath ( 'README.md' ) ) ;
210+ this . fs . copy ( this . templatePath ( boilerPlatePath + 'test/Test.mpr' ) , this . destinationPath ( 'test/Test.mpr' ) ) ;
211+ this . fs . copy ( this . templatePath ( boilerPlatePath + 'xsd/widget.xsd' ) , this . destinationPath ( 'xsd/widget.xsd' ) ) ;
138212
139- this . fs . copy (
140- this . templatePath ( boilerPlatePath + 'src/WidgetName/widget/template/WidgetName.html' ) ,
141- this . destinationPath ( 'src/' + this . widget . widgetName + '/widget/template/' + this . widget . widgetName + '.html' )
142- ) ;
213+ // Copy files based on WidgetName
214+ this . fs . copy (
215+ this . templatePath ( boilerPlatePath + 'src/WidgetName/lib/jquery-1.11.2.js' ) ,
216+ this . destinationPath ( 'src/' + this . widget . widgetName + '/lib/jquery-1.11.2.js' )
217+ ) ;
143218
144- this . fs . copy (
145- this . templatePath ( boilerPlatePath + 'src/WidgetName/widget/ui /WidgetName.css ' ) ,
146- this . destinationPath ( 'src/' + this . widget . widgetName + '/widget/ui /' + this . widget . widgetName + '.css ' )
147- ) ;
219+ this . fs . copy (
220+ this . templatePath ( boilerPlatePath + 'src/WidgetName/widget/template /WidgetName.html ' ) ,
221+ this . destinationPath ( 'src/' + this . widget . widgetName + '/widget/template /' + this . widget . widgetName + '.html ' )
222+ ) ;
148223
149- // Rename references in widget main JS
150- this . fs . copy (
151- this . templatePath ( boilerPlatePath + 'src/WidgetName/widget/WidgetName.js' ) ,
152- this . destinationPath ( 'src/' + this . widget . widgetName + '/widget/' + this . widget . widgetName + '.js' ) ,
153- {
154- process : function ( file ) {
155- var fileText = file . toString ( ) ;
156- fileText = fileText
157- . replace ( / W i d g e t N a m e \. w i d g e t \. W i d g e t N a m e / g, this . widget . packageName + '.widget.' + this . widget . widgetName )
158- . replace ( / W i d g e t N a m e \/ w i d g e t \/ W i d g e t N a m e / g, this . widget . packageName + '/widget/' + this . widget . widgetName )
159- . replace ( / W i d g e t N a m e / g, this . widget . widgetName )
160- . replace ( / \{ \{ v e r s i o n \} \} / g, this . widget . version )
161- . replace ( / \{ \{ d a t e \} \} / g, this . widget . date )
162- . replace ( / \{ \{ c o p y r i g h t \} \} / g, this . widget . copyright )
163- . replace ( / \{ \{ l i c e n s e \} \} / g, this . widget . license )
164- . replace ( / \{ \{ a u t h o r \} \} / g, this . widget . author ) ;
165- return fileText ;
166- } . bind ( this )
167- }
168- ) ;
224+ this . fs . copy (
225+ this . templatePath ( boilerPlatePath + 'src/WidgetName/widget/ui/WidgetName.css' ) ,
226+ this . destinationPath ( 'src/' + this . widget . widgetName + '/widget/ui/' + this . widget . widgetName + '.css' )
227+ ) ;
169228
170- // Rename references package.xml
171- this . fs . copy (
172- this . templatePath ( boilerPlatePath + 'src/package.xml' ) ,
173- this . destinationPath ( 'src/package.xml' ) ,
174- {
175- process : function ( file ) {
176- var fileText = file . toString ( ) ;
177- fileText = fileText
178- . replace ( / W i d g e t N a m e / g, this . widget . widgetName )
179- . replace ( / \{ \{ v e r s i o n \} \} / g, this . widget . version ) ;
180- return fileText ;
181- } . bind ( this )
182- }
183- ) ;
229+ // Rename references in widget main JS
230+ this . fs . copy (
231+ this . templatePath ( boilerPlatePath + 'src/WidgetName/widget/WidgetName.js' ) ,
232+ this . destinationPath ( 'src/' + this . widget . widgetName + '/widget/' + this . widget . widgetName + '.js' ) ,
233+ {
234+ process : function ( file ) {
235+ var fileText = file . toString ( ) ;
236+ fileText = fileText
237+ . replace ( / W i d g e t N a m e \. w i d g e t \. W i d g e t N a m e / g, this . widget . packageName + '.widget.' + this . widget . widgetName )
238+ . replace ( / W i d g e t N a m e \/ w i d g e t \/ W i d g e t N a m e / g, this . widget . packageName + '/widget/' + this . widget . widgetName )
239+ . replace ( / W i d g e t N a m e / g, this . widget . widgetName )
240+ . replace ( / \{ \{ v e r s i o n \} \} / g, this . widget . version )
241+ . replace ( / \{ \{ d a t e \} \} / g, this . widget . date )
242+ . replace ( / \{ \{ c o p y r i g h t \} \} / g, this . widget . copyright )
243+ . replace ( / \{ \{ l i c e n s e \} \} / g, this . widget . license )
244+ . replace ( / \{ \{ a u t h o r \} \} / g, this . widget . author ) ;
245+ return fileText ;
246+ } . bind ( this )
247+ }
248+ ) ;
184249
185- // Rename references WidgetName
186- this . fs . copy (
187- this . templatePath ( boilerPlatePath + 'src/WidgetName/WidgetName.xml' ) ,
188- this . destinationPath ( 'src/' + this . widget . widgetName + '/' + this . widget . widgetName + '.xml' ) ,
189- {
190- process : function ( file ) {
191- var fileText = file . toString ( ) ;
192- fileText = fileText
193- . replace ( / W i d g e t N a m e \. w i d g e t \. W i d g e t N a m e / g, this . widget . packageName + '.widget.' + this . widget . widgetName )
194- . replace ( / W i d g e t N a m e / g, this . widget . widgetName ) ;
195- return fileText ;
196- } . bind ( this )
197- }
198- ) ;
250+ // Rename references package.xml
251+ this . fs . copy (
252+ this . templatePath ( boilerPlatePath + 'src/package.xml' ) ,
253+ this . destinationPath ( 'src/package.xml' ) ,
254+ {
255+ process : function ( file ) {
256+ var fileText = file . toString ( ) ;
257+ fileText = fileText
258+ . replace ( / W i d g e t N a m e / g, this . widget . widgetName )
259+ . replace ( / \{ \{ v e r s i o n \} \} / g, this . widget . version ) ;
260+ return fileText ;
261+ } . bind ( this )
262+ }
263+ ) ;
264+
265+ // Rename references WidgetName
266+ this . fs . copy (
267+ this . templatePath ( boilerPlatePath + 'src/WidgetName/WidgetName.xml' ) ,
268+ this . destinationPath ( 'src/' + this . widget . widgetName + '/' + this . widget . widgetName + '.xml' ) ,
269+ {
270+ process : function ( file ) {
271+ var fileText = file . toString ( ) ;
272+ fileText = fileText
273+ . replace ( / W i d g e t N a m e \. w i d g e t \. W i d g e t N a m e / g, this . widget . packageName + '.widget.' + this . widget . widgetName )
274+ . replace ( / W i d g e t N a m e / g, this . widget . widgetName ) ;
275+ return fileText ;
276+ } . bind ( this )
277+ }
278+ ) ;
279+ }
199280
200281 // Package.JSON
201282 this . template ( '_package.json' , 'package.json' , this . widget , { } ) ;
0 commit comments