From cfc797ec997cc31f4b960e15b28e6a8f408dbd1f Mon Sep 17 00:00:00 2001 From: Joan Piedra Date: Sun, 14 Jul 2019 04:38:44 -0500 Subject: [PATCH 1/2] Support drives other than C:\ on Windows Edited `filesystem.js` functions to support Windows drives - `getDirectoryContents` shows a list of Windows drives when requested `/` root path - Subsequent paths will be formatted as `//`. Eg. `/c/Users/neojp/Desktop/archive.bcup` - A new function `normalizeWindowsPath` will convert server request paths into resolved Windows paths `/c/Users/neojp/Desktop/archive.bcup` -> `c:\\Users\\neojp\\Desktop\\archive.bcup` Fixes #3 --- source/filesystem.js | 74 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 69 insertions(+), 5 deletions(-) diff --git a/source/filesystem.js b/source/filesystem.js index 1ca660a..7e17581 100644 --- a/source/filesystem.js +++ b/source/filesystem.js @@ -9,11 +9,17 @@ const stat = pify(fs.stat); const writeFile = pify(fs.writeFile); const FILES_TO_HIDE = /^\./; +const IS_WINDOWS = process.platform === 'win32'; function getDirectoryContents(dir) { - return readDir(dir) + if (IS_WINDOWS && dir === '/') { + return handleWindowsRootPath(); + } + + let dirRealPath = normalizePath(dir); + return readDir(dirRealPath) .then(contents => Promise.all(contents.map(filename => - stat(path.join(dir, filename)) + stat(path.join(dirRealPath, filename)) .then(stat => ({ name: filename, directory: dir, @@ -21,7 +27,7 @@ function getDirectoryContents(dir) { isDirectory: stat.isDirectory() })) .catch(err => { - console.error(`Error while trying to stat file: ${path.join(dir, filename)} (${err.message})`); + console.error(`Error while trying to stat file: ${path.join(dirRealPath, filename)} (${err.message})`); return null; }) ))) @@ -37,11 +43,69 @@ function getDirectoryContents(dir) { } function getFileContents(path) { - return readFile(path, "utf8"); + return readFile(normalizePath(path), "utf8"); } function putFileContents(path, contents) { - return writeFile(path, contents, "utf8"); + // windows paths must have at least 3 parts due to drive letter + // 2 or less parts mean script is write to a path that doesn't exist + if (IS_WINDOWS && path.split('/').length <= 2) { + return Promise.reject(new Error(`Can't write files on Windows root path`)); + } + return writeFile(normalizePath(path), contents, "utf8"); +} + +function getWindowsDrives() { + return new Promise((resolve, reject) => { + let stdout = ''; + let stderr; + const { spawn } = require('child_process'), + list = spawn('cmd'); + + list.stdout.on('data', (data) => stdout += data); + list.stderr.on('data', (data) => stderr += data); + + list.on('exit', function (code) { + if (code == 0) { + let data = stdout.split('\r\n'); + data = data.splice(4, data.length - 7); + data = data.map(drive => drive.substring(0, 1).toLowerCase()); + resolve(data); + } else { + reject({ code, message: stderr }); + } + }); + list.stdin.write('wmic logicaldisk get caption\n'); + list.stdin.end(); + }); + +} + +function handleWindowsRootPath(dir) { + return getWindowsDrives() + .then(drives => { + return drives.map(drive => { + return { + name: drive, + directory: '/', + type: 'directory' + }; + }); + }) + .catch(err => { + console.error(`Error while trying to get all Windows drives: (${err.message})`); + return null; + }); +} + +function normalizeWindowsPath(dir) { + const drive = dir.substring(1, 2) + ':'; + const filePath = dir.substring(2) || '/'; + return path.join(drive, filePath); +} + +function normalizePath(dir) { + return (IS_WINDOWS) ? normalizeWindowsPath(dir) : dir; } module.exports = { From e51d0e34adccb41eb55e3262410e0cf1724de982 Mon Sep 17 00:00:00 2001 From: Joan Piedra Date: Sun, 14 Jul 2019 05:24:40 -0500 Subject: [PATCH 2/2] handle proper windows paths passed to `filesystem.js` functions --- source/filesystem.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/source/filesystem.js b/source/filesystem.js index 7e17581..8f3ee75 100644 --- a/source/filesystem.js +++ b/source/filesystem.js @@ -49,7 +49,7 @@ function getFileContents(path) { function putFileContents(path, contents) { // windows paths must have at least 3 parts due to drive letter // 2 or less parts mean script is write to a path that doesn't exist - if (IS_WINDOWS && path.split('/').length <= 2) { + if (IS_WINDOWS && path.indexOf('\\') === -1 && path.split('/').length <= 2) { return Promise.reject(new Error(`Can't write files on Windows root path`)); } return writeFile(normalizePath(path), contents, "utf8"); @@ -98,9 +98,20 @@ function handleWindowsRootPath(dir) { }); } +// convert unix like path to windows path function normalizeWindowsPath(dir) { + // ignore proper windows path + if (dir.indexOf('\\') > -1) { + return path.normalize(dir); + } + + // replace drive letter from /c/ to c:/ const drive = dir.substring(1, 2) + ':'; + + // grab rest of the path const filePath = dir.substring(2) || '/'; + + // convert path to Windows format return path.join(drive, filePath); }