Skip to content

Commit 3392db0

Browse files
authored
Don't compile .css files in directories to themselves (#862)
This also adds support for compiling .css files in directories *at all*, which had previously only worked in --watch mode. Closes #853
1 parent 0ea2e0d commit 3392db0

File tree

7 files changed

+69
-9
lines changed

7 files changed

+69
-9
lines changed

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
## 1.23.2
2+
3+
### Command-Line Interface
4+
5+
* Fix a bug when compiling all Sass files in a directory where a CSS file could
6+
be compiled to its own location, creating an infinite loop in `--watch` mode.
7+
8+
* Properly compile CSS entrypoints in directories outside of `--watch` mode.
9+
110
## 1.23.1
211

312
* Fix a bug preventing built-in modules from being loaded within a configured

lib/src/executable/options.dart

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,9 @@ class ExecutableOptions {
373373
Map<String, String> _listSourceDirectory(String source, String destination) {
374374
return {
375375
for (var path in listDir(source, recursive: true))
376-
if (_isEntrypoint(path))
376+
if (_isEntrypoint(path) &&
377+
// Don't compile a CSS file to its own location.
378+
!(source == destination && p.extension(path) == '.css'))
377379
path: p.join(destination,
378380
p.setExtension(p.relative(path, from: source), '.css'))
379381
};
@@ -383,7 +385,7 @@ class ExecutableOptions {
383385
bool _isEntrypoint(String path) {
384386
if (p.basename(path).startsWith("_")) return false;
385387
var extension = p.extension(path);
386-
return extension == ".scss" || extension == ".sass";
388+
return extension == ".scss" || extension == ".sass" || extension == ".css";
387389
}
388390

389391
/// Whether to emit a source map file.

lib/src/executable/watch.dart

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -267,10 +267,14 @@ class _Watcher {
267267
if (p.basename(source).startsWith('_')) return null;
268268

269269
for (var sourceDir in _options.sourceDirectoriesToDestinations.keys) {
270-
if (p.isWithin(sourceDir, source)) {
271-
return p.join(_options.sourceDirectoriesToDestinations[sourceDir],
272-
p.setExtension(p.relative(source, from: sourceDir), '.css'));
273-
}
270+
if (!p.isWithin(sourceDir, source)) continue;
271+
272+
var destination = p.join(
273+
_options.sourceDirectoriesToDestinations[sourceDir],
274+
p.setExtension(p.relative(source, from: sourceDir), '.css'));
275+
276+
// Don't compile ".css" files to their own locations.
277+
if (destination != source) return destination;
274278
}
275279

276280
return null;

pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: sass
2-
version: 1.23.1
2+
version: 1.23.2
33
description: A Sass implementation in Dart.
44
author: Sass Team
55
homepage: https://github.com/sass/dart-sass

test/cli/shared/colon_args.dart

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,8 @@ void sharedTests(Future<TestProcess> runSass(Iterable<String> arguments)) {
106106
test("compiles all the stylesheets in the directory", () async {
107107
await d.dir("in", [
108108
d.file("test1.scss", "a {b: c}"),
109-
d.file("test2.sass", "x\n y: z")
109+
d.file("test2.sass", "x\n y: z"),
110+
d.file("test3.css", "q {r: s}")
110111
]).create();
111112

112113
var sass = await runSass(["--no-source-map", "in:out"]);
@@ -115,7 +116,8 @@ void sharedTests(Future<TestProcess> runSass(Iterable<String> arguments)) {
115116

116117
await d.dir("out", [
117118
d.file("test1.css", equalsIgnoringWhitespace("a { b: c; }")),
118-
d.file("test2.css", equalsIgnoringWhitespace("x { y: z; }"))
119+
d.file("test2.css", equalsIgnoringWhitespace("x { y: z; }")),
120+
d.file("test3.css", equalsIgnoringWhitespace("q { r: s; }"))
119121
]).validate();
120122
});
121123

@@ -183,6 +185,16 @@ void sharedTests(Future<TestProcess> runSass(Iterable<String> arguments)) {
183185
d.nothing("fake.css")
184186
]).validate();
185187
});
188+
189+
test("ignores a CSS file that would compile to itself", () async {
190+
await d.dir("dir", [d.file("test.css", "a {b: c}")]).create();
191+
192+
var sass = await runSass(["dir:dir"]);
193+
expect(sass.stdout, emitsDone);
194+
await sass.shouldExit(0);
195+
196+
await d.file("dir/test.css", "a {b: c}").validate();
197+
});
186198
});
187199

188200
group("reports all", () {

test/cli/shared/update.dart

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,16 @@ void sharedTests(Future<TestProcess> runSass(Iterable<String> arguments)) {
175175

176176
await d.file("out.css", contains(message)).validate();
177177
});
178+
179+
test("from itself", () async {
180+
await d.dir("dir", [d.file("test.css", "a {b: c}")]).create();
181+
182+
var sass = await update(["dir:dir"]);
183+
expect(sass.stdout, emitsDone);
184+
await sass.shouldExit(0);
185+
186+
await d.file("dir/test.css", "a {b: c}").validate();
187+
});
178188
});
179189

180190
group("updates a CSS file", () {

test/cli/shared/watch.dart

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -639,6 +639,29 @@ void sharedTests(Future<TestProcess> runSass(Iterable<String> arguments)) {
639639
await d.nothing("out/test.scss").validate();
640640
});
641641

642+
// Regression test for #853.
643+
test("doesn't try to compile a CSS file to itself", () async {
644+
await d.dir("dir").create();
645+
646+
var sass = await watch(["dir:dir"]);
647+
await expectLater(sass.stdout, _watchingForChanges);
648+
await tickIfPoll();
649+
650+
await d.file("dir/test.css", "a {b: c}").create();
651+
await tick;
652+
653+
// Create a new file that *will* be compiled so that if the first change
654+
// did incorrectly trigger a compilation, it would emit a message
655+
// before the message for this change.
656+
await d.file("dir/test2.scss", "x {y: z}").create();
657+
await expectLater(
658+
sass.stdout, emits(_compiled('dir/test2.scss', 'dir/test2.css')));
659+
660+
await sass.kill();
661+
662+
await d.file("dir/test.css", "a {b: c}").validate();
663+
});
664+
642665
group("doesn't allow", () {
643666
test("--stdin", () async {
644667
var sass = await watch(["--stdin", "test.scss"]);

0 commit comments

Comments
 (0)