UNPKG

2.72 kBJavaScriptView Raw
1var common = require('./common');
2var fs = require('fs');
3
4common.register('touch', _touch, {
5 cmdOptions: {
6 'a': 'atime_only',
7 'c': 'no_create',
8 'd': 'date',
9 'm': 'mtime_only',
10 'r': 'reference',
11 },
12});
13
14//@
15//@ ### touch([options,] file [, file ...])
16//@ ### touch([options,] file_array)
17//@
18//@ Available options:
19//@
20//@ + `-a`: Change only the access time
21//@ + `-c`: Do not create any files
22//@ + `-m`: Change only the modification time
23//@ + `-d DATE`: Parse `DATE` and use it instead of current time
24//@ + `-r FILE`: Use `FILE`'s times instead of current time
25//@
26//@ Examples:
27//@
28//@ ```javascript
29//@ touch('source.js');
30//@ touch('-c', '/path/to/some/dir/source.js');
31//@ touch({ '-r': FILE }, '/path/to/some/dir/source.js');
32//@ ```
33//@
34//@ Update the access and modification times of each `FILE` to the current time.
35//@ A `FILE` argument that does not exist is created empty, unless `-c` is supplied.
36//@ This is a partial implementation of [`touch(1)`](http://linux.die.net/man/1/touch).
37function _touch(opts, files) {
38 if (!files) {
39 common.error('no files given');
40 } else if (typeof files === 'string') {
41 files = [].slice.call(arguments, 1);
42 } else {
43 common.error('file arg should be a string file path or an Array of string file paths');
44 }
45
46 files.forEach(function (f) {
47 touchFile(opts, f);
48 });
49 return '';
50}
51
52function touchFile(opts, file) {
53 var stat = tryStatFile(file);
54
55 if (stat && stat.isDirectory()) {
56 // don't error just exit
57 return;
58 }
59
60 // if the file doesn't already exist and the user has specified --no-create then
61 // this script is finished
62 if (!stat && opts.no_create) {
63 return;
64 }
65
66 // open the file and then close it. this will create it if it doesn't exist but will
67 // not truncate the file
68 fs.closeSync(fs.openSync(file, 'a'));
69
70 //
71 // Set timestamps
72 //
73
74 // setup some defaults
75 var now = new Date();
76 var mtime = opts.date || now;
77 var atime = opts.date || now;
78
79 // use reference file
80 if (opts.reference) {
81 var refStat = tryStatFile(opts.reference);
82 if (!refStat) {
83 common.error('failed to get attributess of ' + opts.reference);
84 }
85 mtime = refStat.mtime;
86 atime = refStat.atime;
87 } else if (opts.date) {
88 mtime = opts.date;
89 atime = opts.date;
90 }
91
92 if (opts.atime_only && opts.mtime_only) {
93 // keep the new values of mtime and atime like GNU
94 } else if (opts.atime_only) {
95 mtime = stat.mtime;
96 } else if (opts.mtime_only) {
97 atime = stat.atime;
98 }
99
100 fs.utimesSync(file, atime, mtime);
101}
102
103module.exports = _touch;
104
105function tryStatFile(filePath) {
106 try {
107 return common.statFollowLinks(filePath);
108 } catch (e) {
109 return null;
110 }
111}