| @@ -199,17 +199,131 @@ const dirs = async (perform, path) => { | |||
| } | |||
| } | |||
| // PB : TODO -- Should return a bunch of promises to wait for... | |||
| var copyrecursive = function(src, dest, perform, args) { | |||
| var exists = fs.existsSync(src); | |||
| var stats = exists && fs.statSync(src); | |||
| var isDirectory = exists && stats.isDirectory(); | |||
| if (isDirectory) { | |||
| fs.mkdirSync(dest); | |||
| dirs( function(childItemName) { | |||
| copyrecursive(path.join(src, childItemName), | |||
| path.join(dest, childItemName)); | |||
| }, src ) | |||
| // fs.readdirSync(src).forEach(function(childItemName) { | |||
| // copyrecursive(path.join(src, childItemName), | |||
| // path.join(dest, childItemName)); | |||
| // }); | |||
| } else { | |||
| fs.copyFileSync(src, dest); | |||
| } | |||
| }; | |||
| // var renamerecursive = function(from, to){ | |||
| // var exists = fs.existsSync(from); | |||
| // var stats = exists && fs.statSync(from); | |||
| // var isDirectory = exists && stats.isDirectory(); | |||
| // if (isDirectory) { | |||
| // fs.mkdirSync(to); | |||
| // dirs( function(childItemName) { | |||
| // renamerecursive(path.join(from, childItemName), | |||
| // path.join(to, childItemName)); | |||
| // }, from ) | |||
| // // fs.readdirSync(from).forEach(function(childItemName) { | |||
| // // copyrecursive(path.join(from, childItemName), | |||
| // // path.join(to, childItemName)); | |||
| // // }); | |||
| // } else { | |||
| // fsrename(from, to); | |||
| // } | |||
| // } | |||
| var regexreplaceall = function(content, strOrregexp, substitutes){ | |||
| var repmatches | |||
| var replaced = content; | |||
| while (repmatches = strOrregexp.exec(content)) { | |||
| if(content.length > 0) { | |||
| var replacement = repmatches[0] | |||
| for(var m = 1; m < repmatches.length; m++) { | |||
| replacement = replacement.replace(matches[i], substitutes[i-1]) | |||
| } | |||
| replaced.replace( repmatches[0], replacement ) | |||
| } | |||
| } | |||
| return replaced | |||
| } | |||
| var fsrecurse = function(target, options, actions, root) { | |||
| var exists = fs.existsSync(target); | |||
| var stats = exists && fs.statSync(target); | |||
| var isDirectory = exists && stats.isDirectory(); | |||
| if (isDirectory) { | |||
| dirs( function(childItemName) { | |||
| fsrecurse(path.join(target, childItemName) | |||
| , options, actions, root); | |||
| }, target ) | |||
| } else { | |||
| var prevActionResult = null; | |||
| actions.forEach( (action) => prevActionResult = action.apply(null, target, options) ) | |||
| } | |||
| }; | |||
| var fslink = function(target, options){ fs.linkSync( options.from, options.to ) } | |||
| var fsrename = function(target, options){ | |||
| var replaced = target; // PB : TODO -- streaming and async.. | |||
| options.patternsubstitutions.forEach( ps => { replaced = regexreplaceall( replaced, ps ) }) | |||
| if(replaced && replaced !== target) fs.renameSync(target, replaced) | |||
| return replaced | |||
| } | |||
| var fscontentreplace = function( target, options ){ | |||
| // do many replacements in one shot in the file. | |||
| if(options.processingtype === 'inplace' && options.sourcetype === 'filesystem' ) { | |||
| var content = fs.readFileSync(target) // PB : TODO -- streaming and async.. | |||
| options.patternsubstitutions.forEach( ps => { content = regexreplaceall( content, ps ) }) | |||
| fs.writeFileSync(target, content) | |||
| } | |||
| } | |||
| var templatelink = function(target, options){ | |||
| var targetPath = target.replace(options.workingtarget, options.destinationroot); | |||
| var targetPathBaseDir = targetPath.split("/").pop() | |||
| var linkTobase = regexreplaceall( target, /(__link__)(__base__)-server-lib/, [ '', options.base] ) | |||
| var linkFromName = regexreplaceall( target, /(__link____base__-server-lib)/, [ '' ] ) | |||
| var linkToName = regexreplaceall( linkFromName, new Regexp(targetPathBaseDir), [ linkTobase ] ) | |||
| if(linkTobase) { // Only if the pattern matches which is link instruction. | |||
| // PB : DONT DLELETE EVERYTHING ??? Only the linkable ones... Or use an add strategy without deleting... | |||
| fs.unlinkSync( target ); fslink( { from : linkFromName, to : linkToName } ) | |||
| } | |||
| } | |||
| // Source and Target are files or folders. We need another version or a unifed version for strings.. | |||
| var processpatterns = function(target, options){ | |||
| // Accept a set of patterns and substitutions and operate on a target and apply all patterns substitutions. | |||
| // options = options || { targettype : 'inplace', sourcetype : 'filesystem' } | |||
| // options.source, options.target sourcetype = 'string' | 'filesystem' options.targettype = 'inplace' | 'copy' | |||
| if(options.processingtype === 'inplace' && options.sourcetype === 'filesystem' ) { | |||
| var templateprocess = function(str, substitutes){ | |||
| const regex = /__(.*?)__/gm; | |||
| // const str = `__link____instance__server-lib__name__`; | |||
| let m; | |||
| options.patternsubstitutions.forEach( ps => { | |||
| // var replacement = regexreplaceall( from, ps.strOrregexp, ps.substitutes ) | |||
| // if(targetname) { // Porcess all files. Even if file names dont have patterns the content needs to be replaced. | |||
| return options.tasks.map( t => { return t( target, ps ) } ) | |||
| // } | |||
| return str.replace(regex, function(match, key) { | |||
| console.log(`Found match, group ${match}: ${key}`); | |||
| return substitutes[key] || match; | |||
| }) | |||
| // return str.replace(regex, function(match, key) { | |||
| // console.log(`Found match, group ${match}: ${key}`); | |||
| // return substitutes[key] || match; | |||
| // }) | |||
| }) | |||
| } | |||
| // while ((m = regex.exec(str)) !== null) { | |||
| // // This is necessary to avoid infinite loops with zero-width matches | |||
| @@ -247,26 +361,26 @@ function copyFileSync( source, target , options) { | |||
| } | |||
| function copyFolderRecursiveSync( source, target, options ) { | |||
| var files = []; | |||
| var files = []; | |||
| // Check if folder needs to be created or integrated | |||
| var targetFolder = path.join( target, path.basename( source ) ); | |||
| if ( !fs.existsSync( targetFolder ) ) { | |||
| fs.mkdirSync( targetFolder ); | |||
| } | |||
| // Check if folder needs to be created or integrated | |||
| var targetFolder = path.join( target, path.basename( source ) ); | |||
| if ( !fs.existsSync( targetFolder ) ) { | |||
| fs.mkdirSync( targetFolder ); | |||
| } | |||
| // Copy | |||
| if ( fs.lstatSync( source ).isDirectory() ) { | |||
| files = fs.readdirSync( source ); | |||
| files.forEach( function ( file ) { | |||
| var curSource = path.join( source, file ); | |||
| if ( fs.lstatSync( curSource ).isDirectory() ) { | |||
| copyFolderRecursiveSync( curSource, targetFolder ); | |||
| } else { | |||
| copyFileSync( curSource, targetFolder ); | |||
| } | |||
| } ); | |||
| } | |||
| // Copy | |||
| if ( fs.lstatSync( source ).isDirectory() ) { | |||
| files = fs.readdirSync( source ); | |||
| files.forEach( function ( file ) { | |||
| var curSource = path.join( source, file ); | |||
| if ( fs.lstatSync( curSource ).isDirectory() ) { | |||
| copyFolderRecursiveSync( curSource, targetFolder ); | |||
| } else { | |||
| copyFileSync( curSource, targetFolder ); | |||
| } | |||
| } ); | |||
| } | |||
| } | |||
| var getShellTask = (command, args, options) => { | |||
| @@ -2025,15 +2139,43 @@ var op = { | |||
| throw 'NOT YET IMPLMENTED' | |||
| } | |||
| , 'vmodel' : ()=>{ | |||
| var verse = [ '__universe__/vmodel' ] | |||
| , 'vmodel' : (options)=>{ | |||
| options = options || { | |||
| generate : processedArgs['all'] ? 'all' : processedArgs['server'] ? 'server' : processedArgs['client'] ? 'client' : null | |||
| } | |||
| // console.dir(templateprocess(`__link____instance__server-lib__name__`, { link( ){ | |||
| // return processed }, instance : 'elixir-', name : 'newmodel' } ) | |||
| // ) | |||
| if(!options.generate) return 'Nothing specified for generation' | |||
| var name = processedArgs._[2]; | |||
| if(!name) return 'No name specified for generation' | |||
| var templateverse = `${selectedinstance.root}/bbhverse/__universe__/vmodel` | |||
| var workingtarget = `${selectedinstance.root}/.elxr/run-${runtimestamp}/temp/vmodelworkingdir` | |||
| var destination = `${selectedinstance.root}` | |||
| // Create a tmp working copy for staging the changes. | |||
| copyrecursive(templateverse, workingtarget) | |||
| var patternsubstitutions = [ { strOrregexp : /(__name__)/, substitutes : [name]} ] | |||
| var options = { source : templateverse, target : workingtarget, destinationroot : destination, workingtarget | |||
| , processingtype : 'inplace', sourcetype : 'filesystem', patternsubstitutions } | |||
| fsrecurse( workingtarget, options | |||
| , [ function(workingtarget, options){ | |||
| // A series of tasks to be executed on each pattern in patternsubstitutions. | |||
| return [ | |||
| // PB : TODO -- Contentreplace is better addressed in memory instead of file IO so do all regexps in sequence in one shot and then rename. | |||
| (filename, options)=>{ fscontentreplace( filename, options ) } | |||
| , (from, options)=>{ fsrename( from, options ) } | |||
| ].map( t => t(workingtarget, options) ) | |||
| }] | |||
| ) | |||
| // Post process links in place. | |||
| fsrecurse( workingtarget, options, [ templatelink ] ) | |||
| // Move to the final destination. Whole tree should move only top level folders are required. | |||
| dirs(( child )=>{ return fs.renameSync(path.join(workingtarget, child), path.join(destination, child) ) }, workingtarget ) | |||
| } | |||
| } | |||
| g[processedArgs._[1]](); | |||
| @@ -3300,7 +3442,7 @@ var __interactive_prompts = function( target, choices, promptsfilter ){ | |||
| var remotenames = [] | |||
| Object.entries(target.remotes).forEach( ([rname, r]) => { | |||
| if(r.server === reposerver){ | |||
| remotes.push(rname) | |||
| // remotes.push(rname) | |||
| // PB : TODO -- Sort and display highest priority target.remotes.sort( ) | |||
| } | |||
| }) | |||