UNPKG

wsl-path

Version:

Convert Windows paths to WSL (1 & 2) paths and vice versa

263 lines (262 loc) 11 kB
"use strict"; var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; Object.defineProperty(exports, "__esModule", { value: true }); exports._setForceRunInWsl = exports.windowsToWslSync = exports.wslToWindowsSync = exports.wslToWindows = exports.windowsToWsl = exports.resetCache = void 0; var child_process_1 = require("child_process"); var path_handling_1 = require("./path-handling"); var mount_1 = require("./mount"); var WSL_UTIL = "wslpath"; var _forceRunInWsl = undefined; var inMemoryCacheInstance = {}; var inMemoryMountPathCacheInstance = {}; var defaultResolveOptions = { wslCommand: "wsl", }; var resetCache = function () { inMemoryCacheInstance = {}; inMemoryMountPathCacheInstance = {}; }; exports.resetCache = resetCache; /** * Return a promise that resolves with a windows path to it's corresponding POSIX path in the wsl environment. * In case the resolution does not succeed, the Promise rejects with the appropriate error response. * * This calls wslpath(.exe) for resolving the base path and caches it in the default * resolve options. Subsequent calls with the same base path are then derived from the cache. * * If you do not want this, pass custom ResolveOptions with an empty or custom cache. * @param windowsPath The windows path to convert to a posix path * @param options Overwrite the resolver options, e.g. for disabling base caching */ var windowsToWsl = function (windowsPath, options) { if (options === void 0) { options = __assign({}, defaultResolveOptions); } return resolveAsync(buildWindowsResolutionContext(windowsPath, options), options); }; exports.windowsToWsl = windowsToWsl; /** * Return a promise that resolves a POSIX path to it's corresponding windows path in the wsl environment. * This calls wslpath for resolving the base path and caches it in the default * resolve options. Subsequent calls with the same base path are then derived from the cache. * * If you do not want this, pass custom ResolveOptions with an empty or custom cache. * @param posixPath The posix path to convert to a windos path * @param options Overwrite the resolver options, e.g. for disabling base caching */ var wslToWindows = function (posixPath, options) { if (options === void 0) { options = __assign({}, defaultResolveOptions); } return resolveAsync(buildPosixResolutionContext(posixPath, options), options); }; exports.wslToWindows = wslToWindows; /** * Resolve the POSIX path for the given windows path in the wsl environment in a synchronous call. * This calls wslpath for resolving the base path and caches it in the default * resolve options. Subsequent calls with the same base path are then derived from the cache. * * If you do not want this, pass custom ResolveOptions with an empty or custom cache. * @param posixPath The posix path to convert to a posix path * @param options Overwrite the resolver options, e.g. for disabling base caching */ var wslToWindowsSync = function (posixPath, options) { if (options === void 0) { options = __assign({}, defaultResolveOptions); } return resolveSync(buildPosixResolutionContext(posixPath, options), options); }; exports.wslToWindowsSync = wslToWindowsSync; /** * Resolve the Windows path for the given POSI path in the wsl environment in a synchronous call. * In case the resolution does not succeed, the Promise rejects with the appropriate error response. * * This calls wslpath(.exe) for resolving the base path and caches it in the default * resolve options. Subsequent calls with the same base path are then derived from the cache. * * If you do not want this, pass custom ResolveOptions with an empty or custom cache. * @param windowsPath The windows path to convert to a posix path * @param options Overwrite the resolver options, e.g. for disabling base caching */ var windowsToWslSync = function (windowsPath, options) { if (options === void 0) { options = __assign({}, defaultResolveOptions); } return resolveSync(buildWindowsResolutionContext(windowsPath, options), options); }; exports.windowsToWslSync = windowsToWslSync; /** * Perform a path resolution for the given @see ResolutionContext in a asynchronous manner. * * @param context The @see ResolutionContext to resolve. * @param options The @see ResolveOptions to resolve */ var resolveAsync = function (context, options) { var cachedResult = lookupCache(context); if (cachedResult) { return Promise.resolve(cachedResult); } return callWslPathUtil(context).then(function (result) { var resultContext = buildResolutionContext(result, options); cacheValue(context, resultContext); return result; }); }; /** * Perform a path resolution for the given @see ResolutionContext in a synchronous manner. * * @param context The @see ResolutionContext to resolve. * @param options The @see ResolveOptions to resolve */ var resolveSync = function (context, options) { var cachedResult = lookupCache(context); if (cachedResult) { return cachedResult; } var result = callWslPathUtilSync(context); var resultContext = buildResolutionContext(result, context); cacheValue(context, resultContext); return result; }; /** * Execute the wsl path resolution synchronously. * * @param context The @see ResolutionContext to resolve; */ var callWslPathUtilSync = function (context) { var wslCall = toWslCommand(context); var stdout = (0, child_process_1.execSync)(wslCall).toString(); return (0, path_handling_1.joinPath)(stdout.trim(), context.restOfPath, !context.isWindowsPath); }; /** * Execute the wsl path resolution asynchronously. * * @param context The @see ResolutionContext to resolve; */ var callWslPathUtil = function (context) { var wslCall = toWslCommand(context); return new Promise(function (resolve, reject) { (0, child_process_1.exec)(wslCall, function (err, stdout, stderr) { if (err) { reject(err); } else if (stderr && !stdout) { reject((stderr || "").trim()); } else { resolve((0, path_handling_1.joinPath)(stdout.trim(), context.restOfPath, !context.isWindowsPath)); } }); }); }; /** * Create the wsl command for resolving the given context. * * @param context The @see ResolutionContext that should be resolved. */ var toWslCommand = function (context) { var baseCommand = "".concat(WSL_UTIL, " ").concat(!context.isWindowsPath ? "-w" : "", " ").concat(context.basePath); if (process.platform !== "win32" && _forceRunInWsl === false) { return baseCommand; } return context.wslCommand + " " + baseCommand.replace(/\\/g, "\\\\"); }; /** * Force to run/not run wslpath in a wsl environment. * This is mostly useful for testing scenarios */ var _setForceRunInWsl = function (value) { return (_forceRunInWsl = value); }; exports._setForceRunInWsl = _setForceRunInWsl; /** * Return the cache key used for storing and retrieving the given @see ResolutionContext. * * @param context The context to create the key for. */ var cacheKey = function (context) { return "".concat(context.wslCommand, ":").concat(context.basePath); }; /** * Mark the resultContext as being the resolution result for sourceContext. * * @param sourceContext The @see ResolutionContext defining the resolve input. * @param resultContext The @see ResolutionContext defining the resolve output. */ var cacheValue = function (sourceContext, resultContext) { if (sourceContext.isWindowsPath === resultContext.isWindowsPath) { return; } sourceContext.cache[cacheKey(sourceContext)] = resultContext.basePath; sourceContext.cache[cacheKey(resultContext)] = sourceContext.basePath; }; /** * Return the result for the given context from the cache if resolution has been already peformed. * * @param context The @see ResolutionContext to lookup */ var lookupCache = function (context) { var result = context.cache[cacheKey(context)]; if (!result) { return; } return (0, path_handling_1.joinPath)(result, context.restOfPath, !context.isWindowsPath); }; var fetchMountPoints = function (wslCommand) { inMemoryMountPathCacheInstance[wslCommand] = (0, mount_1.determineMountPoints)(wslCommand); return inMemoryMountPathCacheInstance[wslCommand]; }; /** * Create a new @see ResolutionContext from the given path and parse options. * * @param path The path to resolve. Can be either POSIX or Windows (see the reverse flag in the result) * @param options The parse options provided by the user. */ var buildResolutionContext = function (path, options, parser) { options.basePathCache = options.basePathCache || inMemoryCacheInstance; options.wslCommand = options.wslCommand || "wsl"; options.mountPoints = options.mountPoints || inMemoryMountPathCacheInstance[options.wslCommand] || fetchMountPoints(options.wslCommand); // TODO: This actually doesn't cover network shares var isWindowsPath = /^\w:\\/i.test(path); var _a = (parser || (!isWindowsPath ? path_handling_1.parsePosixPath : path_handling_1.parseWindowsPath))(path, options.mountPoints), basePath = _a[0], restOfPath = _a[1]; return { basePath: basePath, restOfPath: restOfPath, isWindowsPath: isWindowsPath, wslCommand: options.wslCommand, cache: options.basePathCache, }; }; /** * Stricter version of @see buildResolutionContext which only allows windows paths at path. * Throws an error if a non windows (with drive letter) path is provided * * @param path The windows file path to create a context for. * @param options The user provided resolution options */ var buildWindowsResolutionContext = function (path, options) { var context = buildResolutionContext(path, options, path_handling_1.parseWindowsPath); if (!context.isWindowsPath) { throw Error("Invalid windows path provided:" + path); } return context; }; /** * Stricter version of @see buildResolutionContext which only allows POSIX paths at path. * Throws an error if a non POSIX path is provided * * @param path The POSIX file path to create a context for. * @param options The user provided resolution options */ var buildPosixResolutionContext = function (path, options) { var context = buildResolutionContext(path, options, path_handling_1.parsePosixPath); if (context.isWindowsPath) { throw Error("Invalid POSIX path provided:" + path); } return context; };