Carrying over this often-requested feature from https://github.com/joyent/node/issues/2857. There's two mechanisms in Unix concering the tilde in paths:
~
at the beginning of a path string to the current user's home directory.~user
at the beginning of a path string to the given user's home directory.The first part should be quite trivial to add if #682 get implemented. The second part is far more uncommon and would likely require passwd
parsing (for which consensus seems to be that it's libuv territory - https://github.com/libuv/libuv/issues/11), and god-knows-what on Windows.
Would we be satisified if only the first part gets added to all relevant path
functions? I assume this could be added in a non-breaking way, which wouldn't require a semver-major bump.
> var fs = require('fs');
undefined
> fs.mkdirSync('~test');
undefined
> fs.writeFileSync('~test/~file', 'myData');
undefined
> fs.readFileSync('~test/~file', 'utf8');
'myData'
Seeing as right now one can viably and reliably write to / read from / create directories with a tilde as a prefix, I'd say that this would cause a breaking change and require semver-major
. However, I would favor this feature and wouldn't cry if I 2 wasn't implemented.
I'm -1 on this. On the one hand yes, many developers may expect ~
on *nix to be (internally) replaced with the path to a user's home directory, but I'm not sure Windows users would expect that since Windows does not support ~
in the command prompt and other places?
There's also other issues:
~
expansions (e.g. ~+
, ~-
, ~1
, ~2
, etc)? Do we add support for inline replacing of environment variables in strings (e.g. fs.mkdirSync('$HOME/foo')
)? Do we keep parity when bash adds other new features? What about other shells' features?-1, similar reasons to @mscdex, mainly because this is a shell construct and we are not building a shell.
How do you escape the tilde (in a sane way) to keep expansion from happening?
Good point. While shells allow a simple \~
, the only way I can think of in JS would be '\\~'
which is beyond ugly. Along with the (very slight) possibility of a breaking change, I'm almost convinced to leave this out of core. I'll close this shortly if no serious support is obtained.
I think it's decided then.
For anyone needing tilde expansion, have a look at untildify. I'm planning to add support for the more exotic tilde expansions of bash to it too.
This functionality could be added to the posix._makeLong() function (lib/path.js), and that avoids the problem of what to do on Windows. win32._makeLong() has it's own logic for resolving path names, for POSIX there is no 'smart' logic.
has this been fixed?
it's causing aws-sdk to break, which uses ~/.aws/credentials
CredentialsError: Missing credentials in config
I just tested node 6.3.1 and it's not fixed. You can test it by doing something like require('fs').readFileSync('~/.bash_history').toString()
in the REPL.
No. You can use os.homedir()
to expand the ~
yourself, or use a third party module like untildify
.
For everyone who stumbles upon this. Here's what I came up with (if you're working with a file in a directory / directories):
let credentials = '~/root/foo/bar/key.json';
const credParts = credentials.split(path.sep);
if (credParts[0] === '~') {
credParts[0] = os.homedir();
credentials = credParts.reduce((memo, part) => path.join(memo, part), '');
}
For everyone who stumbles upon this. Here's what I came up with:
Two other variations:
If your original path is OS appropriate
let credentials = '~/root/foo/bar/key.json';
credentials = credentials.replace(/^~/, os.homedir());
If you use node >= v6
```js
let credentials = '~/root/foo/bar/key.json';
const credParts = credentials.split(path.sep);
if (credParts[0] === '~') {
credParts[0] = os.homedir();
}
credentials = path.join(...credParts);
Your examples will fail on files named ~file
. I'd suggest you use untildify.
Your examples will fail on files named ~file
That's valid (asking as an occasional non-expert *inx user)?
Your examples will fail on files named ~file
That's valid (asking as an occasional non-expert *inx user)?
Sure, filenames can start with a literal ~
– tilde expansion is purely a shell thing, the OS or the filesystem doesn’t care. (Also fyi, in shells ~foo
typically expands to the home directory of the user named foo
).
Most helpful comment
No. You can use
os.homedir()
to expand the~
yourself, or use a third party module likeuntildify
.