UNPKG

@nteract/fs-kernels

Version:

A manager for the filesystem aspects of Juyter kernels

227 lines (226 loc) 7.59 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const child_process_1 = require("child_process"); const fs_1 = __importDefault(require("fs")); const os_1 = require("os"); const path_1 = __importDefault(require("path")); let sysPrefixGuess; function home(subDir) { const baseDir = os_1.homedir(); return subDir ? path_1.default.join(baseDir, subDir) : baseDir; } function pushIfExists(paths, pathToPush) { if (fs_1.default.existsSync(pathToPush)) { paths.push(pathToPush); } } function accessCheck(d) { // check if a directory exists and is listable (X_OK) if (!fs_1.default.existsSync(d)) { return false; } try { fs_1.default.accessSync(d, fs_1.default.constants.X_OK); } catch (e) { // [WSA]EACCES return false; } return true; } function guessSysPrefix() { // inexpensive guess for sysPrefix based on location of `which python` // based on shutil.which from Python 3.5 // only run once: if (sysPrefixGuess !== undefined) { return sysPrefixGuess; } const PATH = (process.env.PATH || "").split(path_1.default.delimiter); if (PATH.length === 0) { sysPrefixGuess = null; return; } let pathext = [""]; if (process.platform === "win32") { pathext = (process.env.PATHEXT || "").split(path_1.default.delimiter); } PATH.some(bin => { bin = path_1.default.resolve(bin); const python = path_1.default.join(bin, "python"); return pathext.some((ext) => { const exe = python + ext; if (accessCheck(exe)) { // PREFIX/bin/python exists, return PREFIX // following symlinks if (process.platform === "win32") { // Windows: Prefix\Python.exe sysPrefixGuess = path_1.default.dirname(fs_1.default.realpathSync(exe)); } else { // Everywhere else: prefix/bin/python sysPrefixGuess = path_1.default.dirname(path_1.default.dirname(fs_1.default.realpathSync(exe))); } return true; } return false; }); }); if (sysPrefixGuess === undefined) { // store null as nothing found, but don't run again sysPrefixGuess = null; } return sysPrefixGuess; } let askJupyterPromise = null; function askJupyter() { // ask Jupyter where the paths are if (!askJupyterPromise) { askJupyterPromise = new Promise((resolve, reject) => { child_process_1.exec("python3 -m jupyter --paths --json", (err, stdout) => { if (err) { reject(err); } else { resolve(JSON.parse(stdout.toString().trim())); } }); }); } return askJupyterPromise; } function systemConfigDirs() { const paths = []; // System wide for Windows and Unix if (process.platform === "win32") { const defaultProgramDataPath = "C:\\ProgramData"; pushIfExists(paths, path_1.default.resolve(path_1.default.join(process.env.PROGRAMDATA || defaultProgramDataPath, "jupyter"))); } else { pushIfExists(paths, "/usr/local/etc/jupyter"); pushIfExists(paths, "/etc/jupyter"); } return paths; } async function configDirs(opts) { if (opts && opts.askJupyter) { try { const configPaths = await askJupyter(); return configPaths.config.filter(fs_1.default.existsSync); } catch (_a) { return configDirs(); } } const paths = []; if (process.env.JUPYTER_CONFIG_DIR) { pushIfExists(paths, process.env.JUPYTER_CONFIG_DIR); } pushIfExists(paths, home(".jupyter")); const systemDirs = systemConfigDirs(); if (opts && opts.withSysPrefix) { return new Promise((resolve, reject) => { // deprecated: withSysPrefix expects a Promise // but no change in content resolve(configDirs()); }); } // inexpensive guess, based on location of `python` executable const sysPrefix = guessSysPrefix() || "/usr/local/"; const sysPathed = path_1.default.join(sysPrefix, "etc", "jupyter"); if (systemDirs.indexOf(sysPathed) === -1) { pushIfExists(paths, sysPathed); } return paths.concat(systemDirs); } function systemDataDirs() { const paths = []; // System wide for Windows and Unix if (process.platform === "win32") { const defaultProgramDataPath = "C:\\ProgramData"; pushIfExists(paths, path_1.default.resolve(path_1.default.join(process.env.PROGRAMDATA || defaultProgramDataPath, "jupyter"))); } else { pushIfExists(paths, "/usr/local/share/jupyter"); pushIfExists(paths, "/usr/share/jupyter"); } return paths; } /** * where the userland data directory resides * includes things like the runtime files * @return directory for data */ function userDataDir() { // Userland specific if (process.platform === "darwin") { return home("Library/Jupyter"); } else if (process.platform === "win32") { const defaultAppDataPath = home("AppData"); return path_1.default.resolve(path_1.default.join(process.env.APPDATA || defaultAppDataPath, "jupyter")); } return process.env.XDG_DATA_HOME || home(".local/share/jupyter"); } /** * dataDirs returns all the expected static directories for this OS. * The user of this function should make sure to make sure the directories * exist. * * When withSysPrefix is set, this returns a promise of directories * * @param withSysPrefix include the sys.prefix paths * @return All the Jupyter Data Dirs */ async function dataDirs(opts) { if (opts && opts.askJupyter) { try { const dataPaths = await askJupyter(); return dataPaths.data.filter(fs_1.default.existsSync); } catch (error) { return dataDirs(); } } const paths = []; if (process.env.JUPYTER_PATH) { pushIfExists(paths, process.env.JUPYTER_PATH); } pushIfExists(paths, userDataDir()); const systemDirs = systemDataDirs(); if (opts && opts.withSysPrefix) { // deprecated: withSysPrefix expects a Promise // but no change in content return await (async () => dataDirs())(); } // inexpensive guess, based on location of `python` executable const sysPrefix = guessSysPrefix(); if (sysPrefix) { const sysPathed = path_1.default.join(sysPrefix, "share", "jupyter"); if (systemDirs.indexOf(sysPathed) === -1) { pushIfExists(paths, sysPathed); } } return paths.concat(systemDirs); } async function runtimeDir(opts) { if (opts && opts.askJupyter) { try { const paths = await askJupyter(); return paths.runtime; } catch (error) { return runtimeDir(); } } if (process.env.JUPYTER_RUNTIME_DIR) { return process.env.JUPYTER_RUNTIME_DIR; } if (process.env.XDG_RUNTIME_DIR) { return path_1.default.join(process.env.XDG_RUNTIME_DIR, "jupyter"); } return path_1.default.join(userDataDir(), "runtime"); } exports.default = { dataDirs, runtimeDir, configDirs, guessSysPrefix };