extpath.js 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. /*---------------------------------------------------------------------------------------------
  2. * Copyright (c) Microsoft Corporation. All rights reserved.
  3. * Licensed under the MIT License. See License.txt in the project root for license information.
  4. *--------------------------------------------------------------------------------------------*/
  5. import { normalize, posix, sep } from './path.js';
  6. import { isWindows } from './platform.js';
  7. import { startsWithIgnoreCase } from './strings.js';
  8. /**
  9. * Takes a Windows OS path and changes backward slashes to forward slashes.
  10. * This should only be done for OS paths from Windows (or user provided paths potentially from Windows).
  11. * Using it on a Linux or MaxOS path might change it.
  12. */
  13. export function toSlashes(osPath) {
  14. return osPath.replace(/[\\/]/g, posix.sep);
  15. }
  16. /**
  17. * Takes a Windows OS path (using backward or forward slashes) and turns it into a posix path:
  18. * - turns backward slashes into forward slashes
  19. * - makes it absolute if it starts with a drive letter
  20. * This should only be done for OS paths from Windows (or user provided paths potentially from Windows).
  21. * Using it on a Linux or MaxOS path might change it.
  22. */
  23. export function toPosixPath(osPath) {
  24. if (osPath.indexOf('/') === -1) {
  25. osPath = toSlashes(osPath);
  26. }
  27. if (/^[a-zA-Z]:(\/|$)/.test(osPath)) { // starts with a drive letter
  28. osPath = '/' + osPath;
  29. }
  30. return osPath;
  31. }
  32. export function isEqualOrParent(base, parentCandidate, ignoreCase, separator = sep) {
  33. if (base === parentCandidate) {
  34. return true;
  35. }
  36. if (!base || !parentCandidate) {
  37. return false;
  38. }
  39. if (parentCandidate.length > base.length) {
  40. return false;
  41. }
  42. if (ignoreCase) {
  43. const beginsWith = startsWithIgnoreCase(base, parentCandidate);
  44. if (!beginsWith) {
  45. return false;
  46. }
  47. if (parentCandidate.length === base.length) {
  48. return true; // same path, different casing
  49. }
  50. let sepOffset = parentCandidate.length;
  51. if (parentCandidate.charAt(parentCandidate.length - 1) === separator) {
  52. sepOffset--; // adjust the expected sep offset in case our candidate already ends in separator character
  53. }
  54. return base.charAt(sepOffset) === separator;
  55. }
  56. if (parentCandidate.charAt(parentCandidate.length - 1) !== separator) {
  57. parentCandidate += separator;
  58. }
  59. return base.indexOf(parentCandidate) === 0;
  60. }
  61. export function isWindowsDriveLetter(char0) {
  62. return char0 >= 65 /* A */ && char0 <= 90 /* Z */ || char0 >= 97 /* a */ && char0 <= 122 /* z */;
  63. }
  64. export function isRootOrDriveLetter(path) {
  65. const pathNormalized = normalize(path);
  66. if (isWindows) {
  67. if (path.length > 3) {
  68. return false;
  69. }
  70. return hasDriveLetter(pathNormalized) &&
  71. (path.length === 2 || pathNormalized.charCodeAt(2) === 92 /* Backslash */);
  72. }
  73. return pathNormalized === posix.sep;
  74. }
  75. export function hasDriveLetter(path) {
  76. if (isWindows) {
  77. return isWindowsDriveLetter(path.charCodeAt(0)) && path.charCodeAt(1) === 58 /* Colon */;
  78. }
  79. return false;
  80. }