From 9b136f448e51033f124b12af0c4b3dcf35119672 Mon Sep 17 00:00:00 2001 From: Brad Cornes Date: Sat, 2 May 2020 18:08:50 +0100 Subject: [PATCH] replace glob --- .../tailwindcss-class-names/package-lock.json | 33 +++++- packages/tailwindcss-class-names/package.json | 3 +- .../tailwindcss-class-names/src/getPlugins.js | 1 - .../tailwindcss-class-names/src/globSingle.js | 105 ++++++++++++++++++ packages/tailwindcss-class-names/src/index.js | 9 +- 5 files changed, 139 insertions(+), 12 deletions(-) create mode 100644 packages/tailwindcss-class-names/src/globSingle.js diff --git a/packages/tailwindcss-class-names/package-lock.json b/packages/tailwindcss-class-names/package-lock.json index 6f9f6f4..3e0ef2d 100644 --- a/packages/tailwindcss-class-names/package-lock.json +++ b/packages/tailwindcss-class-names/package-lock.json @@ -1115,7 +1115,8 @@ "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true }, "base": { "version": "0.11.2", @@ -1190,6 +1191,7 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -1422,7 +1424,8 @@ "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true }, "convert-source-map": { "version": "1.7.0", @@ -2022,7 +2025,8 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true }, "fsevents": { "version": "2.1.2", @@ -2076,6 +2080,7 @@ "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -2099,6 +2104,16 @@ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true }, + "globalyzer": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/globalyzer/-/globalyzer-0.1.4.tgz", + "integrity": "sha512-LeguVWaxgHN0MNbWC6YljNMzHkrCny9fzjmEUdnF1kQ7wATFD1RHFRqA1qxaX2tgxGENlcxjOflopBwj3YZiXA==" + }, + "globrex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", + "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==" + }, "graceful-fs": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", @@ -2275,6 +2290,7 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, "requires": { "once": "^1.3.0", "wrappy": "1" @@ -2283,7 +2299,8 @@ "inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true }, "ip-regex": { "version": "2.1.0", @@ -4057,6 +4074,7 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, "requires": { "brace-expansion": "^1.1.7" } @@ -4282,6 +4300,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, "requires": { "wrappy": "1" } @@ -4364,7 +4383,8 @@ "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true }, "path-key": { "version": "2.0.1", @@ -5751,7 +5771,8 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true }, "write-file-atomic": { "version": "3.0.3", diff --git a/packages/tailwindcss-class-names/package.json b/packages/tailwindcss-class-names/package.json index 9562153..44c85bd 100644 --- a/packages/tailwindcss-class-names/package.json +++ b/packages/tailwindcss-class-names/package.json @@ -16,7 +16,8 @@ "chokidar": "^3.3.1", "dlv": "^1.1.3", "dset": "^2.0.1", - "glob": "^7.1.6", + "globalyzer": "^0.1.4", + "globrex": "^0.1.2", "import-from": "^3.0.0", "pkg-up": "^3.1.0", "postcss-selector-parser": "^6.0.2", diff --git a/packages/tailwindcss-class-names/src/getPlugins.js b/packages/tailwindcss-class-names/src/getPlugins.js index 725b4cc..c4a520c 100644 --- a/packages/tailwindcss-class-names/src/getPlugins.js +++ b/packages/tailwindcss-class-names/src/getPlugins.js @@ -1,7 +1,6 @@ import * as path from 'path' import stackTrace from 'stack-trace' import pkgUp from 'pkg-up' -import { glob } from './glob' import { isObject } from './isObject' import importFrom from 'import-from' diff --git a/packages/tailwindcss-class-names/src/globSingle.js b/packages/tailwindcss-class-names/src/globSingle.js new file mode 100644 index 0000000..91d10fb --- /dev/null +++ b/packages/tailwindcss-class-names/src/globSingle.js @@ -0,0 +1,105 @@ +const fs = require('fs') +const globrex = require('globrex') +const { promisify } = require('util') +const globalyzer = require('globalyzer') +const { join, resolve, relative } = require('path') +const isHidden = /(^|[\\\/])\.[^\\\/\.]/g +const readdir = promisify(fs.readdir) +const stat = promisify(fs.stat) +let CACHE = {} + +async function walk(output, prefix, lexer, opts, dirname = '', level = 0) { + if (output.length === 1) return + const rgx = lexer.segments[level] + const dir = join(opts.cwd, prefix, dirname) + const files = await readdir(dir) + const { dot, filesOnly } = opts + + let i = 0, + len = files.length, + file + let fullpath, relpath, stats, isMatch + + for (; i < len; i++) { + file = files[i] + if (file === 'node_modules') continue + fullpath = join(dir, file) + relpath = dirname ? join(dirname, file) : file + if (!dot && isHidden.test(relpath)) continue + isMatch = lexer.regex.test(relpath) + + if ((stats = CACHE[relpath]) === void 0) { + CACHE[relpath] = stats = fs.lstatSync(fullpath) + } + + if (!stats.isDirectory()) { + if (isMatch) { + output.push(relative(opts.cwd, fullpath)) + return + } + continue + } + + if (rgx && !rgx.test(file)) continue + if (!filesOnly && isMatch) { + output.push(join(prefix, relpath)) + return + } + + await walk( + output, + prefix, + lexer, + opts, + relpath, + rgx && rgx.toString() !== lexer.globstar && ++level + ) + } +} + +/** + * Find files using bash-like globbing. + * All paths are normalized compared to node-glob. + * @param {String} str Glob string + * @param {String} [options.cwd='.'] Current working directory + * @param {Boolean} [options.dot=false] Include dotfile matches + * @param {Boolean} [options.absolute=false] Return absolute paths + * @param {Boolean} [options.filesOnly=false] Do not include folders if true + * @param {Boolean} [options.flush=false] Reset cache object + * @returns {Array} array containing matching files + */ +export async function globSingle(str, opts = {}) { + if (!str) return [] + + let glob = globalyzer(str) + + opts.cwd = opts.cwd || '.' + + if (!glob.isGlob) { + try { + let resolved = resolve(opts.cwd, str) + let dirent = await stat(resolved) + if (opts.filesOnly && !dirent.isFile()) return [] + + return opts.absolute ? [resolved] : [str] + } catch (err) { + if (err.code != 'ENOENT') throw err + + return [] + } + } + + if (opts.flush) CACHE = {} + + let matches = [] + const { path } = globrex(glob.glob, { + filepath: true, + globstar: true, + extended: true, + }) + + path.globstar = path.globstar.toString() + await walk(matches, glob.base, path, opts, '.', 0) + + return opts.absolute ? matches.map((x) => resolve(opts.cwd, x)) : matches +} diff --git a/packages/tailwindcss-class-names/src/index.js b/packages/tailwindcss-class-names/src/index.js index 2d852e8..27d2f94 100644 --- a/packages/tailwindcss-class-names/src/index.js +++ b/packages/tailwindcss-class-names/src/index.js @@ -11,7 +11,7 @@ import getVariants from './getVariants' import resolveConfig from './resolveConfig' import * as util from 'util' import * as path from 'path' -import { glob } from './glob' +import { globSingle } from './globSingle' import { getUtilityConfigMap } from './getUtilityConfigMap' function TailwindConfigError(error) { @@ -45,10 +45,11 @@ export default async function getClassNames( let tailwindcss let version - configPath = await glob(CONFIG_GLOB, { + configPath = await globSingle(CONFIG_GLOB, { cwd, - ignore: '**/node_modules/**', - max: 1, + filesOnly: true, + absolute: true, + flush: true, }) invariant(configPath.length === 1, 'No Tailwind CSS config found.') configPath = configPath[0]