From 805fe70cc1f15728e29559327637284790a5661b Mon Sep 17 00:00:00 2001 From: Siddharth Kshetrapal Date: Thu, 17 Nov 2016 18:38:42 +0530 Subject: [PATCH 1/2] Added cronfile support --- lib/index.js | 206 ++++++++++++++++++++++++++++----------------------- 1 file changed, 114 insertions(+), 92 deletions(-) diff --git a/lib/index.js b/lib/index.js index aa760fd..3749335 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,54 +1,51 @@ -/** - * Constants - */ -const COMMAND = 'crontab'; - /** * @ignore */ var Spawn = require('child_process').spawn; var _ = require('underscore'); +var fs = require('fs'); var CronJob = require('./CronJob'); /** * @class CronTab * A JavaScript representation of a user crontab. Each tab has zero or more cron jobs corresponding * to the individual lines in the cron syntax. - * + * * Examples: * new CronTab('bob', function(err, tab) { * if (err) { console.log(err); process.exit(1); } - * + * * console.log("bob's tab: " + tab.render()); * }); - * + * * new CronTab(function(err, tab) { * if (err) { console.log(err); process.exit(1); } - * + * * console.log("current user's tab: " + tab.render()); * }); - * + * * @param {String} __username__ * @param {Function} __callback__ */ -function CronTab(u, cb) { +function CronTab(u, f, cb) { var self = this; var user = u || ''; + var file = f || ''; var root = (process.getuid() == 0); var backup = {lines:[], jobs:[]}; var lines = []; var jobs = []; - + load(cb); - - + + /** * Provides access to the jobs collection. - * + * * Examples: * new CronTab(function(err, tab) { * if (err) { console.log(err); process.exit(1); } - * + * * var jobs = tab.jobs((command:'ls -l /', comment:'this should run every night')); * for (var i = 0; i < jobs.length; i++) { * console.log(jobs[i].render()); @@ -89,20 +86,20 @@ function CronTab(u, cb) { results.push(job); } } - + return results; } this.find = this.jobs; /** * Writes the crontab to the system. Saves all information. - * + * * Examples: * new CronTab(function(err, tab) { * if (err) { console.log(err); process.exit(1); } - * + * * var jobs = tab.jobs({command:'ls -l /'}); * tab.remove(jobs); - * + * * tab.save(function(err, tab) { * if (err) { console.log(err); process.exit(1); } * @@ -113,42 +110,55 @@ function CronTab(u, cb) { * @param {Function} __callback__ */ this.save = function(cb) { - var stdout = ''; - var stderr = ''; - var args = makeChildArgs('save'); - var command = makeChildCommand(); - var child = Spawn(command, args); + if (file) { + saveFile(this, cb); + } + else { + var stdout = ''; + var stderr = ''; + var args = makeChildArgs('save'); + var command = makeChildCommand('save'); + console.log(command, args); + var child = Spawn(command, args); - child.stdout.setEncoding('utf8'); - child.stderr.setEncoding('utf8'); - - child.stdout.on('data', function(chunk) { - stdout += chunk; - }); - child.stderr.on('data', function(chunk) { - stderr += chunk; - }); - child.on('error', function (err) { - }); - child.on('close', function (code) { - if (code == 0) { - cb && cb(null, self); - } - else { - cb && cb({message:stderr}, self); - } + child.stdout.setEncoding('utf8'); + child.stderr.setEncoding('utf8'); + + child.stdout.on('data', function(chunk) { + stdout += chunk; + }); + child.stderr.on('data', function(chunk) { + stderr += chunk; + }); + child.on('error', function (err) { + }); + child.on('close', function (code) { + if (code == 0) { + cb && cb(null, self); + } + else { + cb && cb({message:stderr}, self); + } + }); + + child.stdin.write(this.render()); + child.stdin.end(); + } + } + + function saveFile (crontab, cb) { + fs.writeFile(file, crontab.render(), function (err) { + if (err) cb && cb({message:stderr}, self); + else cb && cb(null, self); }); - - child.stdin.write(this.render()); - child.stdin.end(); } /** * Renders the object to a string as it would be written to the system. - * + * * Examples: * new CronTab(function(err, tab) { * if (err) { console.log(err); process.exit(1); } - * + * * console.log(tab.render()); * }); * @@ -156,29 +166,29 @@ function CronTab(u, cb) { */ this.render = function() { var tokens = []; - + for (var i = 0; i < lines.length; i++) { var job = lines[i]; - + if (job.isValid && !job.isValid()) { tokens.push('# ' + job.toString()); continue; } - + tokens.push(job.toString()); } - + return tokens.join('\n').trim() + '\n'; } /** * Creates a new job with the specified command, comment and date. - * + * * Examples: * new CronTab(function(err, tab) { * if (err) { console.log(err); process.exit(1); } - * + * * var future = Date.parse('2010/7/11'); - * + * * tab.create('ls -l /'); * tab.create('ls -l /', 'just a silly example'); * tab.create('ls -l /', 'just a silly example', future); @@ -230,11 +240,11 @@ function CronTab(u, cb) { } /** * Removes the specified jobs from the crontab. - * + * * Examples: * new CronTab(function(err, tab) { * if (err) { console.log(err); process.exit(1); } - * + * * var jobs = tab.jobs({command:'ls -l /'}); * tab.remove(jobs); * }); @@ -255,20 +265,20 @@ function CronTab(u, cb) { else { jobs = []; } - + for (var i = 0; i < jobs.length; i++) { remove(jobs[i]); } - + truncateLines(); } /** * Restores this crontab to its original state. - * + * * Examples: * new CronTab(function(err, tab) { * if (err) { console.log(err); process.exit(1); } - * + * * var jobs = tab.jobs({command:'ls -l /'}); * tab.remove(jobs); * tab.reset(); @@ -278,25 +288,25 @@ function CronTab(u, cb) { lines = backup.lines.slice(); jobs = backup.jobs.slice(); } - - + + /** * Loads the system crontab into this object. * * @param {function} __callback__ - * + * * @api private */ function load(cb) { var stdout = ''; var stderr = ''; var args = makeChildArgs('load'); - var command = makeChildCommand(); + var command = makeChildCommand('load'); var child = Spawn(command, args); - + jobs = []; lines = []; - + child.stdout.setEncoding('utf8'); child.stderr.setEncoding('utf8'); @@ -313,12 +323,12 @@ function CronTab(u, cb) { cb && cb({message:stderr}, null); return; } - + var tokens = stdout.split('\n'); for (var i = 0; i < tokens.length; i++) { var token = tokens[i]; var job = makeJob(token); - + if (job != null && job.isValid()) { jobs.push(job); lines.push(job); @@ -327,39 +337,39 @@ function CronTab(u, cb) { lines.push(token); } } - + truncateLines(); - + backup.lines = lines.slice(); backup.jobs = jobs.slice(); - - cb && cb(null, self); + + cb && cb(null, self); }); } /** * Removes the specified job from the crontab. * * @param {CronJob} __job__ - * + * * @api private */ function remove(job) { var oldJobs = jobs; var oldLines = lines; - + jobs = []; lines = []; - + for (var i = 0; i < oldJobs.length; i++) { var oldJob = oldJobs[i]; - + if (oldJob != job) { jobs.push(oldJob); } } for (var i = 0; i < oldLines.length; i++) { var oldLine = oldLines[i]; - + if (oldLine != job) { lines.push(oldLine); } @@ -370,37 +380,47 @@ function CronTab(u, cb) { * child_process.spawn. * * @param {String} __action__ 'load' | 'save' - * + * * @api private */ function makeChildArgs(action) { var args = []; + + if (file) { + args.push(file); + return args; + } + if (user) { args = args.concat('-u', user); } - + if (action == 'load') { args.push('-l'); } if (action == 'save' && process.platform !== 'sunos') { args.push('-'); } - + return args; } /** * Creates a system command string to run crontab. Intended to be passed to * child_process.spawn. If this is going to run for another user and the * current user is not root, we prefix the command with sudo. - * + * * @api private */ - function makeChildCommand() { - var command = COMMAND; + function makeChildCommand(action) { + var command; + if (file && action) { + command = 'cat'; + } + else command = 'crontab'; if (user.length > 0 && root == false) { command = 'sudo ' + command; } - + return command; } /** @@ -410,7 +430,7 @@ function CronTab(u, cb) { * @param {String|null} __line__ * @param {String} __[command]__ * @param {String} __[comment]__ - * + * * @api private */ function makeJob(line, command, comment) { @@ -427,17 +447,17 @@ function CronTab(u, cb) { } /** * Compacts the line collection by removes empty lines from the end. - * + * * @api private */ function truncateLines() { var undefined; var line = lines.pop(); - + while (line != undefined && line.toString().trim() == '') { line = lines.pop(); } - + if (line != undefined) { lines.push(line); } @@ -449,12 +469,14 @@ function CronTab(u, cb) { module.exports = { load:function() { if (_.isString(arguments[0]) && _.isFunction(arguments[1])) { - new CronTab(arguments[0], arguments[1]); + new CronTab(arguments[0], '', arguments[1]); } else if (_.isFunction(arguments[0])) { - new CronTab('', arguments[0]); + new CronTab('', '', arguments[0]); + } + else if (_.isString(arguments[0]) && _.isString(arguments[1]) && _.isFunction(arguments[2])) { + new CronTab(arguments[0], arguments[1], arguments[2]); } } }; - From 8678d37c398a19b7bd2ccbac4ef2470012bd8812 Mon Sep 17 00:00:00 2001 From: Siddharth Kshetrapal Date: Thu, 17 Nov 2016 19:08:09 +0530 Subject: [PATCH 2/2] Removed debug statement --- lib/index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/index.js b/lib/index.js index 3749335..01168e0 100644 --- a/lib/index.js +++ b/lib/index.js @@ -118,7 +118,6 @@ function CronTab(u, f, cb) { var stderr = ''; var args = makeChildArgs('save'); var command = makeChildCommand('save'); - console.log(command, args); var child = Spawn(command, args); child.stdout.setEncoding('utf8');