mirror of
https://github.com/wassname/CanvasTextWrapper.git
synced 2026-07-10 20:32:41 +08:00
Compare commits
33 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 055cdaeb13 | |||
| cfdccc0c61 | |||
| bb707cd508 | |||
| 8dda2cb645 | |||
| 7e3d425769 | |||
| 6e03f629ce | |||
| ebb8908812 | |||
| 30c326ed36 | |||
| f464af8c5d | |||
| 5b7a7f9cfe | |||
| 45a2b83782 | |||
| 43c8775359 | |||
| 4924f6f06a | |||
| 60c009b432 | |||
| e5ad6e9e22 | |||
| b6eb83cbbc | |||
| ba409c2f9a | |||
| 9b14e6bc20 | |||
| ab5ee97446 | |||
| 68f08dccf0 | |||
| b86396f979 | |||
| 53f765b0e8 | |||
| 4d7e9ed627 | |||
| 68a9da4826 | |||
| 9534bbbdf7 | |||
| d4566c71cf | |||
| c5464dab42 | |||
| c18627bd6a | |||
| a884a840db | |||
| c53c170d5c | |||
| 19d9b83fea | |||
| 2361b45226 | |||
| f2f142e81b |
+1
-2
@@ -1,2 +1 @@
|
|||||||
.idea/
|
examples
|
||||||
node_modules/
|
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
node_modules
|
||||||
|
examples
|
||||||
|
bower.json
|
||||||
@@ -0,0 +1,206 @@
|
|||||||
|
/*! CanvasTextWrapper (https://github.com/namniak/CanvasTextWrapper)
|
||||||
|
* Version: 0.2.3
|
||||||
|
*
|
||||||
|
* MIT License (http://www.opensource.org/licenses/mit-license.html)
|
||||||
|
* Copyright (c) 2014 Vadim Namniak
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var defaultOptions = {
|
||||||
|
font: '18px Arial, sans-serif',
|
||||||
|
textAlign: 'left', // each line of text is aligned left
|
||||||
|
verticalAlign: 'top', // text lines block is aligned top
|
||||||
|
paddingX: 0, // zero px left & right text padding relative to canvas or parent
|
||||||
|
paddingY: 0, // zero px top & bottom text padding relative to canvas or parent
|
||||||
|
fitParent: false, // text is tested to fit canvas width
|
||||||
|
lineBreak: 'auto', // text fills the element's (canvas or parent) width going to a new line on a whole word
|
||||||
|
sizeToFill: false, // text is resized to fill the container (given font size is ignored)
|
||||||
|
strokeText: false // text is stroked according to context configuration.
|
||||||
|
};
|
||||||
|
|
||||||
|
window.CanvasTextWrapper = function(canvas, text, opts) {
|
||||||
|
|
||||||
|
if (!(this instanceof CanvasTextWrapper)) {
|
||||||
|
throw new TypeError('CanvasTextWrapper constructor failed. Use "new" keyword when instantiating.');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.canvas = canvas;
|
||||||
|
this.text = text;
|
||||||
|
|
||||||
|
// set options to specified or default values
|
||||||
|
for (var property in defaultOptions) {
|
||||||
|
this[property] = (opts && opts[property]) ? opts[property] : defaultOptions[property];
|
||||||
|
}
|
||||||
|
|
||||||
|
// extract font size
|
||||||
|
this.lineHeight = parseInt(this.font.replace(/^\D+/g, ''), 10) || 18;
|
||||||
|
|
||||||
|
// validate all set properties
|
||||||
|
this.validate();
|
||||||
|
|
||||||
|
// basic context settings
|
||||||
|
this.context = this.canvas.getContext('2d');
|
||||||
|
this.context.font = this.font;
|
||||||
|
this.context.textBaseline = 'bottom';
|
||||||
|
|
||||||
|
this.drawText();
|
||||||
|
};
|
||||||
|
|
||||||
|
CanvasTextWrapper.prototype = {
|
||||||
|
|
||||||
|
drawText: function() {
|
||||||
|
var elementWidth = (this.fitParent === false) ? this.canvas.width : this.canvas.parentNode.clientWidth;
|
||||||
|
var textPos = {
|
||||||
|
x: 0,
|
||||||
|
y: 0
|
||||||
|
};
|
||||||
|
|
||||||
|
if (this.sizeToFill) {
|
||||||
|
// starting at 1px increase font size by 1px until text block exceeds the height of its padded container or until words break
|
||||||
|
var elementHeight = ((this.fitParent === false) ? this.canvas.height : this.canvas.parentNode.clientHeight) - (this.paddingX * 2);
|
||||||
|
var numWords = this.text.trim().split(/\s+/).length;
|
||||||
|
var fontSize = 0;
|
||||||
|
do {
|
||||||
|
this.setFontSize(++fontSize);
|
||||||
|
var lines = this.getWrappedText(elementWidth);
|
||||||
|
var textBlockHeight = lines.length * this.lineHeight;
|
||||||
|
} while (textBlockHeight < elementHeight && lines.join(' ').split(/\s+/).length == numWords);
|
||||||
|
|
||||||
|
// use previous font size, not the one that broke the while condition
|
||||||
|
this.setFontSize(--fontSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
var lines = this.getWrappedText(elementWidth);
|
||||||
|
var textBlockHeight = lines.length * this.lineHeight;
|
||||||
|
|
||||||
|
// set vertical align for the whole text block
|
||||||
|
this.setTextVerticalAlign(textPos, textBlockHeight);
|
||||||
|
|
||||||
|
for (var i = 0; i < lines.length; i++) {
|
||||||
|
this.setTextHorizontalAlign(this.context, textPos, elementWidth, lines[i]);
|
||||||
|
|
||||||
|
textPos.y = parseInt(textPos.y) + parseInt(this.lineHeight);
|
||||||
|
this.context.fillText(lines[i], textPos.x, textPos.y);
|
||||||
|
if (this.strokeText) {
|
||||||
|
this.context.strokeText(lines[i], textPos.x, textPos.y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
setFontSize: function(size) {
|
||||||
|
var fontParts = this.context.font.split(/\b\d+px\b/i);
|
||||||
|
this.context.font = fontParts[0] + size + 'px' + fontParts[1];
|
||||||
|
this.lineHeight = size;
|
||||||
|
},
|
||||||
|
|
||||||
|
getWrappedText: function(elementWidth) {
|
||||||
|
var maxTextLength = elementWidth - (this.paddingX * 2);
|
||||||
|
|
||||||
|
var words = this.text.trim().split(/\s+/);
|
||||||
|
var lines = [];
|
||||||
|
|
||||||
|
this.checkWordsLength(this.context, words, maxTextLength);
|
||||||
|
this.breakTextIntoLines(this.context, lines, words, maxTextLength);
|
||||||
|
|
||||||
|
return lines;
|
||||||
|
},
|
||||||
|
|
||||||
|
checkWordsLength: function(context, words, maxTextLength) {
|
||||||
|
for (var i = 0; i < words.length; i++) {
|
||||||
|
var testString = '';
|
||||||
|
var tokenLen = context.measureText(words[i]).width;
|
||||||
|
|
||||||
|
// check if a word exceeds the element's width
|
||||||
|
if (tokenLen > maxTextLength) {
|
||||||
|
for (var k = 0; (context.measureText(testString + words[i][k]).width <= maxTextLength) && (k < words[i].length); k++) {
|
||||||
|
testString += words[i][k];
|
||||||
|
}
|
||||||
|
|
||||||
|
// break the word because it's too long
|
||||||
|
var sliced = words[i].slice(0, k);
|
||||||
|
var leftover = words[i].slice(k);
|
||||||
|
words.splice(i, 1, sliced, leftover);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
breakTextIntoLines: function(context, lines, words, maxTextLength) {
|
||||||
|
for (var i = 0, j = 0; i < words.length; j++) {
|
||||||
|
lines[j] = '';
|
||||||
|
|
||||||
|
if (this.lineBreak === 'auto') {
|
||||||
|
// put as many full words in a line as can fit element
|
||||||
|
while ((context.measureText(lines[j] + words[i]).width <= maxTextLength) && (i < words.length)) {
|
||||||
|
lines[j] += words[i] + ' ';
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
lines[j] = lines[j].trim();
|
||||||
|
} else if (this.lineBreak === 'word') {
|
||||||
|
// put each next word in a new line
|
||||||
|
lines[j] = words[i];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
setTextHorizontalAlign: function(context, textPos, elementWidth, line) {
|
||||||
|
if (this.textAlign === 'center') {
|
||||||
|
textPos.x = (elementWidth - context.measureText(line).width) / 2;
|
||||||
|
} else if (this.textAlign === 'right') {
|
||||||
|
textPos.x = elementWidth - context.measureText(line).width - this.paddingX;
|
||||||
|
} else {
|
||||||
|
textPos.x = this.paddingX;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
setTextVerticalAlign: function(textPos, textBlockHeight) {
|
||||||
|
var elementHeight = (this.fitParent === false) ? this.canvas.height : this.canvas.parentNode.clientHeight;
|
||||||
|
|
||||||
|
if (this.verticalAlign === 'middle') {
|
||||||
|
textPos.y = (elementHeight - textBlockHeight) / 2;
|
||||||
|
} else if (this.verticalAlign === 'bottom') {
|
||||||
|
textPos.y = elementHeight - textBlockHeight - this.paddingY;
|
||||||
|
} else {
|
||||||
|
textPos.y = this.paddingY;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
validate: function() {
|
||||||
|
if (!(this.canvas instanceof HTMLCanvasElement)) {
|
||||||
|
throw new TypeError('From CanvasTextWrapper(): Element passed as the first parameter is not an instance of HTMLCanvasElement.');
|
||||||
|
}
|
||||||
|
if (typeof this.text !== 'string') {
|
||||||
|
throw new TypeError('From CanvasTextWrapper(): The second, dedicated for the text, parameter must be a string.');
|
||||||
|
}
|
||||||
|
if (isNaN(this.lineHeight)) {
|
||||||
|
throw new TypeError('From CanvasTextWrapper(): Cannot parse font size as an Integer. Check "font" property\'s value.');
|
||||||
|
}
|
||||||
|
if (this.textAlign !== 'left' && this.textAlign !== 'center' && this.textAlign !== 'right') {
|
||||||
|
throw new TypeError('From CanvasTextWrapper(): Unsupported horizontal align value is used. Property "textAlign" can only be set to "left", "center", or "right".');
|
||||||
|
}
|
||||||
|
if (this.verticalAlign !== 'top' && this.verticalAlign !== 'middle' && this.verticalAlign !== 'bottom') {
|
||||||
|
throw new TypeError('From CanvasTextWrapper(): Unsupported vertical align value is used. Property "verticalAlign" can only be set to "top", "middle", or "bottom".');
|
||||||
|
}
|
||||||
|
if (isNaN(this.paddingX)) {
|
||||||
|
throw new TypeError('From CanvasTextWrapper(): Unsupported horizontal padding value is used. Property "paddingX" must be set to a number');
|
||||||
|
}
|
||||||
|
if (isNaN(this.paddingY)) {
|
||||||
|
throw new TypeError('From CanvasTextWrapper(): Unsupported vertical padding value is used. Property "paddingY" must be set to a number.');
|
||||||
|
}
|
||||||
|
if (typeof this.fitParent !== 'boolean') {
|
||||||
|
throw new TypeError('From CanvasTextWrapper(): Property "fitParent" must be set to a Boolean.');
|
||||||
|
}
|
||||||
|
if (this.lineBreak !== 'auto' && this.lineBreak !== 'word') {
|
||||||
|
throw new TypeError('From CanvasTextWrapper(): Unsupported line break value is used. Property "lineBreak" can only be set to "auto", or "word".');
|
||||||
|
}
|
||||||
|
if (typeof this.sizeToFill !== 'boolean') {
|
||||||
|
throw new TypeError('From CanvasTextWrapper(): Property "sizeToFill" must be set to a Boolean.');
|
||||||
|
}
|
||||||
|
if (typeof this.strokeText !== 'boolean') {
|
||||||
|
throw new TypeError('From CanvasTextWrapper(): Property "strokeText" must be set to a Boolean.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})();
|
||||||
Vendored
+7
@@ -0,0 +1,7 @@
|
|||||||
|
/*! CanvasTextWrapper (https://github.com/namniak/CanvasTextWrapper)
|
||||||
|
* Version: 0.2.3
|
||||||
|
*
|
||||||
|
* MIT License (http://www.opensource.org/licenses/mit-license.html)
|
||||||
|
* Copyright (c) 2014 Vadim Namniak
|
||||||
|
*/
|
||||||
|
!function(){"use strict";var a={font:"18px Arial, sans-serif",textAlign:"left",verticalAlign:"top",paddingX:0,paddingY:0,fitParent:!1,lineBreak:"auto",sizeToFill:!1,strokeText:!1};window.CanvasTextWrapper=function(b,c,d){if(!(this instanceof CanvasTextWrapper))throw new TypeError('CanvasTextWrapper constructor failed. Use "new" keyword when instantiating.');this.canvas=b,this.text=c;for(var e in a)this[e]=d&&d[e]?d[e]:a[e];this.lineHeight=parseInt(this.font.replace(/^\D+/g,""),10)||18,this.validate(),this.context=this.canvas.getContext("2d"),this.context.font=this.font,this.context.textBaseline="bottom",this.drawText()},CanvasTextWrapper.prototype={drawText:function(){var a=this.fitParent===!1?this.canvas.width:this.canvas.parentNode.clientWidth,b={x:0,y:0};if(this.sizeToFill){var c=(this.fitParent===!1?this.canvas.height:this.canvas.parentNode.clientHeight)-2*this.paddingX,d=this.text.trim().split(/\s+/).length,e=0;do{this.setFontSize(++e);var f=this.getWrappedText(a),g=f.length*this.lineHeight}while(c>g&&f.join(" ").split(/\s+/).length==d);this.setFontSize(--e)}var f=this.getWrappedText(a),g=f.length*this.lineHeight;this.setTextVerticalAlign(b,g);for(var h=0;h<f.length;h++)this.setTextHorizontalAlign(this.context,b,a,f[h]),b.y=parseInt(b.y)+parseInt(this.lineHeight),this.context.fillText(f[h],b.x,b.y),this.strokeText&&this.context.strokeText(f[h],b.x,b.y)},setFontSize:function(a){var b=this.context.font.split(/\b\d+px\b/i);this.context.font=b[0]+a+"px"+b[1],this.lineHeight=a},getWrappedText:function(a){var b=a-2*this.paddingX,c=this.text.trim().split(/\s+/),d=[];return this.checkWordsLength(this.context,c,b),this.breakTextIntoLines(this.context,d,c,b),d},checkWordsLength:function(a,b,c){for(var d=0;d<b.length;d++){var e="",f=a.measureText(b[d]).width;if(f>c){for(var g=0;a.measureText(e+b[d][g]).width<=c&&g<b[d].length;g++)e+=b[d][g];var h=b[d].slice(0,g),i=b[d].slice(g);b.splice(d,1,h,i)}}},breakTextIntoLines:function(a,b,c,d){for(var e=0,f=0;e<c.length;f++)if(b[f]="","auto"===this.lineBreak){for(;a.measureText(b[f]+c[e]).width<=d&&e<c.length;)b[f]+=c[e]+" ",e++;b[f]=b[f].trim()}else"word"===this.lineBreak&&(b[f]=c[e],e++)},setTextHorizontalAlign:function(a,b,c,d){b.x="center"===this.textAlign?(c-a.measureText(d).width)/2:"right"===this.textAlign?c-a.measureText(d).width-this.paddingX:this.paddingX},setTextVerticalAlign:function(a,b){var c=this.fitParent===!1?this.canvas.height:this.canvas.parentNode.clientHeight;a.y="middle"===this.verticalAlign?(c-b)/2:"bottom"===this.verticalAlign?c-b-this.paddingY:this.paddingY},validate:function(){if(!(this.canvas instanceof HTMLCanvasElement))throw new TypeError("From CanvasTextWrapper(): Element passed as the first parameter is not an instance of HTMLCanvasElement.");if("string"!=typeof this.text)throw new TypeError("From CanvasTextWrapper(): The second, dedicated for the text, parameter must be a string.");if(isNaN(this.lineHeight))throw new TypeError('From CanvasTextWrapper(): Cannot parse font size as an Integer. Check "font" property\'s value.');if("left"!==this.textAlign&&"center"!==this.textAlign&&"right"!==this.textAlign)throw new TypeError('From CanvasTextWrapper(): Unsupported horizontal align value is used. Property "textAlign" can only be set to "left", "center", or "right".');if("top"!==this.verticalAlign&&"middle"!==this.verticalAlign&&"bottom"!==this.verticalAlign)throw new TypeError('From CanvasTextWrapper(): Unsupported vertical align value is used. Property "verticalAlign" can only be set to "top", "middle", or "bottom".');if(isNaN(this.paddingX))throw new TypeError('From CanvasTextWrapper(): Unsupported horizontal padding value is used. Property "paddingX" must be set to a number');if(isNaN(this.paddingY))throw new TypeError('From CanvasTextWrapper(): Unsupported vertical padding value is used. Property "paddingY" must be set to a number.');if("boolean"!=typeof this.fitParent)throw new TypeError('From CanvasTextWrapper(): Property "fitParent" must be set to a Boolean.');if("auto"!==this.lineBreak&&"word"!==this.lineBreak)throw new TypeError('From CanvasTextWrapper(): Unsupported line break value is used. Property "lineBreak" can only be set to "auto", or "word".');if("boolean"!=typeof this.sizeToFill)throw new TypeError('From CanvasTextWrapper(): Property "sizeToFill" must be set to a Boolean.');if("boolean"!=typeof this.strokeText)throw new TypeError('From CanvasTextWrapper(): Property "strokeText" must be set to a Boolean.')}}}();
|
||||||
Executable
+27
@@ -0,0 +1,27 @@
|
|||||||
|
module.exports = function (grunt) {
|
||||||
|
|
||||||
|
var saveLicense = require('uglify-save-license');
|
||||||
|
// project configuration
|
||||||
|
grunt.initConfig({
|
||||||
|
pkg: grunt.file.readJSON('package.json'),
|
||||||
|
|
||||||
|
uglify: {
|
||||||
|
my_target: {
|
||||||
|
options: {
|
||||||
|
preserveComments: saveLicense
|
||||||
|
},
|
||||||
|
src: ['CanvasTextWrapper.js'],
|
||||||
|
dest: 'CanvasTextWrapper.min.js'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// load plugins
|
||||||
|
grunt.loadNpmTasks('uglify-save-license');
|
||||||
|
grunt.loadNpmTasks('grunt-contrib-uglify');
|
||||||
|
|
||||||
|
// default tasks.
|
||||||
|
grunt.registerTask('default', [
|
||||||
|
'uglify'
|
||||||
|
]);
|
||||||
|
};
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
CanvasTextWrapper
|
||||||
|
=================
|
||||||
|
|
||||||
|
##Syntax
|
||||||
|
```
|
||||||
|
new CanvasTextWrapper(HTMLCanvasElement, String [, options]);
|
||||||
|
```
|
||||||
|
|
||||||
|
```options``` - is a JavaScript object with the following available properties and values:
|
||||||
|
|
||||||
|
- ```font: String``` - text style that includes font size (in px), weight and family, similarly to CSS font shorthand property
|
||||||
|
- ```textAlign: "left" | "center" | "right"``` - horizontal alignment for each line
|
||||||
|
- ```verticalAlign: "top" | "middle" | "bottom"``` - vertical alignment for the whole text block
|
||||||
|
- ```paddingX: Number``` - horizontal padding in pixels set equally on both, left and right sides of the element
|
||||||
|
- ```paddingY: Number``` - vertical padding in pixels set equally on both, top and bottom sides of the element
|
||||||
|
- ```fitParent: Boolean``` - parameter that controls which element to fit where ```true``` means fit canvas parent's width instead of canvas own width
|
||||||
|
- ```lineBreak: "auto" | "word"``` - text split rule. When using ```"auto"```, text fills the element's width, going to a new line on a whole word when there's no more room. If ```"word"``` is set as value, each next word will be placed on a new line.
|
||||||
|
- ```sizeToFill: Boolean``` - ignore given font size and resize text to fill its padded container
|
||||||
|
- ```strokeText: Boolean``` - add text outline based on context configuration (make sure it doesn't contradict with other context settings such as globalCompositeOperation, etc)
|
||||||
|
|
||||||
|
NOTE: if a single word is too long to fit the width with specified font size, it will be broken into as many lines as required on any letter of the word unless ```sizeToFill``` option is used.
|
||||||
|
|
||||||
|
##Defaults
|
||||||
|
|
||||||
|
The default options object which values will be used if a property is not specified or no object is passed:
|
||||||
|
|
||||||
|
```
|
||||||
|
{
|
||||||
|
font: "18px Arial, sans-serif",
|
||||||
|
textAlign: "left",
|
||||||
|
verticalAlign: "top",
|
||||||
|
paddingX: 0,
|
||||||
|
paddingY: 0,
|
||||||
|
fitParent: false,
|
||||||
|
lineBreak: "auto",
|
||||||
|
sizeToFill: false,
|
||||||
|
strokeText: false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
##Usage
|
||||||
|
Use standard canvas text drawing сщташпгкфешщты such as "fillStyle" and "globalCompositeOperation" when needed before using CanvasTextWrapper like so:
|
||||||
|
```
|
||||||
|
var canvas = document.createElement('canvas');
|
||||||
|
canvas.width = 300;
|
||||||
|
canvas.height = 250;
|
||||||
|
context = canvas.getContext("2d");
|
||||||
|
context.fillStyle = "rgb(255, 255, 255)";
|
||||||
|
context.fillRect(0, 0, canvas.width, canvas.height);
|
||||||
|
|
||||||
|
new CanvasTextWrapper(canvas, "Hi there", {
|
||||||
|
font: "normal 40px Open Sans, sans-serif",
|
||||||
|
textAlign: "center",
|
||||||
|
verticalAlign: "bottom",
|
||||||
|
paddingY: 10,
|
||||||
|
lineBreak: "word",
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
##Examples
|
||||||
|
http://namniak.github.io/CanvasTextWrapper/
|
||||||
|
|
||||||
|
##Installation
|
||||||
|
|
||||||
|
```
|
||||||
|
bower install canvas-text-wrapper
|
||||||
|
|
||||||
|
npm install canvas-text-wrapper
|
||||||
|
```
|
||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"name": "canvas-text-wrapper",
|
||||||
|
"version": "0.2.3",
|
||||||
|
"ignore": [
|
||||||
|
"**/.*",
|
||||||
|
"**/*.log",
|
||||||
|
"**/*.json",
|
||||||
|
"Gruntfile.js",
|
||||||
|
"examples",
|
||||||
|
"node_modules",
|
||||||
|
"README.md"
|
||||||
|
],
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git://github.com/namniak/CanvasTextWrapper.git"
|
||||||
|
},
|
||||||
|
"homepage": "http://namniak.github.io/CanvasTextWrapper/"
|
||||||
|
}
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
/* http://meyerweb.com/eric/tools/css/reset/
|
|
||||||
v2.0 | 20110126
|
|
||||||
License: none (public domain)
|
|
||||||
*/
|
|
||||||
|
|
||||||
html, body, div, span, applet, object, iframe,
|
|
||||||
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
|
|
||||||
a, abbr, acronym, address, big, cite, code,
|
|
||||||
del, dfn, em, img, ins, kbd, q, s, samp,
|
|
||||||
small, strike, strong, sub, sup, tt, var,
|
|
||||||
b, u, i, center,
|
|
||||||
dl, dt, dd, ol, ul, li,
|
|
||||||
fieldset, form, label, legend,
|
|
||||||
table, caption, tbody, tfoot, thead, tr, th, td,
|
|
||||||
article, aside, canvas, details, embed,
|
|
||||||
figure, figcaption, footer, header, hgroup,
|
|
||||||
menu, nav, output, ruby, section, summary,
|
|
||||||
time, mark, audio, video {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
border: 0;
|
|
||||||
font-size: 100%;
|
|
||||||
font: inherit;
|
|
||||||
vertical-align: baseline;
|
|
||||||
}
|
|
||||||
/* HTML5 display-role reset for older browsers */
|
|
||||||
article, aside, details, figcaption, figure,
|
|
||||||
footer, header, hgroup, menu, nav, section {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
body {
|
|
||||||
line-height: 1;
|
|
||||||
}
|
|
||||||
ol, ul {
|
|
||||||
list-style: none;
|
|
||||||
}
|
|
||||||
blockquote, q {
|
|
||||||
quotes: none;
|
|
||||||
}
|
|
||||||
blockquote:before, blockquote:after,
|
|
||||||
q:before, q:after {
|
|
||||||
content: '';
|
|
||||||
content: none;
|
|
||||||
}
|
|
||||||
table {
|
|
||||||
border-collapse: collapse;
|
|
||||||
border-spacing: 0;
|
|
||||||
}
|
|
||||||
-159
@@ -1,159 +0,0 @@
|
|||||||
body {
|
|
||||||
width: 960px;
|
|
||||||
margin: auto;
|
|
||||||
font-family: 'Open Sans', sans-serif;
|
|
||||||
color: #fff;
|
|
||||||
line-height: 140%;
|
|
||||||
}
|
|
||||||
|
|
||||||
div, header, footer, article {
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
header, footer, article {
|
|
||||||
width: 930px;
|
|
||||||
margin: auto;
|
|
||||||
background-color: #3299af;
|
|
||||||
padding: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
header {
|
|
||||||
font-size: 60px;
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
|
|
||||||
.description {
|
|
||||||
width: 800px;
|
|
||||||
margin-top: 20px;
|
|
||||||
font-size: 22px;
|
|
||||||
font-weight: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
footer {
|
|
||||||
margin-top: 40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
font-size: 20px;
|
|
||||||
font-weight: normal;
|
|
||||||
color: #fff;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
a:hover {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
|
|
||||||
article {
|
|
||||||
border-top: 1px solid #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.white-block {
|
|
||||||
display: table-cell;
|
|
||||||
height: 30px;
|
|
||||||
padding: 20px;
|
|
||||||
vertical-align: middle;
|
|
||||||
background-color: #fff;
|
|
||||||
font-weight: 100;
|
|
||||||
color: #2E6571;
|
|
||||||
line-height: 120%;
|
|
||||||
}
|
|
||||||
|
|
||||||
pre.white-block {
|
|
||||||
padding-left: 0;
|
|
||||||
padding-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
margin: 10px 0;
|
|
||||||
line-height: 120%;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
font-size: 30px;
|
|
||||||
padding-top: 40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2:first-of-type {
|
|
||||||
padding-top: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
h6 {
|
|
||||||
font-weight: 700;
|
|
||||||
text-decoration: underline;
|
|
||||||
display: inline;
|
|
||||||
}
|
|
||||||
|
|
||||||
.syntax {
|
|
||||||
padding: 10px 10px 0 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.syntax > li {
|
|
||||||
list-style: none;
|
|
||||||
margin-bottom: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.syntax p {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.values li {
|
|
||||||
text-indent: 20px;
|
|
||||||
list-style: inside circle;
|
|
||||||
line-height: 120%;
|
|
||||||
}
|
|
||||||
|
|
||||||
section {
|
|
||||||
margin-top: 40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
section > div {
|
|
||||||
display: inline-block;
|
|
||||||
position: relative;
|
|
||||||
width: 450px;
|
|
||||||
margin: 15px;
|
|
||||||
border: 1px solid #3299af;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
section h2 {
|
|
||||||
color: #3299af;
|
|
||||||
text-indent: 30px;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
section > div div {
|
|
||||||
width: 100%;
|
|
||||||
height: 240px;
|
|
||||||
background-color: #3299af;
|
|
||||||
margin-top: 250px;
|
|
||||||
padding: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
canvas, img {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
img {
|
|
||||||
width: 100%;
|
|
||||||
z-index: -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
span {
|
|
||||||
margin-left: 20px;
|
|
||||||
margin-right: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
span, .emph {
|
|
||||||
font-weight: 600;
|
|
||||||
display: inline;
|
|
||||||
}
|
|
||||||
|
|
||||||
strong {
|
|
||||||
background: #fff;
|
|
||||||
color: #3299af;
|
|
||||||
font-weight: bold;
|
|
||||||
padding: 0 5px;
|
|
||||||
}
|
|
||||||
-160
@@ -1,160 +0,0 @@
|
|||||||
<!DOCTYPE HTML>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<link href='http://fonts.googleapis.com/css?family=Open+Sans:400,700,600' rel='stylesheet' type='text/css'>
|
|
||||||
<link rel="stylesheet" href="css/reset.css">
|
|
||||||
<link rel="stylesheet" href="css/styles.css">
|
|
||||||
<script src="js/CanvasTextWrapper.js"></script>
|
|
||||||
<script src="js/options.js"></script>
|
|
||||||
<script src="js/examples.js"></script>
|
|
||||||
<title>CanvasTextWrapper</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<header>
|
|
||||||
<p>CanvasTextWrapper</p>
|
|
||||||
|
|
||||||
<p class="description">
|
|
||||||
Pure JavaScript canvas text wrapper that automatically splits a string into lines on specified rule with
|
|
||||||
alignment and padding.
|
|
||||||
</p>
|
|
||||||
</header>
|
|
||||||
<article>
|
|
||||||
<h2>Syntax</h2><br/>
|
|
||||||
|
|
||||||
<p class="white-block">CanvasTextWrapper(HTMLCanvasElement, String [, Options]);</p><br/>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<div class="emph">Options</div>
|
|
||||||
- is an object with the following available properties and values:
|
|
||||||
</div>
|
|
||||||
<ul class="syntax">
|
|
||||||
<li>
|
|
||||||
<div class="emph">font</div>
|
|
||||||
(String) - text style that includes font size in px, weight, font family, etc. Similar to CSS font shorthand
|
|
||||||
property
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<div class="emph">lineHeight</div>
|
|
||||||
(Number or String)
|
|
||||||
<ul class="values">
|
|
||||||
<li>number - n times font size where 1 is equivalent to '100%'</li>
|
|
||||||
<li>"%"</li>
|
|
||||||
<li>"px"</li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<div class="emph">textAlign</div>
|
|
||||||
(String) - horizontal alignment of each line
|
|
||||||
<ul class="values">
|
|
||||||
<li>"left"</li>
|
|
||||||
<li>"center"</li>
|
|
||||||
<li>"right"</li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<div class="emph">verticalAlign</div>
|
|
||||||
(String) - vertical alignment of the whole text block
|
|
||||||
<ul class="values">
|
|
||||||
<li>"top"</li>
|
|
||||||
<li>"middle"</li>
|
|
||||||
<li>"bottom"</li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<div class="emph">paddingX</div>
|
|
||||||
(Number) - horizontal padding (in px) set equally on both, left and right sides
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<div class="emph">paddingY</div>
|
|
||||||
(Number) - vertical padding (in px) set equally on both, top and bottom sides
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<div class="emph">fitParent</div>
|
|
||||||
(Boolean) - parameter that controls which element to fit
|
|
||||||
<ul class="values">
|
|
||||||
<li>true - fit canvas parent's width instead of canvas own width</li>
|
|
||||||
<li>false - fit canvas width</li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<div class="emph">lineBreak</div>
|
|
||||||
(String) - text split rule
|
|
||||||
<ul class="values">
|
|
||||||
<li>"auto" - text fills padded container going to a next line on a whole word</li>
|
|
||||||
<li>"word" - each next word will be placed on a new line</li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<div class="emph">sizeToFill</div>
|
|
||||||
(Boolean) - auto font size to fill text container
|
|
||||||
<ul class="values">
|
|
||||||
<li>true - ignore given font size/line height and resize text to fill its padded container</li>
|
|
||||||
<li>false - use specified or default font size</li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<div class="emph">strokeText</div>
|
|
||||||
(Boolean) - if enabled, all lines match the same width with flexed spaces between words (one-word lines are
|
|
||||||
ignored)
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<div class="emph">justifyLines</div>
|
|
||||||
(Boolean) - if enabled, text breaks on every new line character "\n"
|
|
||||||
</li>
|
|
||||||
<p>
|
|
||||||
NOTE: if a single word is too long to fit the width with specified font size, it will break on any letter
|
|
||||||
unless "sizeToFill" option is enabled.
|
|
||||||
</p>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<h2>Default Options</h2><br/>
|
|
||||||
<pre class="white-block">
|
|
||||||
{
|
|
||||||
<strong>font</strong>: "18px Arial, sans-serif",
|
|
||||||
<strong>lineHeight</strong>: 1,
|
|
||||||
<strong>textAlign</strong>: "left",
|
|
||||||
<strong>verticalAlign</strong>: "top",
|
|
||||||
<strong>paddingX</strong>: 0,
|
|
||||||
<strong>paddingY</strong>: 0,
|
|
||||||
<strong>fitParent</strong>: false,
|
|
||||||
<strong>lineBreak</strong>: "auto",
|
|
||||||
<strong>sizeToFill</strong>: false,
|
|
||||||
<strong>allowNewLine</strong>: true,
|
|
||||||
<strong>justifyLines</strong>: false,
|
|
||||||
<strong>strokeText</strong>: false
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<h2>Usage</h2><br/>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Configure context settings properties such as "fillStyle", "lineWidth" or "strokeStyle" before using
|
|
||||||
CanvasTextWrapper like so:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<pre class="white-block">
|
|
||||||
var canvas = document.getElementById("#canvasText");
|
|
||||||
canvas.width = 200;
|
|
||||||
canvas.height = 200;
|
|
||||||
context = canvas.getContext("2d");
|
|
||||||
context.lineWidth = 2;
|
|
||||||
context.strokeStyle = "#ff0000";
|
|
||||||
CanvasTextWrapper(canvas,"Hello"); //default options will apply
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<h2>Installation</h2><br/>
|
|
||||||
|
|
||||||
<p class="white-block">
|
|
||||||
bower install canvas-text-wrapper<br/>
|
|
||||||
npm install canvas-text-wrapper
|
|
||||||
</p>
|
|
||||||
</article>
|
|
||||||
<section>
|
|
||||||
<h2>Examples</h2>
|
|
||||||
</section>
|
|
||||||
<footer>
|
|
||||||
← <a href="https://github.com/namniak/CanvasTextWrapper">View on GitHub</a>
|
|
||||||
</footer>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,276 +0,0 @@
|
|||||||
(function (root) {
|
|
||||||
|
|
||||||
function CanvasTextWrapper(canvas, text, options) {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
var defaults = {
|
|
||||||
font: '18px Arial, sans-serif',
|
|
||||||
sizeToFill: false, // text is resized to fill the container (given font size is ignored)
|
|
||||||
lineHeight: 1, // default line height equivalent of '100%'
|
|
||||||
allowNewLine: true, // breaks text on every new line character '\n'
|
|
||||||
lineBreak: 'auto', // text fills the element's (canvas or parent) width going to a new line on a whole word
|
|
||||||
textAlign: 'left', // each line of text is aligned left
|
|
||||||
verticalAlign: 'top', // text lines block is aligned top
|
|
||||||
justifyLines: false, // lines are not justified
|
|
||||||
paddingX: 0, // 0px left & right text padding relatively to canvas or its container
|
|
||||||
paddingY: 0, // 0px top & bottom text padding relatively to canvas or its container
|
|
||||||
fitParent: false, // text is set to fit canvas width
|
|
||||||
strokeText: false // text is stroked according to context configuration
|
|
||||||
};
|
|
||||||
|
|
||||||
var opts = {};
|
|
||||||
|
|
||||||
for (var property in defaults) {
|
|
||||||
if (defaults.hasOwnProperty(property)) {
|
|
||||||
opts[property] = (options && options[property]) ? options[property] : defaults[property];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var context = canvas.getContext('2d');
|
|
||||||
context.font = opts.font;
|
|
||||||
context.textBaseline = 'bottom';
|
|
||||||
|
|
||||||
var EL_WIDTH = (opts.fitParent === false) ? canvas.width : canvas.parentNode.clientWidth;
|
|
||||||
var EL_HEIGHT = (opts.fitParent === false) ? canvas.height : canvas.parentNode.clientHeight;
|
|
||||||
var MAX_TXT_WIDTH = EL_WIDTH - (opts.paddingX * 2);
|
|
||||||
var MAX_TXT_HEIGHT = EL_HEIGHT - (opts.paddingY * 2);
|
|
||||||
|
|
||||||
var fontSize, textBlockHeight, lines, newLineIndexes, textPos, lineHeight;
|
|
||||||
|
|
||||||
init();
|
|
||||||
|
|
||||||
function init() {
|
|
||||||
fontSize = opts.font.match(/\d+(px|em|%)/g) ? +opts.font.match(/\d+(px|em|%)/g)[0].match(/\d+/g) : 18;
|
|
||||||
|
|
||||||
textBlockHeight = 0;
|
|
||||||
lines = [];
|
|
||||||
newLineIndexes = [];
|
|
||||||
textPos = {x: 0, y: 0};
|
|
||||||
|
|
||||||
setFont(fontSize);
|
|
||||||
setLineHeight();
|
|
||||||
validate();
|
|
||||||
render();
|
|
||||||
}
|
|
||||||
|
|
||||||
function render() {
|
|
||||||
if (opts.sizeToFill) {
|
|
||||||
var numWords = text.trim().split(/\s+/).length;
|
|
||||||
var fontSize = 0;
|
|
||||||
|
|
||||||
do {
|
|
||||||
setFont(++fontSize);
|
|
||||||
lineHeight = fontSize;
|
|
||||||
wrap();
|
|
||||||
} while (textBlockHeight < MAX_TXT_HEIGHT && (lines.join(' ').split(/\s+/).length == numWords));
|
|
||||||
|
|
||||||
setFont(--fontSize);
|
|
||||||
lineHeight = fontSize;
|
|
||||||
wrap();
|
|
||||||
} else {
|
|
||||||
wrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (opts.justifyLines && opts.lineBreak === 'auto') {
|
|
||||||
justify();
|
|
||||||
}
|
|
||||||
|
|
||||||
setVerticalAlign();
|
|
||||||
drawText();
|
|
||||||
}
|
|
||||||
|
|
||||||
function setFont(fontSize) {
|
|
||||||
var fontParts = (!opts.sizeToFill) ? opts.font.split(/\b\d+px\b/i) : context.font.split(/\b\d+px\b/i);
|
|
||||||
context.font = fontParts[0] + fontSize + 'px' + fontParts[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
function setLineHeight() {
|
|
||||||
if (!isNaN(opts.lineHeight)) {
|
|
||||||
lineHeight = fontSize * opts.lineHeight;
|
|
||||||
} else if (opts.lineHeight.toString().indexOf('px') !== -1) {
|
|
||||||
lineHeight = parseInt(opts.lineHeight);
|
|
||||||
} else if (opts.lineHeight.toString().indexOf('%') !== -1) {
|
|
||||||
lineHeight = (parseInt(opts.lineHeight) / 100) * fontSize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function wrap() {
|
|
||||||
if (opts.allowNewLine) {
|
|
||||||
var newLines = text.trim().split('\n');
|
|
||||||
for (var i = 0, idx = 0; i < newLines.length - 1; i++) {
|
|
||||||
idx += newLines[i].trim().split(/\s+/).length;
|
|
||||||
newLineIndexes.push(idx)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var words = text.trim().split(/\s+/);
|
|
||||||
checkLength(words);
|
|
||||||
breakText(words);
|
|
||||||
|
|
||||||
textBlockHeight = lines.length * lineHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkLength(words) {
|
|
||||||
var testString, tokenLen, sliced, leftover;
|
|
||||||
|
|
||||||
for (var i = 0; i < words.length; i++) {
|
|
||||||
testString = '';
|
|
||||||
tokenLen = context.measureText(words[i]).width;
|
|
||||||
|
|
||||||
if (tokenLen > MAX_TXT_WIDTH) {
|
|
||||||
for (var k = 0; (context.measureText(testString + words[i][k]).width <= MAX_TXT_WIDTH) && (k < words[i].length); k++) {
|
|
||||||
testString += words[i][k];
|
|
||||||
}
|
|
||||||
|
|
||||||
sliced = words[i].slice(0, k);
|
|
||||||
leftover = words[i].slice(k);
|
|
||||||
words.splice(i, 1, sliced, leftover);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function breakText(words) {
|
|
||||||
for (var i = 0, j = 0; i < words.length; j++) {
|
|
||||||
lines[j] = '';
|
|
||||||
|
|
||||||
if (opts.lineBreak === 'auto') {
|
|
||||||
while ((context.measureText(lines[j] + words[i]).width <= MAX_TXT_WIDTH) && (i < words.length)) {
|
|
||||||
|
|
||||||
lines[j] += words[i] + ' ';
|
|
||||||
i++;
|
|
||||||
|
|
||||||
if (opts.allowNewLine) {
|
|
||||||
for (var k = 0; k < newLineIndexes.length; k++) {
|
|
||||||
if (newLineIndexes[k] === i) {
|
|
||||||
j++;
|
|
||||||
lines[j] = '';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lines[j] = lines[j].trim();
|
|
||||||
} else {
|
|
||||||
lines[j] = words[i];
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function justify() {
|
|
||||||
var maxLen, longestLineIndex, tokenLen;
|
|
||||||
for (var i = 0; i < lines.length; i++) {
|
|
||||||
tokenLen = context.measureText(lines[i]).width;
|
|
||||||
|
|
||||||
if (!maxLen || tokenLen > maxLen) {
|
|
||||||
maxLen = tokenLen;
|
|
||||||
longestLineIndex = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// fill lines with extra spaces
|
|
||||||
var numWords, spaceLength, numOfSpaces, num, filler;
|
|
||||||
var delimiter = '\u200A';
|
|
||||||
for (i = 0; i < lines.length; i++) {
|
|
||||||
if (i === longestLineIndex) continue;
|
|
||||||
|
|
||||||
numWords = lines[i].trim().split(/\s+/).length;
|
|
||||||
if (numWords <= 1) continue;
|
|
||||||
|
|
||||||
lines[i] = lines[i].trim().split(/\s+/).join(delimiter);
|
|
||||||
|
|
||||||
spaceLength = context.measureText(delimiter).width;
|
|
||||||
numOfSpaces = (maxLen - context.measureText(lines[i]).width) / spaceLength;
|
|
||||||
num = numOfSpaces / (numWords - 1);
|
|
||||||
|
|
||||||
filler = '';
|
|
||||||
for (var j = 0; j < num; j++) {
|
|
||||||
filler += delimiter;
|
|
||||||
}
|
|
||||||
|
|
||||||
lines[i] = lines[i].trim().split(delimiter).join(filler);
|
|
||||||
//console.log('numWords:', numWords, 'numOfSpaces:', numOfSpaces, 'num:', num);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function drawText() {
|
|
||||||
for (var i = 0; i < lines.length; i++) {
|
|
||||||
setHorizontalAlign(lines[i]);
|
|
||||||
|
|
||||||
textPos.y = parseInt(textPos.y) + lineHeight;
|
|
||||||
context.fillText(lines[i], textPos.x, textPos.y);
|
|
||||||
|
|
||||||
if (opts.strokeText) {
|
|
||||||
context.strokeText(lines[i], textPos.x, textPos.y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function setHorizontalAlign(line) {
|
|
||||||
if (opts.textAlign == 'center') {
|
|
||||||
textPos.x = (EL_WIDTH - context.measureText(line).width) / 2;
|
|
||||||
} else if (opts.textAlign == 'right') {
|
|
||||||
textPos.x = EL_WIDTH - context.measureText(line).width - opts.paddingX;
|
|
||||||
} else {
|
|
||||||
textPos.x = opts.paddingX;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function setVerticalAlign() {
|
|
||||||
if (opts.verticalAlign == 'middle') {
|
|
||||||
textPos.y = (EL_HEIGHT - textBlockHeight) / 2;
|
|
||||||
} else if (opts.verticalAlign == 'bottom') {
|
|
||||||
textPos.y = EL_HEIGHT - textBlockHeight - opts.paddingY;
|
|
||||||
} else {
|
|
||||||
textPos.y = opts.paddingY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function validate() {
|
|
||||||
if (!(canvas instanceof HTMLCanvasElement))
|
|
||||||
throw new TypeError('The first parameter must be an instance of HTMLCanvasElement.');
|
|
||||||
|
|
||||||
if (typeof text !== 'string')
|
|
||||||
throw new TypeError('The second parameter must be a string.');
|
|
||||||
|
|
||||||
if (isNaN(fontSize))
|
|
||||||
throw new TypeError('Cannot parse "font".');
|
|
||||||
|
|
||||||
if (isNaN(lineHeight))
|
|
||||||
throw new TypeError('Cannot parse "lineHeight".');
|
|
||||||
|
|
||||||
if (opts.textAlign.toLocaleLowerCase() !== 'left' && opts.textAlign.toLocaleLowerCase() !== 'center' && opts.textAlign.toLocaleLowerCase() !== 'right')
|
|
||||||
throw new TypeError('Property "textAlign" must be set to either "left", "center", or "right".');
|
|
||||||
|
|
||||||
if (opts.verticalAlign.toLocaleLowerCase() !== 'top' && opts.verticalAlign.toLocaleLowerCase() !== 'middle' && opts.verticalAlign.toLocaleLowerCase() !== 'bottom')
|
|
||||||
throw new TypeError('Property "verticalAlign" must be set to either "top", "middle", or "bottom".');
|
|
||||||
|
|
||||||
if (typeof opts.justifyLines !== 'boolean')
|
|
||||||
throw new TypeError('Property "justifyLines" must be set to a Boolean.');
|
|
||||||
|
|
||||||
if (isNaN(opts.paddingX))
|
|
||||||
throw new TypeError('Property "paddingX" must be set to a Number.');
|
|
||||||
|
|
||||||
if (isNaN(opts.paddingY))
|
|
||||||
throw new TypeError('Property "paddingY" must be set to a Number.');
|
|
||||||
|
|
||||||
if (typeof opts.fitParent !== 'boolean')
|
|
||||||
throw new TypeError('Property "fitParent" must be set to a Boolean.');
|
|
||||||
|
|
||||||
if (opts.lineBreak.toLocaleLowerCase() !== 'auto' && opts.lineBreak.toLocaleLowerCase() !== 'word')
|
|
||||||
throw new TypeError('Property "lineBreak" must be set to either "auto" or "word".');
|
|
||||||
|
|
||||||
if (typeof opts.sizeToFill !== 'boolean')
|
|
||||||
throw new TypeError('Property "sizeToFill" must be set to a Boolean.');
|
|
||||||
|
|
||||||
if (typeof opts.strokeText !== 'boolean')
|
|
||||||
throw new TypeError('Property "strokeText" must be set to a Boolean.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ('module' in root && 'exports' in module) {
|
|
||||||
module.exports = CanvasTextWrapper;
|
|
||||||
} else {
|
|
||||||
root.CanvasTextWrapper = CanvasTextWrapper;
|
|
||||||
}
|
|
||||||
})(this);
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
document.onreadystatechange = function() {
|
|
||||||
'use strict';
|
|
||||||
if (document.readyState === 'complete') {
|
|
||||||
(function() {
|
|
||||||
var container = document.getElementsByTagName('section')[0];
|
|
||||||
var w = 448;
|
|
||||||
var h = 250;
|
|
||||||
var options = model;
|
|
||||||
|
|
||||||
createExamples();
|
|
||||||
|
|
||||||
function createExamples() {
|
|
||||||
var fragment = new DocumentFragment();
|
|
||||||
var context;
|
|
||||||
|
|
||||||
for (var i = 0; i < options.length; i++) {
|
|
||||||
var exampleItem = document.createElement('div');
|
|
||||||
fragment.appendChild(exampleItem);
|
|
||||||
|
|
||||||
var canvas = document.createElement('canvas');
|
|
||||||
exampleItem.appendChild(canvas);
|
|
||||||
canvas.width = w;
|
|
||||||
canvas.height = h;
|
|
||||||
context = canvas.getContext('2d');
|
|
||||||
context.lineWidth = 1;
|
|
||||||
context.strokeStyle = 'yellow';
|
|
||||||
CanvasTextWrapper(canvas,(options[i].txt),options[i]);
|
|
||||||
|
|
||||||
var hint = document.createElement('div');
|
|
||||||
exampleItem.appendChild(hint);
|
|
||||||
var optionsData = '';
|
|
||||||
|
|
||||||
for (var property in options[i]) {
|
|
||||||
if (options[i].hasOwnProperty(property)) {
|
|
||||||
if (property == 'txt') continue;
|
|
||||||
var stringWrapper = (property == 'paddingX' || property == 'paddingY' || property == 'sizeToFill' || property === 'justifyLines' || property === 'allowNewLine' || property === 'strokeText') ? '' : '"';
|
|
||||||
optionsData += ' <span>' + property + ':</span> ' +
|
|
||||||
stringWrapper + options[i][property] + stringWrapper + ',<br/>';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
hint.innerHTML = '<h6>CODE:</h6><p>' +
|
|
||||||
'CanvasTextWrapper(canvas, str, {<br/>' + optionsData + '});' +
|
|
||||||
'</p>';
|
|
||||||
}
|
|
||||||
|
|
||||||
container.appendChild(fragment);
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
var model = [
|
|
||||||
{
|
|
||||||
txt: 'Break text on every next word',
|
|
||||||
font: 'italic 800 25px Arial, sans-serif',
|
|
||||||
textAlign: 'center',
|
|
||||||
lineBreak: 'word',
|
|
||||||
lineHeight: "160%"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
txt: 'Center text block horizontally and vertically',
|
|
||||||
font: 'bold 35px Arial, sans-serif',
|
|
||||||
textAlign: 'center',
|
|
||||||
verticalAlign: 'middle'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
txt: 'Resize text automatically to fill its padded container. Given "font" and "lineHeight" properties are ignored',
|
|
||||||
textAlign: 'center',
|
|
||||||
verticalAlign: 'middle',
|
|
||||||
sizeToFill: true,
|
|
||||||
paddingX: 10,
|
|
||||||
paddingY: 30
|
|
||||||
},
|
|
||||||
{
|
|
||||||
txt: 'Justify text lines takes effect only with "auto" break line. Single word lines are skipped',
|
|
||||||
font: 'bold 40px Arial, sans-serif',
|
|
||||||
paddingX: 20,
|
|
||||||
paddingY: 20,
|
|
||||||
verticalAlign: 'middle',
|
|
||||||
textAlign: 'center',
|
|
||||||
justifyLines: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
txt: 'Apply text stroke is based on context settings',
|
|
||||||
font: 'bold 40px Arial, sans-serif',
|
|
||||||
textAlign: 'right',
|
|
||||||
paddingX: 25,
|
|
||||||
strokeText: true,
|
|
||||||
lineHeight: '60px'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
txt: 'Use\n new line character "\\n"\n to break lines\nwhere needed',
|
|
||||||
font: 'bold 30px Arial, sans-serif',
|
|
||||||
verticalAlign: 'bottom',
|
|
||||||
allowNewLine: true,
|
|
||||||
lineHeight: '200%'
|
|
||||||
}
|
|
||||||
];
|
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
test/fixtures/dontlint.txt
|
||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"curly": true, // true: Require {} for every new block or scope
|
||||||
|
"eqeqeq": true, // true: Require triple equals (===) for comparison
|
||||||
|
"immed": true, // true: Require immediate invocations to be wrapped in parens e.g. `(function () { } ());`
|
||||||
|
"latedef": true, // true: Require variables/functions to be defined before being used
|
||||||
|
"newcap": true, // true: Require capitalization of all constructor functions e.g. `new F()`
|
||||||
|
"noarg": true, // true: Prohibit use of `arguments.caller` and `arguments.callee`
|
||||||
|
"sub": true, // true: Tolerate using `[]` notation when it can still be expressed in dot notation
|
||||||
|
"undef": true, // true: Require all non-global variables to be declared (prevents global leaks)
|
||||||
|
"boss": true, // true: Tolerate assignments where comparisons would be expected
|
||||||
|
"eqnull": true, // true: Tolerate use of `== null`
|
||||||
|
"node": true // Node.js
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
node_modules
|
||||||
|
npm-debug.log
|
||||||
|
tmp
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
language: node_js
|
||||||
|
node_js:
|
||||||
|
- "0.8"
|
||||||
|
- "0.10"
|
||||||
|
before_script:
|
||||||
|
- npm install -g grunt-cli
|
||||||
+2
@@ -0,0 +1,2 @@
|
|||||||
|
"Cowboy" Ben Alman (http://benalman.com/)
|
||||||
|
Tyler Kellen (http://goingslowly.com/)
|
||||||
+93
@@ -0,0 +1,93 @@
|
|||||||
|
v0.6.5:
|
||||||
|
date: 2013-10-23
|
||||||
|
changes:
|
||||||
|
- Fix output when maxerr is low.
|
||||||
|
v0.6.4:
|
||||||
|
date: 2013-08-29
|
||||||
|
changes:
|
||||||
|
- jshintrc now loaded by jshint allowing comments.
|
||||||
|
v0.6.3:
|
||||||
|
date: 2013-08-15
|
||||||
|
changes:
|
||||||
|
- Fix module location for jshint 2.1.10.
|
||||||
|
v0.6.2:
|
||||||
|
date: 2013-07-29
|
||||||
|
changes:
|
||||||
|
- Update to jshint 2.1.7.
|
||||||
|
v0.6.1:
|
||||||
|
date: 2013-07-27
|
||||||
|
changes:
|
||||||
|
- Peg jshint to 2.1.4 until breaking changes in 2.1.5 are fixed.
|
||||||
|
v0.6.0:
|
||||||
|
date: 2013-06-02
|
||||||
|
changes:
|
||||||
|
- Dont always succeed the task when using a custom reporter.
|
||||||
|
- Bump jshint to 2.1.3.
|
||||||
|
v0.5.4:
|
||||||
|
date: 2013-05-22
|
||||||
|
changes:
|
||||||
|
- Fix default reporter to show offending file.
|
||||||
|
v0.5.3:
|
||||||
|
date: 2013-05-19
|
||||||
|
changes:
|
||||||
|
- "Performance: Execute the reporter once rather than per file."
|
||||||
|
v0.5.2:
|
||||||
|
date: 2013-05-18
|
||||||
|
changes:
|
||||||
|
- Fix printing too many erroneous ignored file errors.
|
||||||
|
v0.5.1:
|
||||||
|
date: 2013-05-17
|
||||||
|
changes:
|
||||||
|
- Fix for when only 1 file is lint free.
|
||||||
|
v0.5.0:
|
||||||
|
date: 2013-05-17
|
||||||
|
changes:
|
||||||
|
- Bump to jshint 2.0.
|
||||||
|
- Add support for .jshintignore files and ignores option
|
||||||
|
- Add support for extensions option.
|
||||||
|
- Add support for custom reporters and output report to a file.
|
||||||
|
v0.4.3:
|
||||||
|
date: 2013-04-08
|
||||||
|
changes:
|
||||||
|
- Fix evaluation of predef option when it's an object.
|
||||||
|
v0.4.2:
|
||||||
|
date: 2013-04-08
|
||||||
|
changes:
|
||||||
|
- Avoid wiping force option when jshintrc is used.
|
||||||
|
v0.4.1:
|
||||||
|
date: 2013-04-06
|
||||||
|
changes:
|
||||||
|
- Fix to allow object type for deprecated predef.
|
||||||
|
v0.4.0:
|
||||||
|
date: 2013-04-04
|
||||||
|
changes:
|
||||||
|
- Revert task level options to override jshintrc files.
|
||||||
|
v0.3.0:
|
||||||
|
date: 2013-03-13
|
||||||
|
changes:
|
||||||
|
- Bump to JSHint 1.1.0.
|
||||||
|
- Add force option to report JSHint errors but not fail the task.
|
||||||
|
- Add error/warning code to message.
|
||||||
|
- Allow task level options to override jshintrc file.
|
||||||
|
v0.2.0:
|
||||||
|
date: 2013-02-26
|
||||||
|
changes:
|
||||||
|
- Bump to JSHint 1.0
|
||||||
|
v0.1.1:
|
||||||
|
date: 2013-02-15
|
||||||
|
changes:
|
||||||
|
- First official release for Grunt 0.4.0.
|
||||||
|
v0.1.1rc6:
|
||||||
|
date: 2013-01-18
|
||||||
|
changes:
|
||||||
|
- Updating grunt/gruntplugin dependencies to rc6.
|
||||||
|
- Changing in-development grunt/gruntplugin dependency versions from tilde version ranges to specific versions.
|
||||||
|
v0.1.1rc5:
|
||||||
|
date: 2013-01-09
|
||||||
|
changes:
|
||||||
|
- Updating to work with grunt v0.4.0rc5.
|
||||||
|
- Switching to this.filesSrc api.
|
||||||
|
v0.1.0:
|
||||||
|
date: 2012-10-18
|
||||||
|
changes:
|
||||||
|
- Work in progress, not yet officially released.
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
Please see the [Contributing to grunt](http://gruntjs.com/contributing) guide for information on contributing to this project.
|
||||||
+63
@@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* grunt-contrib-jshint
|
||||||
|
* http://gruntjs.com/
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013 "Cowboy" Ben Alman, contributors
|
||||||
|
* Licensed under the MIT license.
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
module.exports = function(grunt) {
|
||||||
|
|
||||||
|
// Project configuration.
|
||||||
|
grunt.initConfig({
|
||||||
|
jshint: {
|
||||||
|
allFiles: [
|
||||||
|
'Gruntfile.js',
|
||||||
|
'tasks/**/*.js',
|
||||||
|
'<%= nodeunit.tests %>',
|
||||||
|
],
|
||||||
|
individualFiles: {
|
||||||
|
files: [
|
||||||
|
{src: 'Gruntfile.js'},
|
||||||
|
{src: 'tasks/**/*.js'},
|
||||||
|
{src: '<%= nodeunit.tests %>'},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
withReporterShouldFail: {
|
||||||
|
options: {
|
||||||
|
reporter: 'checkstyle',
|
||||||
|
reporterOutput: 'tmp/report.xml',
|
||||||
|
force: true,
|
||||||
|
},
|
||||||
|
src: ['test/fixtures/missingsemicolon.js'],
|
||||||
|
},
|
||||||
|
ignoresSupport: {
|
||||||
|
src: ['test/fixtures/dontlint.txt'],
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
jshintrc: '.jshintrc',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// Unit tests.
|
||||||
|
nodeunit: {
|
||||||
|
tests: ['test/*_test.js'],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Actually load this plugin's task(s).
|
||||||
|
grunt.loadTasks('tasks');
|
||||||
|
|
||||||
|
// These plugins provide necessary tasks.
|
||||||
|
grunt.loadNpmTasks('grunt-contrib-nodeunit');
|
||||||
|
grunt.loadNpmTasks('grunt-contrib-internal');
|
||||||
|
|
||||||
|
// Whenever the "test" task is run, run the "nodeunit" task.
|
||||||
|
grunt.registerTask('test', ['jshint', 'nodeunit']);
|
||||||
|
|
||||||
|
// By default, lint and run all tests.
|
||||||
|
grunt.registerTask('default', ['test', 'build-contrib']);
|
||||||
|
|
||||||
|
};
|
||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
Copyright (c) 2013 "Cowboy" Ben Alman, contributors
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person
|
||||||
|
obtaining a copy of this software and associated documentation
|
||||||
|
files (the "Software"), to deal in the Software without
|
||||||
|
restriction, including without limitation the rights to use,
|
||||||
|
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the
|
||||||
|
Software is furnished to do so, subject to the following
|
||||||
|
conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||||
|
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
|
OTHER DEALINGS IN THE SOFTWARE.
|
||||||
+232
@@ -0,0 +1,232 @@
|
|||||||
|
# grunt-contrib-jshint v0.6.5 [](https://travis-ci.org/gruntjs/grunt-contrib-jshint)
|
||||||
|
|
||||||
|
> Validate files with JSHint.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
This plugin requires Grunt `~0.4.0`
|
||||||
|
|
||||||
|
If you haven't used [Grunt](http://gruntjs.com/) before, be sure to check out the [Getting Started](http://gruntjs.com/getting-started) guide, as it explains how to create a [Gruntfile](http://gruntjs.com/sample-gruntfile) as well as install and use Grunt plugins. Once you're familiar with that process, you may install this plugin with this command:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
npm install grunt-contrib-jshint --save-dev
|
||||||
|
```
|
||||||
|
|
||||||
|
Once the plugin has been installed, it may be enabled inside your Gruntfile with this line of JavaScript:
|
||||||
|
|
||||||
|
```js
|
||||||
|
grunt.loadNpmTasks('grunt-contrib-jshint');
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Jshint task
|
||||||
|
_Run this task with the `grunt jshint` command._
|
||||||
|
|
||||||
|
Task targets, files and options may be specified according to the grunt [Configuring tasks](http://gruntjs.com/configuring-tasks) guide.
|
||||||
|
|
||||||
|
For more explanations of the lint errors JSHint will throw at you please visit [jslinterrors.com](http://jslinterrors.com/).
|
||||||
|
|
||||||
|
### Options
|
||||||
|
|
||||||
|
Any specified option will be passed through directly to [JSHint][], thus you can specify any option that JSHint supports. See the [JSHint documentation][] for a list of supported options.
|
||||||
|
|
||||||
|
[JSHint]: http://www.jshint.com/
|
||||||
|
[JSHint documentation]: http://www.jshint.com/docs/
|
||||||
|
|
||||||
|
A few additional options are supported:
|
||||||
|
|
||||||
|
#### globals
|
||||||
|
Type: `Object`
|
||||||
|
Default value: `null`
|
||||||
|
|
||||||
|
A map of global variables, with keys as names and a boolean value to determine if they are assignable. This is not a standard JSHint option, but is passed into the `JSHINT` function as its third argument. See the [JSHint documentation][] for more information.
|
||||||
|
|
||||||
|
#### jshintrc
|
||||||
|
Type: `String`
|
||||||
|
Default value: `null`
|
||||||
|
|
||||||
|
If this filename is specified, options and globals defined therein will be used. The `jshintrc` file must be valid JSON and looks something like this:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"curly": true,
|
||||||
|
"eqnull": true,
|
||||||
|
"eqeqeq": true,
|
||||||
|
"undef": true,
|
||||||
|
"globals": {
|
||||||
|
"jQuery": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
*Be aware that `jshintrc` settings are not merged with your Grunt options.*
|
||||||
|
|
||||||
|
#### extensions
|
||||||
|
Type: `String`
|
||||||
|
Default value: `''`
|
||||||
|
|
||||||
|
A list of non-dot-js extensions to check.
|
||||||
|
|
||||||
|
#### ignores
|
||||||
|
Type: `Array`
|
||||||
|
Default value: `null`
|
||||||
|
|
||||||
|
A list of files and dirs to ignore. This will override your `.jshintignore` file if set and does not merge.
|
||||||
|
|
||||||
|
#### force
|
||||||
|
Type: `Boolean`
|
||||||
|
Default value: `false`
|
||||||
|
|
||||||
|
Set `force` to `true` to report JSHint errors but not fail the task.
|
||||||
|
|
||||||
|
#### reporter
|
||||||
|
Type: `String`
|
||||||
|
Default value: `null`
|
||||||
|
|
||||||
|
Allows you to modify this plugins output. By default it will use a built-in Grunt reporter. Set the path to your own custom reporter or to one of the built-in JSHint reporters: `jslint` or `checkstyle`.
|
||||||
|
|
||||||
|
See also: [Writing your own JSHint reporter.](http://jshint.com/docs/reporters/)
|
||||||
|
|
||||||
|
#### reporterOutput
|
||||||
|
Type: `String`
|
||||||
|
Default value: `null`
|
||||||
|
|
||||||
|
Specify a filepath to output the results of a reporter. If `reporterOutput` is specified then all output will be written to the given filepath instead of printed to stdout.
|
||||||
|
|
||||||
|
### Usage examples
|
||||||
|
|
||||||
|
#### Wildcards
|
||||||
|
In this example, running `grunt jshint:all` (or `grunt jshint` because `jshint` is a [multi task](http://gruntjs.com/configuring-tasks#task-configuration-and-targets)) will lint the project's Gruntfile as well as all JavaScript files in the `lib` and `test` directories and their subdirectores, using the default JSHint options.
|
||||||
|
|
||||||
|
```js
|
||||||
|
// Project configuration.
|
||||||
|
grunt.initConfig({
|
||||||
|
jshint: {
|
||||||
|
all: ['Gruntfile.js', 'lib/**/*.js', 'test/**/*.js']
|
||||||
|
}
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Linting before and after concatenating
|
||||||
|
In this example, running `grunt jshint` will lint both the "beforeconcat" set and "afterconcat" sets of files. This is not ideal, because `dist/output.js` may get linted before it gets created via the [grunt-contrib-concat plugin](https://github.com/gruntjs/grunt-contrib-concat) `concat` task.
|
||||||
|
|
||||||
|
In this case, you should lint the "beforeconcat" files first, then concat, then lint the "afterconcat" files, by running `grunt jshint:beforeconcat concat jshint:afterconcat`.
|
||||||
|
|
||||||
|
```js
|
||||||
|
// Project configuration.
|
||||||
|
grunt.initConfig({
|
||||||
|
concat: {
|
||||||
|
dist: {
|
||||||
|
src: ['src/foo.js', 'src/bar.js'],
|
||||||
|
dest: 'dist/output.js'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
jshint: {
|
||||||
|
beforeconcat: ['src/foo.js', 'src/bar.js'],
|
||||||
|
afterconcat: ['dist/output.js']
|
||||||
|
}
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Specifying JSHint options and globals
|
||||||
|
|
||||||
|
In this example, custom JSHint options are specified. Note that when `grunt jshint:uses_defaults` is run, those files are linted using the default options, but when `grunt jshint:with_overrides` is run, those files are linted using _merged_ task/target options.
|
||||||
|
|
||||||
|
```js
|
||||||
|
// Project configuration.
|
||||||
|
grunt.initConfig({
|
||||||
|
jshint: {
|
||||||
|
options: {
|
||||||
|
curly: true,
|
||||||
|
eqeqeq: true,
|
||||||
|
eqnull: true,
|
||||||
|
browser: true,
|
||||||
|
globals: {
|
||||||
|
jQuery: true
|
||||||
|
},
|
||||||
|
},
|
||||||
|
uses_defaults: ['dir1/**/*.js', 'dir2/**/*.js'],
|
||||||
|
with_overrides: {
|
||||||
|
options: {
|
||||||
|
curly: false,
|
||||||
|
undef: true,
|
||||||
|
},
|
||||||
|
files: {
|
||||||
|
src: ['dir3/**/*.js', 'dir4/**/*.js']
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Ignoring specific warnings
|
||||||
|
|
||||||
|
If you would like to ignore a specific warning:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
[L24:C9] W015: Expected '}' to have an indentation at 11 instead at 9.
|
||||||
|
```
|
||||||
|
|
||||||
|
You can toggle it by prepending `-` to the warning id as an option:
|
||||||
|
|
||||||
|
```js
|
||||||
|
grunt.initConfig({
|
||||||
|
jshint: {
|
||||||
|
ignore_warning: {
|
||||||
|
options: {
|
||||||
|
'-W015': true,
|
||||||
|
},
|
||||||
|
src: ['**/*.js'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Ignoring specific files
|
||||||
|
|
||||||
|
Occasionally application files and third party libraries share the same directory. To exclude third party code, but include all current and future application files, use a glob for `files` and specifically exclude libraries using `ignores`. In this example, the jQuery file is matched by the glob but subsequently ignored when JSHint does its analysis.
|
||||||
|
|
||||||
|
```js
|
||||||
|
grunt.initConfig({
|
||||||
|
jshint: {
|
||||||
|
files: ['js/*.js'],
|
||||||
|
options: {
|
||||||
|
ignores: ['js/jquery.js']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Release History
|
||||||
|
|
||||||
|
* 2013-10-23 v0.6.5 Fix output when maxerr is low.
|
||||||
|
* 2013-08-29 v0.6.4 jshintrc now loaded by jshint allowing comments.
|
||||||
|
* 2013-08-15 v0.6.3 Fix module location for jshint 2.1.10.
|
||||||
|
* 2013-07-29 v0.6.2 Update to jshint 2.1.7.
|
||||||
|
* 2013-07-27 v0.6.1 Peg jshint to 2.1.4 until breaking changes in 2.1.5 are fixed.
|
||||||
|
* 2013-06-02 v0.6.0 Dont always succeed the task when using a custom reporter. Bump jshint to 2.1.3.
|
||||||
|
* 2013-05-22 v0.5.4 Fix default reporter to show offending file.
|
||||||
|
* 2013-05-19 v0.5.3 Performance: Execute the reporter once rather than per file.
|
||||||
|
* 2013-05-18 v0.5.2 Fix printing too many erroneous ignored file errors.
|
||||||
|
* 2013-05-17 v0.5.1 Fix for when only 1 file is lint free.
|
||||||
|
* 2013-05-17 v0.5.0 Bump to jshint 2.0. Add support for .jshintignore files and ignores option Add support for extensions option. Add support for custom reporters and output report to a file.
|
||||||
|
* 2013-04-08 v0.4.3 Fix evaluation of predef option when it's an object.
|
||||||
|
* 2013-04-08 v0.4.2 Avoid wiping force option when jshintrc is used.
|
||||||
|
* 2013-04-06 v0.4.1 Fix to allow object type for deprecated predef.
|
||||||
|
* 2013-04-04 v0.4.0 Revert task level options to override jshintrc files.
|
||||||
|
* 2013-03-13 v0.3.0 Bump to JSHint 1.1.0. Add force option to report JSHint errors but not fail the task. Add error/warning code to message. Allow task level options to override jshintrc file.
|
||||||
|
* 2013-02-26 v0.2.0 Bump to JSHint 1.0
|
||||||
|
* 2013-02-15 v0.1.1 First official release for Grunt 0.4.0.
|
||||||
|
* 2013-01-18 v0.1.1rc6 Updating grunt/gruntplugin dependencies to rc6. Changing in-development grunt/gruntplugin dependency versions from tilde version ranges to specific versions.
|
||||||
|
* 2013-01-09 v0.1.1rc5 Updating to work with grunt v0.4.0rc5. Switching to this.filesSrc api.
|
||||||
|
* 2012-10-18 v0.1.0 Work in progress, not yet officially released.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Task submitted by ["Cowboy" Ben Alman](http://benalman.com/)
|
||||||
|
|
||||||
|
*This file was generated on Wed Oct 23 2013 20:33:11.*
|
||||||
+103
@@ -0,0 +1,103 @@
|
|||||||
|
# Usage examples
|
||||||
|
|
||||||
|
## Wildcards
|
||||||
|
In this example, running `grunt jshint:all` (or `grunt jshint` because `jshint` is a [multi task](http://gruntjs.com/configuring-tasks#task-configuration-and-targets)) will lint the project's Gruntfile as well as all JavaScript files in the `lib` and `test` directories and their subdirectores, using the default JSHint options.
|
||||||
|
|
||||||
|
```js
|
||||||
|
// Project configuration.
|
||||||
|
grunt.initConfig({
|
||||||
|
jshint: {
|
||||||
|
all: ['Gruntfile.js', 'lib/**/*.js', 'test/**/*.js']
|
||||||
|
}
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## Linting before and after concatenating
|
||||||
|
In this example, running `grunt jshint` will lint both the "beforeconcat" set and "afterconcat" sets of files. This is not ideal, because `dist/output.js` may get linted before it gets created via the [grunt-contrib-concat plugin](https://github.com/gruntjs/grunt-contrib-concat) `concat` task.
|
||||||
|
|
||||||
|
In this case, you should lint the "beforeconcat" files first, then concat, then lint the "afterconcat" files, by running `grunt jshint:beforeconcat concat jshint:afterconcat`.
|
||||||
|
|
||||||
|
```js
|
||||||
|
// Project configuration.
|
||||||
|
grunt.initConfig({
|
||||||
|
concat: {
|
||||||
|
dist: {
|
||||||
|
src: ['src/foo.js', 'src/bar.js'],
|
||||||
|
dest: 'dist/output.js'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
jshint: {
|
||||||
|
beforeconcat: ['src/foo.js', 'src/bar.js'],
|
||||||
|
afterconcat: ['dist/output.js']
|
||||||
|
}
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## Specifying JSHint options and globals
|
||||||
|
|
||||||
|
In this example, custom JSHint options are specified. Note that when `grunt jshint:uses_defaults` is run, those files are linted using the default options, but when `grunt jshint:with_overrides` is run, those files are linted using _merged_ task/target options.
|
||||||
|
|
||||||
|
```js
|
||||||
|
// Project configuration.
|
||||||
|
grunt.initConfig({
|
||||||
|
jshint: {
|
||||||
|
options: {
|
||||||
|
curly: true,
|
||||||
|
eqeqeq: true,
|
||||||
|
eqnull: true,
|
||||||
|
browser: true,
|
||||||
|
globals: {
|
||||||
|
jQuery: true
|
||||||
|
},
|
||||||
|
},
|
||||||
|
uses_defaults: ['dir1/**/*.js', 'dir2/**/*.js'],
|
||||||
|
with_overrides: {
|
||||||
|
options: {
|
||||||
|
curly: false,
|
||||||
|
undef: true,
|
||||||
|
},
|
||||||
|
files: {
|
||||||
|
src: ['dir3/**/*.js', 'dir4/**/*.js']
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## Ignoring specific warnings
|
||||||
|
|
||||||
|
If you would like to ignore a specific warning:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
[L24:C9] W015: Expected '}' to have an indentation at 11 instead at 9.
|
||||||
|
```
|
||||||
|
|
||||||
|
You can toggle it by prepending `-` to the warning id as an option:
|
||||||
|
|
||||||
|
```js
|
||||||
|
grunt.initConfig({
|
||||||
|
jshint: {
|
||||||
|
ignore_warning: {
|
||||||
|
options: {
|
||||||
|
'-W015': true,
|
||||||
|
},
|
||||||
|
src: ['**/*.js'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## Ignoring specific files
|
||||||
|
|
||||||
|
Occasionally application files and third party libraries share the same directory. To exclude third party code, but include all current and future application files, use a glob for `files` and specifically exclude libraries using `ignores`. In this example, the jQuery file is matched by the glob but subsequently ignored when JSHint does its analysis.
|
||||||
|
|
||||||
|
```js
|
||||||
|
grunt.initConfig({
|
||||||
|
jshint: {
|
||||||
|
files: ['js/*.js'],
|
||||||
|
options: {
|
||||||
|
ignores: ['js/jquery.js']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
```
|
||||||
+66
@@ -0,0 +1,66 @@
|
|||||||
|
# Options
|
||||||
|
|
||||||
|
Any specified option will be passed through directly to [JSHint][], thus you can specify any option that JSHint supports. See the [JSHint documentation][] for a list of supported options.
|
||||||
|
|
||||||
|
[JSHint]: http://www.jshint.com/
|
||||||
|
[JSHint documentation]: http://www.jshint.com/docs/
|
||||||
|
|
||||||
|
A few additional options are supported:
|
||||||
|
|
||||||
|
## globals
|
||||||
|
Type: `Object`
|
||||||
|
Default value: `null`
|
||||||
|
|
||||||
|
A map of global variables, with keys as names and a boolean value to determine if they are assignable. This is not a standard JSHint option, but is passed into the `JSHINT` function as its third argument. See the [JSHint documentation][] for more information.
|
||||||
|
|
||||||
|
## jshintrc
|
||||||
|
Type: `String`
|
||||||
|
Default value: `null`
|
||||||
|
|
||||||
|
If this filename is specified, options and globals defined therein will be used. The `jshintrc` file must be valid JSON and looks something like this:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"curly": true,
|
||||||
|
"eqnull": true,
|
||||||
|
"eqeqeq": true,
|
||||||
|
"undef": true,
|
||||||
|
"globals": {
|
||||||
|
"jQuery": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
*Be aware that `jshintrc` settings are not merged with your Grunt options.*
|
||||||
|
|
||||||
|
## extensions
|
||||||
|
Type: `String`
|
||||||
|
Default value: `''`
|
||||||
|
|
||||||
|
A list of non-dot-js extensions to check.
|
||||||
|
|
||||||
|
## ignores
|
||||||
|
Type: `Array`
|
||||||
|
Default value: `null`
|
||||||
|
|
||||||
|
A list of files and dirs to ignore. This will override your `.jshintignore` file if set and does not merge.
|
||||||
|
|
||||||
|
## force
|
||||||
|
Type: `Boolean`
|
||||||
|
Default value: `false`
|
||||||
|
|
||||||
|
Set `force` to `true` to report JSHint errors but not fail the task.
|
||||||
|
|
||||||
|
## reporter
|
||||||
|
Type: `String`
|
||||||
|
Default value: `null`
|
||||||
|
|
||||||
|
Allows you to modify this plugins output. By default it will use a built-in Grunt reporter. Set the path to your own custom reporter or to one of the built-in JSHint reporters: `jslint` or `checkstyle`.
|
||||||
|
|
||||||
|
See also: [Writing your own JSHint reporter.](http://jshint.com/docs/reporters/)
|
||||||
|
|
||||||
|
## reporterOutput
|
||||||
|
Type: `String`
|
||||||
|
Default value: `null`
|
||||||
|
|
||||||
|
Specify a filepath to output the results of a reporter. If `reporterOutput` is specified then all output will be written to the given filepath instead of printed to stdout.
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
Task targets, files and options may be specified according to the grunt [Configuring tasks](http://gruntjs.com/configuring-tasks) guide.
|
||||||
|
|
||||||
|
For more explanations of the lint errors JSHint will throw at you please visit [jslinterrors.com](http://jslinterrors.com/).
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
../jshint/bin/jshint
|
||||||
+40
@@ -0,0 +1,40 @@
|
|||||||
|
JSHint, A Static Code Analysis Tool for JavaScript
|
||||||
|
--------------------------------------------------
|
||||||
|
|
||||||
|
\[ [Use it online](http://jshint.com/) • [About](http://jshint.com/about/) •
|
||||||
|
[Docs](http://jshint.com/docs/) • [FAQ](http://jshint.com/docs/faq) •
|
||||||
|
[Install](http://jshint.com/install/) • [Hack](http://jshint.com/hack/) •
|
||||||
|
[Blog](http://jshint.com/blog/) • [Twitter](https://twitter.com/jshint/) \]
|
||||||
|
|
||||||
|
[](https://travis-ci.org/jshint/jshint)
|
||||||
|
[](http://badge.fury.io/js/jshint)
|
||||||
|
|
||||||
|
JSHint is a community-driven tool to detect errors and potential problems
|
||||||
|
in JavaScript code and to enforce your team’s coding conventions. It is
|
||||||
|
very flexible so you can easily adjust it to your particular coding guidelines
|
||||||
|
and the environment you expect your code to execute in.
|
||||||
|
|
||||||
|
#### Reporting a bug
|
||||||
|
|
||||||
|
To report a bug simply create a
|
||||||
|
[new GitHub Issue](https://github.com/jshint/jshint/issues/new) and describe
|
||||||
|
your problem or suggestion. We welcome all kind of feedback regarding
|
||||||
|
JSHint including but not limited to:
|
||||||
|
|
||||||
|
* When JSHint doesn't work as expected
|
||||||
|
* When JSHint complains about valid JavaScript code that works in all browsers
|
||||||
|
* When you simply want a new option or feature
|
||||||
|
|
||||||
|
Before reporting a bug look around to see if there are any open or closed tickets
|
||||||
|
that cover your issue. And remember the wisdom: pull request > bug report > tweet.
|
||||||
|
|
||||||
|
|
||||||
|
#### License
|
||||||
|
|
||||||
|
JSHint is distributed under the MIT License. One file and one file only
|
||||||
|
(src/stable/jshint.js) is distributed under the slightly modified MIT License.
|
||||||
|
|
||||||
|
|
||||||
|
#### Thank you!
|
||||||
|
|
||||||
|
We really appreciate all kind of feedback and contributions. Thanks for using and supporting JSHint!
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
var shjs = require("shelljs");
|
||||||
|
var url = "https://github.com/jshint/jshint/pull/" + process.argv[2] + ".diff";
|
||||||
|
|
||||||
|
shjs.exec('curl "' + url + '" | git apply');
|
||||||
+32
@@ -0,0 +1,32 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
/*jshint shelljs:true */
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var browserify = require("browserify");
|
||||||
|
var bundle = browserify("./src/jshint.js");
|
||||||
|
var version = require("../package.json").version;
|
||||||
|
require("shelljs/make");
|
||||||
|
|
||||||
|
if (!test("-e", "../dist"))
|
||||||
|
mkdir("../dist");
|
||||||
|
|
||||||
|
bundle.require("./src/jshint.js", { expose: "jshint" });
|
||||||
|
bundle.bundle({}, function (err, src) {
|
||||||
|
var web = "./dist/jshint-" + version + ".js";
|
||||||
|
var rhino = "./dist/jshint-rhino-" + version + ".js";
|
||||||
|
|
||||||
|
[ "// " + version,
|
||||||
|
"var JSHINT;",
|
||||||
|
"var window;",
|
||||||
|
"if (typeof window === 'undefined') window = {};",
|
||||||
|
"(function () {",
|
||||||
|
"var require;",
|
||||||
|
src,
|
||||||
|
"JSHINT = require('jshint').JSHINT;",
|
||||||
|
"}());"
|
||||||
|
].join("\n").to(web);
|
||||||
|
|
||||||
|
("#!/usr/bin/env rhino\nvar window = {};\n" + cat(web, "./src/platforms/rhino.js")).to(rhino);
|
||||||
|
chmod("+x", rhino);
|
||||||
|
});
|
||||||
+36
@@ -0,0 +1,36 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
/*jshint shelljs:true, lastsemic:true, -W101*/
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var version = require("../package.json").version;
|
||||||
|
require("shelljs/make");
|
||||||
|
|
||||||
|
exec("git log --format='%H|%h|%an|%s' " + version + "..HEAD", { silent: true }, function (code, output) {
|
||||||
|
if (code !== 0)
|
||||||
|
return void console.log("git log return code is non-zero");
|
||||||
|
|
||||||
|
var commits = output.split("\n")
|
||||||
|
.filter(function (cmt) { return cmt.trim() !== "" })
|
||||||
|
.map(function (cmt) { return cmt.split("|") });
|
||||||
|
|
||||||
|
var html = "";
|
||||||
|
var authors = {};
|
||||||
|
|
||||||
|
commits.forEach(function (cmt) {
|
||||||
|
var tr = "";
|
||||||
|
tr += "<td class='commit'><a href='https://github.com/jshint/jshint/commit/" + cmt[0] + "'>" + cmt[1] + "</a></td>";
|
||||||
|
tr += "<td class='desc'>" + cmt[3].replace(/(#(\d+))/, "<a href='https://github.com/jshint/jshint/issues/$2/'>$1</a>") + "</td>";
|
||||||
|
html += "<tr>" + tr + "</tr>\n";
|
||||||
|
|
||||||
|
if (cmt[2] !== "Anton Kovalyov")
|
||||||
|
authors[cmt[2]] = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
echo("<!-- auto-generated -->");
|
||||||
|
echo("<table class='changelog'>\n" + html + "</table>\n");
|
||||||
|
|
||||||
|
if (Object.keys(authors).length) {
|
||||||
|
echo("<p class='thx'><strong>Thanks</strong> to " + Object.keys(authors).join(", ") + " for sending patches!</p>");
|
||||||
|
}
|
||||||
|
});
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
require("../src/cli.js").interpret(process.argv);
|
||||||
+37
@@ -0,0 +1,37 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
var url = "https://github.com/jshint/jshint/pull/" + process.argv[2] + ".patch";
|
||||||
|
var https = require("https");
|
||||||
|
var shjs = require("shelljs");
|
||||||
|
var opts = require("url").parse(url);
|
||||||
|
var msg = process.argv[3];
|
||||||
|
|
||||||
|
opts.rejectUnauthorized = false;
|
||||||
|
opts.agent = new https.Agent(opts);
|
||||||
|
|
||||||
|
https.get(opts, succ).on("error", err);
|
||||||
|
|
||||||
|
function succ(res) {
|
||||||
|
if (res.statusCode !== 200)
|
||||||
|
return void console.log("error:", res.statusCode);
|
||||||
|
|
||||||
|
var data = "";
|
||||||
|
res.on("data", function (chunk) {
|
||||||
|
data += chunk.toString();
|
||||||
|
});
|
||||||
|
|
||||||
|
res.on("end", function () {
|
||||||
|
data = data.split("\n");
|
||||||
|
data = data[1].replace(/^From\:\s/, "");
|
||||||
|
data = data.replace(/"/g, "");
|
||||||
|
|
||||||
|
shjs.exec("git commit -s --author=\"" + data + "\" --message=\"" + msg + "\"");
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function err(res) {
|
||||||
|
console.log("error:", res.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Generated
Vendored
Symlink
+1
@@ -0,0 +1 @@
|
|||||||
|
../shelljs/bin/shjs
|
||||||
+196
@@ -0,0 +1,196 @@
|
|||||||
|
**cli is a toolkit for rapidly building command line apps - it includes:**
|
||||||
|
|
||||||
|
- Full featured opts/args parser
|
||||||
|
- Plugin support for adding common options and switches
|
||||||
|
- Helper methods for working with input/output and spawning child processes
|
||||||
|
- Output colored/styled messages, [progress bars](https://github.com/chriso/cli/blob/master/examples/progress.js) or [spinners](https://github.com/chriso/cli/blob/master/examples/spinner.js)
|
||||||
|
- Command [auto-completion](https://github.com/chriso/cli/blob/master/examples/command.js) and [glob support](https://github.com/chriso/cli/blob/master/examples/glob.js)
|
||||||
|
|
||||||
|
Install using `npm install cli` or just bundle [cli.js](https://github.com/chriso/cli/raw/master/cli-min.js) with your app.
|
||||||
|
|
||||||
|
## Example apps
|
||||||
|
|
||||||
|
### sort.js
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
#!/usr/bin/env node
|
||||||
|
require('cli').withStdinLines(function(lines, newline) {
|
||||||
|
this.output(lines.sort().join(newline));
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
Try it out
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ ./sort.js < input.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
Let's add support for an `-n` switch to use a numeric sort, and a `-r` switch to reverse output - only 5 extra lines of code (!)
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var cli = require('cli'), options = cli.parse();
|
||||||
|
|
||||||
|
cli.withStdinLines(function(lines, newline) {
|
||||||
|
lines.sort(!options.n ? null : function(a, b) {
|
||||||
|
return parseInt(a) > parseInt(b);
|
||||||
|
});
|
||||||
|
if (options.r) lines.reverse();
|
||||||
|
this.output(lines.join(newline));
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### static.js
|
||||||
|
|
||||||
|
Let's create a static file server with daemon support to see the opts parser + plugins in use - note: this requires `npm install creationix daemon`
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var cli = require('cli').enable('daemon', 'status'); //Enable 2 plugins
|
||||||
|
|
||||||
|
cli.parse({
|
||||||
|
log: ['l', 'Enable logging'],
|
||||||
|
port: ['p', 'Listen on this port', 'number', 8080],
|
||||||
|
serve: [false, 'Serve static files from PATH', 'path', './public']
|
||||||
|
});
|
||||||
|
|
||||||
|
cli.main(function(args, options) {
|
||||||
|
var server, middleware = [];
|
||||||
|
|
||||||
|
if (options.log) {
|
||||||
|
this.debug('Enabling logging');
|
||||||
|
middleware.push(require('creationix/log')());
|
||||||
|
}
|
||||||
|
|
||||||
|
this.debug('Serving files from ' + options.serve);
|
||||||
|
middleware.push(require('creationix/static')('/', options.serve, 'index.html'));
|
||||||
|
|
||||||
|
server = this.createServer(middleware).listen(options.port);
|
||||||
|
|
||||||
|
this.ok('Listening on port ' + options.port);
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
To output usage information
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ ./static.js --help
|
||||||
|
```
|
||||||
|
|
||||||
|
To create a daemon that serves files from */tmp*, run
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ ./static.js -ld --serve=/tmp
|
||||||
|
```
|
||||||
|
|
||||||
|
For more examples, see [./examples](https://github.com/chriso/cli/tree/master/examples)
|
||||||
|
|
||||||
|
## Helper methods
|
||||||
|
|
||||||
|
cli has methods that collect stdin (newline is autodetected as \n or \r\n)
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
cli.withStdin(callback); //callback receives stdin as a string
|
||||||
|
cli.withStdinLines(callback); //callback receives stdin split into an array of lines (lines, newline)
|
||||||
|
```
|
||||||
|
|
||||||
|
cli also has a lower level method for working with input line by line (see [./examples/cat.js](https://github.com/chriso/cli/blob/master/examples/cat.js) for an example).
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
cli.withInput(file, function (line, newline, eof) {
|
||||||
|
if (!eof) {
|
||||||
|
this.output(line + newline);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
*Note: `file` can be omitted if you want to work with stdin*
|
||||||
|
|
||||||
|
To output a progress bar, call
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
cli.progress(progress); //Where 0 <= progress <= 1
|
||||||
|
```
|
||||||
|
|
||||||
|
To spawn a child process, use
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
cli.exec(cmd, callback); //callback receives the output of the process (split into lines)
|
||||||
|
```
|
||||||
|
|
||||||
|
cli also comes bundled with kof's [node-natives](https://github.com/kof/node-natives) (access with cli.native) and creationix' [stack](https://github.com/creationix/stack) (access with cli.createServer)
|
||||||
|
|
||||||
|
## Plugins
|
||||||
|
|
||||||
|
Plugins are a way of adding common opts and can be enabled using
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
cli.enable(plugin1, [plugin2, ...]); //To disable, use the equivalent disable() method
|
||||||
|
```
|
||||||
|
|
||||||
|
**help** - *enabled by default*
|
||||||
|
|
||||||
|
Adds `-h,--help` to output auto-generated usage information
|
||||||
|
|
||||||
|
**version**
|
||||||
|
|
||||||
|
Adds `-v,--version` to output version information for the app. cli will attempt to locate and parse a nearby *package.json*
|
||||||
|
|
||||||
|
To set your own app name and version, use `cli.setApp(app_name, version)`
|
||||||
|
|
||||||
|
**status**
|
||||||
|
|
||||||
|
Adds options to show/hide the stylized status messages that are output to the console when using one of these methods
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
cli.debug(msg); //Only shown when using --debug
|
||||||
|
cli.error(msg);
|
||||||
|
cli.fatal(msg); //Exits the process after outputting msg
|
||||||
|
cli.info(msg);
|
||||||
|
cli.ok(msg);
|
||||||
|
```
|
||||||
|
|
||||||
|
`-k,--no-color` will omit ANSI color escapes from the output
|
||||||
|
|
||||||
|
**glob** - *requires* `npm install glob`
|
||||||
|
|
||||||
|
Enables glob matching of arguments
|
||||||
|
|
||||||
|
**daemon** - *requires* `npm install daemon`
|
||||||
|
|
||||||
|
Adds `-d,--daemon ARG` for daemonizing the process and controlling the resulting daemon
|
||||||
|
|
||||||
|
`ARG` can be either start (default), stop, restart, pid (outputs the daemon's pid if it's running), or log (output the daemon's stdout+stderr)
|
||||||
|
|
||||||
|
**timeout**
|
||||||
|
|
||||||
|
Adds `-t,--timeout N` to exit the process after N seconds with an error
|
||||||
|
|
||||||
|
**catchall**
|
||||||
|
|
||||||
|
Adds `-c,--catch` to catch and output uncaughtExceptions and resume execution
|
||||||
|
|
||||||
|
*Note: Plugins are automatically disabled if an option or switch of the same name is already defined*
|
||||||
|
|
||||||
|
## LICENSE
|
||||||
|
|
||||||
|
(MIT license)
|
||||||
|
|
||||||
|
Copyright (c) 2010 Chris O'Hara <cohara87@gmail.com>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
+1133
File diff suppressed because it is too large
Load Diff
Generated
Vendored
Executable
+17
@@ -0,0 +1,17 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
var cli = require('cli');
|
||||||
|
|
||||||
|
var output_file = function (file) {
|
||||||
|
cli.withInput(file, function (line, sep, eof) {
|
||||||
|
if (!eof) {
|
||||||
|
cli.output(line + sep);
|
||||||
|
} else if (cli.args.length) {
|
||||||
|
output_file(cli.args.shift());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
if (cli.args.length) {
|
||||||
|
output_file(cli.args.shift());
|
||||||
|
}
|
||||||
Generated
Vendored
Executable
+16
@@ -0,0 +1,16 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
var cli = require('cli');
|
||||||
|
|
||||||
|
//The second (optional) argument of cli.parse() is a command list
|
||||||
|
//Type `./command.js --help` for usage info
|
||||||
|
|
||||||
|
//cli enables auto-completion of commands (similiar to npm), e.g. all of
|
||||||
|
//the following are equivalent and result in "Command is: install":
|
||||||
|
// $ ./command.js install
|
||||||
|
// $ ./command.js inst
|
||||||
|
// $ ./command.js i
|
||||||
|
|
||||||
|
cli.parse(null, ['install', 'test', 'edit', 'remove', 'uninstall', 'ls']);
|
||||||
|
|
||||||
|
console.log('Command is: ' + cli.command);
|
||||||
Generated
Vendored
Executable
+54
@@ -0,0 +1,54 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
/* All of the following commands are equivalent and write `foo\tbar foo` to out.txt
|
||||||
|
$ ./echo.js -n -e --output=out.txt "foo\tbar" "foo"
|
||||||
|
$ ./echo.js --newline --escape --output "out.txt" "foo\tbar" "foo"
|
||||||
|
$ ./echo.js -ne --output=out.txt "foo\tbar" "foo"
|
||||||
|
$ ./echo.js -en --output="out.txt" "foo\tbar" "foo"
|
||||||
|
*/
|
||||||
|
|
||||||
|
var cli = require('cli');
|
||||||
|
|
||||||
|
cli.parse({
|
||||||
|
newline: ['n', 'Do not output the trailing newline'],
|
||||||
|
escape: ['e', 'Enable interpretation of backslash escapes'],
|
||||||
|
separator: ['s', 'Separate arguments using this value', 'string', ' '],
|
||||||
|
output: [false, 'Write to FILE rather than the console', 'file']
|
||||||
|
});
|
||||||
|
|
||||||
|
cli.main(function (args, options) {
|
||||||
|
var output = '', i, j, l, output_stream;
|
||||||
|
|
||||||
|
if (this.argc) {
|
||||||
|
if (options.escape) {
|
||||||
|
var replace = {'\\n':'\n','\\r':'\r','\\t':'\t','\\e':'\e','\\v':'\v','\\f':'\f','\\c':'\c','\\b':'\b','\\a':'\a','\\\\':'\\'};
|
||||||
|
var escape = function (str) {
|
||||||
|
string += '';
|
||||||
|
for (j in replace) {
|
||||||
|
string = string.replace(i, replace[i]);
|
||||||
|
}
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
for (i = 0, l = this.argc; i < l; i++) {
|
||||||
|
args[i] = escape(args[i]);
|
||||||
|
}
|
||||||
|
options.separator = escape(options.separator);
|
||||||
|
}
|
||||||
|
output += args.join(options.separator);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!options.newline) {
|
||||||
|
output += '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (options.output) {
|
||||||
|
output_stream = this.native.fs.createWriteStream(options.output)
|
||||||
|
} else {
|
||||||
|
output_stream = process.stdout;
|
||||||
|
}
|
||||||
|
output_stream.write(output);
|
||||||
|
} catch (e) {
|
||||||
|
this.fatal('Could not write to output stream');
|
||||||
|
}
|
||||||
|
});
|
||||||
Generated
Vendored
Executable
+6
@@ -0,0 +1,6 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
var cli = require('cli').enable('glob');
|
||||||
|
|
||||||
|
//Running `./glob.js *.js` will output a list of .js files in this directory
|
||||||
|
console.log(cli.args);
|
||||||
Generated
Vendored
Executable
+20
@@ -0,0 +1,20 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
var cli = require('../');
|
||||||
|
|
||||||
|
//You can (optionally) boost the width of output with:
|
||||||
|
//cli.width = 120;
|
||||||
|
|
||||||
|
//You can also adjust the width of the options/command definitions
|
||||||
|
//cli.option_width = 25;
|
||||||
|
|
||||||
|
var long_desc = 'Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry\'s '
|
||||||
|
+ 'standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make'
|
||||||
|
+ ' a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, '
|
||||||
|
+ 'remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing '
|
||||||
|
+ 'Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions'
|
||||||
|
+ ' of Lorem Ipsum.';
|
||||||
|
|
||||||
|
cli.parse({
|
||||||
|
foo: ['f', long_desc]
|
||||||
|
});
|
||||||
Generated
Vendored
Executable
+11
@@ -0,0 +1,11 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
var cli = require('cli');
|
||||||
|
|
||||||
|
var i = 0, interval = setInterval(function () {
|
||||||
|
cli.progress(++i / 100);
|
||||||
|
if (i === 100) {
|
||||||
|
clearInterval(interval);
|
||||||
|
cli.ok('Finished!');
|
||||||
|
}
|
||||||
|
}, 50);
|
||||||
Generated
Vendored
Executable
+18
@@ -0,0 +1,18 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
var cli = require('cli');
|
||||||
|
|
||||||
|
var options = cli.parse({
|
||||||
|
numeric: ['n', 'Compare using a numeric sort'],
|
||||||
|
reverse: ['r', 'Reverse the results']
|
||||||
|
});
|
||||||
|
|
||||||
|
cli.withStdinLines(function (lines, newline) {
|
||||||
|
lines.sort(!options.numeric ? null : function (a, b) {
|
||||||
|
return parseInt(a) > parseInt(b);
|
||||||
|
});
|
||||||
|
if (options.reverse) {
|
||||||
|
lines.reverse();
|
||||||
|
}
|
||||||
|
this.output(lines.join(newline));
|
||||||
|
});
|
||||||
Generated
Vendored
Executable
+9
@@ -0,0 +1,9 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
var cli = require('cli');
|
||||||
|
|
||||||
|
cli.spinner('Working..');
|
||||||
|
|
||||||
|
setTimeout(function () {
|
||||||
|
cli.spinner('Working.. done!', true); //End the spinner
|
||||||
|
}, 3000);
|
||||||
Generated
Vendored
Executable
+27
@@ -0,0 +1,27 @@
|
|||||||
|
#!/usr/bin/env coffee
|
||||||
|
|
||||||
|
cli = require 'cli'
|
||||||
|
|
||||||
|
cli.enable('daemon','status')
|
||||||
|
.setUsage('static.coffee [OPTIONS]')
|
||||||
|
|
||||||
|
cli.parse {
|
||||||
|
log: ['l', 'Enable logging']
|
||||||
|
port: ['p', 'Listen on this port', 'number', 8080]
|
||||||
|
serve: [false, 'Serve static files from PATH', 'path', './public']
|
||||||
|
}
|
||||||
|
|
||||||
|
middleware = []
|
||||||
|
|
||||||
|
cli.main (args, options) ->
|
||||||
|
|
||||||
|
if options.log
|
||||||
|
@debug 'Enabling logging'
|
||||||
|
middleware.push require('creationix/log')()
|
||||||
|
|
||||||
|
@debug 'Serving files from ' + options.serve
|
||||||
|
middleware.push require('creationix/static')('/', options.serve, 'index.html')
|
||||||
|
|
||||||
|
server = @createServer(middleware).listen options.port
|
||||||
|
|
||||||
|
@ok 'Listening on port ' + options.port
|
||||||
Generated
Vendored
Executable
+25
@@ -0,0 +1,25 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
var cli = require('cli').enable('status', 'daemon');
|
||||||
|
|
||||||
|
cli.parse({
|
||||||
|
log: ['l', 'Enable logging'],
|
||||||
|
port: ['p', 'Listen on this port', 'number', 8080],
|
||||||
|
serve: [false, 'Serve static files from PATH', 'path', './public']
|
||||||
|
});
|
||||||
|
|
||||||
|
cli.main(function (args, options) {
|
||||||
|
var server, middleware = [];
|
||||||
|
|
||||||
|
if (options.log) {
|
||||||
|
this.debug('Enabling logging');
|
||||||
|
middleware.push(require('creationix/log')());
|
||||||
|
}
|
||||||
|
|
||||||
|
this.debug('Serving files from ' + options.serve);
|
||||||
|
middleware.push(require('creationix/static')('/', options.serve, 'index.html'));
|
||||||
|
|
||||||
|
server = this.createServer(middleware).listen(options.port);
|
||||||
|
|
||||||
|
this.ok('Listening on port ' + options.port);
|
||||||
|
});
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
module.exports = require('./cli');
|
||||||
Generated
Vendored
+2
@@ -0,0 +1,2 @@
|
|||||||
|
.*.swp
|
||||||
|
test/a/
|
||||||
node_modules/grunt-contrib-jshint/node_modules/jshint/node_modules/cli/node_modules/glob/.travis.yml
Generated
Vendored
+4
@@ -0,0 +1,4 @@
|
|||||||
|
language: node_js
|
||||||
|
node_js:
|
||||||
|
- 0.10
|
||||||
|
- 0.11
|
||||||
Generated
Vendored
+27
@@ -0,0 +1,27 @@
|
|||||||
|
Copyright (c) Isaac Z. Schlueter ("Author")
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
The BSD License
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
|
||||||
|
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
Generated
Vendored
+250
@@ -0,0 +1,250 @@
|
|||||||
|
# Glob
|
||||||
|
|
||||||
|
Match files using the patterns the shell uses, like stars and stuff.
|
||||||
|
|
||||||
|
This is a glob implementation in JavaScript. It uses the `minimatch`
|
||||||
|
library to do its matching.
|
||||||
|
|
||||||
|
## Attention: node-glob users!
|
||||||
|
|
||||||
|
The API has changed dramatically between 2.x and 3.x. This library is
|
||||||
|
now 100% JavaScript, and the integer flags have been replaced with an
|
||||||
|
options object.
|
||||||
|
|
||||||
|
Also, there's an event emitter class, proper tests, and all the other
|
||||||
|
things you've come to expect from node modules.
|
||||||
|
|
||||||
|
And best of all, no compilation!
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var glob = require("glob")
|
||||||
|
|
||||||
|
// options is optional
|
||||||
|
glob("**/*.js", options, function (er, files) {
|
||||||
|
// files is an array of filenames.
|
||||||
|
// If the `nonull` option is set, and nothing
|
||||||
|
// was found, then files is ["**/*.js"]
|
||||||
|
// er is an error object or null.
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
Please see the [minimatch
|
||||||
|
documentation](https://github.com/isaacs/minimatch) for more details.
|
||||||
|
|
||||||
|
Supports these glob features:
|
||||||
|
|
||||||
|
* Brace Expansion
|
||||||
|
* Extended glob matching
|
||||||
|
* "Globstar" `**` matching
|
||||||
|
|
||||||
|
See:
|
||||||
|
|
||||||
|
* `man sh`
|
||||||
|
* `man bash`
|
||||||
|
* `man 3 fnmatch`
|
||||||
|
* `man 5 gitignore`
|
||||||
|
* [minimatch documentation](https://github.com/isaacs/minimatch)
|
||||||
|
|
||||||
|
## glob(pattern, [options], cb)
|
||||||
|
|
||||||
|
* `pattern` {String} Pattern to be matched
|
||||||
|
* `options` {Object}
|
||||||
|
* `cb` {Function}
|
||||||
|
* `err` {Error | null}
|
||||||
|
* `matches` {Array<String>} filenames found matching the pattern
|
||||||
|
|
||||||
|
Perform an asynchronous glob search.
|
||||||
|
|
||||||
|
## glob.sync(pattern, [options])
|
||||||
|
|
||||||
|
* `pattern` {String} Pattern to be matched
|
||||||
|
* `options` {Object}
|
||||||
|
* return: {Array<String>} filenames found matching the pattern
|
||||||
|
|
||||||
|
Perform a synchronous glob search.
|
||||||
|
|
||||||
|
## Class: glob.Glob
|
||||||
|
|
||||||
|
Create a Glob object by instanting the `glob.Glob` class.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var Glob = require("glob").Glob
|
||||||
|
var mg = new Glob(pattern, options, cb)
|
||||||
|
```
|
||||||
|
|
||||||
|
It's an EventEmitter, and starts walking the filesystem to find matches
|
||||||
|
immediately.
|
||||||
|
|
||||||
|
### new glob.Glob(pattern, [options], [cb])
|
||||||
|
|
||||||
|
* `pattern` {String} pattern to search for
|
||||||
|
* `options` {Object}
|
||||||
|
* `cb` {Function} Called when an error occurs, or matches are found
|
||||||
|
* `err` {Error | null}
|
||||||
|
* `matches` {Array<String>} filenames found matching the pattern
|
||||||
|
|
||||||
|
Note that if the `sync` flag is set in the options, then matches will
|
||||||
|
be immediately available on the `g.found` member.
|
||||||
|
|
||||||
|
### Properties
|
||||||
|
|
||||||
|
* `minimatch` The minimatch object that the glob uses.
|
||||||
|
* `options` The options object passed in.
|
||||||
|
* `error` The error encountered. When an error is encountered, the
|
||||||
|
glob object is in an undefined state, and should be discarded.
|
||||||
|
* `aborted` Boolean which is set to true when calling `abort()`. There
|
||||||
|
is no way at this time to continue a glob search after aborting, but
|
||||||
|
you can re-use the statCache to avoid having to duplicate syscalls.
|
||||||
|
* `statCache` Collection of all the stat results the glob search
|
||||||
|
performed.
|
||||||
|
* `cache` Convenience object. Each field has the following possible
|
||||||
|
values:
|
||||||
|
* `false` - Path does not exist
|
||||||
|
* `true` - Path exists
|
||||||
|
* `1` - Path exists, and is not a directory
|
||||||
|
* `2` - Path exists, and is a directory
|
||||||
|
* `[file, entries, ...]` - Path exists, is a directory, and the
|
||||||
|
array value is the results of `fs.readdir`
|
||||||
|
|
||||||
|
### Events
|
||||||
|
|
||||||
|
* `end` When the matching is finished, this is emitted with all the
|
||||||
|
matches found. If the `nonull` option is set, and no match was found,
|
||||||
|
then the `matches` list contains the original pattern. The matches
|
||||||
|
are sorted, unless the `nosort` flag is set.
|
||||||
|
* `match` Every time a match is found, this is emitted with the matched.
|
||||||
|
* `error` Emitted when an unexpected error is encountered, or whenever
|
||||||
|
any fs error occurs if `options.strict` is set.
|
||||||
|
* `abort` When `abort()` is called, this event is raised.
|
||||||
|
|
||||||
|
### Methods
|
||||||
|
|
||||||
|
* `abort` Stop the search.
|
||||||
|
|
||||||
|
### Options
|
||||||
|
|
||||||
|
All the options that can be passed to Minimatch can also be passed to
|
||||||
|
Glob to change pattern matching behavior. Also, some have been added,
|
||||||
|
or have glob-specific ramifications.
|
||||||
|
|
||||||
|
All options are false by default, unless otherwise noted.
|
||||||
|
|
||||||
|
All options are added to the glob object, as well.
|
||||||
|
|
||||||
|
* `cwd` The current working directory in which to search. Defaults
|
||||||
|
to `process.cwd()`.
|
||||||
|
* `root` The place where patterns starting with `/` will be mounted
|
||||||
|
onto. Defaults to `path.resolve(options.cwd, "/")` (`/` on Unix
|
||||||
|
systems, and `C:\` or some such on Windows.)
|
||||||
|
* `dot` Include `.dot` files in normal matches and `globstar` matches.
|
||||||
|
Note that an explicit dot in a portion of the pattern will always
|
||||||
|
match dot files.
|
||||||
|
* `nomount` By default, a pattern starting with a forward-slash will be
|
||||||
|
"mounted" onto the root setting, so that a valid filesystem path is
|
||||||
|
returned. Set this flag to disable that behavior.
|
||||||
|
* `mark` Add a `/` character to directory matches. Note that this
|
||||||
|
requires additional stat calls.
|
||||||
|
* `nosort` Don't sort the results.
|
||||||
|
* `stat` Set to true to stat *all* results. This reduces performance
|
||||||
|
somewhat, and is completely unnecessary, unless `readdir` is presumed
|
||||||
|
to be an untrustworthy indicator of file existence. It will cause
|
||||||
|
ELOOP to be triggered one level sooner in the case of cyclical
|
||||||
|
symbolic links.
|
||||||
|
* `silent` When an unusual error is encountered
|
||||||
|
when attempting to read a directory, a warning will be printed to
|
||||||
|
stderr. Set the `silent` option to true to suppress these warnings.
|
||||||
|
* `strict` When an unusual error is encountered
|
||||||
|
when attempting to read a directory, the process will just continue on
|
||||||
|
in search of other matches. Set the `strict` option to raise an error
|
||||||
|
in these cases.
|
||||||
|
* `cache` See `cache` property above. Pass in a previously generated
|
||||||
|
cache object to save some fs calls.
|
||||||
|
* `statCache` A cache of results of filesystem information, to prevent
|
||||||
|
unnecessary stat calls. While it should not normally be necessary to
|
||||||
|
set this, you may pass the statCache from one glob() call to the
|
||||||
|
options object of another, if you know that the filesystem will not
|
||||||
|
change between calls. (See "Race Conditions" below.)
|
||||||
|
* `sync` Perform a synchronous glob search.
|
||||||
|
* `nounique` In some cases, brace-expanded patterns can result in the
|
||||||
|
same file showing up multiple times in the result set. By default,
|
||||||
|
this implementation prevents duplicates in the result set.
|
||||||
|
Set this flag to disable that behavior.
|
||||||
|
* `nonull` Set to never return an empty set, instead returning a set
|
||||||
|
containing the pattern itself. This is the default in glob(3).
|
||||||
|
* `nocase` Perform a case-insensitive match. Note that case-insensitive
|
||||||
|
filesystems will sometimes result in glob returning results that are
|
||||||
|
case-insensitively matched anyway, since readdir and stat will not
|
||||||
|
raise an error.
|
||||||
|
* `debug` Set to enable debug logging in minimatch and glob.
|
||||||
|
* `globDebug` Set to enable debug logging in glob, but not minimatch.
|
||||||
|
|
||||||
|
## Comparisons to other fnmatch/glob implementations
|
||||||
|
|
||||||
|
While strict compliance with the existing standards is a worthwhile
|
||||||
|
goal, some discrepancies exist between node-glob and other
|
||||||
|
implementations, and are intentional.
|
||||||
|
|
||||||
|
If the pattern starts with a `!` character, then it is negated. Set the
|
||||||
|
`nonegate` flag to suppress this behavior, and treat leading `!`
|
||||||
|
characters normally. This is perhaps relevant if you wish to start the
|
||||||
|
pattern with a negative extglob pattern like `!(a|B)`. Multiple `!`
|
||||||
|
characters at the start of a pattern will negate the pattern multiple
|
||||||
|
times.
|
||||||
|
|
||||||
|
If a pattern starts with `#`, then it is treated as a comment, and
|
||||||
|
will not match anything. Use `\#` to match a literal `#` at the
|
||||||
|
start of a line, or set the `nocomment` flag to suppress this behavior.
|
||||||
|
|
||||||
|
The double-star character `**` is supported by default, unless the
|
||||||
|
`noglobstar` flag is set. This is supported in the manner of bsdglob
|
||||||
|
and bash 4.1, where `**` only has special significance if it is the only
|
||||||
|
thing in a path part. That is, `a/**/b` will match `a/x/y/b`, but
|
||||||
|
`a/**b` will not.
|
||||||
|
|
||||||
|
If an escaped pattern has no matches, and the `nonull` flag is set,
|
||||||
|
then glob returns the pattern as-provided, rather than
|
||||||
|
interpreting the character escapes. For example,
|
||||||
|
`glob.match([], "\\*a\\?")` will return `"\\*a\\?"` rather than
|
||||||
|
`"*a?"`. This is akin to setting the `nullglob` option in bash, except
|
||||||
|
that it does not resolve escaped pattern characters.
|
||||||
|
|
||||||
|
If brace expansion is not disabled, then it is performed before any
|
||||||
|
other interpretation of the glob pattern. Thus, a pattern like
|
||||||
|
`+(a|{b),c)}`, which would not be valid in bash or zsh, is expanded
|
||||||
|
**first** into the set of `+(a|b)` and `+(a|c)`, and those patterns are
|
||||||
|
checked for validity. Since those two are valid, matching proceeds.
|
||||||
|
|
||||||
|
## Windows
|
||||||
|
|
||||||
|
**Please only use forward-slashes in glob expressions.**
|
||||||
|
|
||||||
|
Though windows uses either `/` or `\` as its path separator, only `/`
|
||||||
|
characters are used by this glob implementation. You must use
|
||||||
|
forward-slashes **only** in glob expressions. Back-slashes will always
|
||||||
|
be interpreted as escape characters, not path separators.
|
||||||
|
|
||||||
|
Results from absolute patterns such as `/foo/*` are mounted onto the
|
||||||
|
root setting using `path.join`. On windows, this will by default result
|
||||||
|
in `/foo/*` matching `C:\foo\bar.txt`.
|
||||||
|
|
||||||
|
## Race Conditions
|
||||||
|
|
||||||
|
Glob searching, by its very nature, is susceptible to race conditions,
|
||||||
|
since it relies on directory walking and such.
|
||||||
|
|
||||||
|
As a result, it is possible that a file that exists when glob looks for
|
||||||
|
it may have been deleted or modified by the time it returns the result.
|
||||||
|
|
||||||
|
As part of its internal implementation, this program caches all stat
|
||||||
|
and readdir calls that it makes, in order to cut down on system
|
||||||
|
overhead. However, this also makes it even more susceptible to races,
|
||||||
|
especially if the cache or statCache objects are reused between glob
|
||||||
|
calls.
|
||||||
|
|
||||||
|
Users are thus advised not to use a glob result as a guarantee of
|
||||||
|
filesystem state in the face of rapid changes. For the vast majority
|
||||||
|
of operations, this is never a problem.
|
||||||
Generated
Vendored
+9
@@ -0,0 +1,9 @@
|
|||||||
|
var Glob = require("../").Glob
|
||||||
|
|
||||||
|
var pattern = "test/a/**/[cg]/../[cg]"
|
||||||
|
console.log(pattern)
|
||||||
|
|
||||||
|
var mg = new Glob(pattern, {mark: true, sync:true}, function (er, matches) {
|
||||||
|
console.log("matches", matches)
|
||||||
|
})
|
||||||
|
console.log("after")
|
||||||
Generated
Vendored
+9
@@ -0,0 +1,9 @@
|
|||||||
|
var Glob = require("../").Glob
|
||||||
|
|
||||||
|
var pattern = "{./*/*,/*,/usr/local/*}"
|
||||||
|
console.log(pattern)
|
||||||
|
|
||||||
|
var mg = new Glob(pattern, {mark: true}, function (er, matches) {
|
||||||
|
console.log("matches", matches)
|
||||||
|
})
|
||||||
|
console.log("after")
|
||||||
Generated
Vendored
+738
@@ -0,0 +1,738 @@
|
|||||||
|
// Approach:
|
||||||
|
//
|
||||||
|
// 1. Get the minimatch set
|
||||||
|
// 2. For each pattern in the set, PROCESS(pattern)
|
||||||
|
// 3. Store matches per-set, then uniq them
|
||||||
|
//
|
||||||
|
// PROCESS(pattern)
|
||||||
|
// Get the first [n] items from pattern that are all strings
|
||||||
|
// Join these together. This is PREFIX.
|
||||||
|
// If there is no more remaining, then stat(PREFIX) and
|
||||||
|
// add to matches if it succeeds. END.
|
||||||
|
// readdir(PREFIX) as ENTRIES
|
||||||
|
// If fails, END
|
||||||
|
// If pattern[n] is GLOBSTAR
|
||||||
|
// // handle the case where the globstar match is empty
|
||||||
|
// // by pruning it out, and testing the resulting pattern
|
||||||
|
// PROCESS(pattern[0..n] + pattern[n+1 .. $])
|
||||||
|
// // handle other cases.
|
||||||
|
// for ENTRY in ENTRIES (not dotfiles)
|
||||||
|
// // attach globstar + tail onto the entry
|
||||||
|
// PROCESS(pattern[0..n] + ENTRY + pattern[n .. $])
|
||||||
|
//
|
||||||
|
// else // not globstar
|
||||||
|
// for ENTRY in ENTRIES (not dotfiles, unless pattern[n] is dot)
|
||||||
|
// Test ENTRY against pattern[n]
|
||||||
|
// If fails, continue
|
||||||
|
// If passes, PROCESS(pattern[0..n] + item + pattern[n+1 .. $])
|
||||||
|
//
|
||||||
|
// Caveat:
|
||||||
|
// Cache all stats and readdirs results to minimize syscall. Since all
|
||||||
|
// we ever care about is existence and directory-ness, we can just keep
|
||||||
|
// `true` for files, and [children,...] for directories, or `false` for
|
||||||
|
// things that don't exist.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = glob
|
||||||
|
|
||||||
|
var fs = require("fs")
|
||||||
|
, minimatch = require("minimatch")
|
||||||
|
, Minimatch = minimatch.Minimatch
|
||||||
|
, inherits = require("inherits")
|
||||||
|
, EE = require("events").EventEmitter
|
||||||
|
, path = require("path")
|
||||||
|
, isDir = {}
|
||||||
|
, assert = require("assert").ok
|
||||||
|
, once = require("once")
|
||||||
|
|
||||||
|
function glob (pattern, options, cb) {
|
||||||
|
if (typeof options === "function") cb = options, options = {}
|
||||||
|
if (!options) options = {}
|
||||||
|
|
||||||
|
if (typeof options === "number") {
|
||||||
|
deprecated()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var g = new Glob(pattern, options, cb)
|
||||||
|
return g.sync ? g.found : g
|
||||||
|
}
|
||||||
|
|
||||||
|
glob.fnmatch = deprecated
|
||||||
|
|
||||||
|
function deprecated () {
|
||||||
|
throw new Error("glob's interface has changed. Please see the docs.")
|
||||||
|
}
|
||||||
|
|
||||||
|
glob.sync = globSync
|
||||||
|
function globSync (pattern, options) {
|
||||||
|
if (typeof options === "number") {
|
||||||
|
deprecated()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
options = options || {}
|
||||||
|
options.sync = true
|
||||||
|
return glob(pattern, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
this._processingEmitQueue = false
|
||||||
|
|
||||||
|
glob.Glob = Glob
|
||||||
|
inherits(Glob, EE)
|
||||||
|
function Glob (pattern, options, cb) {
|
||||||
|
if (!(this instanceof Glob)) {
|
||||||
|
return new Glob(pattern, options, cb)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof options === "function") {
|
||||||
|
cb = options
|
||||||
|
options = null
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof cb === "function") {
|
||||||
|
cb = once(cb)
|
||||||
|
this.on("error", cb)
|
||||||
|
this.on("end", function (matches) {
|
||||||
|
cb(null, matches)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
options = options || {}
|
||||||
|
|
||||||
|
this._endEmitted = false
|
||||||
|
this.EOF = {}
|
||||||
|
this._emitQueue = []
|
||||||
|
|
||||||
|
this.paused = false
|
||||||
|
this._processingEmitQueue = false
|
||||||
|
|
||||||
|
this.maxDepth = options.maxDepth || 1000
|
||||||
|
this.maxLength = options.maxLength || Infinity
|
||||||
|
this.cache = options.cache || {}
|
||||||
|
this.statCache = options.statCache || {}
|
||||||
|
|
||||||
|
this.changedCwd = false
|
||||||
|
var cwd = process.cwd()
|
||||||
|
if (!options.hasOwnProperty("cwd")) this.cwd = cwd
|
||||||
|
else {
|
||||||
|
this.cwd = options.cwd
|
||||||
|
this.changedCwd = path.resolve(options.cwd) !== cwd
|
||||||
|
}
|
||||||
|
|
||||||
|
this.root = options.root || path.resolve(this.cwd, "/")
|
||||||
|
this.root = path.resolve(this.root)
|
||||||
|
if (process.platform === "win32")
|
||||||
|
this.root = this.root.replace(/\\/g, "/")
|
||||||
|
|
||||||
|
this.nomount = !!options.nomount
|
||||||
|
|
||||||
|
if (!pattern) {
|
||||||
|
throw new Error("must provide pattern")
|
||||||
|
}
|
||||||
|
|
||||||
|
// base-matching: just use globstar for that.
|
||||||
|
if (options.matchBase && -1 === pattern.indexOf("/")) {
|
||||||
|
if (options.noglobstar) {
|
||||||
|
throw new Error("base matching requires globstar")
|
||||||
|
}
|
||||||
|
pattern = "**/" + pattern
|
||||||
|
}
|
||||||
|
|
||||||
|
this.strict = options.strict !== false
|
||||||
|
this.dot = !!options.dot
|
||||||
|
this.mark = !!options.mark
|
||||||
|
this.sync = !!options.sync
|
||||||
|
this.nounique = !!options.nounique
|
||||||
|
this.nonull = !!options.nonull
|
||||||
|
this.nosort = !!options.nosort
|
||||||
|
this.nocase = !!options.nocase
|
||||||
|
this.stat = !!options.stat
|
||||||
|
|
||||||
|
this.debug = !!options.debug || !!options.globDebug
|
||||||
|
|
||||||
|
if (/\bglob\b/.test(process.env.NODE_DEBUG || ''))
|
||||||
|
this.debug = true
|
||||||
|
|
||||||
|
if (this.debug)
|
||||||
|
this.log = console.error
|
||||||
|
|
||||||
|
this.silent = !!options.silent
|
||||||
|
|
||||||
|
var mm = this.minimatch = new Minimatch(pattern, options)
|
||||||
|
this.options = mm.options
|
||||||
|
pattern = this.pattern = mm.pattern
|
||||||
|
|
||||||
|
this.error = null
|
||||||
|
this.aborted = false
|
||||||
|
|
||||||
|
// list of all the patterns that ** has resolved do, so
|
||||||
|
// we can avoid visiting multiple times.
|
||||||
|
this._globstars = {}
|
||||||
|
|
||||||
|
EE.call(this)
|
||||||
|
|
||||||
|
// process each pattern in the minimatch set
|
||||||
|
var n = this.minimatch.set.length
|
||||||
|
|
||||||
|
// The matches are stored as {<filename>: true,...} so that
|
||||||
|
// duplicates are automagically pruned.
|
||||||
|
// Later, we do an Object.keys() on these.
|
||||||
|
// Keep them as a list so we can fill in when nonull is set.
|
||||||
|
this.matches = new Array(n)
|
||||||
|
|
||||||
|
if (this.minimatch.set.length === 0) {
|
||||||
|
return process.nextTick(this._finish.bind(this))
|
||||||
|
}
|
||||||
|
|
||||||
|
this.minimatch.set.forEach(iterator.bind(this))
|
||||||
|
function iterator (pattern, i, set) {
|
||||||
|
this._process(pattern, 0, i, function (er) {
|
||||||
|
if (er) this.emit("error", er)
|
||||||
|
if (-- n <= 0) this._finish()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Glob.prototype.log = function () {}
|
||||||
|
|
||||||
|
Glob.prototype._finish = function () {
|
||||||
|
assert(this instanceof Glob)
|
||||||
|
|
||||||
|
var nou = this.nounique
|
||||||
|
, all = nou ? [] : {}
|
||||||
|
|
||||||
|
for (var i = 0, l = this.matches.length; i < l; i ++) {
|
||||||
|
var matches = this.matches[i]
|
||||||
|
this.log("matches[%d] =", i, matches)
|
||||||
|
// do like the shell, and spit out the literal glob
|
||||||
|
if (!matches) {
|
||||||
|
if (this.nonull) {
|
||||||
|
var literal = this.minimatch.globSet[i]
|
||||||
|
if (nou) all.push(literal)
|
||||||
|
else all[literal] = true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// had matches
|
||||||
|
var m = Object.keys(matches)
|
||||||
|
if (nou) all.push.apply(all, m)
|
||||||
|
else m.forEach(function (m) {
|
||||||
|
all[m] = true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!nou) all = Object.keys(all)
|
||||||
|
|
||||||
|
if (!this.nosort) {
|
||||||
|
all = all.sort(this.nocase ? alphasorti : alphasort)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.mark) {
|
||||||
|
// at *some* point we statted all of these
|
||||||
|
all = all.map(this._mark, this)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.log("emitting end", all)
|
||||||
|
|
||||||
|
this.EOF = this.found = all
|
||||||
|
this.emitMatch(this.EOF)
|
||||||
|
}
|
||||||
|
|
||||||
|
function alphasorti (a, b) {
|
||||||
|
a = a.toLowerCase()
|
||||||
|
b = b.toLowerCase()
|
||||||
|
return alphasort(a, b)
|
||||||
|
}
|
||||||
|
|
||||||
|
function alphasort (a, b) {
|
||||||
|
return a > b ? 1 : a < b ? -1 : 0
|
||||||
|
}
|
||||||
|
|
||||||
|
Glob.prototype._mark = function (p) {
|
||||||
|
var c = this.cache[p]
|
||||||
|
var m = p
|
||||||
|
if (c) {
|
||||||
|
var isDir = c === 2 || Array.isArray(c)
|
||||||
|
var slash = p.slice(-1) === '/'
|
||||||
|
|
||||||
|
if (isDir && !slash)
|
||||||
|
m += '/'
|
||||||
|
else if (!isDir && slash)
|
||||||
|
m = m.slice(0, -1)
|
||||||
|
|
||||||
|
if (m !== p) {
|
||||||
|
this.statCache[m] = this.statCache[p]
|
||||||
|
this.cache[m] = this.cache[p]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
|
Glob.prototype.abort = function () {
|
||||||
|
this.aborted = true
|
||||||
|
this.emit("abort")
|
||||||
|
}
|
||||||
|
|
||||||
|
Glob.prototype.pause = function () {
|
||||||
|
if (this.paused) return
|
||||||
|
if (this.sync)
|
||||||
|
this.emit("error", new Error("Can't pause/resume sync glob"))
|
||||||
|
this.paused = true
|
||||||
|
this.emit("pause")
|
||||||
|
}
|
||||||
|
|
||||||
|
Glob.prototype.resume = function () {
|
||||||
|
if (!this.paused) return
|
||||||
|
if (this.sync)
|
||||||
|
this.emit("error", new Error("Can't pause/resume sync glob"))
|
||||||
|
this.paused = false
|
||||||
|
this.emit("resume")
|
||||||
|
this._processEmitQueue()
|
||||||
|
//process.nextTick(this.emit.bind(this, "resume"))
|
||||||
|
}
|
||||||
|
|
||||||
|
Glob.prototype.emitMatch = function (m) {
|
||||||
|
this.log('emitMatch', m)
|
||||||
|
this._emitQueue.push(m)
|
||||||
|
this._processEmitQueue()
|
||||||
|
}
|
||||||
|
|
||||||
|
Glob.prototype._processEmitQueue = function (m) {
|
||||||
|
this.log("pEQ paused=%j processing=%j m=%j", this.paused,
|
||||||
|
this._processingEmitQueue, m)
|
||||||
|
var done = false
|
||||||
|
while (!this._processingEmitQueue &&
|
||||||
|
!this.paused) {
|
||||||
|
this._processingEmitQueue = true
|
||||||
|
var m = this._emitQueue.shift()
|
||||||
|
this.log(">processEmitQueue", m === this.EOF ? ":EOF:" : m)
|
||||||
|
if (!m) {
|
||||||
|
this.log(">processEmitQueue, falsey m")
|
||||||
|
this._processingEmitQueue = false
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m === this.EOF || !(this.mark && !this.stat)) {
|
||||||
|
this.log("peq: unmarked, or eof")
|
||||||
|
next.call(this, 0, false)
|
||||||
|
} else if (this.statCache[m]) {
|
||||||
|
var sc = this.statCache[m]
|
||||||
|
var exists
|
||||||
|
if (sc)
|
||||||
|
exists = sc.isDirectory() ? 2 : 1
|
||||||
|
this.log("peq: stat cached")
|
||||||
|
next.call(this, exists, exists === 2)
|
||||||
|
} else {
|
||||||
|
this.log("peq: _stat, then next")
|
||||||
|
this._stat(m, next)
|
||||||
|
}
|
||||||
|
|
||||||
|
function next(exists, isDir) {
|
||||||
|
this.log("next", m, exists, isDir)
|
||||||
|
var ev = m === this.EOF ? "end" : "match"
|
||||||
|
|
||||||
|
// "end" can only happen once.
|
||||||
|
assert(!this._endEmitted)
|
||||||
|
if (ev === "end")
|
||||||
|
this._endEmitted = true
|
||||||
|
|
||||||
|
if (exists) {
|
||||||
|
// Doesn't mean it necessarily doesn't exist, it's possible
|
||||||
|
// we just didn't check because we don't care that much, or
|
||||||
|
// this is EOF anyway.
|
||||||
|
if (isDir && !m.match(/\/$/)) {
|
||||||
|
m = m + "/"
|
||||||
|
} else if (!isDir && m.match(/\/$/)) {
|
||||||
|
m = m.replace(/\/+$/, "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.log("emit", ev, m)
|
||||||
|
this.emit(ev, m)
|
||||||
|
this._processingEmitQueue = false
|
||||||
|
if (done && m !== this.EOF && !this.paused)
|
||||||
|
this._processEmitQueue()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
done = true
|
||||||
|
}
|
||||||
|
|
||||||
|
Glob.prototype._process = function (pattern, depth, index, cb_) {
|
||||||
|
assert(this instanceof Glob)
|
||||||
|
|
||||||
|
var cb = function cb (er, res) {
|
||||||
|
assert(this instanceof Glob)
|
||||||
|
if (this.paused) {
|
||||||
|
if (!this._processQueue) {
|
||||||
|
this._processQueue = []
|
||||||
|
this.once("resume", function () {
|
||||||
|
var q = this._processQueue
|
||||||
|
this._processQueue = null
|
||||||
|
q.forEach(function (cb) { cb() })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
this._processQueue.push(cb_.bind(this, er, res))
|
||||||
|
} else {
|
||||||
|
cb_.call(this, er, res)
|
||||||
|
}
|
||||||
|
}.bind(this)
|
||||||
|
|
||||||
|
if (this.aborted) return cb()
|
||||||
|
|
||||||
|
if (depth > this.maxDepth) return cb()
|
||||||
|
|
||||||
|
// Get the first [n] parts of pattern that are all strings.
|
||||||
|
var n = 0
|
||||||
|
while (typeof pattern[n] === "string") {
|
||||||
|
n ++
|
||||||
|
}
|
||||||
|
// now n is the index of the first one that is *not* a string.
|
||||||
|
|
||||||
|
// see if there's anything else
|
||||||
|
var prefix
|
||||||
|
switch (n) {
|
||||||
|
// if not, then this is rather simple
|
||||||
|
case pattern.length:
|
||||||
|
prefix = pattern.join("/")
|
||||||
|
this._stat(prefix, function (exists, isDir) {
|
||||||
|
// either it's there, or it isn't.
|
||||||
|
// nothing more to do, either way.
|
||||||
|
if (exists) {
|
||||||
|
if (prefix && isAbsolute(prefix) && !this.nomount) {
|
||||||
|
if (prefix.charAt(0) === "/") {
|
||||||
|
prefix = path.join(this.root, prefix)
|
||||||
|
} else {
|
||||||
|
prefix = path.resolve(this.root, prefix)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (process.platform === "win32")
|
||||||
|
prefix = prefix.replace(/\\/g, "/")
|
||||||
|
|
||||||
|
this.matches[index] = this.matches[index] || {}
|
||||||
|
this.matches[index][prefix] = true
|
||||||
|
this.emitMatch(prefix)
|
||||||
|
}
|
||||||
|
return cb()
|
||||||
|
})
|
||||||
|
return
|
||||||
|
|
||||||
|
case 0:
|
||||||
|
// pattern *starts* with some non-trivial item.
|
||||||
|
// going to readdir(cwd), but not include the prefix in matches.
|
||||||
|
prefix = null
|
||||||
|
break
|
||||||
|
|
||||||
|
default:
|
||||||
|
// pattern has some string bits in the front.
|
||||||
|
// whatever it starts with, whether that's "absolute" like /foo/bar,
|
||||||
|
// or "relative" like "../baz"
|
||||||
|
prefix = pattern.slice(0, n)
|
||||||
|
prefix = prefix.join("/")
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the list of entries.
|
||||||
|
var read
|
||||||
|
if (prefix === null) read = "."
|
||||||
|
else if (isAbsolute(prefix) || isAbsolute(pattern.join("/"))) {
|
||||||
|
if (!prefix || !isAbsolute(prefix)) {
|
||||||
|
prefix = "/" + prefix
|
||||||
|
}
|
||||||
|
read = prefix
|
||||||
|
|
||||||
|
// if (process.platform === "win32")
|
||||||
|
// read = prefix = prefix.replace(/^[a-zA-Z]:|\\/g, "/")
|
||||||
|
|
||||||
|
this.log('absolute: ', prefix, this.root, pattern, read)
|
||||||
|
} else {
|
||||||
|
read = prefix
|
||||||
|
}
|
||||||
|
|
||||||
|
this.log('readdir(%j)', read, this.cwd, this.root)
|
||||||
|
|
||||||
|
return this._readdir(read, function (er, entries) {
|
||||||
|
if (er) {
|
||||||
|
// not a directory!
|
||||||
|
// this means that, whatever else comes after this, it can never match
|
||||||
|
return cb()
|
||||||
|
}
|
||||||
|
|
||||||
|
// globstar is special
|
||||||
|
if (pattern[n] === minimatch.GLOBSTAR) {
|
||||||
|
// test without the globstar, and with every child both below
|
||||||
|
// and replacing the globstar.
|
||||||
|
var s = [ pattern.slice(0, n).concat(pattern.slice(n + 1)) ]
|
||||||
|
entries.forEach(function (e) {
|
||||||
|
if (e.charAt(0) === "." && !this.dot) return
|
||||||
|
// instead of the globstar
|
||||||
|
s.push(pattern.slice(0, n).concat(e).concat(pattern.slice(n + 1)))
|
||||||
|
// below the globstar
|
||||||
|
s.push(pattern.slice(0, n).concat(e).concat(pattern.slice(n)))
|
||||||
|
}, this)
|
||||||
|
|
||||||
|
s = s.filter(function (pattern) {
|
||||||
|
var key = gsKey(pattern)
|
||||||
|
var seen = !this._globstars[key]
|
||||||
|
this._globstars[key] = true
|
||||||
|
return seen
|
||||||
|
}, this)
|
||||||
|
|
||||||
|
if (!s.length)
|
||||||
|
return cb()
|
||||||
|
|
||||||
|
// now asyncForEach over this
|
||||||
|
var l = s.length
|
||||||
|
, errState = null
|
||||||
|
s.forEach(function (gsPattern) {
|
||||||
|
this._process(gsPattern, depth + 1, index, function (er) {
|
||||||
|
if (errState) return
|
||||||
|
if (er) return cb(errState = er)
|
||||||
|
if (--l <= 0) return cb()
|
||||||
|
})
|
||||||
|
}, this)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// not a globstar
|
||||||
|
// It will only match dot entries if it starts with a dot, or if
|
||||||
|
// dot is set. Stuff like @(.foo|.bar) isn't allowed.
|
||||||
|
var pn = pattern[n]
|
||||||
|
var rawGlob = pattern[n]._glob
|
||||||
|
, dotOk = this.dot || rawGlob.charAt(0) === "."
|
||||||
|
|
||||||
|
entries = entries.filter(function (e) {
|
||||||
|
return (e.charAt(0) !== "." || dotOk) &&
|
||||||
|
e.match(pattern[n])
|
||||||
|
})
|
||||||
|
|
||||||
|
// If n === pattern.length - 1, then there's no need for the extra stat
|
||||||
|
// *unless* the user has specified "mark" or "stat" explicitly.
|
||||||
|
// We know that they exist, since the readdir returned them.
|
||||||
|
if (n === pattern.length - 1 &&
|
||||||
|
!this.mark &&
|
||||||
|
!this.stat) {
|
||||||
|
entries.forEach(function (e) {
|
||||||
|
if (prefix) {
|
||||||
|
if (prefix !== "/") e = prefix + "/" + e
|
||||||
|
else e = prefix + e
|
||||||
|
}
|
||||||
|
if (e.charAt(0) === "/" && !this.nomount) {
|
||||||
|
e = path.join(this.root, e)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (process.platform === "win32")
|
||||||
|
e = e.replace(/\\/g, "/")
|
||||||
|
|
||||||
|
this.matches[index] = this.matches[index] || {}
|
||||||
|
this.matches[index][e] = true
|
||||||
|
this.emitMatch(e)
|
||||||
|
}, this)
|
||||||
|
return cb.call(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// now test all the remaining entries as stand-ins for that part
|
||||||
|
// of the pattern.
|
||||||
|
var l = entries.length
|
||||||
|
, errState = null
|
||||||
|
if (l === 0) return cb() // no matches possible
|
||||||
|
entries.forEach(function (e) {
|
||||||
|
var p = pattern.slice(0, n).concat(e).concat(pattern.slice(n + 1))
|
||||||
|
this._process(p, depth + 1, index, function (er) {
|
||||||
|
if (errState) return
|
||||||
|
if (er) return cb(errState = er)
|
||||||
|
if (--l === 0) return cb.call(this)
|
||||||
|
})
|
||||||
|
}, this)
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function gsKey (pattern) {
|
||||||
|
return '**' + pattern.map(function (p) {
|
||||||
|
return (p === minimatch.GLOBSTAR) ? '**' : (''+p)
|
||||||
|
}).join('/')
|
||||||
|
}
|
||||||
|
|
||||||
|
Glob.prototype._stat = function (f, cb) {
|
||||||
|
assert(this instanceof Glob)
|
||||||
|
var abs = f
|
||||||
|
if (f.charAt(0) === "/") {
|
||||||
|
abs = path.join(this.root, f)
|
||||||
|
} else if (this.changedCwd) {
|
||||||
|
abs = path.resolve(this.cwd, f)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (f.length > this.maxLength) {
|
||||||
|
var er = new Error("Path name too long")
|
||||||
|
er.code = "ENAMETOOLONG"
|
||||||
|
er.path = f
|
||||||
|
return this._afterStat(f, abs, cb, er)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.log('stat', [this.cwd, f, '=', abs])
|
||||||
|
|
||||||
|
if (!this.stat && this.cache.hasOwnProperty(f)) {
|
||||||
|
var exists = this.cache[f]
|
||||||
|
, isDir = exists && (Array.isArray(exists) || exists === 2)
|
||||||
|
if (this.sync) return cb.call(this, !!exists, isDir)
|
||||||
|
return process.nextTick(cb.bind(this, !!exists, isDir))
|
||||||
|
}
|
||||||
|
|
||||||
|
var stat = this.statCache[abs]
|
||||||
|
if (this.sync || stat) {
|
||||||
|
var er
|
||||||
|
try {
|
||||||
|
stat = fs.statSync(abs)
|
||||||
|
} catch (e) {
|
||||||
|
er = e
|
||||||
|
}
|
||||||
|
this._afterStat(f, abs, cb, er, stat)
|
||||||
|
} else {
|
||||||
|
fs.stat(abs, this._afterStat.bind(this, f, abs, cb))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Glob.prototype._afterStat = function (f, abs, cb, er, stat) {
|
||||||
|
var exists
|
||||||
|
assert(this instanceof Glob)
|
||||||
|
|
||||||
|
if (abs.slice(-1) === "/" && stat && !stat.isDirectory()) {
|
||||||
|
this.log("should be ENOTDIR, fake it")
|
||||||
|
|
||||||
|
er = new Error("ENOTDIR, not a directory '" + abs + "'")
|
||||||
|
er.path = abs
|
||||||
|
er.code = "ENOTDIR"
|
||||||
|
stat = null
|
||||||
|
}
|
||||||
|
|
||||||
|
var emit = !this.statCache[abs]
|
||||||
|
this.statCache[abs] = stat
|
||||||
|
|
||||||
|
if (er || !stat) {
|
||||||
|
exists = false
|
||||||
|
} else {
|
||||||
|
exists = stat.isDirectory() ? 2 : 1
|
||||||
|
if (emit)
|
||||||
|
this.emit('stat', f, stat)
|
||||||
|
}
|
||||||
|
this.cache[f] = this.cache[f] || exists
|
||||||
|
cb.call(this, !!exists, exists === 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
Glob.prototype._readdir = function (f, cb) {
|
||||||
|
assert(this instanceof Glob)
|
||||||
|
var abs = f
|
||||||
|
if (f.charAt(0) === "/") {
|
||||||
|
abs = path.join(this.root, f)
|
||||||
|
} else if (isAbsolute(f)) {
|
||||||
|
abs = f
|
||||||
|
} else if (this.changedCwd) {
|
||||||
|
abs = path.resolve(this.cwd, f)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (f.length > this.maxLength) {
|
||||||
|
var er = new Error("Path name too long")
|
||||||
|
er.code = "ENAMETOOLONG"
|
||||||
|
er.path = f
|
||||||
|
return this._afterReaddir(f, abs, cb, er)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.log('readdir', [this.cwd, f, abs])
|
||||||
|
if (this.cache.hasOwnProperty(f)) {
|
||||||
|
var c = this.cache[f]
|
||||||
|
if (Array.isArray(c)) {
|
||||||
|
if (this.sync) return cb.call(this, null, c)
|
||||||
|
return process.nextTick(cb.bind(this, null, c))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!c || c === 1) {
|
||||||
|
// either ENOENT or ENOTDIR
|
||||||
|
var code = c ? "ENOTDIR" : "ENOENT"
|
||||||
|
, er = new Error((c ? "Not a directory" : "Not found") + ": " + f)
|
||||||
|
er.path = f
|
||||||
|
er.code = code
|
||||||
|
this.log(f, er)
|
||||||
|
if (this.sync) return cb.call(this, er)
|
||||||
|
return process.nextTick(cb.bind(this, er))
|
||||||
|
}
|
||||||
|
|
||||||
|
// at this point, c === 2, meaning it's a dir, but we haven't
|
||||||
|
// had to read it yet, or c === true, meaning it's *something*
|
||||||
|
// but we don't have any idea what. Need to read it, either way.
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.sync) {
|
||||||
|
var er, entries
|
||||||
|
try {
|
||||||
|
entries = fs.readdirSync(abs)
|
||||||
|
} catch (e) {
|
||||||
|
er = e
|
||||||
|
}
|
||||||
|
return this._afterReaddir(f, abs, cb, er, entries)
|
||||||
|
}
|
||||||
|
|
||||||
|
fs.readdir(abs, this._afterReaddir.bind(this, f, abs, cb))
|
||||||
|
}
|
||||||
|
|
||||||
|
Glob.prototype._afterReaddir = function (f, abs, cb, er, entries) {
|
||||||
|
assert(this instanceof Glob)
|
||||||
|
if (entries && !er) {
|
||||||
|
this.cache[f] = entries
|
||||||
|
// if we haven't asked to stat everything for suresies, then just
|
||||||
|
// assume that everything in there exists, so we can avoid
|
||||||
|
// having to stat it a second time. This also gets us one step
|
||||||
|
// further into ELOOP territory.
|
||||||
|
if (!this.mark && !this.stat) {
|
||||||
|
entries.forEach(function (e) {
|
||||||
|
if (f === "/") e = f + e
|
||||||
|
else e = f + "/" + e
|
||||||
|
this.cache[e] = true
|
||||||
|
}, this)
|
||||||
|
}
|
||||||
|
|
||||||
|
return cb.call(this, er, entries)
|
||||||
|
}
|
||||||
|
|
||||||
|
// now handle errors, and cache the information
|
||||||
|
if (er) switch (er.code) {
|
||||||
|
case "ENOTDIR": // totally normal. means it *does* exist.
|
||||||
|
this.cache[f] = 1
|
||||||
|
return cb.call(this, er)
|
||||||
|
case "ENOENT": // not terribly unusual
|
||||||
|
case "ELOOP":
|
||||||
|
case "ENAMETOOLONG":
|
||||||
|
case "UNKNOWN":
|
||||||
|
this.cache[f] = false
|
||||||
|
return cb.call(this, er)
|
||||||
|
default: // some unusual error. Treat as failure.
|
||||||
|
this.cache[f] = false
|
||||||
|
if (this.strict) this.emit("error", er)
|
||||||
|
if (!this.silent) console.error("glob error", er)
|
||||||
|
return cb.call(this, er)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var isAbsolute = process.platform === "win32" ? absWin : absUnix
|
||||||
|
|
||||||
|
function absWin (p) {
|
||||||
|
if (absUnix(p)) return true
|
||||||
|
// pull off the device/UNC bit from a windows path.
|
||||||
|
// from node's lib/path.js
|
||||||
|
var splitDeviceRe =
|
||||||
|
/^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/
|
||||||
|
, result = splitDeviceRe.exec(p)
|
||||||
|
, device = result[1] || ''
|
||||||
|
, isUnc = device && device.charAt(1) !== ':'
|
||||||
|
, isAbsolute = !!result[2] || isUnc // UNC paths are always absolute
|
||||||
|
|
||||||
|
return isAbsolute
|
||||||
|
}
|
||||||
|
|
||||||
|
function absUnix (p) {
|
||||||
|
return p.charAt(0) === "/" || p === ""
|
||||||
|
}
|
||||||
Generated
Vendored
+16
@@ -0,0 +1,16 @@
|
|||||||
|
The ISC License
|
||||||
|
|
||||||
|
Copyright (c) Isaac Z. Schlueter
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||||
|
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||||
|
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||||
|
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||||
|
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||||
|
PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
Generated
Vendored
+42
@@ -0,0 +1,42 @@
|
|||||||
|
Browser-friendly inheritance fully compatible with standard node.js
|
||||||
|
[inherits](http://nodejs.org/api/util.html#util_util_inherits_constructor_superconstructor).
|
||||||
|
|
||||||
|
This package exports standard `inherits` from node.js `util` module in
|
||||||
|
node environment, but also provides alternative browser-friendly
|
||||||
|
implementation through [browser
|
||||||
|
field](https://gist.github.com/shtylman/4339901). Alternative
|
||||||
|
implementation is a literal copy of standard one located in standalone
|
||||||
|
module to avoid requiring of `util`. It also has a shim for old
|
||||||
|
browsers with no `Object.create` support.
|
||||||
|
|
||||||
|
While keeping you sure you are using standard `inherits`
|
||||||
|
implementation in node.js environment, it allows bundlers such as
|
||||||
|
[browserify](https://github.com/substack/node-browserify) to not
|
||||||
|
include full `util` package to your client code if all you need is
|
||||||
|
just `inherits` function. It worth, because browser shim for `util`
|
||||||
|
package is large and `inherits` is often the single function you need
|
||||||
|
from it.
|
||||||
|
|
||||||
|
It's recommended to use this package instead of
|
||||||
|
`require('util').inherits` for any code that has chances to be used
|
||||||
|
not only in node.js but in browser too.
|
||||||
|
|
||||||
|
## usage
|
||||||
|
|
||||||
|
```js
|
||||||
|
var inherits = require('inherits');
|
||||||
|
// then use exactly as the standard one
|
||||||
|
```
|
||||||
|
|
||||||
|
## note on version ~1.0
|
||||||
|
|
||||||
|
Version ~1.0 had completely different motivation and is not compatible
|
||||||
|
neither with 2.0 nor with standard node.js `inherits`.
|
||||||
|
|
||||||
|
If you are using version ~1.0 and planning to switch to ~2.0, be
|
||||||
|
careful:
|
||||||
|
|
||||||
|
* new version uses `super_` instead of `super` for referencing
|
||||||
|
superclass
|
||||||
|
* new version overwrites current prototype while old one preserves any
|
||||||
|
existing fields on it
|
||||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
|||||||
|
module.exports = require('util').inherits
|
||||||
Generated
Vendored
+23
@@ -0,0 +1,23 @@
|
|||||||
|
if (typeof Object.create === 'function') {
|
||||||
|
// implementation from standard node.js 'util' module
|
||||||
|
module.exports = function inherits(ctor, superCtor) {
|
||||||
|
ctor.super_ = superCtor
|
||||||
|
ctor.prototype = Object.create(superCtor.prototype, {
|
||||||
|
constructor: {
|
||||||
|
value: ctor,
|
||||||
|
enumerable: false,
|
||||||
|
writable: true,
|
||||||
|
configurable: true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
// old school shim for old browsers
|
||||||
|
module.exports = function inherits(ctor, superCtor) {
|
||||||
|
ctor.super_ = superCtor
|
||||||
|
var TempCtor = function () {}
|
||||||
|
TempCtor.prototype = superCtor.prototype
|
||||||
|
ctor.prototype = new TempCtor()
|
||||||
|
ctor.prototype.constructor = ctor
|
||||||
|
}
|
||||||
|
}
|
||||||
Generated
Vendored
+33
@@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
"name": "inherits",
|
||||||
|
"description": "Browser-friendly inheritance fully compatible with standard node.js inherits()",
|
||||||
|
"version": "2.0.1",
|
||||||
|
"keywords": [
|
||||||
|
"inheritance",
|
||||||
|
"class",
|
||||||
|
"klass",
|
||||||
|
"oop",
|
||||||
|
"object-oriented",
|
||||||
|
"inherits",
|
||||||
|
"browser",
|
||||||
|
"browserify"
|
||||||
|
],
|
||||||
|
"main": "./inherits.js",
|
||||||
|
"browser": "./inherits_browser.js",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git://github.com/isaacs/inherits"
|
||||||
|
},
|
||||||
|
"license": "ISC",
|
||||||
|
"scripts": {
|
||||||
|
"test": "node test"
|
||||||
|
},
|
||||||
|
"readme": "Browser-friendly inheritance fully compatible with standard node.js\n[inherits](http://nodejs.org/api/util.html#util_util_inherits_constructor_superconstructor).\n\nThis package exports standard `inherits` from node.js `util` module in\nnode environment, but also provides alternative browser-friendly\nimplementation through [browser\nfield](https://gist.github.com/shtylman/4339901). Alternative\nimplementation is a literal copy of standard one located in standalone\nmodule to avoid requiring of `util`. It also has a shim for old\nbrowsers with no `Object.create` support.\n\nWhile keeping you sure you are using standard `inherits`\nimplementation in node.js environment, it allows bundlers such as\n[browserify](https://github.com/substack/node-browserify) to not\ninclude full `util` package to your client code if all you need is\njust `inherits` function. It worth, because browser shim for `util`\npackage is large and `inherits` is often the single function you need\nfrom it.\n\nIt's recommended to use this package instead of\n`require('util').inherits` for any code that has chances to be used\nnot only in node.js but in browser too.\n\n## usage\n\n```js\nvar inherits = require('inherits');\n// then use exactly as the standard one\n```\n\n## note on version ~1.0\n\nVersion ~1.0 had completely different motivation and is not compatible\nneither with 2.0 nor with standard node.js `inherits`.\n\nIf you are using version ~1.0 and planning to switch to ~2.0, be\ncareful:\n\n* new version uses `super_` instead of `super` for referencing\n superclass\n* new version overwrites current prototype while old one preserves any\n existing fields on it\n",
|
||||||
|
"readmeFilename": "README.md",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/isaacs/inherits/issues"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/isaacs/inherits",
|
||||||
|
"_id": "inherits@2.0.1",
|
||||||
|
"_from": "inherits@2"
|
||||||
|
}
|
||||||
Generated
Vendored
+25
@@ -0,0 +1,25 @@
|
|||||||
|
var inherits = require('./inherits.js')
|
||||||
|
var assert = require('assert')
|
||||||
|
|
||||||
|
function test(c) {
|
||||||
|
assert(c.constructor === Child)
|
||||||
|
assert(c.constructor.super_ === Parent)
|
||||||
|
assert(Object.getPrototypeOf(c) === Child.prototype)
|
||||||
|
assert(Object.getPrototypeOf(Object.getPrototypeOf(c)) === Parent.prototype)
|
||||||
|
assert(c instanceof Child)
|
||||||
|
assert(c instanceof Parent)
|
||||||
|
}
|
||||||
|
|
||||||
|
function Child() {
|
||||||
|
Parent.call(this)
|
||||||
|
test(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
function Parent() {}
|
||||||
|
|
||||||
|
inherits(Child, Parent)
|
||||||
|
|
||||||
|
var c = new Child
|
||||||
|
test(c)
|
||||||
|
|
||||||
|
console.log('ok')
|
||||||
Generated
Vendored
+27
@@ -0,0 +1,27 @@
|
|||||||
|
Copyright (c) Isaac Z. Schlueter ("Author")
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
The BSD License
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
|
||||||
|
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||||
|
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
Generated
Vendored
+51
@@ -0,0 +1,51 @@
|
|||||||
|
# once
|
||||||
|
|
||||||
|
Only call a function once.
|
||||||
|
|
||||||
|
## usage
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var once = require('once')
|
||||||
|
|
||||||
|
function load (file, cb) {
|
||||||
|
cb = once(cb)
|
||||||
|
loader.load('file')
|
||||||
|
loader.once('load', cb)
|
||||||
|
loader.once('error', cb)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Or add to the Function.prototype in a responsible way:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// only has to be done once
|
||||||
|
require('once').proto()
|
||||||
|
|
||||||
|
function load (file, cb) {
|
||||||
|
cb = cb.once()
|
||||||
|
loader.load('file')
|
||||||
|
loader.once('load', cb)
|
||||||
|
loader.once('error', cb)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Ironically, the prototype feature makes this module twice as
|
||||||
|
complicated as necessary.
|
||||||
|
|
||||||
|
To check whether you function has been called, use `fn.called`. Once the
|
||||||
|
function is called for the first time the return value of the original
|
||||||
|
function is saved in `fn.value` and subsequent calls will continue to
|
||||||
|
return this value.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var once = require('once')
|
||||||
|
|
||||||
|
function load (cb) {
|
||||||
|
cb = once(cb)
|
||||||
|
var stream = createStream()
|
||||||
|
stream.once('data', cb)
|
||||||
|
stream.once('end', function () {
|
||||||
|
if (!cb.called) cb(new Error('not found'))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
```
|
||||||
Generated
Vendored
+20
@@ -0,0 +1,20 @@
|
|||||||
|
module.exports = once
|
||||||
|
|
||||||
|
once.proto = once(function () {
|
||||||
|
Object.defineProperty(Function.prototype, 'once', {
|
||||||
|
value: function () {
|
||||||
|
return once(this)
|
||||||
|
},
|
||||||
|
configurable: true
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
function once (fn) {
|
||||||
|
var f = function () {
|
||||||
|
if (f.called) return f.value
|
||||||
|
f.called = true
|
||||||
|
return f.value = fn.apply(this, arguments)
|
||||||
|
}
|
||||||
|
f.called = false
|
||||||
|
return f
|
||||||
|
}
|
||||||
Generated
Vendored
+42
@@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"name": "once",
|
||||||
|
"version": "1.3.0",
|
||||||
|
"description": "Run a function exactly one time",
|
||||||
|
"main": "once.js",
|
||||||
|
"directories": {
|
||||||
|
"test": "test"
|
||||||
|
},
|
||||||
|
"dependencies": {},
|
||||||
|
"devDependencies": {
|
||||||
|
"tap": "~0.3.0"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"test": "tap test/*.js"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git://github.com/isaacs/once"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"once",
|
||||||
|
"function",
|
||||||
|
"one",
|
||||||
|
"single"
|
||||||
|
],
|
||||||
|
"author": {
|
||||||
|
"name": "Isaac Z. Schlueter",
|
||||||
|
"email": "i@izs.me",
|
||||||
|
"url": "http://blog.izs.me/"
|
||||||
|
},
|
||||||
|
"license": "BSD",
|
||||||
|
"readme": "# once\n\nOnly call a function once.\n\n## usage\n\n```javascript\nvar once = require('once')\n\nfunction load (file, cb) {\n cb = once(cb)\n loader.load('file')\n loader.once('load', cb)\n loader.once('error', cb)\n}\n```\n\nOr add to the Function.prototype in a responsible way:\n\n```javascript\n// only has to be done once\nrequire('once').proto()\n\nfunction load (file, cb) {\n cb = cb.once()\n loader.load('file')\n loader.once('load', cb)\n loader.once('error', cb)\n}\n```\n\nIronically, the prototype feature makes this module twice as\ncomplicated as necessary.\n\nTo check whether you function has been called, use `fn.called`. Once the\nfunction is called for the first time the return value of the original\nfunction is saved in `fn.value` and subsequent calls will continue to\nreturn this value.\n\n```javascript\nvar once = require('once')\n\nfunction load (cb) {\n cb = once(cb)\n var stream = createStream()\n stream.once('data', cb)\n stream.once('end', function () {\n if (!cb.called) cb(new Error('not found'))\n })\n}\n```\n",
|
||||||
|
"readmeFilename": "README.md",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/isaacs/once/issues"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/isaacs/once",
|
||||||
|
"_id": "once@1.3.0",
|
||||||
|
"_shasum": "151af86bfc1f08c4b9f07d06ab250ffcbeb56581",
|
||||||
|
"_from": "once@^1.3.0",
|
||||||
|
"_resolved": "https://registry.npmjs.org/once/-/once-1.3.0.tgz"
|
||||||
|
}
|
||||||
Generated
Vendored
+20
@@ -0,0 +1,20 @@
|
|||||||
|
var test = require('tap').test
|
||||||
|
var once = require('../once.js')
|
||||||
|
|
||||||
|
test('once', function (t) {
|
||||||
|
var f = 0
|
||||||
|
var foo = once(function (g) {
|
||||||
|
t.equal(f, 0)
|
||||||
|
f ++
|
||||||
|
return f + g + this
|
||||||
|
})
|
||||||
|
t.notOk(foo.called)
|
||||||
|
for (var i = 0; i < 1E3; i++) {
|
||||||
|
t.same(f, i === 0 ? 0 : 1)
|
||||||
|
var g = foo.call(1, 1)
|
||||||
|
t.ok(foo.called)
|
||||||
|
t.same(g, 3)
|
||||||
|
t.same(f, 1)
|
||||||
|
}
|
||||||
|
t.end()
|
||||||
|
})
|
||||||
Generated
Vendored
+43
File diff suppressed because one or more lines are too long
Generated
Vendored
+176
@@ -0,0 +1,176 @@
|
|||||||
|
// just a little pre-run script to set up the fixtures.
|
||||||
|
// zz-finish cleans it up
|
||||||
|
|
||||||
|
var mkdirp = require("mkdirp")
|
||||||
|
var path = require("path")
|
||||||
|
var i = 0
|
||||||
|
var tap = require("tap")
|
||||||
|
var fs = require("fs")
|
||||||
|
var rimraf = require("rimraf")
|
||||||
|
|
||||||
|
var files =
|
||||||
|
[ "a/.abcdef/x/y/z/a"
|
||||||
|
, "a/abcdef/g/h"
|
||||||
|
, "a/abcfed/g/h"
|
||||||
|
, "a/b/c/d"
|
||||||
|
, "a/bc/e/f"
|
||||||
|
, "a/c/d/c/b"
|
||||||
|
, "a/cb/e/f"
|
||||||
|
]
|
||||||
|
|
||||||
|
var symlinkTo = path.resolve(__dirname, "a/symlink/a/b/c")
|
||||||
|
var symlinkFrom = "../.."
|
||||||
|
|
||||||
|
files = files.map(function (f) {
|
||||||
|
return path.resolve(__dirname, f)
|
||||||
|
})
|
||||||
|
|
||||||
|
tap.test("remove fixtures", function (t) {
|
||||||
|
rimraf(path.resolve(__dirname, "a"), function (er) {
|
||||||
|
t.ifError(er, "remove fixtures")
|
||||||
|
t.end()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
files.forEach(function (f) {
|
||||||
|
tap.test(f, function (t) {
|
||||||
|
var d = path.dirname(f)
|
||||||
|
mkdirp(d, 0755, function (er) {
|
||||||
|
if (er) {
|
||||||
|
t.fail(er)
|
||||||
|
return t.bailout()
|
||||||
|
}
|
||||||
|
fs.writeFile(f, "i like tests", function (er) {
|
||||||
|
t.ifError(er, "make file")
|
||||||
|
t.end()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
if (process.platform !== "win32") {
|
||||||
|
tap.test("symlinky", function (t) {
|
||||||
|
var d = path.dirname(symlinkTo)
|
||||||
|
console.error("mkdirp", d)
|
||||||
|
mkdirp(d, 0755, function (er) {
|
||||||
|
t.ifError(er)
|
||||||
|
fs.symlink(symlinkFrom, symlinkTo, "dir", function (er) {
|
||||||
|
t.ifError(er, "make symlink")
|
||||||
|
t.end()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
;["foo","bar","baz","asdf","quux","qwer","rewq"].forEach(function (w) {
|
||||||
|
w = "/tmp/glob-test/" + w
|
||||||
|
tap.test("create " + w, function (t) {
|
||||||
|
mkdirp(w, function (er) {
|
||||||
|
if (er)
|
||||||
|
throw er
|
||||||
|
t.pass(w)
|
||||||
|
t.end()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
// generate the bash pattern test-fixtures if possible
|
||||||
|
if (process.platform === "win32" || !process.env.TEST_REGEN) {
|
||||||
|
console.error("Windows, or TEST_REGEN unset. Using cached fixtures.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var spawn = require("child_process").spawn;
|
||||||
|
var globs =
|
||||||
|
// put more patterns here.
|
||||||
|
// anything that would be directly in / should be in /tmp/glob-test
|
||||||
|
["test/a/*/+(c|g)/./d"
|
||||||
|
,"test/a/**/[cg]/../[cg]"
|
||||||
|
,"test/a/{b,c,d,e,f}/**/g"
|
||||||
|
,"test/a/b/**"
|
||||||
|
,"test/**/g"
|
||||||
|
,"test/a/abc{fed,def}/g/h"
|
||||||
|
,"test/a/abc{fed/g,def}/**/"
|
||||||
|
,"test/a/abc{fed/g,def}/**///**/"
|
||||||
|
,"test/**/a/**/"
|
||||||
|
,"test/+(a|b|c)/a{/,bc*}/**"
|
||||||
|
,"test/*/*/*/f"
|
||||||
|
,"test/**/f"
|
||||||
|
,"test/a/symlink/a/b/c/a/b/c/a/b/c//a/b/c////a/b/c/**/b/c/**"
|
||||||
|
,"{./*/*,/tmp/glob-test/*}"
|
||||||
|
,"{/tmp/glob-test/*,*}" // evil owl face! how you taunt me!
|
||||||
|
,"test/a/!(symlink)/**"
|
||||||
|
]
|
||||||
|
var bashOutput = {}
|
||||||
|
var fs = require("fs")
|
||||||
|
|
||||||
|
globs.forEach(function (pattern) {
|
||||||
|
tap.test("generate fixture " + pattern, function (t) {
|
||||||
|
var cmd = "shopt -s globstar && " +
|
||||||
|
"shopt -s extglob && " +
|
||||||
|
"shopt -s nullglob && " +
|
||||||
|
// "shopt >&2; " +
|
||||||
|
"eval \'for i in " + pattern + "; do echo $i; done\'"
|
||||||
|
var cp = spawn("bash", ["-c", cmd], { cwd: path.dirname(__dirname) })
|
||||||
|
var out = []
|
||||||
|
cp.stdout.on("data", function (c) {
|
||||||
|
out.push(c)
|
||||||
|
})
|
||||||
|
cp.stderr.pipe(process.stderr)
|
||||||
|
cp.on("close", function (code) {
|
||||||
|
out = flatten(out)
|
||||||
|
if (!out)
|
||||||
|
out = []
|
||||||
|
else
|
||||||
|
out = cleanResults(out.split(/\r*\n/))
|
||||||
|
|
||||||
|
bashOutput[pattern] = out
|
||||||
|
t.notOk(code, "bash test should finish nicely")
|
||||||
|
t.end()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
tap.test("save fixtures", function (t) {
|
||||||
|
var fname = path.resolve(__dirname, "bash-results.json")
|
||||||
|
var data = JSON.stringify(bashOutput, null, 2) + "\n"
|
||||||
|
fs.writeFile(fname, data, function (er) {
|
||||||
|
t.ifError(er)
|
||||||
|
t.end()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
function cleanResults (m) {
|
||||||
|
// normalize discrepancies in ordering, duplication,
|
||||||
|
// and ending slashes.
|
||||||
|
return m.map(function (m) {
|
||||||
|
return m.replace(/\/+/g, "/").replace(/\/$/, "")
|
||||||
|
}).sort(alphasort).reduce(function (set, f) {
|
||||||
|
if (f !== set[set.length - 1]) set.push(f)
|
||||||
|
return set
|
||||||
|
}, []).sort(alphasort).map(function (f) {
|
||||||
|
// de-windows
|
||||||
|
return (process.platform !== 'win32') ? f
|
||||||
|
: f.replace(/^[a-zA-Z]:\\\\/, '/').replace(/\\/g, '/')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function flatten (chunks) {
|
||||||
|
var s = 0
|
||||||
|
chunks.forEach(function (c) { s += c.length })
|
||||||
|
var out = new Buffer(s)
|
||||||
|
s = 0
|
||||||
|
chunks.forEach(function (c) {
|
||||||
|
c.copy(out, s)
|
||||||
|
s += c.length
|
||||||
|
})
|
||||||
|
|
||||||
|
return out.toString().trim()
|
||||||
|
}
|
||||||
|
|
||||||
|
function alphasort (a, b) {
|
||||||
|
a = a.toLowerCase()
|
||||||
|
b = b.toLowerCase()
|
||||||
|
return a > b ? 1 : a < b ? -1 : 0
|
||||||
|
}
|
||||||
Generated
Vendored
+63
@@ -0,0 +1,63 @@
|
|||||||
|
// basic test
|
||||||
|
// show that it does the same thing by default as the shell.
|
||||||
|
var tap = require("tap")
|
||||||
|
, child_process = require("child_process")
|
||||||
|
, bashResults = require("./bash-results.json")
|
||||||
|
, globs = Object.keys(bashResults)
|
||||||
|
, glob = require("../")
|
||||||
|
, path = require("path")
|
||||||
|
|
||||||
|
// run from the root of the project
|
||||||
|
// this is usually where you're at anyway, but be sure.
|
||||||
|
process.chdir(path.resolve(__dirname, ".."))
|
||||||
|
|
||||||
|
function alphasort (a, b) {
|
||||||
|
a = a.toLowerCase()
|
||||||
|
b = b.toLowerCase()
|
||||||
|
return a > b ? 1 : a < b ? -1 : 0
|
||||||
|
}
|
||||||
|
|
||||||
|
globs.forEach(function (pattern) {
|
||||||
|
var expect = bashResults[pattern]
|
||||||
|
// anything regarding the symlink thing will fail on windows, so just skip it
|
||||||
|
if (process.platform === "win32" &&
|
||||||
|
expect.some(function (m) {
|
||||||
|
return /\/symlink\//.test(m)
|
||||||
|
}))
|
||||||
|
return
|
||||||
|
|
||||||
|
tap.test(pattern, function (t) {
|
||||||
|
glob(pattern, function (er, matches) {
|
||||||
|
if (er)
|
||||||
|
throw er
|
||||||
|
|
||||||
|
// sort and unmark, just to match the shell results
|
||||||
|
matches = cleanResults(matches)
|
||||||
|
|
||||||
|
t.deepEqual(matches, expect, pattern)
|
||||||
|
t.end()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
tap.test(pattern + " sync", function (t) {
|
||||||
|
var matches = cleanResults(glob.sync(pattern))
|
||||||
|
|
||||||
|
t.deepEqual(matches, expect, "should match shell")
|
||||||
|
t.end()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
function cleanResults (m) {
|
||||||
|
// normalize discrepancies in ordering, duplication,
|
||||||
|
// and ending slashes.
|
||||||
|
return m.map(function (m) {
|
||||||
|
return m.replace(/\/+/g, "/").replace(/\/$/, "")
|
||||||
|
}).sort(alphasort).reduce(function (set, f) {
|
||||||
|
if (f !== set[set.length - 1]) set.push(f)
|
||||||
|
return set
|
||||||
|
}, []).sort(alphasort).map(function (f) {
|
||||||
|
// de-windows
|
||||||
|
return (process.platform !== 'win32') ? f
|
||||||
|
: f.replace(/^[a-zA-Z]:[\/\\]+/, '/').replace(/[\\\/]+/g, '/')
|
||||||
|
})
|
||||||
|
}
|
||||||
Generated
Vendored
+354
@@ -0,0 +1,354 @@
|
|||||||
|
{
|
||||||
|
"test/a/*/+(c|g)/./d": [
|
||||||
|
"test/a/b/c/./d"
|
||||||
|
],
|
||||||
|
"test/a/**/[cg]/../[cg]": [
|
||||||
|
"test/a/abcdef/g/../g",
|
||||||
|
"test/a/abcfed/g/../g",
|
||||||
|
"test/a/b/c/../c",
|
||||||
|
"test/a/c/../c",
|
||||||
|
"test/a/c/d/c/../c",
|
||||||
|
"test/a/symlink/a/b/c/../c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/../c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/../c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/../c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c"
|
||||||
|
],
|
||||||
|
"test/a/{b,c,d,e,f}/**/g": [],
|
||||||
|
"test/a/b/**": [
|
||||||
|
"test/a/b",
|
||||||
|
"test/a/b/c",
|
||||||
|
"test/a/b/c/d"
|
||||||
|
],
|
||||||
|
"test/**/g": [
|
||||||
|
"test/a/abcdef/g",
|
||||||
|
"test/a/abcfed/g"
|
||||||
|
],
|
||||||
|
"test/a/abc{fed,def}/g/h": [
|
||||||
|
"test/a/abcdef/g/h",
|
||||||
|
"test/a/abcfed/g/h"
|
||||||
|
],
|
||||||
|
"test/a/abc{fed/g,def}/**/": [
|
||||||
|
"test/a/abcdef",
|
||||||
|
"test/a/abcdef/g",
|
||||||
|
"test/a/abcfed/g"
|
||||||
|
],
|
||||||
|
"test/a/abc{fed/g,def}/**///**/": [
|
||||||
|
"test/a/abcdef",
|
||||||
|
"test/a/abcdef/g",
|
||||||
|
"test/a/abcfed/g"
|
||||||
|
],
|
||||||
|
"test/**/a/**/": [
|
||||||
|
"test/a",
|
||||||
|
"test/a/abcdef",
|
||||||
|
"test/a/abcdef/g",
|
||||||
|
"test/a/abcfed",
|
||||||
|
"test/a/abcfed/g",
|
||||||
|
"test/a/b",
|
||||||
|
"test/a/b/c",
|
||||||
|
"test/a/bc",
|
||||||
|
"test/a/bc/e",
|
||||||
|
"test/a/c",
|
||||||
|
"test/a/c/d",
|
||||||
|
"test/a/c/d/c",
|
||||||
|
"test/a/cb",
|
||||||
|
"test/a/cb/e",
|
||||||
|
"test/a/symlink",
|
||||||
|
"test/a/symlink/a",
|
||||||
|
"test/a/symlink/a/b",
|
||||||
|
"test/a/symlink/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b"
|
||||||
|
],
|
||||||
|
"test/+(a|b|c)/a{/,bc*}/**": [
|
||||||
|
"test/a/abcdef",
|
||||||
|
"test/a/abcdef/g",
|
||||||
|
"test/a/abcdef/g/h",
|
||||||
|
"test/a/abcfed",
|
||||||
|
"test/a/abcfed/g",
|
||||||
|
"test/a/abcfed/g/h"
|
||||||
|
],
|
||||||
|
"test/*/*/*/f": [
|
||||||
|
"test/a/bc/e/f",
|
||||||
|
"test/a/cb/e/f"
|
||||||
|
],
|
||||||
|
"test/**/f": [
|
||||||
|
"test/a/bc/e/f",
|
||||||
|
"test/a/cb/e/f"
|
||||||
|
],
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c//a/b/c////a/b/c/**/b/c/**": [
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
|
||||||
|
"test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c"
|
||||||
|
],
|
||||||
|
"{./*/*,/tmp/glob-test/*}": [
|
||||||
|
"./examples/g.js",
|
||||||
|
"./examples/usr-local.js",
|
||||||
|
"./node_modules/inherits",
|
||||||
|
"./node_modules/minimatch",
|
||||||
|
"./node_modules/mkdirp",
|
||||||
|
"./node_modules/once",
|
||||||
|
"./node_modules/rimraf",
|
||||||
|
"./node_modules/tap",
|
||||||
|
"./test/00-setup.js",
|
||||||
|
"./test/a",
|
||||||
|
"./test/bash-comparison.js",
|
||||||
|
"./test/bash-results.json",
|
||||||
|
"./test/cwd-test.js",
|
||||||
|
"./test/empty-set.js",
|
||||||
|
"./test/error-callback.js",
|
||||||
|
"./test/globstar-match.js",
|
||||||
|
"./test/mark.js",
|
||||||
|
"./test/new-glob-optional-options.js",
|
||||||
|
"./test/nocase-nomagic.js",
|
||||||
|
"./test/pause-resume.js",
|
||||||
|
"./test/readme-issue.js",
|
||||||
|
"./test/root-nomount.js",
|
||||||
|
"./test/root.js",
|
||||||
|
"./test/stat.js",
|
||||||
|
"./test/zz-cleanup.js",
|
||||||
|
"/tmp/glob-test/asdf",
|
||||||
|
"/tmp/glob-test/bar",
|
||||||
|
"/tmp/glob-test/baz",
|
||||||
|
"/tmp/glob-test/foo",
|
||||||
|
"/tmp/glob-test/quux",
|
||||||
|
"/tmp/glob-test/qwer",
|
||||||
|
"/tmp/glob-test/rewq"
|
||||||
|
],
|
||||||
|
"{/tmp/glob-test/*,*}": [
|
||||||
|
"/tmp/glob-test/asdf",
|
||||||
|
"/tmp/glob-test/bar",
|
||||||
|
"/tmp/glob-test/baz",
|
||||||
|
"/tmp/glob-test/foo",
|
||||||
|
"/tmp/glob-test/quux",
|
||||||
|
"/tmp/glob-test/qwer",
|
||||||
|
"/tmp/glob-test/rewq",
|
||||||
|
"examples",
|
||||||
|
"glob.js",
|
||||||
|
"LICENSE",
|
||||||
|
"node_modules",
|
||||||
|
"package.json",
|
||||||
|
"README.md",
|
||||||
|
"test"
|
||||||
|
],
|
||||||
|
"test/a/!(symlink)/**": [
|
||||||
|
"test/a/abcdef",
|
||||||
|
"test/a/abcdef/g",
|
||||||
|
"test/a/abcdef/g/h",
|
||||||
|
"test/a/abcfed",
|
||||||
|
"test/a/abcfed/g",
|
||||||
|
"test/a/abcfed/g/h",
|
||||||
|
"test/a/b",
|
||||||
|
"test/a/b/c",
|
||||||
|
"test/a/b/c/d",
|
||||||
|
"test/a/bc",
|
||||||
|
"test/a/bc/e",
|
||||||
|
"test/a/bc/e/f",
|
||||||
|
"test/a/c",
|
||||||
|
"test/a/c/d",
|
||||||
|
"test/a/c/d/c",
|
||||||
|
"test/a/c/d/c/b",
|
||||||
|
"test/a/cb",
|
||||||
|
"test/a/cb/e",
|
||||||
|
"test/a/cb/e/f"
|
||||||
|
]
|
||||||
|
}
|
||||||
Generated
Vendored
+55
@@ -0,0 +1,55 @@
|
|||||||
|
var tap = require("tap")
|
||||||
|
|
||||||
|
var origCwd = process.cwd()
|
||||||
|
process.chdir(__dirname)
|
||||||
|
|
||||||
|
tap.test("changing cwd and searching for **/d", function (t) {
|
||||||
|
var glob = require('../')
|
||||||
|
var path = require('path')
|
||||||
|
t.test('.', function (t) {
|
||||||
|
glob('**/d', function (er, matches) {
|
||||||
|
t.ifError(er)
|
||||||
|
t.like(matches, [ 'a/b/c/d', 'a/c/d' ])
|
||||||
|
t.end()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
t.test('a', function (t) {
|
||||||
|
glob('**/d', {cwd:path.resolve('a')}, function (er, matches) {
|
||||||
|
t.ifError(er)
|
||||||
|
t.like(matches, [ 'b/c/d', 'c/d' ])
|
||||||
|
t.end()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
t.test('a/b', function (t) {
|
||||||
|
glob('**/d', {cwd:path.resolve('a/b')}, function (er, matches) {
|
||||||
|
t.ifError(er)
|
||||||
|
t.like(matches, [ 'c/d' ])
|
||||||
|
t.end()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
t.test('a/b/', function (t) {
|
||||||
|
glob('**/d', {cwd:path.resolve('a/b/')}, function (er, matches) {
|
||||||
|
t.ifError(er)
|
||||||
|
t.like(matches, [ 'c/d' ])
|
||||||
|
t.end()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
t.test('.', function (t) {
|
||||||
|
glob('**/d', {cwd: process.cwd()}, function (er, matches) {
|
||||||
|
t.ifError(er)
|
||||||
|
t.like(matches, [ 'a/b/c/d', 'a/c/d' ])
|
||||||
|
t.end()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
t.test('cd -', function (t) {
|
||||||
|
process.chdir(origCwd)
|
||||||
|
t.end()
|
||||||
|
})
|
||||||
|
|
||||||
|
t.end()
|
||||||
|
})
|
||||||
Generated
Vendored
+20
@@ -0,0 +1,20 @@
|
|||||||
|
var test = require('tap').test
|
||||||
|
var glob = require("../glob.js")
|
||||||
|
|
||||||
|
// Patterns that cannot match anything
|
||||||
|
var patterns = [
|
||||||
|
'# comment',
|
||||||
|
' ',
|
||||||
|
'\n',
|
||||||
|
'just doesnt happen to match anything so this is a control'
|
||||||
|
]
|
||||||
|
|
||||||
|
patterns.forEach(function (p) {
|
||||||
|
test(JSON.stringify(p), function (t) {
|
||||||
|
glob(p, function (e, f) {
|
||||||
|
t.equal(e, null, 'no error')
|
||||||
|
t.same(f, [], 'no returned values')
|
||||||
|
t.end()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
Generated
Vendored
+20
@@ -0,0 +1,20 @@
|
|||||||
|
var fs = require('fs')
|
||||||
|
var test = require('tap').test
|
||||||
|
var glob = require('../')
|
||||||
|
|
||||||
|
test('mock fs', function(t) {
|
||||||
|
fs.readdir = function(path, cb) {
|
||||||
|
process.nextTick(function() {
|
||||||
|
cb(new Error('mock fs.readdir error'))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
t.pass('mocked')
|
||||||
|
t.end()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('error callback', function(t) {
|
||||||
|
glob('*', function(err, res) {
|
||||||
|
t.ok(err, 'expecting mock error')
|
||||||
|
t.end()
|
||||||
|
})
|
||||||
|
})
|
||||||
Generated
Vendored
+19
@@ -0,0 +1,19 @@
|
|||||||
|
var Glob = require("../glob.js").Glob
|
||||||
|
var test = require('tap').test
|
||||||
|
|
||||||
|
test('globstar should not have dupe matches', function(t) {
|
||||||
|
var pattern = 'a/**/[gh]'
|
||||||
|
var g = new Glob(pattern, { cwd: __dirname })
|
||||||
|
var matches = []
|
||||||
|
g.on('match', function(m) {
|
||||||
|
console.error('match %j', m)
|
||||||
|
matches.push(m)
|
||||||
|
})
|
||||||
|
g.on('end', function(set) {
|
||||||
|
console.error('set', set)
|
||||||
|
matches = matches.sort()
|
||||||
|
set = set.sort()
|
||||||
|
t.same(matches, set, 'should have same set of matches')
|
||||||
|
t.end()
|
||||||
|
})
|
||||||
|
})
|
||||||
Generated
Vendored
+118
@@ -0,0 +1,118 @@
|
|||||||
|
var test = require("tap").test
|
||||||
|
var glob = require('../')
|
||||||
|
process.chdir(__dirname)
|
||||||
|
|
||||||
|
// expose timing issues
|
||||||
|
var lag = 5
|
||||||
|
glob.Glob.prototype._stat = function(o) { return function(f, cb) {
|
||||||
|
var args = arguments
|
||||||
|
setTimeout(function() {
|
||||||
|
o.call(this, f, cb)
|
||||||
|
}.bind(this), lag += 5)
|
||||||
|
}}(glob.Glob.prototype._stat)
|
||||||
|
|
||||||
|
|
||||||
|
test("mark, with **", function (t) {
|
||||||
|
glob("a/*b*/**", {mark: true}, function (er, results) {
|
||||||
|
if (er)
|
||||||
|
throw er
|
||||||
|
var expect =
|
||||||
|
[ 'a/abcdef/',
|
||||||
|
'a/abcdef/g/',
|
||||||
|
'a/abcdef/g/h',
|
||||||
|
'a/abcfed/',
|
||||||
|
'a/abcfed/g/',
|
||||||
|
'a/abcfed/g/h',
|
||||||
|
'a/b/',
|
||||||
|
'a/b/c/',
|
||||||
|
'a/b/c/d',
|
||||||
|
'a/bc/',
|
||||||
|
'a/bc/e/',
|
||||||
|
'a/bc/e/f',
|
||||||
|
'a/cb/',
|
||||||
|
'a/cb/e/',
|
||||||
|
'a/cb/e/f' ]
|
||||||
|
|
||||||
|
t.same(results, expect)
|
||||||
|
t.end()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
test("mark, no / on pattern", function (t) {
|
||||||
|
glob("a/*", {mark: true}, function (er, results) {
|
||||||
|
if (er)
|
||||||
|
throw er
|
||||||
|
var expect = [ 'a/abcdef/',
|
||||||
|
'a/abcfed/',
|
||||||
|
'a/b/',
|
||||||
|
'a/bc/',
|
||||||
|
'a/c/',
|
||||||
|
'a/cb/' ]
|
||||||
|
|
||||||
|
if (process.platform !== "win32")
|
||||||
|
expect.push('a/symlink/')
|
||||||
|
|
||||||
|
t.same(results, expect)
|
||||||
|
t.end()
|
||||||
|
}).on('match', function(m) {
|
||||||
|
t.similar(m, /\/$/)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
test("mark=false, no / on pattern", function (t) {
|
||||||
|
glob("a/*", function (er, results) {
|
||||||
|
if (er)
|
||||||
|
throw er
|
||||||
|
var expect = [ 'a/abcdef',
|
||||||
|
'a/abcfed',
|
||||||
|
'a/b',
|
||||||
|
'a/bc',
|
||||||
|
'a/c',
|
||||||
|
'a/cb' ]
|
||||||
|
|
||||||
|
if (process.platform !== "win32")
|
||||||
|
expect.push('a/symlink')
|
||||||
|
t.same(results, expect)
|
||||||
|
t.end()
|
||||||
|
}).on('match', function(m) {
|
||||||
|
t.similar(m, /[^\/]$/)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
test("mark=true, / on pattern", function (t) {
|
||||||
|
glob("a/*/", {mark: true}, function (er, results) {
|
||||||
|
if (er)
|
||||||
|
throw er
|
||||||
|
var expect = [ 'a/abcdef/',
|
||||||
|
'a/abcfed/',
|
||||||
|
'a/b/',
|
||||||
|
'a/bc/',
|
||||||
|
'a/c/',
|
||||||
|
'a/cb/' ]
|
||||||
|
if (process.platform !== "win32")
|
||||||
|
expect.push('a/symlink/')
|
||||||
|
t.same(results, expect)
|
||||||
|
t.end()
|
||||||
|
}).on('match', function(m) {
|
||||||
|
t.similar(m, /\/$/)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
test("mark=false, / on pattern", function (t) {
|
||||||
|
glob("a/*/", function (er, results) {
|
||||||
|
if (er)
|
||||||
|
throw er
|
||||||
|
var expect = [ 'a/abcdef/',
|
||||||
|
'a/abcfed/',
|
||||||
|
'a/b/',
|
||||||
|
'a/bc/',
|
||||||
|
'a/c/',
|
||||||
|
'a/cb/' ]
|
||||||
|
if (process.platform !== "win32")
|
||||||
|
expect.push('a/symlink/')
|
||||||
|
t.same(results, expect)
|
||||||
|
t.end()
|
||||||
|
}).on('match', function(m) {
|
||||||
|
t.similar(m, /\/$/)
|
||||||
|
})
|
||||||
|
})
|
||||||
Generated
Vendored
+10
@@ -0,0 +1,10 @@
|
|||||||
|
var Glob = require('../glob.js').Glob;
|
||||||
|
var test = require('tap').test;
|
||||||
|
|
||||||
|
test('new glob, with cb, and no options', function (t) {
|
||||||
|
new Glob(__filename, function(er, results) {
|
||||||
|
if (er) throw er;
|
||||||
|
t.same(results, [__filename]);
|
||||||
|
t.end();
|
||||||
|
});
|
||||||
|
});
|
||||||
Generated
Vendored
+124
@@ -0,0 +1,124 @@
|
|||||||
|
var fs = require('fs');
|
||||||
|
var test = require('tap').test;
|
||||||
|
var glob = require('../');
|
||||||
|
|
||||||
|
test('mock fs', function(t) {
|
||||||
|
var stat = fs.stat
|
||||||
|
var statSync = fs.statSync
|
||||||
|
var readdir = fs.readdir
|
||||||
|
var readdirSync = fs.readdirSync
|
||||||
|
|
||||||
|
function fakeStat(path) {
|
||||||
|
var ret
|
||||||
|
switch (path.toLowerCase()) {
|
||||||
|
case '/tmp': case '/tmp/': case 'c:\\tmp': case 'c:\\tmp\\':
|
||||||
|
ret = { isDirectory: function() { return true } }
|
||||||
|
break
|
||||||
|
case '/tmp/a': case 'c:\\tmp\\a':
|
||||||
|
ret = { isDirectory: function() { return false } }
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
fs.stat = function(path, cb) {
|
||||||
|
var f = fakeStat(path);
|
||||||
|
if (f) {
|
||||||
|
process.nextTick(function() {
|
||||||
|
cb(null, f)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
stat.call(fs, path, cb)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fs.statSync = function(path) {
|
||||||
|
return fakeStat(path) || statSync.call(fs, path)
|
||||||
|
}
|
||||||
|
|
||||||
|
function fakeReaddir(path) {
|
||||||
|
var ret
|
||||||
|
switch (path.toLowerCase()) {
|
||||||
|
case '/tmp': case '/tmp/': case 'c:\\tmp': case 'c:\\tmp\\':
|
||||||
|
ret = [ 'a', 'A' ]
|
||||||
|
break
|
||||||
|
case '/': case 'c:\\':
|
||||||
|
ret = ['tmp', 'tMp', 'tMP', 'TMP']
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
fs.readdir = function(path, cb) {
|
||||||
|
var f = fakeReaddir(path)
|
||||||
|
if (f)
|
||||||
|
process.nextTick(function() {
|
||||||
|
cb(null, f)
|
||||||
|
})
|
||||||
|
else
|
||||||
|
readdir.call(fs, path, cb)
|
||||||
|
}
|
||||||
|
|
||||||
|
fs.readdirSync = function(path) {
|
||||||
|
return fakeReaddir(path) || readdirSync.call(fs, path)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.pass('mocked')
|
||||||
|
t.end()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('nocase, nomagic', function(t) {
|
||||||
|
var n = 2
|
||||||
|
var want = [ '/TMP/A',
|
||||||
|
'/TMP/a',
|
||||||
|
'/tMP/A',
|
||||||
|
'/tMP/a',
|
||||||
|
'/tMp/A',
|
||||||
|
'/tMp/a',
|
||||||
|
'/tmp/A',
|
||||||
|
'/tmp/a' ]
|
||||||
|
if(process.platform.match(/^win/)) {
|
||||||
|
want = want.map(function(p) {
|
||||||
|
return 'C:' + p
|
||||||
|
})
|
||||||
|
}
|
||||||
|
glob('/tmp/a', { nocase: true }, function(er, res) {
|
||||||
|
if (er)
|
||||||
|
throw er
|
||||||
|
t.same(res.sort(), want)
|
||||||
|
if (--n === 0) t.end()
|
||||||
|
})
|
||||||
|
glob('/tmp/A', { nocase: true }, function(er, res) {
|
||||||
|
if (er)
|
||||||
|
throw er
|
||||||
|
t.same(res.sort(), want)
|
||||||
|
if (--n === 0) t.end()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
test('nocase, with some magic', function(t) {
|
||||||
|
t.plan(2)
|
||||||
|
var want = [ '/TMP/A',
|
||||||
|
'/TMP/a',
|
||||||
|
'/tMP/A',
|
||||||
|
'/tMP/a',
|
||||||
|
'/tMp/A',
|
||||||
|
'/tMp/a',
|
||||||
|
'/tmp/A',
|
||||||
|
'/tmp/a' ]
|
||||||
|
if(process.platform.match(/^win/)) {
|
||||||
|
want = want.map(function(p) {
|
||||||
|
return 'C:' + p
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
glob('/tmp/*', { nocase: true }, function(er, res) {
|
||||||
|
if (er)
|
||||||
|
throw er
|
||||||
|
t.same(res.sort(), want)
|
||||||
|
})
|
||||||
|
glob('/tmp/*', { nocase: true }, function(er, res) {
|
||||||
|
if (er)
|
||||||
|
throw er
|
||||||
|
t.same(res.sort(), want)
|
||||||
|
})
|
||||||
|
})
|
||||||
Generated
Vendored
+73
@@ -0,0 +1,73 @@
|
|||||||
|
// show that no match events happen while paused.
|
||||||
|
var tap = require("tap")
|
||||||
|
, child_process = require("child_process")
|
||||||
|
// just some gnarly pattern with lots of matches
|
||||||
|
, pattern = "test/a/!(symlink)/**"
|
||||||
|
, bashResults = require("./bash-results.json")
|
||||||
|
, patterns = Object.keys(bashResults)
|
||||||
|
, glob = require("../")
|
||||||
|
, Glob = glob.Glob
|
||||||
|
, path = require("path")
|
||||||
|
|
||||||
|
// run from the root of the project
|
||||||
|
// this is usually where you're at anyway, but be sure.
|
||||||
|
process.chdir(path.resolve(__dirname, ".."))
|
||||||
|
|
||||||
|
function alphasort (a, b) {
|
||||||
|
a = a.toLowerCase()
|
||||||
|
b = b.toLowerCase()
|
||||||
|
return a > b ? 1 : a < b ? -1 : 0
|
||||||
|
}
|
||||||
|
|
||||||
|
function cleanResults (m) {
|
||||||
|
// normalize discrepancies in ordering, duplication,
|
||||||
|
// and ending slashes.
|
||||||
|
return m.map(function (m) {
|
||||||
|
return m.replace(/\/+/g, "/").replace(/\/$/, "")
|
||||||
|
}).sort(alphasort).reduce(function (set, f) {
|
||||||
|
if (f !== set[set.length - 1]) set.push(f)
|
||||||
|
return set
|
||||||
|
}, []).sort(alphasort).map(function (f) {
|
||||||
|
// de-windows
|
||||||
|
return (process.platform !== 'win32') ? f
|
||||||
|
: f.replace(/^[a-zA-Z]:\\\\/, '/').replace(/\\/g, '/')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
var globResults = []
|
||||||
|
tap.test("use a Glob object, and pause/resume it", function (t) {
|
||||||
|
var g = new Glob(pattern)
|
||||||
|
, paused = false
|
||||||
|
, res = []
|
||||||
|
, expect = bashResults[pattern]
|
||||||
|
|
||||||
|
g.on("pause", function () {
|
||||||
|
console.error("pause")
|
||||||
|
})
|
||||||
|
|
||||||
|
g.on("resume", function () {
|
||||||
|
console.error("resume")
|
||||||
|
})
|
||||||
|
|
||||||
|
g.on("match", function (m) {
|
||||||
|
t.notOk(g.paused, "must not be paused")
|
||||||
|
globResults.push(m)
|
||||||
|
g.pause()
|
||||||
|
t.ok(g.paused, "must be paused")
|
||||||
|
setTimeout(g.resume.bind(g), 10)
|
||||||
|
})
|
||||||
|
|
||||||
|
g.on("end", function (matches) {
|
||||||
|
t.pass("reached glob end")
|
||||||
|
globResults = cleanResults(globResults)
|
||||||
|
matches = cleanResults(matches)
|
||||||
|
t.deepEqual(matches, globResults,
|
||||||
|
"end event matches should be the same as match events")
|
||||||
|
|
||||||
|
t.deepEqual(matches, expect,
|
||||||
|
"glob matches should be the same as bash results")
|
||||||
|
|
||||||
|
t.end()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
Generated
Vendored
+36
@@ -0,0 +1,36 @@
|
|||||||
|
var test = require("tap").test
|
||||||
|
var glob = require("../")
|
||||||
|
|
||||||
|
var mkdirp = require("mkdirp")
|
||||||
|
var fs = require("fs")
|
||||||
|
var rimraf = require("rimraf")
|
||||||
|
var dir = __dirname + "/package"
|
||||||
|
|
||||||
|
test("setup", function (t) {
|
||||||
|
mkdirp.sync(dir)
|
||||||
|
fs.writeFileSync(dir + "/package.json", "{}", "ascii")
|
||||||
|
fs.writeFileSync(dir + "/README", "x", "ascii")
|
||||||
|
t.pass("setup done")
|
||||||
|
t.end()
|
||||||
|
})
|
||||||
|
|
||||||
|
test("glob", function (t) {
|
||||||
|
var opt = {
|
||||||
|
cwd: dir,
|
||||||
|
nocase: true,
|
||||||
|
mark: true
|
||||||
|
}
|
||||||
|
|
||||||
|
glob("README?(.*)", opt, function (er, files) {
|
||||||
|
if (er)
|
||||||
|
throw er
|
||||||
|
t.same(files, ["README"])
|
||||||
|
t.end()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
test("cleanup", function (t) {
|
||||||
|
rimraf.sync(dir)
|
||||||
|
t.pass("clean")
|
||||||
|
t.end()
|
||||||
|
})
|
||||||
Generated
Vendored
+39
@@ -0,0 +1,39 @@
|
|||||||
|
var tap = require("tap")
|
||||||
|
|
||||||
|
var origCwd = process.cwd()
|
||||||
|
process.chdir(__dirname)
|
||||||
|
|
||||||
|
tap.test("changing root and searching for /b*/**", function (t) {
|
||||||
|
var glob = require('../')
|
||||||
|
var path = require('path')
|
||||||
|
t.test('.', function (t) {
|
||||||
|
glob('/b*/**', { globDebug: true, root: '.', nomount: true }, function (er, matches) {
|
||||||
|
t.ifError(er)
|
||||||
|
t.like(matches, [])
|
||||||
|
t.end()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
t.test('a', function (t) {
|
||||||
|
glob('/b*/**', { globDebug: true, root: path.resolve('a'), nomount: true }, function (er, matches) {
|
||||||
|
t.ifError(er)
|
||||||
|
t.like(matches, [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ])
|
||||||
|
t.end()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
t.test('root=a, cwd=a/b', function (t) {
|
||||||
|
glob('/b*/**', { globDebug: true, root: 'a', cwd: path.resolve('a/b'), nomount: true }, function (er, matches) {
|
||||||
|
t.ifError(er)
|
||||||
|
t.like(matches, [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ])
|
||||||
|
t.end()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
t.test('cd -', function (t) {
|
||||||
|
process.chdir(origCwd)
|
||||||
|
t.end()
|
||||||
|
})
|
||||||
|
|
||||||
|
t.end()
|
||||||
|
})
|
||||||
Generated
Vendored
+46
@@ -0,0 +1,46 @@
|
|||||||
|
var t = require("tap")
|
||||||
|
|
||||||
|
var origCwd = process.cwd()
|
||||||
|
process.chdir(__dirname)
|
||||||
|
|
||||||
|
var glob = require('../')
|
||||||
|
var path = require('path')
|
||||||
|
|
||||||
|
t.test('.', function (t) {
|
||||||
|
glob('/b*/**', { globDebug: true, root: '.' }, function (er, matches) {
|
||||||
|
t.ifError(er)
|
||||||
|
t.like(matches, [])
|
||||||
|
t.end()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
t.test('a', function (t) {
|
||||||
|
console.error("root=" + path.resolve('a'))
|
||||||
|
glob('/b*/**', { globDebug: true, root: path.resolve('a') }, function (er, matches) {
|
||||||
|
t.ifError(er)
|
||||||
|
var wanted = [
|
||||||
|
'/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f'
|
||||||
|
].map(function (m) {
|
||||||
|
return path.join(path.resolve('a'), m).replace(/\\/g, '/')
|
||||||
|
})
|
||||||
|
|
||||||
|
t.like(matches, wanted)
|
||||||
|
t.end()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
t.test('root=a, cwd=a/b', function (t) {
|
||||||
|
glob('/b*/**', { globDebug: true, root: 'a', cwd: path.resolve('a/b') }, function (er, matches) {
|
||||||
|
t.ifError(er)
|
||||||
|
t.like(matches, [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ].map(function (m) {
|
||||||
|
return path.join(path.resolve('a'), m).replace(/\\/g, '/')
|
||||||
|
}))
|
||||||
|
t.end()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
t.test('cd -', function (t) {
|
||||||
|
process.chdir(origCwd)
|
||||||
|
t.end()
|
||||||
|
})
|
||||||
Generated
Vendored
+32
@@ -0,0 +1,32 @@
|
|||||||
|
var glob = require('../')
|
||||||
|
var test = require('tap').test
|
||||||
|
var path = require('path')
|
||||||
|
|
||||||
|
test('stat all the things', function(t) {
|
||||||
|
var g = new glob.Glob('a/*abc*/**', { stat: true, cwd: __dirname })
|
||||||
|
var matches = []
|
||||||
|
g.on('match', function(m) {
|
||||||
|
matches.push(m)
|
||||||
|
})
|
||||||
|
var stats = []
|
||||||
|
g.on('stat', function(m) {
|
||||||
|
stats.push(m)
|
||||||
|
})
|
||||||
|
g.on('end', function(eof) {
|
||||||
|
stats = stats.sort()
|
||||||
|
matches = matches.sort()
|
||||||
|
eof = eof.sort()
|
||||||
|
t.same(stats, matches)
|
||||||
|
t.same(eof, matches)
|
||||||
|
var cache = Object.keys(this.statCache)
|
||||||
|
t.same(cache.map(function (f) {
|
||||||
|
return path.relative(__dirname, f).replace(/\\/g, '/')
|
||||||
|
}).sort(), matches)
|
||||||
|
|
||||||
|
cache.forEach(function(c) {
|
||||||
|
t.equal(typeof this.statCache[c], 'object')
|
||||||
|
}, this)
|
||||||
|
|
||||||
|
t.end()
|
||||||
|
})
|
||||||
|
})
|
||||||
Generated
Vendored
+11
@@ -0,0 +1,11 @@
|
|||||||
|
// remove the fixtures
|
||||||
|
var tap = require("tap")
|
||||||
|
, rimraf = require("rimraf")
|
||||||
|
, path = require("path")
|
||||||
|
|
||||||
|
tap.test("cleanup fixtures", function (t) {
|
||||||
|
rimraf(path.resolve(__dirname, "a"), function (er) {
|
||||||
|
t.ifError(er, "removed")
|
||||||
|
t.end()
|
||||||
|
})
|
||||||
|
})
|
||||||
Generated
Vendored
Executable
+53
File diff suppressed because one or more lines are too long
Generated
Vendored
+14
@@ -0,0 +1,14 @@
|
|||||||
|
.DS_Store
|
||||||
|
.monitor
|
||||||
|
.*.swp
|
||||||
|
.nodemonignore
|
||||||
|
releases
|
||||||
|
*.log
|
||||||
|
*.err
|
||||||
|
fleet.json
|
||||||
|
public/browserify
|
||||||
|
bin/*.json
|
||||||
|
.bin
|
||||||
|
build
|
||||||
|
compile
|
||||||
|
.lock-wscript
|
||||||
Generated
Vendored
+14
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"launchers": {
|
||||||
|
"node": {
|
||||||
|
"command": "npm test"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"src_files": [
|
||||||
|
"./**/*.js"
|
||||||
|
],
|
||||||
|
"before_tests": "npm run build",
|
||||||
|
"on_exit": "rm test/static/bundle.js",
|
||||||
|
"test_page": "test/static/index.html",
|
||||||
|
"launch_in_dev": ["node", "phantomjs"]
|
||||||
|
}
|
||||||
Generated
Vendored
+4
@@ -0,0 +1,4 @@
|
|||||||
|
language: node_js
|
||||||
|
node_js:
|
||||||
|
- 0.8
|
||||||
|
- 0.9
|
||||||
Generated
Vendored
+19
@@ -0,0 +1,19 @@
|
|||||||
|
Copyright (c) 2012 Raynos.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
Generated
Vendored
+32
@@ -0,0 +1,32 @@
|
|||||||
|
# console-browserify
|
||||||
|
|
||||||
|
[![build status][1]][2]
|
||||||
|
|
||||||
|
[![browser support][3]][4]
|
||||||
|
|
||||||
|
Emulate console for all the browsers
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
```js
|
||||||
|
var console = require("console-browserify")
|
||||||
|
|
||||||
|
console.log("hello world!")
|
||||||
|
```
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
`npm install console-browserify`
|
||||||
|
|
||||||
|
## Contributors
|
||||||
|
|
||||||
|
- Raynos
|
||||||
|
|
||||||
|
## MIT Licenced
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[1]: https://secure.travis-ci.org/Raynos/console-browserify.png
|
||||||
|
[2]: http://travis-ci.org/Raynos/console-browserify
|
||||||
|
[3]: http://ci.testling.com/Raynos/console-browserify.png
|
||||||
|
[4]: http://ci.testling.com/Raynos/console-browserify
|
||||||
Generated
Vendored
+85
@@ -0,0 +1,85 @@
|
|||||||
|
/*global window, global*/
|
||||||
|
var util = require("util")
|
||||||
|
var assert = require("assert")
|
||||||
|
|
||||||
|
var slice = Array.prototype.slice
|
||||||
|
var console
|
||||||
|
var times = {}
|
||||||
|
|
||||||
|
if (typeof global !== "undefined" && global.console) {
|
||||||
|
console = global.console
|
||||||
|
} else if (typeof window !== "undefined" && window.console) {
|
||||||
|
console = window.console
|
||||||
|
} else {
|
||||||
|
console = window.console = {}
|
||||||
|
}
|
||||||
|
|
||||||
|
var functions = [
|
||||||
|
[log, "log"]
|
||||||
|
, [info, "info"]
|
||||||
|
, [warn, "warn"]
|
||||||
|
, [error, "error"]
|
||||||
|
, [time, "time"]
|
||||||
|
, [timeEnd, "timeEnd"]
|
||||||
|
, [trace, "trace"]
|
||||||
|
, [dir, "dir"]
|
||||||
|
, [assert, "assert"]
|
||||||
|
]
|
||||||
|
|
||||||
|
for (var i = 0; i < functions.length; i++) {
|
||||||
|
var tuple = functions[i]
|
||||||
|
var f = tuple[0]
|
||||||
|
var name = tuple[1]
|
||||||
|
|
||||||
|
if (!console[name]) {
|
||||||
|
console[name] = f
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = console
|
||||||
|
|
||||||
|
function log() {}
|
||||||
|
|
||||||
|
function info() {
|
||||||
|
console.log.apply(console, arguments)
|
||||||
|
}
|
||||||
|
|
||||||
|
function warn() {
|
||||||
|
console.log.apply(console, arguments)
|
||||||
|
}
|
||||||
|
|
||||||
|
function error() {
|
||||||
|
console.warn.apply(console, arguments)
|
||||||
|
}
|
||||||
|
|
||||||
|
function time(label) {
|
||||||
|
times[label] = Date.now()
|
||||||
|
}
|
||||||
|
|
||||||
|
function timeEnd(label) {
|
||||||
|
var time = times[label]
|
||||||
|
if (!time) {
|
||||||
|
throw new Error("No such label: " + label)
|
||||||
|
}
|
||||||
|
|
||||||
|
var duration = Date.now() - time
|
||||||
|
console.log(label + ": " + duration + "ms")
|
||||||
|
}
|
||||||
|
|
||||||
|
function trace() {
|
||||||
|
var err = new Error()
|
||||||
|
err.name = "Trace"
|
||||||
|
err.message = util.format.apply(null, arguments)
|
||||||
|
console.error(err.stack)
|
||||||
|
}
|
||||||
|
|
||||||
|
function dir(object) {
|
||||||
|
console.log(util.inspect(object) + "\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
function assert(expression) {
|
||||||
|
if (!expression) {
|
||||||
|
var arr = slice.call(arguments, 1)
|
||||||
|
assert.ok(false, util.format.apply(null, arr))
|
||||||
|
}
|
||||||
|
}
|
||||||
Generated
Vendored
+76
@@ -0,0 +1,76 @@
|
|||||||
|
{
|
||||||
|
"name": "console-browserify",
|
||||||
|
"version": "0.1.6",
|
||||||
|
"description": "Emulate console for all the browsers",
|
||||||
|
"keywords": [],
|
||||||
|
"author": {
|
||||||
|
"name": "Raynos",
|
||||||
|
"email": "raynos2@gmail.com"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git://github.com/Raynos/console-browserify.git"
|
||||||
|
},
|
||||||
|
"main": "index",
|
||||||
|
"homepage": "https://github.com/Raynos/console-browserify",
|
||||||
|
"contributors": [
|
||||||
|
{
|
||||||
|
"name": "Raynos"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/Raynos/console-browserify/issues",
|
||||||
|
"email": "raynos2@gmail.com"
|
||||||
|
},
|
||||||
|
"dependencies": {},
|
||||||
|
"devDependencies": {
|
||||||
|
"tape": "~0.2.2",
|
||||||
|
"browserify": "https://github.com/raynos/node-browserify/tarball/master",
|
||||||
|
"testem": "~0.2.55",
|
||||||
|
"jsonify": "0.0.0"
|
||||||
|
},
|
||||||
|
"licenses": [
|
||||||
|
{
|
||||||
|
"type": "MIT",
|
||||||
|
"url": "http://github.com/Raynos/console-browserify/raw/master/LICENSE"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"scripts": {
|
||||||
|
"test": "node ./test",
|
||||||
|
"build": "browserify test/index.js -o test/static/bundle.js",
|
||||||
|
"testem": "testem"
|
||||||
|
},
|
||||||
|
"testling": {
|
||||||
|
"files": "test/index.js",
|
||||||
|
"browsers": {
|
||||||
|
"ie": [
|
||||||
|
"6",
|
||||||
|
"7",
|
||||||
|
"8",
|
||||||
|
"9",
|
||||||
|
"10"
|
||||||
|
],
|
||||||
|
"firefox": [
|
||||||
|
"16",
|
||||||
|
"17",
|
||||||
|
"nightly"
|
||||||
|
],
|
||||||
|
"chrome": [
|
||||||
|
"22",
|
||||||
|
"23",
|
||||||
|
"canary"
|
||||||
|
],
|
||||||
|
"opera": [
|
||||||
|
"12",
|
||||||
|
"next"
|
||||||
|
],
|
||||||
|
"safari": [
|
||||||
|
"5.1"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"readme": "# console-browserify\n\n[![build status][1]][2]\n\n[![browser support][3]][4]\n\nEmulate console for all the browsers\n\n## Example\n\n```js\nvar console = require(\"console-browserify\")\n\nconsole.log(\"hello world!\")\n```\n\n## Installation\n\n`npm install console-browserify`\n\n## Contributors\n\n - Raynos\n\n## MIT Licenced\n\n\n\n [1]: https://secure.travis-ci.org/Raynos/console-browserify.png\n [2]: http://travis-ci.org/Raynos/console-browserify\n [3]: http://ci.testling.com/Raynos/console-browserify.png\n [4]: http://ci.testling.com/Raynos/console-browserify\n",
|
||||||
|
"readmeFilename": "README.md",
|
||||||
|
"_id": "console-browserify@0.1.6",
|
||||||
|
"_from": "console-browserify@0.1.x"
|
||||||
|
}
|
||||||
Generated
Vendored
+67
@@ -0,0 +1,67 @@
|
|||||||
|
var console = require("../index")
|
||||||
|
var test = require("tape")
|
||||||
|
|
||||||
|
if (typeof window !== "undefined" && !window.JSON) {
|
||||||
|
window.JSON = require("jsonify")
|
||||||
|
}
|
||||||
|
|
||||||
|
test("console has expected methods", function (assert) {
|
||||||
|
assert.ok(console.log)
|
||||||
|
assert.ok(console.info)
|
||||||
|
assert.ok(console.warn)
|
||||||
|
assert.ok(console.dir)
|
||||||
|
assert.ok(console.time, "time")
|
||||||
|
assert.ok(console.timeEnd, "timeEnd")
|
||||||
|
assert.ok(console.trace, "trace")
|
||||||
|
assert.ok(console.assert)
|
||||||
|
|
||||||
|
assert.end()
|
||||||
|
})
|
||||||
|
|
||||||
|
test("invoke console.log", function (assert) {
|
||||||
|
console.log("test-log")
|
||||||
|
|
||||||
|
assert.end()
|
||||||
|
})
|
||||||
|
|
||||||
|
test("invoke console.info", function (assert) {
|
||||||
|
console.info("test-info")
|
||||||
|
|
||||||
|
assert.end()
|
||||||
|
})
|
||||||
|
|
||||||
|
test("invoke console.warn", function (assert) {
|
||||||
|
console.warn("test-warn")
|
||||||
|
|
||||||
|
assert.end()
|
||||||
|
})
|
||||||
|
|
||||||
|
test("invoke console.time", function (assert) {
|
||||||
|
console.time("label")
|
||||||
|
|
||||||
|
assert.end()
|
||||||
|
})
|
||||||
|
|
||||||
|
test("invoke console.trace", function (assert) {
|
||||||
|
console.trace("test-trace")
|
||||||
|
|
||||||
|
assert.end()
|
||||||
|
})
|
||||||
|
|
||||||
|
test("invoke console.assert", function (assert) {
|
||||||
|
console.assert(true)
|
||||||
|
|
||||||
|
assert.end()
|
||||||
|
})
|
||||||
|
|
||||||
|
test("invoke console.dir", function (assert) {
|
||||||
|
console.dir("test-dir")
|
||||||
|
|
||||||
|
assert.end()
|
||||||
|
})
|
||||||
|
|
||||||
|
test("invoke console.timeEnd", function (assert) {
|
||||||
|
console.timeEnd("label")
|
||||||
|
|
||||||
|
assert.end()
|
||||||
|
})
|
||||||
Generated
Vendored
+12
@@ -0,0 +1,12 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="x-ua-compatible" content="IE=8" >
|
||||||
|
<title>TAPE Example</title>
|
||||||
|
<script src="/testem.js"></script>
|
||||||
|
<script src="test-adapter.js"></script>
|
||||||
|
<script src="bundle.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Generated
Vendored
+53
@@ -0,0 +1,53 @@
|
|||||||
|
(function () {
|
||||||
|
var Testem = window.Testem
|
||||||
|
var regex = /^((?:not )?ok) (\d+) (.+)$/
|
||||||
|
|
||||||
|
Testem.useCustomAdapter(tapAdapter)
|
||||||
|
|
||||||
|
function tapAdapter(socket){
|
||||||
|
var results = {
|
||||||
|
failed: 0
|
||||||
|
, passed: 0
|
||||||
|
, total: 0
|
||||||
|
, tests: []
|
||||||
|
}
|
||||||
|
|
||||||
|
socket.emit('tests-start')
|
||||||
|
|
||||||
|
Testem.handleConsoleMessage = function(msg){
|
||||||
|
var m = msg.match(regex)
|
||||||
|
if (m) {
|
||||||
|
var passed = m[1] === 'ok'
|
||||||
|
var test = {
|
||||||
|
passed: passed ? 1 : 0,
|
||||||
|
failed: passed ? 0 : 1,
|
||||||
|
total: 1,
|
||||||
|
id: m[2],
|
||||||
|
name: m[3],
|
||||||
|
items: []
|
||||||
|
}
|
||||||
|
|
||||||
|
if (passed) {
|
||||||
|
results.passed++
|
||||||
|
} else {
|
||||||
|
console.error("failure", m)
|
||||||
|
|
||||||
|
results.failed++
|
||||||
|
}
|
||||||
|
|
||||||
|
results.total++
|
||||||
|
|
||||||
|
// console.log("emitted test", test)
|
||||||
|
socket.emit('test-result', test)
|
||||||
|
results.tests.push(test)
|
||||||
|
} else if (msg === '# ok' || msg.match(/^# tests \d+/)){
|
||||||
|
// console.log("emitted all test")
|
||||||
|
socket.emit('all-test-results', results)
|
||||||
|
}
|
||||||
|
|
||||||
|
// return false if you want to prevent the console message from
|
||||||
|
// going to the console
|
||||||
|
// return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}())
|
||||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
|||||||
|
node_modules
|
||||||
Generated
Vendored
+23
@@ -0,0 +1,23 @@
|
|||||||
|
Copyright 2009, 2010, 2011 Isaac Z. Schlueter.
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person
|
||||||
|
obtaining a copy of this software and associated documentation
|
||||||
|
files (the "Software"), to deal in the Software without
|
||||||
|
restriction, including without limitation the rights to use,
|
||||||
|
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the
|
||||||
|
Software is furnished to do so, subject to the following
|
||||||
|
conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||||
|
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
|
OTHER DEALINGS IN THE SOFTWARE.
|
||||||
Generated
Vendored
+218
@@ -0,0 +1,218 @@
|
|||||||
|
# minimatch
|
||||||
|
|
||||||
|
A minimal matching utility.
|
||||||
|
|
||||||
|
[](http://travis-ci.org/isaacs/minimatch)
|
||||||
|
|
||||||
|
|
||||||
|
This is the matching library used internally by npm.
|
||||||
|
|
||||||
|
Eventually, it will replace the C binding in node-glob.
|
||||||
|
|
||||||
|
It works by converting glob expressions into JavaScript `RegExp`
|
||||||
|
objects.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var minimatch = require("minimatch")
|
||||||
|
|
||||||
|
minimatch("bar.foo", "*.foo") // true!
|
||||||
|
minimatch("bar.foo", "*.bar") // false!
|
||||||
|
minimatch("bar.foo", "*.+(bar|foo)", { debug: true }) // true, and noisy!
|
||||||
|
```
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
Supports these glob features:
|
||||||
|
|
||||||
|
* Brace Expansion
|
||||||
|
* Extended glob matching
|
||||||
|
* "Globstar" `**` matching
|
||||||
|
|
||||||
|
See:
|
||||||
|
|
||||||
|
* `man sh`
|
||||||
|
* `man bash`
|
||||||
|
* `man 3 fnmatch`
|
||||||
|
* `man 5 gitignore`
|
||||||
|
|
||||||
|
## Minimatch Class
|
||||||
|
|
||||||
|
Create a minimatch object by instanting the `minimatch.Minimatch` class.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var Minimatch = require("minimatch").Minimatch
|
||||||
|
var mm = new Minimatch(pattern, options)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Properties
|
||||||
|
|
||||||
|
* `pattern` The original pattern the minimatch object represents.
|
||||||
|
* `options` The options supplied to the constructor.
|
||||||
|
* `set` A 2-dimensional array of regexp or string expressions.
|
||||||
|
Each row in the
|
||||||
|
array corresponds to a brace-expanded pattern. Each item in the row
|
||||||
|
corresponds to a single path-part. For example, the pattern
|
||||||
|
`{a,b/c}/d` would expand to a set of patterns like:
|
||||||
|
|
||||||
|
[ [ a, d ]
|
||||||
|
, [ b, c, d ] ]
|
||||||
|
|
||||||
|
If a portion of the pattern doesn't have any "magic" in it
|
||||||
|
(that is, it's something like `"foo"` rather than `fo*o?`), then it
|
||||||
|
will be left as a string rather than converted to a regular
|
||||||
|
expression.
|
||||||
|
|
||||||
|
* `regexp` Created by the `makeRe` method. A single regular expression
|
||||||
|
expressing the entire pattern. This is useful in cases where you wish
|
||||||
|
to use the pattern somewhat like `fnmatch(3)` with `FNM_PATH` enabled.
|
||||||
|
* `negate` True if the pattern is negated.
|
||||||
|
* `comment` True if the pattern is a comment.
|
||||||
|
* `empty` True if the pattern is `""`.
|
||||||
|
|
||||||
|
### Methods
|
||||||
|
|
||||||
|
* `makeRe` Generate the `regexp` member if necessary, and return it.
|
||||||
|
Will return `false` if the pattern is invalid.
|
||||||
|
* `match(fname)` Return true if the filename matches the pattern, or
|
||||||
|
false otherwise.
|
||||||
|
* `matchOne(fileArray, patternArray, partial)` Take a `/`-split
|
||||||
|
filename, and match it against a single row in the `regExpSet`. This
|
||||||
|
method is mainly for internal use, but is exposed so that it can be
|
||||||
|
used by a glob-walker that needs to avoid excessive filesystem calls.
|
||||||
|
|
||||||
|
All other methods are internal, and will be called as necessary.
|
||||||
|
|
||||||
|
## Functions
|
||||||
|
|
||||||
|
The top-level exported function has a `cache` property, which is an LRU
|
||||||
|
cache set to store 100 items. So, calling these methods repeatedly
|
||||||
|
with the same pattern and options will use the same Minimatch object,
|
||||||
|
saving the cost of parsing it multiple times.
|
||||||
|
|
||||||
|
### minimatch(path, pattern, options)
|
||||||
|
|
||||||
|
Main export. Tests a path against the pattern using the options.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var isJS = minimatch(file, "*.js", { matchBase: true })
|
||||||
|
```
|
||||||
|
|
||||||
|
### minimatch.filter(pattern, options)
|
||||||
|
|
||||||
|
Returns a function that tests its
|
||||||
|
supplied argument, suitable for use with `Array.filter`. Example:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var javascripts = fileList.filter(minimatch.filter("*.js", {matchBase: true}))
|
||||||
|
```
|
||||||
|
|
||||||
|
### minimatch.match(list, pattern, options)
|
||||||
|
|
||||||
|
Match against the list of
|
||||||
|
files, in the style of fnmatch or glob. If nothing is matched, and
|
||||||
|
options.nonull is set, then return a list containing the pattern itself.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var javascripts = minimatch.match(fileList, "*.js", {matchBase: true}))
|
||||||
|
```
|
||||||
|
|
||||||
|
### minimatch.makeRe(pattern, options)
|
||||||
|
|
||||||
|
Make a regular expression object from the pattern.
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
All options are `false` by default.
|
||||||
|
|
||||||
|
### debug
|
||||||
|
|
||||||
|
Dump a ton of stuff to stderr.
|
||||||
|
|
||||||
|
### nobrace
|
||||||
|
|
||||||
|
Do not expand `{a,b}` and `{1..3}` brace sets.
|
||||||
|
|
||||||
|
### noglobstar
|
||||||
|
|
||||||
|
Disable `**` matching against multiple folder names.
|
||||||
|
|
||||||
|
### dot
|
||||||
|
|
||||||
|
Allow patterns to match filenames starting with a period, even if
|
||||||
|
the pattern does not explicitly have a period in that spot.
|
||||||
|
|
||||||
|
Note that by default, `a/**/b` will **not** match `a/.d/b`, unless `dot`
|
||||||
|
is set.
|
||||||
|
|
||||||
|
### noext
|
||||||
|
|
||||||
|
Disable "extglob" style patterns like `+(a|b)`.
|
||||||
|
|
||||||
|
### nocase
|
||||||
|
|
||||||
|
Perform a case-insensitive match.
|
||||||
|
|
||||||
|
### nonull
|
||||||
|
|
||||||
|
When a match is not found by `minimatch.match`, return a list containing
|
||||||
|
the pattern itself if this option is set. When not set, an empty list
|
||||||
|
is returned if there are no matches.
|
||||||
|
|
||||||
|
### matchBase
|
||||||
|
|
||||||
|
If set, then patterns without slashes will be matched
|
||||||
|
against the basename of the path if it contains slashes. For example,
|
||||||
|
`a?b` would match the path `/xyz/123/acb`, but not `/xyz/acb/123`.
|
||||||
|
|
||||||
|
### nocomment
|
||||||
|
|
||||||
|
Suppress the behavior of treating `#` at the start of a pattern as a
|
||||||
|
comment.
|
||||||
|
|
||||||
|
### nonegate
|
||||||
|
|
||||||
|
Suppress the behavior of treating a leading `!` character as negation.
|
||||||
|
|
||||||
|
### flipNegate
|
||||||
|
|
||||||
|
Returns from negate expressions the same as if they were not negated.
|
||||||
|
(Ie, true on a hit, false on a miss.)
|
||||||
|
|
||||||
|
|
||||||
|
## Comparisons to other fnmatch/glob implementations
|
||||||
|
|
||||||
|
While strict compliance with the existing standards is a worthwhile
|
||||||
|
goal, some discrepancies exist between minimatch and other
|
||||||
|
implementations, and are intentional.
|
||||||
|
|
||||||
|
If the pattern starts with a `!` character, then it is negated. Set the
|
||||||
|
`nonegate` flag to suppress this behavior, and treat leading `!`
|
||||||
|
characters normally. This is perhaps relevant if you wish to start the
|
||||||
|
pattern with a negative extglob pattern like `!(a|B)`. Multiple `!`
|
||||||
|
characters at the start of a pattern will negate the pattern multiple
|
||||||
|
times.
|
||||||
|
|
||||||
|
If a pattern starts with `#`, then it is treated as a comment, and
|
||||||
|
will not match anything. Use `\#` to match a literal `#` at the
|
||||||
|
start of a line, or set the `nocomment` flag to suppress this behavior.
|
||||||
|
|
||||||
|
The double-star character `**` is supported by default, unless the
|
||||||
|
`noglobstar` flag is set. This is supported in the manner of bsdglob
|
||||||
|
and bash 4.1, where `**` only has special significance if it is the only
|
||||||
|
thing in a path part. That is, `a/**/b` will match `a/x/y/b`, but
|
||||||
|
`a/**b` will not.
|
||||||
|
|
||||||
|
If an escaped pattern has no matches, and the `nonull` flag is set,
|
||||||
|
then minimatch.match returns the pattern as-provided, rather than
|
||||||
|
interpreting the character escapes. For example,
|
||||||
|
`minimatch.match([], "\\*a\\?")` will return `"\\*a\\?"` rather than
|
||||||
|
`"*a?"`. This is akin to setting the `nullglob` option in bash, except
|
||||||
|
that it does not resolve escaped pattern characters.
|
||||||
|
|
||||||
|
If brace expansion is not disabled, then it is performed before any
|
||||||
|
other interpretation of the glob pattern. Thus, a pattern like
|
||||||
|
`+(a|{b),c)}`, which would not be valid in bash or zsh, is expanded
|
||||||
|
**first** into the set of `+(a|b)` and `+(a|c)`, and those patterns are
|
||||||
|
checked for validity. Since those two are valid, matching proceeds.
|
||||||
Generated
Vendored
+1061
File diff suppressed because it is too large
Load Diff
Generated
Vendored
+1
@@ -0,0 +1 @@
|
|||||||
|
/node_modules
|
||||||
Generated
Vendored
+14
@@ -0,0 +1,14 @@
|
|||||||
|
# Authors, sorted by whether or not they are me
|
||||||
|
Isaac Z. Schlueter <i@izs.me>
|
||||||
|
Brian Cottingham <spiffytech@gmail.com>
|
||||||
|
Carlos Brito Lage <carlos@carloslage.net>
|
||||||
|
Jesse Dailey <jesse.dailey@gmail.com>
|
||||||
|
Kevin O'Hara <kevinohara80@gmail.com>
|
||||||
|
Marco Rogers <marco.rogers@gmail.com>
|
||||||
|
Mark Cavage <mcavage@gmail.com>
|
||||||
|
Marko Mikulicic <marko.mikulicic@isti.cnr.it>
|
||||||
|
Nathan Rajlich <nathan@tootallnate.net>
|
||||||
|
Satheesh Natesan <snateshan@myspace-inc.com>
|
||||||
|
Trent Mick <trentm@gmail.com>
|
||||||
|
ashleybrener <ashley@starlogik.com>
|
||||||
|
n4kz <n4kz@n4kz.com>
|
||||||
Generated
Vendored
+23
@@ -0,0 +1,23 @@
|
|||||||
|
Copyright 2009, 2010, 2011 Isaac Z. Schlueter.
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person
|
||||||
|
obtaining a copy of this software and associated documentation
|
||||||
|
files (the "Software"), to deal in the Software without
|
||||||
|
restriction, including without limitation the rights to use,
|
||||||
|
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the
|
||||||
|
Software is furnished to do so, subject to the following
|
||||||
|
conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||||
|
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
|
OTHER DEALINGS IN THE SOFTWARE.
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user