Skip to content

Commit 69fe8c1

Browse files
committed
Merge pull request #34 from kswedberg/add-glob
Add glob option (Boolean, with default false). Closes gh-8
2 parents ae027df + 281dda9 commit 69fe8c1

File tree

7 files changed

+77
-2
lines changed

7 files changed

+77
-2
lines changed

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,13 @@ Default: `null`
114114

115115
Function called after the import process. Take one argument (array of imported files).
116116

117+
#### `glob`
118+
119+
Type: `Boolean`
120+
Default: `false`
121+
122+
Set to `true` if you want @import rules to parse glob patterns.
123+
117124
#### Example with some options
118125

119126
```js

index.js

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ var resolve = require("resolve")
1111
var postcss = require("postcss")
1212
var helpers = require("postcss-message-helpers")
1313
var hash = require("string-hash")
14+
var glob = require("glob")
1415

1516
/**
1617
* Constants
@@ -81,14 +82,57 @@ function AtImport(options) {
8182
*/
8283
function parseStyles(styles, options, cb, importedFiles, ignoredAtRules, media, hashFiles) {
8384
var imports = []
84-
styles.eachAtRule("import", function checkAtRule(atRule) {imports.push(atRule)})
85+
styles.eachAtRule("import", function checkAtRule(atRule) {
86+
if (options.glob && glob.hasMagic(atRule.params)) {
87+
imports = parseGlob(atRule, options, imports)
88+
}
89+
else {
90+
imports.push(atRule)
91+
}
92+
})
8593
imports.forEach(function(atRule) {
8694
helpers.try(function transformAtImport() {
8795
readAtImport(atRule, options, cb, importedFiles, ignoredAtRules, media, hashFiles)
8896
}, atRule.source)
8997
})
9098
}
9199

100+
/**
101+
* parse glob patterns (for relative paths only)
102+
*
103+
* @param {Object} atRule
104+
* @param {Object} options
105+
* @param {Array} imports
106+
*/
107+
function parseGlob(atRule, options, imports) {
108+
var globPattern = atRule.params.replace(/"/g, "")
109+
var files = []
110+
var dir = options.source && options.source.input && options.source.input.file ?
111+
path.dirname(path.resolve(options.root, options.source.input.file)) :
112+
options.root
113+
options.path.forEach(function(p) {
114+
p = path.resolve(dir, p)
115+
var globbed = glob.sync(path.join(p, globPattern))
116+
globbed.forEach(function(file) {
117+
file = path.relative(p, file)
118+
files.push(file)
119+
});
120+
});
121+
122+
files.forEach(function(file) {
123+
var deglobbedAtRule = atRule.clone({
124+
params: "\"" + file + "\""
125+
})
126+
if (deglobbedAtRule.source && deglobbedAtRule.source.input && deglobbedAtRule.source.input.css) {
127+
deglobbedAtRule.source.input.css = atRule.source.input.css.replace(globPattern, file)
128+
}
129+
atRule.parent.insertBefore(atRule, deglobbedAtRule)
130+
imports.push(deglobbedAtRule)
131+
});
132+
atRule.removeSelf()
133+
return imports;
134+
}
135+
92136
/**
93137
* put back at the top ignored url (absolute url)
94138
*

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
],
2424
"dependencies": {
2525
"clone": "^0.1.17",
26+
"glob": "^5.0.1",
2627
"postcss": "^4.0.2",
2728
"postcss-message-helpers": "^2.0.0",
2829
"resolve": "^1.0.0",

test/fixtures/glob.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
@import "./foobar*.css";

test/fixtures/glob.expected.css

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
foobar{}
2+
foobarbaz{}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
@import "./missing*.css";
2+
@import "foobar.css";

test/index.js

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@ test("@import", function(t) {
3636

3737
compareFixtures(t, "ignore", "should ignore & adjust external import")
3838

39+
compareFixtures(t, "glob", "should handle a glob pattern", {
40+
path: importsDir,
41+
glob: true
42+
})
43+
3944
compareFixtures(t, "recursive", "should import stylsheets recursively")
4045

4146
compareFixtures(t, "relative", "should import stylsheets relatively")
@@ -75,7 +80,6 @@ test("@import", function(t) {
7580
t.end()
7681
})
7782

78-
7983
test("@import error output", function(t) {
8084
var file = importsDir + "/import-missing.css"
8185
t.throws(
@@ -92,6 +96,20 @@ test("@import error output", function(t) {
9296
t.end()
9397
})
9498

99+
test("@import glob pattern matches no files", function(t) {
100+
var file = importsDir + "/glob-missing.css"
101+
t.equal(
102+
postcss()
103+
.use(atImport({glob: true}))
104+
.process(fs.readFileSync(file), {from: file})
105+
.css.trim(),
106+
"foobar{}",
107+
"should fail silently, skipping the globbed import, if no files found"
108+
)
109+
110+
t.end()
111+
})
112+
95113
test("@import sourcemap", function(t) {
96114
t.equal(
97115
postcss()

0 commit comments

Comments
 (0)