Comparing version 3.0.0 to 3.1.0
#!/usr/bin/env node | ||
var touch = require("../touch") | ||
, fs = require("fs") | ||
, path = require("path") | ||
, nopt = require("nopt") | ||
, types = { atime: Boolean | ||
, mtime: Boolean | ||
, time: Date | ||
, ref: path | ||
, nocreate: Boolean | ||
, force: Boolean } | ||
, shorthands = { a: "--atime" | ||
, m: "--mtime" | ||
, r: "--ref" | ||
, t: "--time" | ||
, c: "--nocreate" | ||
, f: "--force" } | ||
const touch = require("../index.js") | ||
var options = nopt(types, shorthands) | ||
const usage = code => { | ||
console[code ? 'error' : 'log']( | ||
'usage:\n' + | ||
'touch [-acfm] [-r file] [-t [[CC]YY]MMDDhhmm[.SS]] file ...' | ||
) | ||
process.exit(code) | ||
} | ||
var files = options.argv.remain | ||
delete options.argv | ||
const singleFlags = { | ||
a: 'atime', | ||
m: 'mtime', | ||
c: 'nocreate', | ||
f: 'force' | ||
} | ||
const singleOpts = { | ||
r: 'ref', | ||
t: 'time' | ||
} | ||
const files = [] | ||
const args = process.argv.slice(2) | ||
const options = {} | ||
for (let i = 0; i < args.length; i++) { | ||
const arg = args[i] | ||
if (!arg.match(/^-/)) { | ||
files.push(arg) | ||
continue | ||
} | ||
// expand shorthands | ||
if (arg.charAt(1) !== '-') { | ||
const expand = [] | ||
for (let f = 1; f < arg.length; f++) { | ||
const fc = arg.charAt(f) | ||
const sf = singleFlags[fc] | ||
const so = singleOpts[fc] | ||
if (sf) | ||
expand.push('--' + sf) | ||
else if (so) { | ||
const soslice = arg.slice(f + 1) | ||
const soval = soslice.charAt(0) === '=' ? soslice : '=' + soslice | ||
expand.push('--' + so + soval) | ||
f = arg.length | ||
} else if (arg !== '-' + fc) | ||
expand.push('-' + fc) | ||
} | ||
if (expand.length) { | ||
args.splice.apply(args, [i, 1].concat(expand)) | ||
i-- | ||
continue | ||
} | ||
} | ||
const argsplit = arg.split('=') | ||
const key = argsplit.shift().replace(/^\-\-/, '') | ||
const val = argsplit.length ? argsplit.join('=') : null | ||
switch (key) { | ||
case 'time': | ||
const timestr = val || args[++i] | ||
// [-t [[CC]YY]MMDDhhmm[.SS]] | ||
const parsedtime = timestr.match( | ||
/^(([0-9]{2})?([0-9]{2}))?([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})(\.([0-9]{2}))?$/ | ||
) | ||
if (!parsedtime) { | ||
console.error('touch: out of range or illegal ' + | ||
'time specification: ' + | ||
'[[CC]YY]MMDDhhmm[.SS]') | ||
process.exit(1) | ||
} else { | ||
const y = +parsedtime[1] | ||
const year = parsedtime[2] ? y | ||
: y <= 68 ? 2000 + y | ||
: 1900 + y | ||
const MM = +parsedtime[4] - 1 | ||
const dd = +parsedtime[5] | ||
const hh = +parsedtime[6] | ||
const mm = +parsedtime[7] | ||
const ss = +parsedtime[8] | ||
options.time = new Date(Date.UTC(year, MM, dd, hh, mm, ss)) | ||
} | ||
continue | ||
case 'ref': | ||
options.ref = val || args[++i] | ||
continue | ||
case 'mtime': | ||
case 'nocreate': | ||
case 'atime': | ||
case 'force': | ||
options[key] = true | ||
continue | ||
default: | ||
console.error('touch: illegal option -- ' + arg) | ||
usage(1) | ||
} | ||
} | ||
if (!files.length) | ||
usage() | ||
process.exitCode = 0 | ||
files.forEach(function (file) { | ||
touch(file, options, function (er) { | ||
if (er) | ||
process.exitCode = 1 | ||
}) | ||
}) | ||
Promise.all(files.map(f => touch(f, options))) | ||
.catch(er => process.exitCode = 1) |
60
index.js
@@ -74,2 +74,4 @@ 'use strict' | ||
this.ref = options.ref | ||
this.nocreate = !!options.nocreate | ||
this.force = !!options.force | ||
this.closeAfter = options.closeAfter | ||
@@ -83,3 +85,3 @@ this.oflags = options.oflags | ||
} else | ||
this.onopen(this.fd) | ||
this.onopen(null, this.fd) | ||
} | ||
@@ -100,20 +102,24 @@ | ||
open () { | ||
fs.open(this.path, this.oflags, (er, fd) => { | ||
if (er) | ||
fs.open(this.path, this.oflags, (er, fd) => this.onopen(er, fd)) | ||
} | ||
onopen (er, fd) { | ||
if (er) { | ||
if (er.code === 'EISDIR') | ||
this.onopen(null, null) | ||
else if (er.code === 'ENOENT' && this.nocreate) | ||
this.emit('done') | ||
else | ||
this.emit('error', er) | ||
} else { | ||
this.fd = fd | ||
if (this.ref) | ||
this.statref() | ||
else if (!this.atime || !this.mtime) | ||
this.fstat() | ||
else | ||
this.onopen(fd) | ||
}) | ||
this.futimes() | ||
} | ||
} | ||
onopen (fd) { | ||
this.fd = fd | ||
if (this.ref) | ||
this.statref() | ||
else if (!this.atime || !this.mtime) | ||
this.fstat() | ||
else | ||
this.futimes() | ||
} | ||
statref () { | ||
@@ -138,3 +144,5 @@ fs.stat(this.ref, (er, st) => { | ||
fstat () { | ||
fs.fstat(this.fd, (er, st) => { | ||
const stat = this.fd ? 'fstat' : 'stat' | ||
const target = this.fd || this.path | ||
fs[stat](target, (er, st) => { | ||
if (er) | ||
@@ -158,3 +166,5 @@ this.emit('error', er) | ||
futimes () { | ||
fs.futimes(this.fd, this.atime, this.mtime, er => { | ||
const utimes = this.fd ? 'futimes' : 'utimes' | ||
const target = this.fd || this.path | ||
fs[utimes](target, ''+this.atime, ''+this.mtime, er => { | ||
if (er) | ||
@@ -170,3 +180,7 @@ this.emit('error', er) | ||
open () { | ||
this.onopen(fs.openSync(this.path, this.oflags)) | ||
try { | ||
this.onopen(null, fs.openSync(this.path, this.oflags)) | ||
} catch (er) { | ||
this.onopen(er) | ||
} | ||
} | ||
@@ -187,4 +201,6 @@ | ||
let threw = true | ||
const stat = this.fd ? 'fstatSync' : 'statSync' | ||
const target = this.fd || this.path | ||
try { | ||
this.onfstat(fs.fstatSync(this.fd)) | ||
this.onfstat(fs[stat](target)) | ||
threw = false | ||
@@ -199,4 +215,6 @@ } finally { | ||
let threw = true | ||
const utimes = this.fd ? 'futimesSync' : 'utimesSync' | ||
const target = this.fd || this.path | ||
try { | ||
fs.futimesSync(this.fd, this.atime, this.mtime) | ||
fs[utimes](target, this.atime, this.mtime) | ||
threw = false | ||
@@ -212,4 +230,4 @@ } finally { | ||
if (typeof this.fd === 'number' && this.closeAfter) | ||
fs.closeSync(this.fd) | ||
try { fs.closeSync(this.fd) } catch (er) {} | ||
} | ||
} |
@@ -5,3 +5,3 @@ { | ||
"description": "like touch(1) in node", | ||
"version": "3.0.0", | ||
"version": "3.1.0", | ||
"repository": "git://github.com/isaacs/node-touch.git", | ||
@@ -16,3 +16,3 @@ "bin": { | ||
"scripts": { | ||
"test": "tap test/*.js --100", | ||
"test": "tap test/*.js --100 -J", | ||
"preversion": "npm test", | ||
@@ -19,0 +19,0 @@ "postversion": "npm publish", |
@@ -48,1 +48,6 @@ # node-touch | ||
one of them is set, then the other is not. | ||
## cli | ||
This package creates a `nodetouch` command line executable that works | ||
very much like the unix builtin `touch(1)` |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
10276
289
53
2
0