github.com/yrj2011/jx-test-infra@v0.0.0-20190529031832-7a2065ee98eb/triage/node_modules/fs.realpath/old.js (about)

     1  // Copyright Joyent, Inc. and other Node contributors.
     2  //
     3  // Permission is hereby granted, free of charge, to any person obtaining a
     4  // copy of this software and associated documentation files (the
     5  // "Software"), to deal in the Software without restriction, including
     6  // without limitation the rights to use, copy, modify, merge, publish,
     7  // distribute, sublicense, and/or sell copies of the Software, and to permit
     8  // persons to whom the Software is furnished to do so, subject to the
     9  // following conditions:
    10  //
    11  // The above copyright notice and this permission notice shall be included
    12  // in all copies or substantial portions of the Software.
    13  //
    14  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
    15  // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    16  // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
    17  // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
    18  // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
    19  // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
    20  // USE OR OTHER DEALINGS IN THE SOFTWARE.
    21  
    22  var pathModule = require('path');
    23  var isWindows = process.platform === 'win32';
    24  var fs = require('fs');
    25  
    26  // JavaScript implementation of realpath, ported from node pre-v6
    27  
    28  var DEBUG = process.env.NODE_DEBUG && /fs/.test(process.env.NODE_DEBUG);
    29  
    30  function rethrow() {
    31    // Only enable in debug mode. A backtrace uses ~1000 bytes of heap space and
    32    // is fairly slow to generate.
    33    var callback;
    34    if (DEBUG) {
    35      var backtrace = new Error;
    36      callback = debugCallback;
    37    } else
    38      callback = missingCallback;
    39  
    40    return callback;
    41  
    42    function debugCallback(err) {
    43      if (err) {
    44        backtrace.message = err.message;
    45        err = backtrace;
    46        missingCallback(err);
    47      }
    48    }
    49  
    50    function missingCallback(err) {
    51      if (err) {
    52        if (process.throwDeprecation)
    53          throw err;  // Forgot a callback but don't know where? Use NODE_DEBUG=fs
    54        else if (!process.noDeprecation) {
    55          var msg = 'fs: missing callback ' + (err.stack || err.message);
    56          if (process.traceDeprecation)
    57            console.trace(msg);
    58          else
    59            console.error(msg);
    60        }
    61      }
    62    }
    63  }
    64  
    65  function maybeCallback(cb) {
    66    return typeof cb === 'function' ? cb : rethrow();
    67  }
    68  
    69  var normalize = pathModule.normalize;
    70  
    71  // Regexp that finds the next partion of a (partial) path
    72  // result is [base_with_slash, base], e.g. ['somedir/', 'somedir']
    73  if (isWindows) {
    74    var nextPartRe = /(.*?)(?:[\/\\]+|$)/g;
    75  } else {
    76    var nextPartRe = /(.*?)(?:[\/]+|$)/g;
    77  }
    78  
    79  // Regex to find the device root, including trailing slash. E.g. 'c:\\'.
    80  if (isWindows) {
    81    var splitRootRe = /^(?:[a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?[\\\/]*/;
    82  } else {
    83    var splitRootRe = /^[\/]*/;
    84  }
    85  
    86  exports.realpathSync = function realpathSync(p, cache) {
    87    // make p is absolute
    88    p = pathModule.resolve(p);
    89  
    90    if (cache && Object.prototype.hasOwnProperty.call(cache, p)) {
    91      return cache[p];
    92    }
    93  
    94    var original = p,
    95        seenLinks = {},
    96        knownHard = {};
    97  
    98    // current character position in p
    99    var pos;
   100    // the partial path so far, including a trailing slash if any
   101    var current;
   102    // the partial path without a trailing slash (except when pointing at a root)
   103    var base;
   104    // the partial path scanned in the previous round, with slash
   105    var previous;
   106  
   107    start();
   108  
   109    function start() {
   110      // Skip over roots
   111      var m = splitRootRe.exec(p);
   112      pos = m[0].length;
   113      current = m[0];
   114      base = m[0];
   115      previous = '';
   116  
   117      // On windows, check that the root exists. On unix there is no need.
   118      if (isWindows && !knownHard[base]) {
   119        fs.lstatSync(base);
   120        knownHard[base] = true;
   121      }
   122    }
   123  
   124    // walk down the path, swapping out linked pathparts for their real
   125    // values
   126    // NB: p.length changes.
   127    while (pos < p.length) {
   128      // find the next part
   129      nextPartRe.lastIndex = pos;
   130      var result = nextPartRe.exec(p);
   131      previous = current;
   132      current += result[0];
   133      base = previous + result[1];
   134      pos = nextPartRe.lastIndex;
   135  
   136      // continue if not a symlink
   137      if (knownHard[base] || (cache && cache[base] === base)) {
   138        continue;
   139      }
   140  
   141      var resolvedLink;
   142      if (cache && Object.prototype.hasOwnProperty.call(cache, base)) {
   143        // some known symbolic link.  no need to stat again.
   144        resolvedLink = cache[base];
   145      } else {
   146        var stat = fs.lstatSync(base);
   147        if (!stat.isSymbolicLink()) {
   148          knownHard[base] = true;
   149          if (cache) cache[base] = base;
   150          continue;
   151        }
   152  
   153        // read the link if it wasn't read before
   154        // dev/ino always return 0 on windows, so skip the check.
   155        var linkTarget = null;
   156        if (!isWindows) {
   157          var id = stat.dev.toString(32) + ':' + stat.ino.toString(32);
   158          if (seenLinks.hasOwnProperty(id)) {
   159            linkTarget = seenLinks[id];
   160          }
   161        }
   162        if (linkTarget === null) {
   163          fs.statSync(base);
   164          linkTarget = fs.readlinkSync(base);
   165        }
   166        resolvedLink = pathModule.resolve(previous, linkTarget);
   167        // track this, if given a cache.
   168        if (cache) cache[base] = resolvedLink;
   169        if (!isWindows) seenLinks[id] = linkTarget;
   170      }
   171  
   172      // resolve the link, then start over
   173      p = pathModule.resolve(resolvedLink, p.slice(pos));
   174      start();
   175    }
   176  
   177    if (cache) cache[original] = p;
   178  
   179    return p;
   180  };
   181  
   182  
   183  exports.realpath = function realpath(p, cache, cb) {
   184    if (typeof cb !== 'function') {
   185      cb = maybeCallback(cache);
   186      cache = null;
   187    }
   188  
   189    // make p is absolute
   190    p = pathModule.resolve(p);
   191  
   192    if (cache && Object.prototype.hasOwnProperty.call(cache, p)) {
   193      return process.nextTick(cb.bind(null, null, cache[p]));
   194    }
   195  
   196    var original = p,
   197        seenLinks = {},
   198        knownHard = {};
   199  
   200    // current character position in p
   201    var pos;
   202    // the partial path so far, including a trailing slash if any
   203    var current;
   204    // the partial path without a trailing slash (except when pointing at a root)
   205    var base;
   206    // the partial path scanned in the previous round, with slash
   207    var previous;
   208  
   209    start();
   210  
   211    function start() {
   212      // Skip over roots
   213      var m = splitRootRe.exec(p);
   214      pos = m[0].length;
   215      current = m[0];
   216      base = m[0];
   217      previous = '';
   218  
   219      // On windows, check that the root exists. On unix there is no need.
   220      if (isWindows && !knownHard[base]) {
   221        fs.lstat(base, function(err) {
   222          if (err) return cb(err);
   223          knownHard[base] = true;
   224          LOOP();
   225        });
   226      } else {
   227        process.nextTick(LOOP);
   228      }
   229    }
   230  
   231    // walk down the path, swapping out linked pathparts for their real
   232    // values
   233    function LOOP() {
   234      // stop if scanned past end of path
   235      if (pos >= p.length) {
   236        if (cache) cache[original] = p;
   237        return cb(null, p);
   238      }
   239  
   240      // find the next part
   241      nextPartRe.lastIndex = pos;
   242      var result = nextPartRe.exec(p);
   243      previous = current;
   244      current += result[0];
   245      base = previous + result[1];
   246      pos = nextPartRe.lastIndex;
   247  
   248      // continue if not a symlink
   249      if (knownHard[base] || (cache && cache[base] === base)) {
   250        return process.nextTick(LOOP);
   251      }
   252  
   253      if (cache && Object.prototype.hasOwnProperty.call(cache, base)) {
   254        // known symbolic link.  no need to stat again.
   255        return gotResolvedLink(cache[base]);
   256      }
   257  
   258      return fs.lstat(base, gotStat);
   259    }
   260  
   261    function gotStat(err, stat) {
   262      if (err) return cb(err);
   263  
   264      // if not a symlink, skip to the next path part
   265      if (!stat.isSymbolicLink()) {
   266        knownHard[base] = true;
   267        if (cache) cache[base] = base;
   268        return process.nextTick(LOOP);
   269      }
   270  
   271      // stat & read the link if not read before
   272      // call gotTarget as soon as the link target is known
   273      // dev/ino always return 0 on windows, so skip the check.
   274      if (!isWindows) {
   275        var id = stat.dev.toString(32) + ':' + stat.ino.toString(32);
   276        if (seenLinks.hasOwnProperty(id)) {
   277          return gotTarget(null, seenLinks[id], base);
   278        }
   279      }
   280      fs.stat(base, function(err) {
   281        if (err) return cb(err);
   282  
   283        fs.readlink(base, function(err, target) {
   284          if (!isWindows) seenLinks[id] = target;
   285          gotTarget(err, target);
   286        });
   287      });
   288    }
   289  
   290    function gotTarget(err, target, base) {
   291      if (err) return cb(err);
   292  
   293      var resolvedLink = pathModule.resolve(previous, target);
   294      if (cache) cache[base] = resolvedLink;
   295      gotResolvedLink(resolvedLink);
   296    }
   297  
   298    function gotResolvedLink(resolvedLink) {
   299      // resolve the link, then start over
   300      p = pathModule.resolve(resolvedLink, p.slice(pos));
   301      start();
   302    }
   303  };