Move all scripts to webpack, add wip cmd script for bin

This commit is contained in:
Chen Asraf
2018-01-05 03:06:25 +02:00
parent eecec82aaa
commit 3e42ac5a95
22 changed files with 259 additions and 80 deletions

24
.vscode/launch.json vendored
View File

@@ -4,18 +4,26 @@
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Debug Scaffold",
"type": "node",
"request": "launch",
"protocol": "inspector",
"cwd": "${workspaceFolder}",
"program": "${workspaceFolder}/test.ts",
"outFiles": [
"${workspaceRoot}/dist/test.js"
],
"env": {
"NODE_ENV": "develop"
},
"sourceMaps": true,
},
{
"type": "node",
"request": "attach",
"name": "Attach by Process ID",
"processId": "${command:PickProcess}"
},
{
"type": "node",
"request": "launch",
"name": "Debug Scaffold",
"protocol": "inspector",
"program": "${workspaceFolder}/dist/scaffold.js"
}
}
]
}

3
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,3 @@
{
"typescript.tsdk": "./node_modules/typescript/lib"
}

7
.vscode/tasks.json vendored Normal file
View File

@@ -0,0 +1,7 @@
{
"version": "0.1.0",
"command": "webpack",
"isShellCommand": true,
"args": [],
"showOutput": "always"
}

66
cmd.ts Normal file
View File

@@ -0,0 +1,66 @@
import Scaffolder from './scaffold'
import * as fs from 'fs'
import IScaffold from './index'
const args = process.argv.slice(2)
class ScaffoldCmd {
constructor() {
console.log(this.getOptionsFromArgs())
}
private getOptionsFromArgs() {
let skipNext = false
const options = {} as any
args.forEach((arg, i) => {
if (skipNext) {
skipNext = false
return
}
if (arg.slice(0, 2) == '--') {
skipNext = true
let value: string
if (arg.indexOf('=') >= 0) {
value = arg.split('=').slice(1).join('')
} else if (args.length >= i + 1 && args[i + 1].slice(0, 2) !== '--') {
value = args[i + 1]
} else {
value = 'true'
}
options[arg] = this.getArgValue(arg.slice(2), value, options)
}
})
return options
}
private getArgValue(arg: string, value: string, options: IScaffold.IConfig) {
switch (arg) {
case 'template':
return (options.templates || []).concat([value])
case 'output':
return value
case 'locals':
const split = value.split(',')
const locals = options.locals || {}
for (const item of split) {
const [k, v] = item.split('=')
locals[k] = v
}
default:
throw TypeError(`arguments invalid for config: arg=\`${arg}\`, value=\`${value}\``)
}
}
private run(config: IScaffold.IConfig) {
const scf = new Scaffolder({
templates: config.templates,
output: config.output,
locals: config.locals,
}).run()
}
}

3
dist/cmd.js vendored Executable file
View File

@@ -0,0 +1,3 @@
#!/usr/bin/env node
!function(t){function e(r){if(n[r])return n[r].exports;var o=n[r]={i:r,l:!1,exports:{}};return t[r].call(o.exports,o,o.exports,e),o.l=!0,o.exports}var n={};e.m=t,e.c=n,e.d=function(t,n,r){e.o(t,n)||Object.defineProperty(t,n,{configurable:!1,enumerable:!0,get:r})},e.n=function(t){var n=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(n,"a",n),n},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="",e(e.s=5)}([function(t,e){t.exports=require("path")},function(t,e,n){"use strict";var r=this&&this.__generator||function(t,e){function n(t){return function(e){return r([t,e])}}function r(n){if(o)throw new TypeError("Generator is already executing.");for(;l;)try{if(o=1,i&&(s=i[2&n[0]?"return":n[0]?"throw":"next"])&&!(s=s.call(i,n[1])).done)return s;switch(i=0,s&&(n=[0,s.value]),n[0]){case 0:case 1:s=n;break;case 4:return l.label++,{value:n[1],done:!1};case 5:l.label++,i=n[1],n=[0];continue;case 7:n=l.ops.pop(),l.trys.pop();continue;default:if(s=l.trys,!(s=s.length>0&&s[s.length-1])&&(6===n[0]||2===n[0])){l=0;continue}if(3===n[0]&&(!s||n[1]>s[0]&&n[1]<s[3])){l.label=n[1];break}if(6===n[0]&&l.label<s[1]){l.label=s[1],s=n;break}if(s&&l.label<s[2]){l.label=s[2],l.ops.push(n);break}s[2]&&l.ops.pop(),l.trys.pop();continue}n=e.call(t,l)}catch(t){n=[6,t],i=0}finally{o=s=0}if(5&n[0])throw n[1];return{value:n[0]?n[1]:void 0,done:!0}}var o,i,s,a,l={label:0,sent:function(){if(1&s[0])throw s[1];return s[1]},trys:[],ops:[]};return a={next:n(0),throw:n(1),return:n(2)},"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a};Object.defineProperty(e,"__esModule",{value:!0});var o=n(2),i=n(0),s=n(3),a=function(){function t(t){this.locals={};var e={name:"scaffold",templates:[],output:process.cwd()};this.config=Object.assign({},e,t);var n={Name:this.config.name[0].toUpperCase()+this.config.name.slice(1),name:this.config.name[0].toLowerCase()+this.config.name.slice(1)};this.locals=Object.assign({},n,t.locals)}return t.prototype.parseLocals=function(t){var e=this,n=t.toString(),r=/{[%]\s*([^%{}]+)\s*[%]}/gi;return n.replace(r,function(t,n){return e.locals[n]})},t.prototype.fileList=function(t){var e,n,o,a,l,c,u,f,p;return r(this,function(r){switch(r.label){case 0:console.info("input:",t),e=0,n=t,r.label=1;case 1:if(!(e<n.length))return[3,6];o=n[e],a=s.sync(o).map(function(t){return i.resolve(t)}),l=o.indexOf("*"),c=o,l>=0&&(c=o.slice(0,l-1)),u=0,f=a,r.label=2;case 2:return u<f.length?(p=f[u],[4,{base:c,file:p}]):[3,5];case 3:r.sent(),r.label=4;case 4:return u++,[3,2];case 5:return e++,[3,1];case 6:return[2]}})},t.prototype.getFileContents=function(t){return o.readFileSync(t).toString()},t.prototype.getOutputPath=function(t,e){var n;if("function"==typeof this.config.output)n=this.config.output(t,e);else{var r=this.config.output+"/"+this.config.name+"/",o=t.indexOf(e),i=t;o>=0&&(i=t.slice(o+e.length+1)),n=r+i}return this.parseLocals(n)},t.prototype.writeFile=function(t,e){o.existsSync(i.dirname(t))||o.mkdirSync(i.dirname(t)),console.info("Writing file:",t),o.writeFileSync(t,e,{encoding:"utf-8"})},t.prototype.run=function(){var t=this.fileList(this.config.templates);console.info("Templates input:",t),console.info("Locals:",this.locals);for(var e;e=t.next().value;){var n=e.file,r=e.base,o=this.getOutputPath(n,r),i=this.getFileContents(n),s=this.parseLocals(i);this.writeFile(o,s),console.info("Parsing:",{file:n,base:r,outputPath:o,outputContents:s.replace("\n","\\n")})}},t}();e.default=a},function(t,e){t.exports=require("fs")},function(t,e){t.exports=require("glob")},,function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(1),o=process.argv.slice(2);!function(){function t(){console.log(this.getOptionsFromArgs())}t.prototype.getOptionsFromArgs=function(){var t=this,e=!1,n={};return o.forEach(function(r,i){if(e)return void(e=!1);if("--"==r.slice(0,2)){e=!0;var s=void 0;s=r.indexOf("=")>=0?r.split("=").slice(1).join(""):o.length>=i+1&&"--"!==o[i+1].slice(0,2)?o[i+1]:"true",n[r]=t.getArgValue(r.slice(2),s,n)}}),n},t.prototype.getArgValue=function(t,e,n){switch(t){case"template":return(n.templates||[]).concat([e]);case"output":return e;case"locals":for(var r=e.split(","),o=n.locals||{},i=0,s=r;i<s.length;i++){var a=s[i],l=a.split("="),c=l[0],u=l[1];o[c]=u}default:throw TypeError("arguments invalid for config: arg=`"+t+"`, value=`"+e+"`")}},t.prototype.run=function(t){new r.default({templates:t.templates,output:t.output,locals:t.locals}).run()}}()}]);
//# sourceMappingURL=cmd.js.map

1
dist/cmd.js.map vendored Executable file

File diff suppressed because one or more lines are too long

0
dist/dist/cmd.d.ts vendored Executable file
View File

13
dist/dist/scaffold.d.ts vendored Normal file → Executable file
View File

@@ -0,0 +1,13 @@
import IScaffold from './index';
declare class SimpleScaffold {
private config;
private locals;
constructor(config: IScaffold.IConfig);
private parseLocals(text);
private fileList(input);
private getFileContents(filePath);
private getOutputPath(file, basePath);
private writeFile(filePath, fileContents);
run(): void;
}
export default SimpleScaffold;

0
dist/dist/test.d.ts vendored Executable file
View File

3
dist/scaffold.js vendored
View File

@@ -1 +1,2 @@
!function(t){function e(n){if(o[n])return o[n].exports;var i=o[n]={i:n,l:!1,exports:{}};return t[n].call(i.exports,i,i.exports,e),i.l=!0,i.exports}var o={};e.m=t,e.c=o,e.d=function(t,o,n){e.o(t,o)||Object.defineProperty(t,o,{configurable:!1,enumerable:!0,get:n})},e.n=function(t){var o=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(o,"a",o),o},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="",e(e.s=0)}([function(t,e,o){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var n=o(1),i=(o.n(n),o(2)),s=(o.n(i),function(){function t(t){if(this.locals={},this.scaffoldName=process.argv[2],this.DefaultConfig={templates:[],output:i.resolve(process.cwd()),locals:{Name:this.scaffoldName[0].toUpperCase()+this.scaffoldName.slice(1),name:this.scaffoldName[0].toLowerCase()+this.scaffoldName.slice(1)}},!this.scaffoldName)throw new Error("Must provide scaffold name");this.config=Object.assign({},this.DefaultConfig,t),this.locals=Object.assign({},this.DefaultConfig.locals,t.locals),console.info("Config loaded:",this.config),console.info("Locals:",this.locals)}return t.prototype.parseLocals=function(t){var e=this,o=t.toString(),n=/{[%]\s*([^%{}]+)\s*[%]}/gi;return o.replace(n,function(t,o){return e.locals[o]})},t.prototype.getFileList=function(t){var e=this,o=[];return t.forEach(function(t){var s=n.lstatSync(t);if(s.isFile())console.info("pushing",t),o.push(t);else if(s.isDirectory()){console.info("going into dir",t);var r=n.readdirSync(t).map(function(e){return i.join(t,e)});o=o.concat(e.getFileList(r))}}),o},t.prototype.getFileContents=function(t){return n.readFileSync(t).toString()},t.prototype.getOutputPath=function(t){var e;return e="function"==typeof this.config.output?this.config.output(t):this.config.output+"/"+this.scaffoldName+"/"+i.basename(t),this.parseLocals(e)},t.prototype.writeFile=function(t,e){n.existsSync(i.dirname(t))||n.mkdirSync(i.dirname(t)),console.info("Writing file:",t),n.writeFileSync(t,e,{encoding:"utf-8"})},t.prototype.run=function(){var t=this,e=this.getFileList(this.config.templates);console.info(e),e.forEach(function(e){var o=t.getOutputPath(e),n=t.getFileContents(e),i=t.parseLocals(n);t.writeFile(o,i)})},t}());exports.default=s},function(t,e){t.exports=require("fs")},function(t,e){t.exports=require("path")}]);
!function(e){function t(r){if(n[r])return n[r].exports;var o=n[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,t),o.l=!0,o.exports}var n={};t.m=e,t.c=n,t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=1)}([function(e,t){e.exports=require("path")},function(e,t,n){"use strict";var r=this&&this.__generator||function(e,t){function n(e){return function(t){return r([e,t])}}function r(n){if(o)throw new TypeError("Generator is already executing.");for(;c;)try{if(o=1,i&&(s=i[2&n[0]?"return":n[0]?"throw":"next"])&&!(s=s.call(i,n[1])).done)return s;switch(i=0,s&&(n=[0,s.value]),n[0]){case 0:case 1:s=n;break;case 4:return c.label++,{value:n[1],done:!1};case 5:c.label++,i=n[1],n=[0];continue;case 7:n=c.ops.pop(),c.trys.pop();continue;default:if(s=c.trys,!(s=s.length>0&&s[s.length-1])&&(6===n[0]||2===n[0])){c=0;continue}if(3===n[0]&&(!s||n[1]>s[0]&&n[1]<s[3])){c.label=n[1];break}if(6===n[0]&&c.label<s[1]){c.label=s[1],s=n;break}if(s&&c.label<s[2]){c.label=s[2],c.ops.push(n);break}s[2]&&c.ops.pop(),c.trys.pop();continue}n=t.call(e,c)}catch(e){n=[6,e],i=0}finally{o=s=0}if(5&n[0])throw n[1];return{value:n[0]?n[1]:void 0,done:!0}}var o,i,s,a,c={label:0,sent:function(){if(1&s[0])throw s[1];return s[1]},trys:[],ops:[]};return a={next:n(0),throw:n(1),return:n(2)},"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a};Object.defineProperty(t,"__esModule",{value:!0});var o=n(2),i=n(0),s=n(3),a=function(){function e(e){this.locals={};var t={name:"scaffold",templates:[],output:process.cwd()};this.config=Object.assign({},t,e);var n={Name:this.config.name[0].toUpperCase()+this.config.name.slice(1),name:this.config.name[0].toLowerCase()+this.config.name.slice(1)};this.locals=Object.assign({},n,e.locals)}return e.prototype.parseLocals=function(e){var t=this,n=e.toString(),r=/{[%]\s*([^%{}]+)\s*[%]}/gi;return n.replace(r,function(e,n){return t.locals[n]})},e.prototype.fileList=function(e){var t,n,o,a,c,l,u,f,p;return r(this,function(r){switch(r.label){case 0:console.info("input:",e),t=0,n=e,r.label=1;case 1:if(!(t<n.length))return[3,6];o=n[t],a=s.sync(o).map(function(e){return i.resolve(e)}),c=o.indexOf("*"),l=o,c>=0&&(l=o.slice(0,c-1)),u=0,f=a,r.label=2;case 2:return u<f.length?(p=f[u],[4,{base:l,file:p}]):[3,5];case 3:r.sent(),r.label=4;case 4:return u++,[3,2];case 5:return t++,[3,1];case 6:return[2]}})},e.prototype.getFileContents=function(e){return o.readFileSync(e).toString()},e.prototype.getOutputPath=function(e,t){var n;if("function"==typeof this.config.output)n=this.config.output(e,t);else{var r=this.config.output+"/"+this.config.name+"/",o=e.indexOf(t),i=e;o>=0&&(i=e.slice(o+t.length+1)),n=r+i}return this.parseLocals(n)},e.prototype.writeFile=function(e,t){o.existsSync(i.dirname(e))||o.mkdirSync(i.dirname(e)),console.info("Writing file:",e),o.writeFileSync(e,t,{encoding:"utf-8"})},e.prototype.run=function(){var e=this.fileList(this.config.templates);console.info("Templates input:",e),console.info("Locals:",this.locals);for(var t;t=e.next().value;){var n=t.file,r=t.base,o=this.getOutputPath(n,r),i=this.getFileContents(n),s=this.parseLocals(i);this.writeFile(o,s),console.info("Parsing:",{file:n,base:r,outputPath:o,outputContents:s.replace("\n","\\n")})}},e}();t.default=a},function(e,t){e.exports=require("fs")},function(e,t){e.exports=require("glob")}]);
//# sourceMappingURL=scaffold.js.map

1
dist/scaffold.js.map vendored Executable file

File diff suppressed because one or more lines are too long

2
dist/test.js vendored Executable file
View File

@@ -0,0 +1,2 @@
!function(e){function t(r){if(n[r])return n[r].exports;var o=n[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,t),o.l=!0,o.exports}var n={};t.m=e,t.c=n,t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=4)}([function(e,t){e.exports=require("path")},function(e,t,n){"use strict";var r=this&&this.__generator||function(e,t){function n(e){return function(t){return r([e,t])}}function r(n){if(o)throw new TypeError("Generator is already executing.");for(;u;)try{if(o=1,i&&(s=i[2&n[0]?"return":n[0]?"throw":"next"])&&!(s=s.call(i,n[1])).done)return s;switch(i=0,s&&(n=[0,s.value]),n[0]){case 0:case 1:s=n;break;case 4:return u.label++,{value:n[1],done:!1};case 5:u.label++,i=n[1],n=[0];continue;case 7:n=u.ops.pop(),u.trys.pop();continue;default:if(s=u.trys,!(s=s.length>0&&s[s.length-1])&&(6===n[0]||2===n[0])){u=0;continue}if(3===n[0]&&(!s||n[1]>s[0]&&n[1]<s[3])){u.label=n[1];break}if(6===n[0]&&u.label<s[1]){u.label=s[1],s=n;break}if(s&&u.label<s[2]){u.label=s[2],u.ops.push(n);break}s[2]&&u.ops.pop(),u.trys.pop();continue}n=t.call(e,u)}catch(e){n=[6,e],i=0}finally{o=s=0}if(5&n[0])throw n[1];return{value:n[0]?n[1]:void 0,done:!0}}var o,i,s,a,u={label:0,sent:function(){if(1&s[0])throw s[1];return s[1]},trys:[],ops:[]};return a={next:n(0),throw:n(1),return:n(2)},"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a};Object.defineProperty(t,"__esModule",{value:!0});var o=n(2),i=n(0),s=n(3),a=function(){function e(e){this.locals={};var t={name:"scaffold",templates:[],output:process.cwd()};this.config=Object.assign({},t,e);var n={Name:this.config.name[0].toUpperCase()+this.config.name.slice(1),name:this.config.name[0].toLowerCase()+this.config.name.slice(1)};this.locals=Object.assign({},n,e.locals)}return e.prototype.parseLocals=function(e){var t=this,n=e.toString(),r=/{[%]\s*([^%{}]+)\s*[%]}/gi;return n.replace(r,function(e,n){return t.locals[n]})},e.prototype.fileList=function(e){var t,n,o,a,u,l,c,f,p;return r(this,function(r){switch(r.label){case 0:console.info("input:",e),t=0,n=e,r.label=1;case 1:if(!(t<n.length))return[3,6];o=n[t],a=s.sync(o).map(function(e){return i.resolve(e)}),u=o.indexOf("*"),l=o,u>=0&&(l=o.slice(0,u-1)),c=0,f=a,r.label=2;case 2:return c<f.length?(p=f[c],[4,{base:l,file:p}]):[3,5];case 3:r.sent(),r.label=4;case 4:return c++,[3,2];case 5:return t++,[3,1];case 6:return[2]}})},e.prototype.getFileContents=function(e){return o.readFileSync(e).toString()},e.prototype.getOutputPath=function(e,t){var n;if("function"==typeof this.config.output)n=this.config.output(e,t);else{var r=this.config.output+"/"+this.config.name+"/",o=e.indexOf(t),i=e;o>=0&&(i=e.slice(o+t.length+1)),n=r+i}return this.parseLocals(n)},e.prototype.writeFile=function(e,t){o.existsSync(i.dirname(e))||o.mkdirSync(i.dirname(e)),console.info("Writing file:",e),o.writeFileSync(e,t,{encoding:"utf-8"})},e.prototype.run=function(){var e=this.fileList(this.config.templates);console.info("Templates input:",e),console.info("Locals:",this.locals);for(var t;t=e.next().value;){var n=t.file,r=t.base,o=this.getOutputPath(n,r),i=this.getFileContents(n),s=this.parseLocals(i);this.writeFile(o,s),console.info("Parsing:",{file:n,base:r,outputPath:o,outputContents:s.replace("\n","\\n")})}},e}();t.default=a},function(e,t){e.exports=require("fs")},function(e,t){e.exports=require("glob")},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(1),o=n(0),i=o.join(process.cwd(),"examples");new r.default({templates:[i+"/test-input/Component/**/*"],output:i+"/test-output",locals:{property:"myProp",value:'"value"'}}).run()}]);
//# sourceMappingURL=test.js.map

1
dist/test.js.map vendored Executable file

File diff suppressed because one or more lines are too long

View File

@@ -1,13 +1,18 @@
import * as React from 'react'
class {%Name%} extends React.Component {
class {%Name%} extends React.Component<any> {
private {%property%}
constructor() {
constructor(props: any) {
super(props)
this.{%property%} = {%value%}
}
<div className={css.{%Name%}} />
public render() {
return (
<div className={css.{%Name%}} />
)
}
}
export default {%Name%}

11
index.d.ts vendored
View File

@@ -1,8 +1,9 @@
export namespace IScaffold {
declare namespace IScaffold {
export interface IConfig {
name?: string
templates: string[]
output: string | ((path: string) => string)
output: string | ((path: string, base: string) => string)
locals?: any
}
@@ -12,4 +13,10 @@ export namespace IScaffold {
[other: string]: any
}
export interface IFileRepr {
base: string
file: string
}
}
export default IScaffold

View File

@@ -6,18 +6,22 @@
"author": "Chen Asraf <inbox@casraf.com>",
"license": "MIT",
"main": "dist/scaffold.js",
"bin": "dist/scaffold.js",
"bin": "dist/cmd.js",
"types": "index.d.ts",
"scripts": {
"build": "webpack -p && chmod +x dist/scaffold.js",
"build": "NODE_ENV=${NODE_ENV:-production} webpack -p && chmod -R +x ./dist",
"dev": "webpack --watch",
"start": "node dist/scaffold.js",
"test": "yarn build && node scripts/test.js"
"test": "yarn build && node dist/test.js"
},
"devDependencies": {
"dependencies": {
"@types/glob": "^5.0.34",
"@types/node": "^8.0.50",
"glob": "^7.1.2",
"ts-loader": "^3.1.1",
"typescript": "^2.6.1",
"webpack": "^3.8.1",
"webpack-dev-server": "^2.9.4"
"webpack-dev-server": "^2.9.4",
"webpack-node-externals": "^1.6.0"
}
}

View File

@@ -1,28 +1,29 @@
import * as fs from 'fs'
import * as path from 'path'
import { IScaffold } from './index'
import IScaffold from './index'
import * as glob from 'glob'
class SimpleScaffold {
private config: IScaffold.IConfig
private locals = {} as any
public scaffoldName = process.argv[2]
private DefaultConfig: IScaffold.IConfig = {
templates: [],
output: path.resolve(process.cwd()),
locals: {
Name: this.scaffoldName[0].toUpperCase() + this.scaffoldName.slice(1),
name: this.scaffoldName[0].toLowerCase() + this.scaffoldName.slice(1)
}
}
constructor(config: IScaffold.IConfig) {
if (!this.scaffoldName) {
throw new Error('Must provide scaffold name')
const DefaultConfig: IScaffold.IConfig = {
name: 'scaffold',
templates: [],
output: process.cwd(),
}
this.config = (Object as any).assign({}, this.DefaultConfig, config)
this.locals = (Object as any).assign({}, this.DefaultConfig.locals, config.locals)
console.info('Config loaded:', this.config)
console.info('Locals:', this.locals)
this.config = (Object as any).assign({}, DefaultConfig, config)
const DefaultLocals = {
Name: this.config.name![0].toUpperCase() + this.config.name!.slice(1),
name: this.config.name![0].toLowerCase() + this.config.name!.slice(1)
}
this.locals = (Object as any).assign({}, DefaultLocals, config.locals)
// console.info('Config loaded:', this.config)
}
private parseLocals(text: string): string {
@@ -31,35 +32,39 @@ class SimpleScaffold {
return out.replace(pattern, (match: string, $1: string) => this.locals[$1])
}
private getFileList(pathList: string[]): string[] {
let outList: string[] = []
pathList.forEach((checkPath: string) => {
const stat = fs.lstatSync(checkPath)
if (stat.isFile()) {
console.info('pushing', checkPath)
outList.push(checkPath)
} else if (stat.isDirectory()) {
console.info('going into dir', checkPath)
const innerFiles = fs.readdirSync(checkPath).map(p => path.join(checkPath, p))
outList = outList.concat(this.getFileList(innerFiles))
private *fileList(input: string[]): IterableIterator<IScaffold.IFileRepr> {
console.info('input:', input)
for (const checkPath of input) {
const files = glob.sync(checkPath).map(g => path.resolve(g))
const idx = checkPath.indexOf('*')
let cleanCheckPath = checkPath
if (idx >= 0) {
cleanCheckPath = checkPath.slice(0, idx - 1)
}
})
return outList
for (const file of files) {
yield {base: cleanCheckPath, file}
}
}
}
private getFileContents(filePath: string): string {
return fs.readFileSync(filePath).toString()
}
private getOutputPath(file: string): string {
private getOutputPath(file: string, basePath: string): string {
let out
if (typeof this.config.output === 'function') {
out = this.config.output(file)
out = this.config.output(file, basePath)
} else {
out = this.config.output + `/${this.scaffoldName}/` + path.basename(file)
const outputDir = this.config.output + `/${this.config.name}/`
const idx = file.indexOf(basePath)
let relativeFilePath = file
if (idx >= 0) {
// console.info('file:', {file, idx, basePath})
relativeFilePath = file.slice(idx + basePath.length + 1)
}
out = outputDir + relativeFilePath
}
return this.parseLocals(out)
@@ -73,16 +78,23 @@ class SimpleScaffold {
fs.writeFileSync(filePath, fileContents, { encoding: 'utf-8' })
}
public run() {
const inputFiles = this.getFileList(this.config.templates)
console.info(inputFiles)
inputFiles.forEach((file: string) => {
const outputPath = this.getOutputPath(file)
public run(): void {
const templates = this.fileList(this.config.templates)
console.info('Templates input:', templates)
console.info('Locals:', this.locals)
let fileConf
while (fileConf = templates.next().value) {
const {file, base} = fileConf
const outputPath = this.getOutputPath(file, base)
const contents = this.getFileContents(file)
const outputContents = this.parseLocals(contents)
this.writeFile(outputPath, outputContents)
})
console.info('Parsing:', {file, base, outputPath, outputContents: outputContents.replace("\n", "\\n")})
}
}
}
exports.default = SimpleScaffold
export default SimpleScaffold

View File

@@ -1,12 +0,0 @@
const Scaffolder = require('../dist/scaffold').default
const templateDir = process.cwd() + '/examples'
const scf = new Scaffolder({
templates: [templateDir + '/test-input/Component'],
output: templateDir + '/test-output',
locals: {
property: 'myProp',
value: '"value"'
}
}).run()

13
test.ts Normal file
View File

@@ -0,0 +1,13 @@
import SimpleScaffold from './scaffold'
import * as path from 'path'
const templateDir = path.join(process.cwd(), 'examples')
new SimpleScaffold({
templates: [templateDir + '/test-input/Component/**/*'],
output: templateDir + '/test-output',
locals: {
property: 'myProp',
value: '"value"'
}
}).run()

View File

@@ -1,9 +1,10 @@
{
"compilerOptions": {
"target": "es5",
"module": "es2015",
"module": "commonjs",
"lib": ["es2017", "es6"],
"declaration": true,
"outDir": "./dist",
"outDir": "dist",
"strict": true,
"sourceMap": true
},

View File

@@ -1,22 +1,41 @@
const path = require('path')
const webpack = require('webpack')
const nodeExternals = require('webpack-node-externals')
module.exports = {
devtool: process.env.NODE_ENV === 'develop' ? 'inline-source-map' : 'source-map',
target: 'node',
entry: './scaffold.ts',
entry: {
scaffold: './scaffold.ts',
test: './test.ts',
cmd: './cmd.ts',
},
output: {
filename: 'scaffold.js',
path: path.resolve(__dirname, 'dist')
filename: '[name].js',
path: path.resolve(__dirname, 'dist'),
devtoolModuleFilenameTemplate: '[absolute-resource-path]',
},
resolve: {
extensions: ['.ts']
},
externals: [nodeExternals()],
module: {
rules: [
{
test: /\.tsx?$/,
loader: 'ts-loader',
exclude: ['./examples']
exclude: ['./examples', 'node_modules']
}
]
}
},
plugins: [
new webpack.DefinePlugin({
'__dirname': '__dirname'
}),
new webpack.BannerPlugin({
banner: '#!/usr/bin/env node',
raw: true,
include: /cmd\.js/,
})
],
}

View File

@@ -2,6 +2,26 @@
# yarn lockfile v1
"@types/events@*":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@types/events/-/events-1.1.0.tgz#93b1be91f63c184450385272c47b6496fd028e02"
"@types/glob@^5.0.34":
version "5.0.34"
resolved "https://registry.yarnpkg.com/@types/glob/-/glob-5.0.34.tgz#ee626c9be3da877d717911c6101eee0a9871bbf4"
dependencies:
"@types/events" "*"
"@types/minimatch" "*"
"@types/node" "*"
"@types/minimatch@*":
version "3.0.3"
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
"@types/node@*":
version "0.12.14"
resolved "https://registry.yarnpkg.com/@types/node/-/node-0.12.14.tgz#117c531e3f49b0ecfa1b439495abe22517fdfa7f"
"@types/node@^8.0.50":
version "8.0.50"
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.50.tgz#dc545448e128c88c4eec7cd64025fcc3b7604541"
@@ -1125,7 +1145,7 @@ glob-parent@^2.0.0:
dependencies:
is-glob "^2.0.0"
glob@^7.0.3, glob@^7.0.5:
glob@^7.0.3, glob@^7.0.5, glob@^7.1.2:
version "7.1.2"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15"
dependencies:
@@ -2888,6 +2908,10 @@ webpack-dev-server@^2.9.4:
webpack-dev-middleware "^1.11.0"
yargs "^6.6.0"
webpack-node-externals@^1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/webpack-node-externals/-/webpack-node-externals-1.6.0.tgz#232c62ec6092b100635a3d29d83c1747128df9bd"
webpack-sources@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.0.2.tgz#d0148ec083b3b5ccef1035a6b3ec16442983b27a"