blob: 4a4b017e567ad73e6f3036c51ce683331ff20648 [file] [log] [blame]
var common = require('./common');
var fs = require('fs');
//@
//@ ### touch([options,] file [, file ...])
//@ ### touch([options,] file_array)
//@ Available options:
//@
//@ + `-a`: Change only the access time
//@ + `-c`: Do not create any files
//@ + `-m`: Change only the modification time
//@ + `-d DATE`: Parse DATE and use it instead of current time
//@ + `-r FILE`: Use FILE's times instead of current time
//@
//@ Examples:
//@
//@ ```javascript
//@ touch('source.js');
//@ touch('-c', '/path/to/some/dir/source.js');
//@ touch({ '-r': FILE }, '/path/to/some/dir/source.js');
//@ ```
//@
//@ Update the access and modification times of each FILE to the current time.
//@ A FILE argument that does not exist is created empty, unless -c is supplied.
//@ This is a partial implementation of *[touch(1)](http://linux.die.net/man/1/touch)*.
function _touch(opts, files) {
opts = common.parseOptions(opts, {
'a': 'atime_only',
'c': 'no_create',
'd': 'date',
'm': 'mtime_only',
'r': 'reference',
});
if (!files)
common.error('no files given');
else if (typeof files === 'string')
files = [].slice.call(arguments, 1);
else
common.error('file arg should be a string file path or an Array of string file paths');
files.forEach(function(f) {
touchFile(opts, f);
});
return new common.ShellString('', common.state.error, common.state.errorCode);
}
function touchFile(opts, file) {
var stat = tryStatFile(file);
if (stat && stat.isDirectory()) {
// don't error just exit
return;
}
// if the file doesn't already exist and the user has specified --no-create then
// this script is finished
if (!stat && opts.no_create) {
return;
}
// open the file and then close it. this will create it if it doesn't exist but will
// not truncate the file
fs.closeSync(fs.openSync(file, 'a'));
//
// Set timestamps
//
// setup some defaults
var now = new Date();
var mtime = opts.date || now;
var atime = opts.date || now;
// use reference file
if (opts.reference) {
var refStat = tryStatFile(opts.reference);
if (!refStat) {
common.error('failed to get attributess of ' + opts.reference);
}
mtime = refStat.mtime;
atime = refStat.atime;
} else if (opts.date) {
mtime = opts.date;
atime = opts.date;
}
if (opts.atime_only && opts.mtime_only) {
// keep the new values of mtime and atime like GNU
} else if (opts.atime_only) {
mtime = stat.mtime;
} else if (opts.mtime_only) {
atime = stat.atime;
}
fs.utimesSync(file, atime, mtime);
}
module.exports = _touch;
function tryStatFile(filePath) {
try {
return fs.statSync(filePath);
} catch (e) {
return null;
}
}