Compare commits

...

9 Commits

Author SHA1 Message Date
Chen Asraf
fa2ddca57e v0.3.1 2018-01-15 02:23:14 +02:00
Chen Asraf
686b0bf227 Update README.md 2018-01-15 02:23:05 +02:00
Chen Asraf
0be29dd89e v0.3.0 2018-01-15 02:19:23 +02:00
Chen Asraf
4f29a612a3 cleanups 2018-01-15 02:18:39 +02:00
Chen Asraf
14b60ffc79 output is optional 2018-01-15 02:16:51 +02:00
Chen Asraf
1275743764 Update README.md 2018-01-07 02:25:27 +02:00
Chen Asraf
b09299b432 Uodate README.md 2018-01-05 04:53:41 +02:00
Chen Asraf
45e8de3034 Rename 2018-01-05 04:52:52 +02:00
Chen Asraf
a3a77e2ab5 Update README.md 2018-01-05 04:52:26 +02:00
13 changed files with 1059 additions and 33 deletions

119
README.md
View File

@@ -1,36 +1,56 @@
# scaffolder
Scaffolder allows you to create your structured files based on templates.
# simple-scaffold
Simple Scaffold allows you to create your structured files based on templates.
## Install
You can either use it as a command line tool or import into your own code and run from there.
You can install simple-scaffold globally like so:
```bash
# npm
npm install -g simple-scaffold
npm install [-g] simple-scaffold
# yarn
yarn global add simple-scaffold
yarn [global] add simple-scaffold
```
## Use as a command line tool
#### Command line options
The first non-token argument (that has no `--` prefix) will be used as the scaffold name.
The rest is ignored, of course except for the available arguments below.
```bash
simple-scaffold MyComponent --template scaffolds/component \
simple-scaffold MyComponent --template scaffolds/component/**/* \
--output src/components \
--locals myProp="propname",myVal=123
```
##### `--template`
A glob pattern of template files to load.
You can add this as a script in your `package.json`:
```json
{
"scripts": {
"scaffold": "node node_modules/simple-scaffold/dist/cmd.js --template scaffolds/component/**/* --output src/components --locals myProp=\"propname\",myVal=123"
}
}
```
## Scaffolding
Scaffolding will replace {{vars}} in both the file name and its contents and put the transformed files
in `<output>/<{{Name}}`.
Your context will be pre-populated with the following:
- `{{Name}}`: CapitalizedName of the component
- `{{name}}`: camelCasedName of the component
Any `locals` you add in the config will populate with their names wrapped in `{{` and `}}`.
They are all stringified, so be sure to parse them accordingly by creating a script, if necessary.
### Command line options
##### `--template glob [--template glob2 [...]]` (required)
A glob pattern of template files to load.
A template file may be of any type and extension, and supports [Handlebars](https://handlebarsjs.com) as a parsing engine for the file names and contents, so you may customize both with variables from your configuration.
You may load more than one template list by simple adding more `--template` arguments.
You can load more than one template list by simple adding more `--template` arguments.
##### `--output`
##### `--output path` (optional)
The output directory to put the new files in. They will attempt to maintain their regular structure as they are found, if possible.
Your new scaffold will be placed under a directory with the scaffold name from the argumemts.
@@ -38,10 +58,77 @@ Your new scaffold will be placed under a directory with the scaffold name from t
You may also pass a function to transform the output path for each file individually.
This function takes 2 arguments: filename, and base glob path
##### `--locals`
You may set local variables to be pushed into the template and replaced.
The format for the value of this argument is:
##### `--locals key=value[,key=value[,...]]` (optional)
Pass a KV map to the template for parsing.
### Use in Node.js
You can also build the scaffold yourself, if you want to create more complex arguments or scaffold groups.
Simply pass a config object to the constructor, and invoke `run()` when you are ready to start.
The config takes similar arguments to the command line:
```javascript
const SimpleScaffold = require('simple-scaffold').default
const scaffold = new SimpleScaffold({
name: 'component',
templates: [path.join(__dirname, 'scaffolds', 'component')],
output: path.join(__dirname, 'src', 'components'),
locals: {
property: 'value',
}
}).run()
```
property=value[,property=value[,...]]
## Example Scaffold Input
### Input Directory structure
```
- project
- scaffold
- {{Name}}.js
- {{Name}}.css
- src
- components
- ...
```
#### project/scaffold/{{Name}}.js
```js
const React = require('react')
module.exports = class {{Name}} extends React.Component {
render() {
<div className="{{className}}">{{Name}} Component</div>
}
}
```
### Run Example
```bash
simple-scaffold MyComponent \
--template project/scaffold/**/* \
--output src/components \
--locals 'className=my-component`
```
## Example Scaffold Output
#### Directory structure
```
- project
- src
- components
- MyComponent
- MyComponent.css
- ...
```
#### project/scaffold/MyComponent/MyComponent.js
```js
const React = require('react')
module.exports = class MyComponent extends React.Component {
render() {
<div className="my-component">MyComponent Component</div>
}
}
```

2
cmd.ts
View File

@@ -44,7 +44,7 @@ class ScaffoldCmd {
}
})
if (!['name', 'templates', 'output'].every(o => options[o] !== undefined)) {
if (!['name', 'templates'].every(o => options[o] !== undefined)) {
throw new Error(`Config is missing keys: ${JSON.stringify(options)}`)
}

332
dist/cmd.js vendored

File diff suppressed because one or more lines are too long

2
dist/cmd.js.map vendored

File diff suppressed because one or more lines are too long

96
dist/main.js vendored Normal file
View File

@@ -0,0 +1,96 @@
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define([], factory);
else if(typeof exports === 'object')
exports["library"] = factory();
else
root["library"] = factory();
})(this, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 7);
/******/ })
/************************************************************************/
/******/ ({
/***/ 7:
/***/ (function(module, exports, __webpack_require__) {
(function webpackMissingModule() { throw new Error("Cannot find module \"add\""); }());
module.exports = __webpack_require__(8);
/***/ }),
/***/ 8:
/***/ (function(module, exports) {
module.exports = require("jest");
/***/ })
/******/ });
});
//# sourceMappingURL=main.js.map

1
dist/main.js.map vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"sources":["webpack/universalModuleDefinition","webpack/bootstrap c994c2c400fa1fc61abe","external \"jest\""],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AACD,O;ACVA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAK;AACL;AACA;;AAEA;AACA;AACA;AACA,mCAA2B,0BAA0B,EAAE;AACvD,yCAAiC,eAAe;AAChD;AACA;AACA;;AAEA;AACA,8DAAsD,+DAA+D;;AAErH;AACA;;AAEA;AACA;;;;;;;;;;;;;;;;;AC7DA,iC","file":"main.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"library\"] = factory();\n\telse\n\t\troot[\"library\"] = factory();\n})(this, function() {\nreturn \n\n\n// WEBPACK FOOTER //\n// webpack/universalModuleDefinition"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 7);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap c994c2c400fa1fc61abe","module.exports = require(\"jest\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"jest\"\n// module id = 8\n// module chunks = 3"],"sourceRoot":""}

246
dist/scaffold.js vendored
View File

@@ -1,2 +1,246 @@
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.library=t():e.library=t()}(this,function(){return function(e){function t(o){if(n[o])return n[o].exports;var r=n[o]={i:o,l:!1,exports:{}};return e[o].call(r.exports,r,r.exports,t),r.l=!0,r.exports}var n={};return t.m=e,t.c=n,t.d=function(e,n,o){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:o})},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 o=this&&this.__generator||function(e,t){function n(e){return function(t){return o([e,t])}}function o(n){if(r)throw new TypeError("Generator is already executing.");for(;c;)try{if(r=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{r=s=0}if(5&n[0])throw n[1];return{value:n[0]?n[1]:void 0,done:!0}}var r,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 r=n(2),i=n(0),s=n(3),a=n(4),c=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){return a.compile(e,{noEscape:!0})(this.locals)},e.prototype.fileList=function(e){var t,n,r,a,c,u,l,f,p;return o(this,function(o){switch(o.label){case 0:t=0,n=e,o.label=1;case 1:if(!(t<n.length))return[3,6];r=n[t],a=s.sync(r).map(function(e){return"/"==e[0]?e:i.join(process.cwd(),e)}),c=r.indexOf("*"),u=r,c>=0&&(u=r.slice(0,c-1)),l=0,f=a,o.label=2;case 2:return l<f.length?(p=f[l],[4,{base:u,file:p}]):[3,5];case 3:o.sent(),o.label=4;case 4:return l++,[3,2];case 5:return t++,[3,1];case 6:return[2]}})},e.prototype.getFileContents=function(e){return r.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 o=this.config.output+"/"+this.config.name+"/",r=e.indexOf(t),i=e;r>=0&&(i=e.slice(r+t.length+1)),n=o+i}return this.parseLocals(n)},e.prototype.writeFile=function(e,t){r.existsSync(i.dirname(e))||r.mkdirSync(i.dirname(e)),console.info("Writing file:",e),r.writeFileSync(e,t,{encoding:"utf-8"})},e.prototype.run=function(){console.log("Generating scaffold: "+this.config.name+"...");for(var e,t=this.fileList(this.config.templates),n=0;e=t.next().value;){n++;var o=e.file,r=e.base,i=this.getOutputPath(o,r),s=this.getFileContents(o),a=this.parseLocals(s);this.writeFile(i,a),console.info("Parsing:",{file:o,base:r,outputPath:i,outputContents:a.replace("\n","\\n")})}if(!n)throw new Error("No files to scaffold!");console.log("Done")},e}();t.default=c},function(e,t){e.exports=require("fs")},function(e,t){e.exports=require("glob")},function(e,t){e.exports=require("handlebars")}])});
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define([], factory);
else if(typeof exports === 'object')
exports["library"] = factory();
else
root["library"] = factory();
})(this, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 1);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports) {
module.exports = require("path");
/***/ }),
/* 1 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [0, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
Object.defineProperty(exports, "__esModule", { value: true });
var fs = __webpack_require__(2);
var path = __webpack_require__(0);
var glob = __webpack_require__(3);
var handlebars = __webpack_require__(4);
var SimpleScaffold = /** @class */ (function () {
function SimpleScaffold(config) {
this.locals = {};
var DefaultConfig = {
name: 'scaffold',
templates: [],
output: process.cwd(),
};
this.config = Object.assign({}, DefaultConfig, config);
var 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.assign({}, DefaultLocals, config.locals);
}
SimpleScaffold.prototype.parseLocals = function (text) {
var template = handlebars.compile(text, {
noEscape: true
});
return template(this.locals);
};
SimpleScaffold.prototype.fileList = function (input) {
var _i, input_1, checkPath, files, idx, cleanCheckPath, _a, files_1, file;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
_i = 0, input_1 = input;
_b.label = 1;
case 1:
if (!(_i < input_1.length)) return [3 /*break*/, 6];
checkPath = input_1[_i];
files = glob.sync(checkPath).map(function (g) { return g[0] == '/' ? g : path.join(process.cwd(), g); });
idx = checkPath.indexOf('*');
cleanCheckPath = checkPath;
if (idx >= 0) {
cleanCheckPath = checkPath.slice(0, idx - 1);
}
_a = 0, files_1 = files;
_b.label = 2;
case 2:
if (!(_a < files_1.length)) return [3 /*break*/, 5];
file = files_1[_a];
return [4 /*yield*/, { base: cleanCheckPath, file: file }];
case 3:
_b.sent();
_b.label = 4;
case 4:
_a++;
return [3 /*break*/, 2];
case 5:
_i++;
return [3 /*break*/, 1];
case 6: return [2 /*return*/];
}
});
};
SimpleScaffold.prototype.getFileContents = function (filePath) {
return fs.readFileSync(filePath).toString();
};
SimpleScaffold.prototype.getOutputPath = function (file, basePath) {
var out;
if (typeof this.config.output === 'function') {
out = this.config.output(file, basePath);
}
else {
var outputDir = this.config.output + ("/" + this.config.name + "/");
var idx = file.indexOf(basePath);
var relativeFilePath = file;
if (idx >= 0) {
relativeFilePath = file.slice(idx + basePath.length + 1);
}
out = outputDir + relativeFilePath;
}
return this.parseLocals(out);
};
SimpleScaffold.prototype.writeFile = function (filePath, fileContents) {
if (!fs.existsSync(path.dirname(filePath))) {
fs.mkdirSync(path.dirname(filePath));
}
console.info('Writing file:', filePath);
fs.writeFileSync(filePath, fileContents, { encoding: 'utf-8' });
};
SimpleScaffold.prototype.run = function () {
console.log("Generating scaffold: " + this.config.name + "...");
var templates = this.fileList(this.config.templates);
var fileConf, count = 0;
while (fileConf = templates.next().value) {
count++;
var file = fileConf.file, base = fileConf.base;
var outputPath = this.getOutputPath(file, base);
var contents = this.getFileContents(file);
var outputContents = this.parseLocals(contents);
this.writeFile(outputPath, outputContents);
console.info('Parsing:', { file: file, base: base, outputPath: outputPath, outputContents: outputContents.replace("\n", "\\n") });
}
if (!count) {
throw new Error('No files to scaffold!');
}
console.log('Done');
};
return SimpleScaffold;
}());
exports.default = SimpleScaffold;
/***/ }),
/* 2 */
/***/ (function(module, exports) {
module.exports = require("fs");
/***/ }),
/* 3 */
/***/ (function(module, exports) {
module.exports = require("glob");
/***/ }),
/* 4 */
/***/ (function(module, exports) {
module.exports = require("handlebars");
/***/ })
/******/ ]);
});
//# sourceMappingURL=scaffold.js.map

File diff suppressed because one or more lines are too long

266
dist/test.js vendored
View File

@@ -1,2 +1,266 @@
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.library=t():e.library=t()}(this,function(){return function(e){function t(o){if(n[o])return n[o].exports;var r=n[o]={i:o,l:!1,exports:{}};return e[o].call(r.exports,r,r.exports,t),r.l=!0,r.exports}var n={};return t.m=e,t.c=n,t.d=function(e,n,o){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:o})},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=5)}([function(e,t){e.exports=require("path")},function(e,t,n){"use strict";var o=this&&this.__generator||function(e,t){function n(e){return function(t){return o([e,t])}}function o(n){if(r)throw new TypeError("Generator is already executing.");for(;u;)try{if(r=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{r=s=0}if(5&n[0])throw n[1];return{value:n[0]?n[1]:void 0,done:!0}}var r,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 r=n(2),i=n(0),s=n(3),a=n(4),u=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){return a.compile(e,{noEscape:!0})(this.locals)},e.prototype.fileList=function(e){var t,n,r,a,u,c,l,f,p;return o(this,function(o){switch(o.label){case 0:t=0,n=e,o.label=1;case 1:if(!(t<n.length))return[3,6];r=n[t],a=s.sync(r).map(function(e){return"/"==e[0]?e:i.join(process.cwd(),e)}),u=r.indexOf("*"),c=r,u>=0&&(c=r.slice(0,u-1)),l=0,f=a,o.label=2;case 2:return l<f.length?(p=f[l],[4,{base:c,file:p}]):[3,5];case 3:o.sent(),o.label=4;case 4:return l++,[3,2];case 5:return t++,[3,1];case 6:return[2]}})},e.prototype.getFileContents=function(e){return r.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 o=this.config.output+"/"+this.config.name+"/",r=e.indexOf(t),i=e;r>=0&&(i=e.slice(r+t.length+1)),n=o+i}return this.parseLocals(n)},e.prototype.writeFile=function(e,t){r.existsSync(i.dirname(e))||r.mkdirSync(i.dirname(e)),console.info("Writing file:",e),r.writeFileSync(e,t,{encoding:"utf-8"})},e.prototype.run=function(){console.log("Generating scaffold: "+this.config.name+"...");for(var e,t=this.fileList(this.config.templates),n=0;e=t.next().value;){n++;var o=e.file,r=e.base,i=this.getOutputPath(o,r),s=this.getFileContents(o),a=this.parseLocals(s);this.writeFile(i,a),console.info("Parsing:",{file:o,base:r,outputPath:i,outputContents:a.replace("\n","\\n")})}if(!n)throw new Error("No files to scaffold!");console.log("Done")},e}();t.default=u},function(e,t){e.exports=require("fs")},function(e,t){e.exports=require("glob")},function(e,t){e.exports=require("handlebars")},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=n(1),r=n(0),i=r.join(process.cwd(),"examples");new o.default({templates:[i+"/test-input/Component/**/*"],output:i+"/test-output",locals:{property:"myProp",value:'"value"'}}).run()}])});
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define([], factory);
else if(typeof exports === 'object')
exports["library"] = factory();
else
root["library"] = factory();
})(this, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 5);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports) {
module.exports = require("path");
/***/ }),
/* 1 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [0, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
Object.defineProperty(exports, "__esModule", { value: true });
var fs = __webpack_require__(2);
var path = __webpack_require__(0);
var glob = __webpack_require__(3);
var handlebars = __webpack_require__(4);
var SimpleScaffold = /** @class */ (function () {
function SimpleScaffold(config) {
this.locals = {};
var DefaultConfig = {
name: 'scaffold',
templates: [],
output: process.cwd(),
};
this.config = Object.assign({}, DefaultConfig, config);
var 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.assign({}, DefaultLocals, config.locals);
}
SimpleScaffold.prototype.parseLocals = function (text) {
var template = handlebars.compile(text, {
noEscape: true
});
return template(this.locals);
};
SimpleScaffold.prototype.fileList = function (input) {
var _i, input_1, checkPath, files, idx, cleanCheckPath, _a, files_1, file;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
_i = 0, input_1 = input;
_b.label = 1;
case 1:
if (!(_i < input_1.length)) return [3 /*break*/, 6];
checkPath = input_1[_i];
files = glob.sync(checkPath).map(function (g) { return g[0] == '/' ? g : path.join(process.cwd(), g); });
idx = checkPath.indexOf('*');
cleanCheckPath = checkPath;
if (idx >= 0) {
cleanCheckPath = checkPath.slice(0, idx - 1);
}
_a = 0, files_1 = files;
_b.label = 2;
case 2:
if (!(_a < files_1.length)) return [3 /*break*/, 5];
file = files_1[_a];
return [4 /*yield*/, { base: cleanCheckPath, file: file }];
case 3:
_b.sent();
_b.label = 4;
case 4:
_a++;
return [3 /*break*/, 2];
case 5:
_i++;
return [3 /*break*/, 1];
case 6: return [2 /*return*/];
}
});
};
SimpleScaffold.prototype.getFileContents = function (filePath) {
return fs.readFileSync(filePath).toString();
};
SimpleScaffold.prototype.getOutputPath = function (file, basePath) {
var out;
if (typeof this.config.output === 'function') {
out = this.config.output(file, basePath);
}
else {
var outputDir = this.config.output + ("/" + this.config.name + "/");
var idx = file.indexOf(basePath);
var relativeFilePath = file;
if (idx >= 0) {
relativeFilePath = file.slice(idx + basePath.length + 1);
}
out = outputDir + relativeFilePath;
}
return this.parseLocals(out);
};
SimpleScaffold.prototype.writeFile = function (filePath, fileContents) {
if (!fs.existsSync(path.dirname(filePath))) {
fs.mkdirSync(path.dirname(filePath));
}
console.info('Writing file:', filePath);
fs.writeFileSync(filePath, fileContents, { encoding: 'utf-8' });
};
SimpleScaffold.prototype.run = function () {
console.log("Generating scaffold: " + this.config.name + "...");
var templates = this.fileList(this.config.templates);
var fileConf, count = 0;
while (fileConf = templates.next().value) {
count++;
var file = fileConf.file, base = fileConf.base;
var outputPath = this.getOutputPath(file, base);
var contents = this.getFileContents(file);
var outputContents = this.parseLocals(contents);
this.writeFile(outputPath, outputContents);
console.info('Parsing:', { file: file, base: base, outputPath: outputPath, outputContents: outputContents.replace("\n", "\\n") });
}
if (!count) {
throw new Error('No files to scaffold!');
}
console.log('Done');
};
return SimpleScaffold;
}());
exports.default = SimpleScaffold;
/***/ }),
/* 2 */
/***/ (function(module, exports) {
module.exports = require("fs");
/***/ }),
/* 3 */
/***/ (function(module, exports) {
module.exports = require("glob");
/***/ }),
/* 4 */
/***/ (function(module, exports) {
module.exports = require("handlebars");
/***/ }),
/* 5 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var scaffold_1 = __webpack_require__(1);
var path = __webpack_require__(0);
var templateDir = path.join(process.cwd(), 'examples');
new scaffold_1.default({
templates: [templateDir + '/test-input/Component/**/*'],
output: templateDir + '/test-output',
locals: {
property: 'myProp',
value: '"value"'
}
}).run();
/***/ })
/******/ ]);
});
//# sourceMappingURL=test.js.map

2
dist/test.js.map vendored

File diff suppressed because one or more lines are too long

6
index.d.ts vendored
View File

@@ -7,12 +7,6 @@ declare namespace IScaffold {
locals?: any
}
export interface IReplacement {
find: string | RegExp
replace(): string
[other: string]: any
}
export interface IFileRepr {
base: string
file: string

View File

@@ -1,6 +1,6 @@
{
"name": "simple-scaffold",
"version": "0.2.0",
"version": "0.3.1",
"description": "Create files based on templates",
"repository": "https://github.com/chenasraf/simple-scaffold.git",
"author": "Chen Asraf <inbox@casraf.com>",
@@ -12,7 +12,7 @@
"build": "NODE_ENV=${NODE_ENV:-production} webpack -p && chmod -R +x ./dist",
"dev": "webpack --watch",
"start": "node dist/scaffold.js",
"test": "node dist/test.js",
"test": "jest",
"cmd": "dist/cmd.js",
"build-test": "yarn build && yarn test",
"build-cmd": "yarn build && yarn cmd"
@@ -28,5 +28,14 @@
"webpack": "^3.8.1",
"webpack-dev-server": "^2.9.4",
"webpack-node-externals": "^1.6.0"
},
"devDependencies": {
"jest": "^22.0.4"
},
"jest": {
"testPathIgnorePatterns": [
"node_modules",
"dist"
]
}
}

View File

@@ -5,8 +5,8 @@ import * as glob from 'glob'
import * as handlebars from 'handlebars'
class SimpleScaffold {
private config: IScaffold.IConfig
private locals = {} as any
public config: IScaffold.IConfig
public locals = {} as any
constructor(config: IScaffold.IConfig) {
const DefaultConfig: IScaffold.IConfig = {
@@ -47,6 +47,7 @@ class SimpleScaffold {
}
private getFileContents(filePath: string): string {
console.log(fs.readFileSync(filePath))
return fs.readFileSync(filePath).toString()
}