@@ -9,17 +9,23 @@ import path from "path";
99
1010import ejs from "ejs" ;
1111
12+ import { type SpecValues } from "../spec-parse" ;
13+ import templatesHelperAPI from "./templates-helper-api"
1214import * as utils from "../utils" ;
1315
1416
1517const EJS_FILE_EXTENSION = ".ejs" ;
18+ const HELPERS_EXTENSION = ".ejshelpers" ;
1619const PACKAGES_DIR_NAME = "packages" ;
1720const CLINGO_WRAPPER_PATH = "../clingo-wrapper" ;
1821
19- export interface Substitutions {
20- name : string ;
21- encoding : string ;
22- constraints : string ;
22+ const reExtension = / .[ a - z A - Z 0 - 9 ] + $ / ;
23+
24+ type HelperTemplateFn = ( subs : { [ key : string ] : string } ) => string ;
25+ type HelperTemplates = Map < string , { [ key : string ] : HelperTemplateFn } > ;
26+
27+ export interface Substitutions extends SpecValues {
28+ // Nothing for now
2329}
2430
2531/*
@@ -32,7 +38,7 @@ export function copyDirAndApplyTemplate(
3238 dst : string ,
3339 substitutions : Substitutions ,
3440) {
35- const retypedSubstitutions : { [ key : string ] : string } = Object . fromEntries (
41+ const retypedSubstitutions : { [ key : string ] : any } = Object . fromEntries (
3642 Object . entries ( substitutions ) ,
3743 ) ;
3844 _copyDirAndApplyTemplate ( src , dst , retypedSubstitutions ) ;
@@ -45,7 +51,7 @@ export function copyDirAndApplyTemplate(
4551function _copyDirAndApplyTemplate (
4652 src : string ,
4753 dst : string ,
48- substitutions : { [ key : string ] : string } ,
54+ substitutions : { [ key : string ] : any } ,
4955) {
5056 if ( ! utils . lstatIfExist ( src ) ?. isDirectory ( ) ) {
5157 throw new Error ( "Source isn't a directory." ) ;
@@ -55,21 +61,60 @@ function _copyDirAndApplyTemplate(
5561 }
5662 fs . mkdirSync ( dst ) ;
5763
58- for ( const direntObj of fs . readdirSync ( src , { withFileTypes : true } ) ) {
64+ // We first process helper templates
65+ const direntObjs = fs . readdirSync ( src , { withFileTypes : true } ) ;
66+ const helperTemplates : HelperTemplates = new Map ( ) ;
67+ for ( const direntObj of direntObjs ) {
68+ const newSRC = path . join ( src , direntObj . name ) ;
69+ if ( direntObj . name . endsWith ( HELPERS_EXTENSION ) ) {
70+ helperTemplates . set ( path . basename ( newSRC ) , readHelpersDir ( newSRC ) ) ;
71+ }
72+ }
73+
74+ for ( const direntObj of direntObjs ) {
5975 const newSRC = path . join ( src , direntObj . name ) ;
6076 const newDST = path . join ( dst , direntObj . name ) ;
77+ if ( helperTemplates . has ( path . basename ( newSRC ) ) ) continue ;
78+
6179 if ( direntObj . isDirectory ( ) ) {
6280 _copyDirAndApplyTemplate ( newSRC , newDST , substitutions ) ;
6381 } else if ( direntObj . name . endsWith ( EJS_FILE_EXTENSION ) ) {
6482 const fileData = fs . readFileSync ( newSRC ) . toString ( ) ;
6583 const modifiedDST = newDST . slice ( 0 , - EJS_FILE_EXTENSION . length ) ;
66- fs . writeFileSync ( modifiedDST , ejs . render ( fileData , substitutions ) ) ;
84+ const nameWithoutExt = path
85+ . basename ( newSRC )
86+ . slice ( 0 , - EJS_FILE_EXTENSION . length ) ;
87+
88+ const modifiedSubstitutions = { ...substitutions , ...templatesHelperAPI } ;
89+ const ht = helperTemplates . get ( nameWithoutExt + HELPERS_EXTENSION ) ;
90+ if ( ht !== undefined ) modifiedSubstitutions [ "ht" ] = ht ;
91+ console . log ( modifiedSubstitutions ) ;
92+ try {
93+ fs . writeFileSync ( modifiedDST , ejs . render ( fileData , modifiedSubstitutions ) ) ;
94+ } catch ( err ) {
95+ console . error ( `Error when rendering template '${ newSRC } '.` ) ;
96+ throw err ;
97+ }
6798 } else {
6899 fs . copyFileSync ( newSRC , newDST ) ;
69100 }
70101 }
71102}
72103
104+
105+ function readHelpersDir ( basePath : string ) : { [ key : string ] : HelperTemplateFn } {
106+ const ret : { [ key : string ] : HelperTemplateFn } = { } ;
107+ for ( const direntObj of fs . readdirSync ( basePath , { withFileTypes : true } ) ) {
108+ const filePath = path . join ( basePath , direntObj . name ) ;
109+ const fileData = fs . readFileSync ( filePath ) . toString ( ) ;
110+ const key = direntObj . name
111+ . slice ( 0 , - EJS_FILE_EXTENSION . length )
112+ . replace ( reExtension , "" ) ; // We ignore the extra extension!
113+ ret [ key ] = subs => ejs . render ( fileData , { ...subs , ...templatesHelperAPI } ) ;
114+ }
115+ return ret ;
116+ }
117+
73118/*
74119 * Copies helper workspaces into the new project.
75120 */
0 commit comments