Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support drives other than C:\ on Windows #4

Closed
wants to merge 2 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 80 additions & 5 deletions source/filesystem.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,25 @@ 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,
isFile: stat.isFile(),
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;
})
)))
Expand All @@ -37,11 +43,80 @@ 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.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");
}

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;
});
}

// 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);
}

function normalizePath(dir) {
return (IS_WINDOWS) ? normalizeWindowsPath(dir) : dir;
}

module.exports = {
Expand Down