github.com/yrj2011/jx-test-infra@v0.0.0-20190529031832-7a2065ee98eb/triage/node_modules/brace-expansion/index.js (about)

     1  var concatMap = require('concat-map');
     2  var balanced = require('balanced-match');
     3  
     4  module.exports = expandTop;
     5  
     6  var escSlash = '\0SLASH'+Math.random()+'\0';
     7  var escOpen = '\0OPEN'+Math.random()+'\0';
     8  var escClose = '\0CLOSE'+Math.random()+'\0';
     9  var escComma = '\0COMMA'+Math.random()+'\0';
    10  var escPeriod = '\0PERIOD'+Math.random()+'\0';
    11  
    12  function numeric(str) {
    13    return parseInt(str, 10) == str
    14      ? parseInt(str, 10)
    15      : str.charCodeAt(0);
    16  }
    17  
    18  function escapeBraces(str) {
    19    return str.split('\\\\').join(escSlash)
    20              .split('\\{').join(escOpen)
    21              .split('\\}').join(escClose)
    22              .split('\\,').join(escComma)
    23              .split('\\.').join(escPeriod);
    24  }
    25  
    26  function unescapeBraces(str) {
    27    return str.split(escSlash).join('\\')
    28              .split(escOpen).join('{')
    29              .split(escClose).join('}')
    30              .split(escComma).join(',')
    31              .split(escPeriod).join('.');
    32  }
    33  
    34  
    35  // Basically just str.split(","), but handling cases
    36  // where we have nested braced sections, which should be
    37  // treated as individual members, like {a,{b,c},d}
    38  function parseCommaParts(str) {
    39    if (!str)
    40      return [''];
    41  
    42    var parts = [];
    43    var m = balanced('{', '}', str);
    44  
    45    if (!m)
    46      return str.split(',');
    47  
    48    var pre = m.pre;
    49    var body = m.body;
    50    var post = m.post;
    51    var p = pre.split(',');
    52  
    53    p[p.length-1] += '{' + body + '}';
    54    var postParts = parseCommaParts(post);
    55    if (post.length) {
    56      p[p.length-1] += postParts.shift();
    57      p.push.apply(p, postParts);
    58    }
    59  
    60    parts.push.apply(parts, p);
    61  
    62    return parts;
    63  }
    64  
    65  function expandTop(str) {
    66    if (!str)
    67      return [];
    68  
    69    // I don't know why Bash 4.3 does this, but it does.
    70    // Anything starting with {} will have the first two bytes preserved
    71    // but *only* at the top level, so {},a}b will not expand to anything,
    72    // but a{},b}c will be expanded to [a}c,abc].
    73    // One could argue that this is a bug in Bash, but since the goal of
    74    // this module is to match Bash's rules, we escape a leading {}
    75    if (str.substr(0, 2) === '{}') {
    76      str = '\\{\\}' + str.substr(2);
    77    }
    78  
    79    return expand(escapeBraces(str), true).map(unescapeBraces);
    80  }
    81  
    82  function identity(e) {
    83    return e;
    84  }
    85  
    86  function embrace(str) {
    87    return '{' + str + '}';
    88  }
    89  function isPadded(el) {
    90    return /^-?0\d/.test(el);
    91  }
    92  
    93  function lte(i, y) {
    94    return i <= y;
    95  }
    96  function gte(i, y) {
    97    return i >= y;
    98  }
    99  
   100  function expand(str, isTop) {
   101    var expansions = [];
   102  
   103    var m = balanced('{', '}', str);
   104    if (!m || /\$$/.test(m.pre)) return [str];
   105  
   106    var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body);
   107    var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body);
   108    var isSequence = isNumericSequence || isAlphaSequence;
   109    var isOptions = m.body.indexOf(',') >= 0;
   110    if (!isSequence && !isOptions) {
   111      // {a},b}
   112      if (m.post.match(/,.*\}/)) {
   113        str = m.pre + '{' + m.body + escClose + m.post;
   114        return expand(str);
   115      }
   116      return [str];
   117    }
   118  
   119    var n;
   120    if (isSequence) {
   121      n = m.body.split(/\.\./);
   122    } else {
   123      n = parseCommaParts(m.body);
   124      if (n.length === 1) {
   125        // x{{a,b}}y ==> x{a}y x{b}y
   126        n = expand(n[0], false).map(embrace);
   127        if (n.length === 1) {
   128          var post = m.post.length
   129            ? expand(m.post, false)
   130            : [''];
   131          return post.map(function(p) {
   132            return m.pre + n[0] + p;
   133          });
   134        }
   135      }
   136    }
   137  
   138    // at this point, n is the parts, and we know it's not a comma set
   139    // with a single entry.
   140  
   141    // no need to expand pre, since it is guaranteed to be free of brace-sets
   142    var pre = m.pre;
   143    var post = m.post.length
   144      ? expand(m.post, false)
   145      : [''];
   146  
   147    var N;
   148  
   149    if (isSequence) {
   150      var x = numeric(n[0]);
   151      var y = numeric(n[1]);
   152      var width = Math.max(n[0].length, n[1].length)
   153      var incr = n.length == 3
   154        ? Math.abs(numeric(n[2]))
   155        : 1;
   156      var test = lte;
   157      var reverse = y < x;
   158      if (reverse) {
   159        incr *= -1;
   160        test = gte;
   161      }
   162      var pad = n.some(isPadded);
   163  
   164      N = [];
   165  
   166      for (var i = x; test(i, y); i += incr) {
   167        var c;
   168        if (isAlphaSequence) {
   169          c = String.fromCharCode(i);
   170          if (c === '\\')
   171            c = '';
   172        } else {
   173          c = String(i);
   174          if (pad) {
   175            var need = width - c.length;
   176            if (need > 0) {
   177              var z = new Array(need + 1).join('0');
   178              if (i < 0)
   179                c = '-' + z + c.slice(1);
   180              else
   181                c = z + c;
   182            }
   183          }
   184        }
   185        N.push(c);
   186      }
   187    } else {
   188      N = concatMap(n, function(el) { return expand(el, false) });
   189    }
   190  
   191    for (var j = 0; j < N.length; j++) {
   192      for (var k = 0; k < post.length; k++) {
   193        var expansion = pre + N[j] + post[k];
   194        if (!isTop || isSequence || expansion)
   195          expansions.push(expansion);
   196      }
   197    }
   198  
   199    return expansions;
   200  }
   201