jstty / beelzebub Goto Github PK
View Code? Open in Web Editor NEWOne hell of a Task Master!
Home Page: http://beelzebub.io
License: Other
One hell of a Task Master!
Home Page: http://beelzebub.io
License: Other
bz.add(MyTasks);
bz.run( // all args run in sequence
['MyTasks.task1',
'MyTasks.task2'
]);
(Full example):
'use strict';
// !-- FOR TESTS
let wrapper = function (options) {
// --!
// =====================================================
let Beelzebub = require('../../');
let bz = Beelzebub(options || { verbose: true });
class MyTasks extends Beelzebub.Tasks {
constructor (config) {
super(config);
this.$setName('MyTasks');
this._delayTime = 500;
}
_delay (message, delay) {
return new Promise((resolve, reject) => {
setTimeout(() => {
this.logger.log(message);
resolve();
}, delay);
});
}
/**
* Promise based task
*/
task1 () {
this.logger.log('MyTasks task1: before');
return this._delay('MyTasks task1: promise delay ' + this._delayTime, this._delayTime)
.then(() => {
this.logger.log('MyTasks task1: after');
});
}
/**
* generator based tasks
*/
* task2 () {
let delay = this._delayTime + 200;
this.logger.log('MyTasks task2: before');
yield this._delay('MyTasks task2: yield delay ' + delay, delay);
this.logger.log('MyTasks task2: after');
}
/**
* async/await based task
*/
// async task3() {
// this.logger.log('MyTasks task3: before');
// await this._delay('MyTasks task3: await delay'+this._delayTime);
// this.logger.log('MyTasks task3: after');
// }
}
bz.add(MyTasks);
bz.run( // all args run in sequence
[ // arrays run in parallel
'MyTasks.task1',
'MyTasks.task2'
//, 'MyTasks.task3'
]
);
// =====================================================
// !-- FOR TESTS
return bz; };
module.exports = wrapper;
// if not running in test, then run wrapper
if (typeof global.it !== 'function') wrapper();
// --!
test should fail on release before PR #17
Imagine I have a lint task:
class Lint extends Beelzebub.Tasks {
constructor(config) {
super(config);
this.$setName('lint');
this.$setDefault('default');
}
default(options) {
if (options.verbose) {
this.$setGlobalVars({ verbose: true });
}
this.sequence('lint.frontend', 'lint.server');
}
frontend() {
// lint for frontend
}
server() {
// lint for server
}
}
Now imagine I call bz lint --verbose
, meaning I want verbose logs. The above example properly sets verbose
as global since we are going through the default
task.
However, if I go through bz lint.frontend --verbose
or bz lint.server --verbose
instead of bz lint --verbose
, the global variable is no longer set. This means I need to add another verbose check to each task that could be invoked by beelzebub:
class Lint extends Beelzebub.Tasks {
constructor(config) {
super(config);
this.$setName('lint');
this.$setDefault('default');
}
default(options) {
if (options.verbose) {
this.$setGlobalVars({ verbose: true });
}
this.sequence('lint.frontend', 'lint.server');
}
frontend(options) {
if (options.verbose) {
this.$setGlobalVars({ verbose: true });
}
// lint for frontend
}
server(options) {
if (options.verbose) {
this.$setGlobalVars({ verbose: true });
}
// lint for server
}
}
This works but is tedious, especially for classes with many tasks. Ideally there would be just one place where global variables are set. Is this currently possible with beelzebub? If not, I think a good place could be the $init
method
class Lint extends Beelzebub.Tasks {
constructor(config) {
super(config);
this.$setName('lint');
this.$setDefault('default');
}
$init(options) {
if (options.verbose) {
this.$setGlobalVars({ verbose: true });
}
}
default() {
this.sequence('lint.frontend', 'lint.server');
}
frontend() {
// lint for frontend
}
server() {
// lint for server
}
}
When printing help docs, it would using the var definition to print "help" docs for each arg
let Beelzebub = require('beelzebub');
let bz = Beelzebub();
class MyTasks extends Beelzebub.Tasks {
constructor (config) {
super(config);
this.$setDefault('task');
}
task () {
this.logger.log('task');
}
}
bz.add(MyTasks);
let p = bz.run('MyTasks'
, 'MyTasks.task' // this throws errors
);
Adding a virtual file system would:
let Beelzebub = require('beelzebub');
let bz = Beelzebub();
class MyTasks extends Beelzebub.Tasks {
default () {
var globalVars = this.$getGlobalVars() // will result return "null", it should be an empty object
this.logger.log('globalVars:', globalVars);
}
}
bz.add(MyTasks);
bz.run('MyTasks');
record how long each task takes for reporting
If we run 1 separate task, $init methods of every task would be invoked. It strongly decreases performance in cases, when we have yanpm installing modules in this $init hooks.
Like transfuser ~ vs $
Something like
bz-bundle --type=sh --in=mytasks.js --out=bundle.sh
Would bundle all the js code into one single bundled file that is marked executable and wrapped to execute shell script (# !/bin/sh)
There is lots of ways the file(s) could be bundled/compressed as well. So an optimzation flag could be added later.
imagine we have:
class MyBaseTasks extends Beelzebub.Tasks {
$beforeEach () {
console.log('MyBaseTasks beforeEach');
}
$afterEach () {
console.log('MyBaseTasks afterEach');
}
$beforeAll () {
console.log('MyBaseTasks beforeAll');
}
$afterAll () {
console.log('MyBaseTasks afterAll');
}
task() {}
}
class MyTasks extends Beelzebub.Tasks {
$init () {
console.log('MyTasks init');
this.$addSubTasks(MyBaseTasks);
}
default() {
return this.$sequence('.MyBaseTasks.task');
}
$beforeEach () {
console.log('MyTasks beforeEach');
}
$afterEach () {
console.log('MyTasks afterEach');
}
$beforeAll () {
console.log('MyTasks beforeAll');
}
$afterAll () {
console.log('MyTasks afterAll');
}
}
bz.add(MyTasks);
let p = bz.run('MyTasks.MyBaseTasks.task');
output would be:
MyTasks init
MyBaseTasks beforeAll
MyBaseTasks beforeEach
[00:00.014] └─┐ task
[00:00.017] ┌─┘ task (0.23ms)
MyBaseTasks afterEach
MyBaseTasks afterAll
MyTasks afterAll
should be at least with $beforeAll hook, because it's used for initialization that subtask could rely on :
MyTasks init
MyTasks beforeAll
MyBaseTasks beforeAll
MyBaseTasks beforeEach
[00:00.014] └─┐ task
[00:00.017] ┌─┘ task (0.23ms)
MyBaseTasks afterEach
MyBaseTasks afterAll
MyTasks afterAll
see #30 for details
could be used for CLI and making your own scripts
Example:
#!/bin/env bz
const bz = require('bz');
class MyTask extends bz {
...
}
This will make testing tasks much easier
[2016...] Test 1
[2016...] -> Starting Task
[2016...] | Test 1 Logs...
[2016...] | Sub Test 1
[2016...] | -> Starting Task
[2016...] | | Sub Test 1 Logs...
[2016...] | <- Finished Task []
[2016...] | Sub Test 2
[2016...] | -> Starting Task
[2016...] | | Sub Test 2 Log 1...
[2016...] | | Sub Test 2 Log 2...
[2016...] | <- Finished Task []
[2016...] <- Finished Task []
[2016...] Summary
[2016...] Total Time: <>
Maybe use:
https://github.com/substack/node-archy
or
https://github.com/MrRaindrop/tree-cli
With lots of awesome animation and stuff exploding!
Either using decorators and/or $ bzTask functions
[Feature request]: If task not found, output help
Example:
"build.frontend" -> "frontend.build"
let Beelzebub = require('beelzebub');
let bz = Beelzebub();
class MyRealTasks extends Beelzebub.Tasks {
task1 () {
this.logger.log('MyRealTasks task1');
}
task2 () {
this.logger.log('MySubTasks task2');
}
}
class MyTaskInterface extends Beelzebub.Tasks {
constructor (config) {
super(config);
}
$beforeAll () {
// this allows for dynamic interfacing base on configuration
this.$isInterfactFor(MyRealTasks);
}
task1 () {
this.logger.error('should be overriden');
}
task2 () {
this.logger.error('should be overriden');
}
}
bz.add(MyTaskInterface);
bz.run('MyTaskInterface.task1');
let Beelzebub = require('beelzebub');
let bz = Beelzebub();
class MySubTasks extends Beelzebub.Tasks {
default () {
this.logger.log('MySubTasks default');
}
}
class MyTasks extends Beelzebub.Tasks {
$beforeAll () {
this.$addSubTasks(MySubTasks);
}
default () {
this.logger.log('MyTasks default');
}
}
bz.add(MyTasks);
bz.run('MyTasks.MySubTasks');
Calling this.$setGlobalVars(payload) in multiple places overwrites existing globalVars.
Easy fix on the user would be to cache existing before adding new vars, should be documented somewhere
replace the npm scripts with alias to internal bz tasks
cd, mkdir, writeJSON, readJSON...
interface class type for dynamic configuration driven sub task selection
It would be nice to have these hooks. $beforeEach and $afterEach would be useful for better logging, for example log entering and leaving functions. $before would be useful for executing all heavy init logic.
It seems like the files from PR #17 (bin/index.js & lib/bzCLI.js) remain unchanged in the latest release and all current branches. Perhaps they got reverted back ( I think from c0fdb9d ). For example, what should be merged vs what is currently there
the build task should use a template to create the index.html
If a task has a hard error the rest of the tasks will proceed-- perhaps config to hard stop on errors?
Print a summary at the end of total time/mem usage
Print how long init, befor/after*
add more examples with each example highlighting each features
possible get rid of "kitchen sink" example
from subtask method:
return this.$sequence(
{
task: '.build.native',
vars: {
type: this.type
}
}
);
works only with absolute path:
return this.$sequence(
{
task: `app.${this.name}.build.native`,
vars: {
type: this.type
}
}
);
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.