UNPKG

serins

Version:

Initializes a new Serenity project using StartSharp ASP.NET Core template

273 lines (233 loc) 9.87 kB
#! /usr/bin/env node console.log('Welcome to StartSharp Initializer!'); console.log(''); var fs = require('fs'); var path = require('path'); var parseXml = require('xml2js').parseString; var util = require('util'); var readline = require('readline'); var https = require('https'); var decompress = require('decompress'); var rl = readline.createInterface({ input: process.stdin, output: process.stdout }); function replaceAll(s, oldValue, newValue) { newValue = newValue || ''; return s.split(oldValue).join(newValue); }; function toPath(s) { if (path.sep == '/') return replaceAll(s, '\\', '/'); return replaceAll(s, '/', '\\'); }; var replacements = { }; function replaceParams(s) { for (var k in replacements) { if (replacements.hasOwnProperty(k)) { s = replaceAll(s, k, replacements[k]); } } return s; } function getUserHome() { return process.env[(process.platform == 'win32') ? 'USERPROFILE' : 'HOME']; } function downloadHttps(url, cb) { var data = [], dataLen = 0; https.get(url, function(res) { res.on('data', function(chunk) { data.push(chunk); dataLen += chunk.length; }).on('end', function() { var buf = new Buffer(dataLen); for (var i=0, len = data.length, pos = 0; i < len; i++) { data[i].copy(buf, pos); pos += data[i].length; } cb(buf); }); }); } var sourceFileByPath = {}; function createSolution() { parseXml(sourceFileByPath['StartSharpCore.vstemplate'].toString('utf8'), function(err, result) { var vst = result.VSTemplate; var solutionName = vst.TemplateData[0].DefaultName[0]; rl.question('Enter a project name (press enter for ' + solutionName + '1)? ', (answer) => { solutionName = answer || (solutionName + '1'); console.log('Creating solution ' + solutionName); var projectTemplateLinks = vst.TemplateContent[0].ProjectCollection[0].ProjectTemplateLink; var features = vst.WizardData[0].features[0].feature.map(x => { return { key: x.$.key, title: x.$.title, dependencies: (x.dependency || []).map(y => y.$.feature) } }); replacements["$ext_projectname$"] = solutionName; var safeName = solutionName.replace(/\W/g, ''); safeName = safeName.substr(0, 1).toUpperCase() + safeName.substr(1); replacements["$ext_safeprojectname$"] = safeName; for (var i = 0; i < projectTemplateLinks.length; i++) { var templateLink = projectTemplateLinks[i]; var projectName = replaceParams(templateLink.$.ProjectName.replace('$projectname$', solutionName)); var templatePath = toPath(templateLink._.trim()); createProject(solutionName, projectName, templatePath); } rl.close(); }); }); } function useCacheZip(cacheZip) { var prefix = 'projecttemplates/startcore.template/'; decompress(fs.readFileSync(cacheZip), null, { }).then(files => { for (var i = 0; i < files.length; i++) { var path = files[i].path; if (!path.toLowerCase().startsWith(prefix)) continue; path = toPath(path.substr(prefix.length)); sourceFileByPath[path] = files[i].data; } createSolution(); }); } if (fs.readdirSync('./').length) { console.log('Please run this application in an empty directory!'); process.exit(1); } var cacheZip = process.argv[2]; if (cacheZip == null || !fs.existsSync(cacheZip)) { console.log('Please specify path to .VSIX file') process.exit(1); } useCacheZip(cacheZip); function PathMatcher(includesStr, excludesStr) { function wildcardToRegex(wildcard) { var pattern = wildcard.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); if (path.sep == '/') { // regex wildcard adjustments for *nix-style file systems pattern = replaceAll(pattern, "\\.\\*\\*", "\\.[^/.]*"); pattern = replaceAll(pattern, "\\*\\*/", "(.+/)*"); pattern = replaceAll(pattern, "\\*\\*", ".*"); pattern = replaceAll(pattern, "\\*", "[^/]*(/)?"); pattern = replaceAll("\\?", "."); } else { // regex wildcard adjustments for Windows-style file systems pattern = replaceAll(pattern, "/", "\\\\"); pattern = replaceAll(pattern, "\\.\\*\\*", "\\.[^\\\\.]*") pattern = replaceAll(pattern, "\\*\\*\\\\", "(.+\\\\)*") pattern = replaceAll(pattern, "\\*\\*", ".*") pattern = replaceAll(pattern, "\\*", "[^\\\\]*(\\\\)?"); pattern = replaceAll("\\?", "."); } return new RegExp('^' + pattern + '$', /ig/); } includes = includesStr.map(wildcardToRegex); excludes = excludesStr.map(wildcardToRegex); this.isMatch = function(p) { for (var i = 0; i < excludes.length; i++) if (p.match(excludes[i])) return false; for (var i = 0; i < includes.length; i++) if (p.match(includes[i])) return true; return false; } } function createProject(solutionName, projectName, vsTemplatePath) { console.log('Creating project ' + projectName + ' (using ' + vsTemplatePath + ')'); replacements["$projectname$"] = projectName; replacements["$safeprojectname$"] = projectName.replace(/\W/g, ''); function copyFile(source, target, replace) { var targetFolder = path.dirname(target); if (!fs.existsSync(targetFolder)) fs.mkdirSync(targetFolder); if (replace) { var content = sourceFileByPath[source].toString("utf8"); content = replaceParams(content); fs.writeFileSync(target, content, { encoding: "utf8" }); } else { fs.writeFileSync(target, sourceFileByPath[source]); } } function traverse(container, sourceRoot, targetRoot) { if (container.Folder) { for (var f = 0; f < container.Folder.length; f++) { var folder = container.Folder[f]; var targetFolderName = replaceParams(folder.$.TargetFolderName); var sourceFolderName = folder.$.Name; var targetPath = path.resolve(targetRoot, targetFolderName); if (!fs.existsSync(targetPath)) fs.mkdirSync(targetPath); traverse(folder, sourceRoot + path.sep + sourceFolderName, targetPath); } } if (container.ProjectItem) { for (var i = 0; i < container.ProjectItem.length; i++) { var item = container.ProjectItem[i]; var sourceFile = sourceRoot + path.sep + item._.trim(); var targetFile = path.resolve(targetRoot, replaceParams(item.$.TargetFileName)); copyFile(sourceFile, targetFile, item.$.ReplaceParameters == 'true' || item.$.ReplaceParameters == 'True'); } } } parseXml(sourceFileByPath[vsTemplatePath].toString("utf8"), function(err, result) { var vst = result.VSTemplate; var prj = vst.TemplateContent[0].Project[0]; var sourceRoot = path.dirname(vsTemplatePath); var targetRoot = path.resolve('./', projectName); var xprojSource = sourceRoot + path.sep + prj.$.File; var xprojTarget = path.resolve(targetRoot, replaceParams(prj.$.TargetFileName)); copyFile(xprojSource, xprojTarget, true); traverse(prj, sourceRoot, targetRoot); if (path.sep == '/') { var appSettingsPath = path.resolve(targetRoot, 'appsettings.json'); var appSettings = JSON.parse(fs.readFileSync(appSettingsPath, 'utf8').replace(/^\uFEFF/, '')); if (appSettings.Data) { var keys = Object.keys(appSettings.Data); for (var i = 0; i < keys.length; i++) { var k = keys[i]; if (appSettings.Data.hasOwnProperty(k)) { var d = appSettings.Data[k]; d.ConnectionString = "Filename=./App_Data/" + solutionName + "_" + k + "_v1.sqlite"; d.ProviderName = "Microsoft.Data.Sqlite"; } } fs.writeFileSync(appSettingsPath, JSON.stringify(appSettings, null, ' '), 'utf8'); } } var exec = require('child_process').exec; console.log("Restoring packages for " + projectName); var child1 = exec('dotnet restore', { cwd: targetRoot }); child1.stdout.pipe(process.stdout); child1.stderr.pipe(process.stdin); child1.on('close', function() { console.log("Running Sergen to restore content for " + projectName); var child2 = exec('dotnet sergen restore', { cwd: targetRoot }); child2.stdout.pipe(process.stdout); child2.stderr.pipe(process.stderr); child2.on('close', function() { console.log("Installing node modules for " + projectName); var child3 = exec('npm install', { cwd: targetRoot }); child3.stdout.pipe(process.stdout); child3.stderr.pipe(process.stderr); child3.on('close', function() { console.log('Your project is generated.'); process.exit(0); }); }); }); }); }