prepare to be used as a standalone binary package with pkg

pull/116/merge
Maciej Winnicki 2018-01-03 12:23:46 +01:00
parent 87bfcff493
commit 6cf8a3391f
No known key found for this signature in database
GPG Key ID: 035AA4FA2183ADFA
22 changed files with 2940 additions and 65 deletions

View File

@ -1,2 +1,2 @@
lib/web/assets/tinycon.min.js
lib/web/assets/ansi_up.js
web/assets/tinycon.min.js
web/assets/ansi_up.js

View File

@ -7,4 +7,4 @@
"env": {
"node": true
}
}
}

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
node_modules
test/fixtures/*.pem
npm-debug.log
dist

View File

@ -10,6 +10,8 @@ const connectBuilder = require('./lib/connect_builder');
const program = require('./lib/options_parser');
const serverBuilder = require('./lib/server_builder');
const daemonize = require('./lib/daemonize');
const fs = require('fs');
const untildify = require('untildify');
/**
* Parse args
@ -45,8 +47,8 @@ if (program.daemonize) {
appBuilder.authorize(program.user, program.password);
}
appBuilder
.static(path.join(__dirname, 'lib/web/assets'))
.index(path.join(__dirname, 'lib/web/index.html'), files, filesNamespace, program.theme);
.static(path.join(__dirname, 'web/assets'))
.index(path.join(__dirname, 'web/index.html'), files, filesNamespace, program.theme);
const builder = serverBuilder();
if (doSecure) {
@ -90,7 +92,19 @@ if (program.daemonize) {
*/
let highlightConfig;
if (program.uiHighlight) {
highlightConfig = require(path.resolve(__dirname, program.uiHighlightPreset)); // eslint-disable-line
let presetPath;
if (!program.uiHighlightPreset) {
presetPath = path.join(__dirname, 'preset/default.json');
} else {
presetPath = path.resolve(untildify(program.uiHighlightPreset));
}
if (fs.existsSync(presetPath)) {
highlightConfig = JSON.parse(fs.readFileSync(presetPath));
} else {
throw new Error(`Preset file ${presetPath} doesn't exists`);
}
}
/**

View File

@ -27,10 +27,12 @@ ConnectBuilder.prototype.index = function index(path, files, filesNamespace, the
res.writeHead(200, {
'Content-Type': 'text/html',
});
res.end(data.toString('utf-8')
.replace(/__TITLE__/g, files)
.replace(/__THEME__/g, theme)
.replace(/__NAMESPACE__/g, filesNamespace),
res.end(
data
.toString('utf-8')
.replace(/__TITLE__/g, files)
.replace(/__THEME__/g, theme)
.replace(/__NAMESPACE__/g, filesNamespace),
'utf-8'
);
});
@ -41,10 +43,12 @@ ConnectBuilder.prototype.index = function index(path, files, filesNamespace, the
ConnectBuilder.prototype.session = function session(secret, key) {
this.app.use(connect.cookieParser());
this.app.use(connect.session({
secret,
key,
}));
this.app.use(
connect.session({
secret,
key,
})
);
return this;
};

View File

@ -22,17 +22,11 @@ module.exports = (script, params, opts) => {
];
if (options.doAuthorization) {
args.push(
'-U', params.user,
'-P', params.password
);
args.push('-U', params.user, '-P', params.password);
}
if (options.doSecure) {
args.push(
'-k', params.key,
'-c', params.certificate
);
args.push('-k', params.key, '-c', params.certificate);
}
if (params.uiHideTopbar) {
@ -44,7 +38,11 @@ module.exports = (script, params, opts) => {
}
if (params.uiHighlight) {
args.push('--ui-highlight', '--ui-highlight-preset', params.uiHighlightPreset);
args.push('--ui-highlight');
}
if (params.uiHighlightPreset) {
args.push('--ui-highlight-preset', params.uiHighlightPreset);
}
args = args.concat(params.args);

View File

@ -9,22 +9,51 @@ program
.option('-l, --lines <lines>', 'number on lines stored in browser, default 2000', Number, 2000)
.option('-t, --theme <theme>', 'name of the theme (default, dark)', String, 'default')
.option('-d, --daemonize', 'run as daemon')
.option('-U, --user <username>', 'Basic Authentication username, option works only along with -P option',
String, false)
.option('-P, --password <password>', 'Basic Authentication password, option works only along with -U option',
String, false)
.option('-k, --key <key.pem>', 'Private Key for HTTPS, option works only along with -c option',
String, false)
.option('-c, --certificate <cert.pem>', 'Certificate for HTTPS, option works only along with -k option',
String, false)
.option('--pid-path <path>', 'if run as daemon file that will store the process id, default /var/run/frontail.pid',
String, '/var/run/frontail.pid')
.option('--log-path <path>', 'if run as daemon file that will be used as a log, default /dev/null',
String, '/dev/null')
.option(
'-U, --user <username>',
'Basic Authentication username, option works only along with -P option',
String,
false
)
.option(
'-P, --password <password>',
'Basic Authentication password, option works only along with -U option',
String,
false
)
.option(
'-k, --key <key.pem>',
'Private Key for HTTPS, option works only along with -c option',
String,
false
)
.option(
'-c, --certificate <cert.pem>',
'Certificate for HTTPS, option works only along with -k option',
String,
false
)
.option(
'--pid-path <path>',
'if run as daemon file that will store the process id, default /var/run/frontail.pid',
String,
'/var/run/frontail.pid'
)
.option(
'--log-path <path>',
'if run as daemon file that will be used as a log, default /dev/null',
String,
'/dev/null'
)
.option('--ui-hide-topbar', 'hide topbar (log file name and search box)')
.option('--ui-no-indent', 'don\'t indent log lines')
.option('--ui-highlight', 'highlight words or lines if defined string found in logs, default preset')
.option('--ui-highlight-preset <path>', 'custom preset for highlighting (see ./preset/default.json)', String,
'./preset/default.json');
.option('--ui-no-indent', "don't indent log lines")
.option(
'--ui-highlight',
'highlight words or lines if defined string found in logs, default preset'
)
.option(
'--ui-highlight-preset <path>',
'custom preset for highlighting (see ./preset/default.json)'
);
module.exports = program;

2783
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -13,13 +13,14 @@
"connect": "2.11.0",
"cookie": "0.1.0",
"daemon": "github:zipang/daemon.node#48d0977c26fb3a6a44ae99aae3471b9d5a761085",
"socket.io": "1.4.8"
"socket.io": "1.4.8",
"untildify": "^3.0.2"
},
"devDependencies": {
"eslint": "^3.6.0",
"eslint-config-airbnb-base": "^8.0.0",
"eslint-plugin-import": "^1.16.0",
"jsdom": "^8.5.0",
"jsdom": "^9.12.0",
"mocha": "~2.3.2",
"should": "~3.3.2",
"sinon": "~1.7.3",
@ -28,13 +29,32 @@
},
"scripts": {
"lint": "eslint .",
"test": "mocha -r should --reporter spec test/*.js"
"test": "mocha -r should --reporter spec test/*.js",
"pkg": "pkg --out-path=dist ."
},
"pkg": {
"assets": [
"preset/*.json",
"web/**/*"
],
"targets": [
"node8-alpine-x64",
"node8-linux-x64",
"node8-macos-x64",
"node8-win-x64"
]
},
"repository": {
"type": "git",
"url": "http://github.com/mthenw/frontail.git"
},
"keywords": ["tail", "syslog", "realtime", "log", "devops"],
"keywords": [
"tail",
"syslog",
"realtime",
"log",
"devops"
],
"main": "index",
"preferGlobal": true
}

View File

@ -1,8 +1,8 @@
{
"words": {
"err": "color: red;"
},
"lines": {
"err": "font-weight: bold;"
}
"words": {
"err": "color: red;"
},
"lines": {
"err": "font-weight: bold;"
}
}

View File

@ -26,10 +26,11 @@ describe('browser application', () => {
beforeEach((done) => {
io = new EventEmitter();
const html = '<title></title><body><div class="topbar"></div>' +
const html =
'<title></title><body><div class="topbar"></div>' +
'<div class="log"></div><input type="test" id="filter"/></body>';
const ansiup = fs.readFileSync('./lib/web/assets/ansi_up.js', 'utf-8');
const src = fs.readFileSync('./lib/web/assets/app.js', 'utf-8');
const ansiup = fs.readFileSync('./web/assets/ansi_up.js', 'utf-8');
const src = fs.readFileSync('./web/assets/app.js', 'utf-8');
jsdom.env({
html,
@ -122,9 +123,7 @@ describe('browser application', () => {
io.emit('line', 'line1');
const line = window.document.querySelector('.line');
line.parentNode.innerHTML.should.equal(
'<div class="line" style="background: black"><p class="inner-line">line1</p></div>'
);
line.parentNode.innerHTML.should.equal('<div class="line" style="background: black"><p class="inner-line">line1</p></div>');
});
it('should escape HTML', () => {

View File

@ -6,12 +6,18 @@ const path = require('path');
describe('connectBuilder', () => {
it('should build connect app', () => {
connectBuilder().build().should.have.property('use');
connectBuilder().build().should.have.property('listen');
connectBuilder()
.build()
.should.have.property('use');
connectBuilder()
.build()
.should.have.property('listen');
});
it('should build app requiring authorized user', (done) => {
const app = connectBuilder().authorize('user', 'pass').build();
const app = connectBuilder()
.authorize('user', 'pass')
.build();
request(app)
.get('/')
@ -20,7 +26,9 @@ describe('connectBuilder', () => {
});
it('should build app allowing user to login', (done) => {
const app = connectBuilder().authorize('user', 'pass').build();
const app = connectBuilder()
.authorize('user', 'pass')
.build();
app.use((req, res) => {
res.end('secret!');
});
@ -32,7 +40,9 @@ describe('connectBuilder', () => {
});
it('should build app that setup session', (done) => {
const app = connectBuilder().session('secret', 'sessionkey').build();
const app = connectBuilder()
.session('secret', 'sessionkey')
.build();
app.use((req, res) => {
res.end();
});
@ -43,7 +53,9 @@ describe('connectBuilder', () => {
});
it('should build app that serve static files', (done) => {
const app = connectBuilder().static(path.join(__dirname, 'fixtures')).build();
const app = connectBuilder()
.static(path.join(__dirname, 'fixtures'))
.build();
request(app)
.get('/foo')
@ -51,7 +63,9 @@ describe('connectBuilder', () => {
});
it('should build app that serve index file', (done) => {
const app = connectBuilder().index(path.join(__dirname, 'fixtures/index'), '/testfile').build();
const app = connectBuilder()
.index(path.join(__dirname, 'fixtures/index'), '/testfile')
.build();
request(app)
.get('/')
@ -89,7 +103,7 @@ describe('connectBuilder', () => {
.expect(
'<head><title>/testfile</title><link href="dark.css" rel="stylesheet" type="text/css"/></head>',
done
);
);
});
it('should build app that sets default theme', (done) => {
@ -102,6 +116,6 @@ describe('connectBuilder', () => {
.expect(
'<head><title>/testfile</title><link href="default.css" rel="stylesheet" type="text/css"/></head>',
done
);
);
});
});

View File

@ -129,7 +129,20 @@ describe('daemonize', () => {
daemonize('script', optionsParser);
daemon.daemon.lastCall.args[1].should.containDeep(['--ui-highlight']);
daemon.daemon.lastCall.args[1].should.containDeep(['--ui-highlight-preset', './preset/default.json']);
});
it('with highlight preset option', () => {
optionsParser.parse([
'node',
'/path/to/frontail',
'--ui-highlight',
'--ui-highlight-preset',
'test.json',
]);
daemonize('script', optionsParser);
daemon.daemon.lastCall.args[1].should.containDeep(['--ui-highlight-preset', 'test.json']);
});
it('with file to tail', () => {

View File

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB