@@ -69,6 +69,9 @@ export class TemplateGenerationCommand {
6969 if ( typeof this . configureSubcommand !== 'function' ) {
7070 throw new TypeError ( 'Cannot construct instance of TemplateGenerationCommand without overriding async method "configureSubcommand()"!' ) ;
7171 }
72+ if ( typeof this . filterByFileName !== 'function' ) {
73+ throw new TypeError ( 'Cannot construct instance of TemplateGenerationCommand without overriding async method "filterByFileName(string) -> bool"!' ) ;
74+ }
7275 // Set options controlling direct behavior
7376 this . program = program ;
7477 this . resourceName = resourceName ;
@@ -158,7 +161,9 @@ export class TemplateGenerationCommand {
158161 globTree ( tree , glob ) {
159162 debug ( 'Checking for templates that include the glob pattern: %s' , glob ) ;
160163 const filterFunc = minimatch . filter ( glob , { matchBase : true } ) ;
161- return _ . filter ( tree , ( f ) => f . type === 'blob' && filterFunc ( f . path ) ) ;
164+ const res = _ . filter ( tree , ( f ) => f . type === 'blob' && filterFunc ( f . path ) ) ;
165+ debug ( 'Number of results matching glob pattern "%s": %s' , glob , res . length ) ;
166+ return res ;
162167 }
163168
164169 /**
@@ -236,6 +241,7 @@ export class TemplateGenerationCommand {
236241 const loadMetadata = async ( value ) => {
237242 // TODO: this should have error handling to avoid a bad template crashing the CLI
238243 const data = JSON . parse ( ( await this . readFile ( value . path ) ) . toString ( ) ) ;
244+ debug ( 'Successfully read metadata file: %s' , value . path ) ;
239245 return {
240246 name : data . title ,
241247 value : { ...data , path : value . path } ,
@@ -299,13 +305,44 @@ export class TemplateGenerationCommand {
299305 [ this . resourceTemplateName ] : generateNameFromTitle ( templateName ) ,
300306 } ) ;
301307 } catch ( err ) {
302- printError ( err . message , this . options ) ;
308+ this . handleTemplatingError ( templateName , f , err ) ;
303309 }
304310 return undefined ;
305311 } ) . join ( '<br>' ) ;
306312 return generatedFiles ;
307313 }
308314
315+ /**
316+ * Error handler for templating specific scenarios - exits the program.
317+ *
318+ * @param {string } templateName Name of the template being copied
319+ * @param {GitTreeWrapper } file File object that was being templated
320+ * @param {Error } err Error that was thrown
321+ */
322+ handleTemplatingError ( templateName , file , err ) {
323+ debug ( 'Template Name: %s' , templateName ) ;
324+ debug ( 'File details: %s' , file ) ;
325+ debug ( 'Error details: %s' , err ) ;
326+ const message = `Failed to generate file "${ file . path } " in template "${ templateName } "!\n`
327+ + `This is possibly the result of the ${ this . resourceName } template having an invalid syntax.\n`
328+ + `\nError: ${ err . message } ` ;
329+ printError ( message , this . options ) ;
330+ }
331+
332+ /**
333+ * Returns whether a given file (path) in the template should be excluded from the template.
334+ * Should return `true` if the file should be copied without modification.
335+ *
336+ * The default implementation allows for all files to be templated.
337+ *
338+ * @param {string } filepath
339+ * @returns {boolean } true if the file should NOT be templated, false otherwise
340+ */
341+ // eslint-disable-next-line no-unused-vars
342+ filterByFileName ( filepath ) {
343+ return false ;
344+ }
345+
309346 /**
310347 * Generates the selected template by templating its contents and writing its content to disk.
311348 * Returns the file tree with what files were created.
@@ -328,8 +365,8 @@ export class TemplateGenerationCommand {
328365 template : template . template ,
329366 } ;
330367 let buf = await this . readFile ( f . path ) ;
331- /// Try not to template any non-text files.
332- if ( isText ( null , buf ) ) {
368+ /// Try not to template any non-text files, and allow for a filter
369+ if ( isText ( null , buf ) && ! this . filterByFileName ( f . path ) ) {
333370 buf = Buffer . from ( _ . template ( buf . toString ( ) , { interpolate : / { { ( [ \s \S ] + ?) } } / g } ) ( templateVars ) ) ;
334371 }
335372 const relPath = f . path . slice ( path . dirname ( template . template . path ) . length ) ;
@@ -340,7 +377,7 @@ export class TemplateGenerationCommand {
340377 _ . set ( treeObj , sourcePath . split ( '/' ) , null ) ;
341378 }
342379 } catch ( err ) {
343- printError ( err . message , this . options ) ;
380+ this . handleTemplatingError ( template . name , f , err ) ;
344381 }
345382 } ) ) ;
346383 return treeObj ;
0 commit comments