codekingpro/portable-devtools
114k
1// make sure that bins are executable, and that they don't have
2// windows line-endings on the hashbang line.
3const {
4 chmod,
5 open,
6 readFile,
7} = require('fs/promises')
8
9const execMode = 0o777 & (~process.umask())
10
11const writeFileAtomic = require('write-file-atomic')
12
13const isWindowsHashBang = buf =>
14 buf[0] === '#'.charCodeAt(0) &&
15 buf[1] === '!'.charCodeAt(0) &&
16 /^#![^\n]+\r\n/.test(buf.toString())
17
18const isWindowsHashbangFile = file => {
19 const FALSE = () => false
20 return open(file, 'r').then(fh => {
21 const buf = Buffer.alloc(2048)
22 return fh.read(buf, 0, 2048, 0)
23 .then(
24 () => {
25 const isWHB = isWindowsHashBang(buf)
26 return fh.close().then(() => isWHB, () => isWHB)
27 },
28 // don't leak FD if read() fails
29 () => fh.close().then(FALSE, FALSE)
30 )
31 }, FALSE)
32}
33
34const dos2Unix = file =>
35 readFile(file, 'utf8').then(content =>
36 writeFileAtomic(file, content.replace(/^(#![^\n]+)\r\n/, '$1\n')))
37
38const fixBin = (file, mode = execMode) => chmod(file, mode)
39 .then(() => isWindowsHashbangFile(file))
40 .then(isWHB => isWHB ? dos2Unix(file) : null)
41
42module.exports = fixBin
43 