mirror of
https://github.com/danog/dart-sass.git
synced 2024-11-27 04:34:59 +01:00
Don't consider drive separators to be path-separating colons (#342)
Closes #340
This commit is contained in:
parent
a4b076560c
commit
c26903e30e
@ -1,3 +1,8 @@
|
||||
## 1.5.1
|
||||
|
||||
* Fix a bug where an absolute Windows path would be considered an `input:output`
|
||||
pair.
|
||||
|
||||
## 1.5.0
|
||||
|
||||
* Fix a bug where an importer would be passed an incorrectly-resolved URL when
|
||||
|
@ -3,10 +3,12 @@
|
||||
// https://opensource.org/licenses/MIT.
|
||||
|
||||
import 'package:args/args.dart';
|
||||
import 'package:charcode/charcode.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
|
||||
import '../../sass.dart';
|
||||
import '../io.dart';
|
||||
import '../util/character.dart';
|
||||
import '../util/path.dart';
|
||||
|
||||
/// The parsed and processed command-line options for the Sass executable.
|
||||
@ -180,12 +182,18 @@ class ExecutableOptions {
|
||||
var colonArgs = false;
|
||||
var positionalArgs = false;
|
||||
for (var argument in _options.rest) {
|
||||
if (argument.isEmpty) {
|
||||
_fail('Invalid argument "".');
|
||||
} else if (argument.contains(":")) {
|
||||
colonArgs = true;
|
||||
} else {
|
||||
if (argument.isEmpty) _fail('Invalid argument "".');
|
||||
|
||||
// If the colon appears at position 1, treat it as a Windows drive
|
||||
// letter.
|
||||
if (!argument.contains(":") ||
|
||||
(_isWindowsPath(argument, 0) &&
|
||||
// Look for colons after index 1, since that's where the drive
|
||||
// letter is on Windows paths.
|
||||
argument.indexOf(":", 2) == -1)) {
|
||||
positionalArgs = true;
|
||||
} else {
|
||||
colonArgs = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -220,14 +228,26 @@ class ExecutableOptions {
|
||||
var seen = new Set<String>();
|
||||
var sourcesToDestinations = <String, String>{};
|
||||
for (var argument in _options.rest) {
|
||||
var components = argument.split(":");
|
||||
if (components.length > 2) {
|
||||
_fail('"$argument" may only contain one ":".');
|
||||
}
|
||||
assert(components.length == 2);
|
||||
String source;
|
||||
String destination;
|
||||
for (var i = 0; i < argument.length; i++) {
|
||||
// A colon at position 1 may be a Windows drive letter and not a
|
||||
// separator.
|
||||
if (i == 1 && _isWindowsPath(argument, i - 1)) continue;
|
||||
|
||||
if (argument.codeUnitAt(i) == $colon) {
|
||||
if (source == null) {
|
||||
source = argument.substring(0, i);
|
||||
destination = argument.substring(i + 1);
|
||||
} else if (i != source.length + 2 ||
|
||||
!_isWindowsPath(argument, i - 1)) {
|
||||
// A colon 2 character after the separator may also be a Windows
|
||||
// drive letter.
|
||||
_fail('"$argument" may only contain one ":".');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var source = components.first;
|
||||
var destination = components.last;
|
||||
if (!seen.add(source)) {
|
||||
_fail('Duplicate source "${source}".');
|
||||
}
|
||||
@ -246,6 +266,12 @@ class ExecutableOptions {
|
||||
|
||||
Map<String, String> _sourcesToDestinations;
|
||||
|
||||
/// Returns whether [string] contains an absolute Windows path at [index].
|
||||
bool _isWindowsPath(String string, int index) =>
|
||||
string.length > index + 2 &&
|
||||
isAlphabetic(string.codeUnitAt(index)) &&
|
||||
string.codeUnitAt(index + 1) == $colon;
|
||||
|
||||
/// Returns the sub-map of [sourcesToDestinations] for the given [source] and
|
||||
/// [destination] directories.
|
||||
Map<String, String> _listSourceDirectory(String source, String destination) {
|
||||
|
@ -6,7 +6,6 @@ import 'package:source_span/source_span.dart';
|
||||
import 'package:stack_trace/stack_trace.dart';
|
||||
|
||||
import 'logger/stderr.dart';
|
||||
import 'util/path.dart';
|
||||
|
||||
/// An interface for loggers that print messages produced by Sass stylesheets.
|
||||
///
|
||||
|
@ -1,5 +1,5 @@
|
||||
name: sass
|
||||
version: 1.5.0
|
||||
version: 1.5.1
|
||||
description: A Sass implementation in Dart.
|
||||
author: Dart Team <misc@dartlang.org>
|
||||
homepage: https://github.com/sass/dart-sass
|
||||
|
@ -8,6 +8,8 @@ import 'package:test/test.dart';
|
||||
import 'package:test_descriptor/test_descriptor.dart' as d;
|
||||
import 'package:test_process/test_process.dart';
|
||||
|
||||
import 'package:sass/src/util/path.dart';
|
||||
|
||||
/// Defines test that are shared between the Dart and Node.js CLI test suites.
|
||||
void sharedTests(Future<TestProcess> runSass(Iterable<String> arguments)) {
|
||||
/// Runs the executable on [arguments] plus an output file, then verifies that
|
||||
@ -43,6 +45,22 @@ void sharedTests(Future<TestProcess> runSass(Iterable<String> arguments)) {
|
||||
await sass.shouldExit(0);
|
||||
});
|
||||
|
||||
// On Windows, this verifies that we don't consider the colon after a drive
|
||||
// letter to be an `input:output` separator.
|
||||
test("compiles an absolute Sass file to CSS", () async {
|
||||
await d.file("test.scss", "a {b: 1 + 2}").create();
|
||||
|
||||
var sass = await runSass([p.absolute(p.join(d.sandbox, "test.scss"))]);
|
||||
expect(
|
||||
sass.stdout,
|
||||
emitsInOrder([
|
||||
"a {",
|
||||
" b: 3;",
|
||||
"}",
|
||||
]));
|
||||
await sass.shouldExit(0);
|
||||
});
|
||||
|
||||
test("writes a CSS file to disk", () async {
|
||||
await d.file("test.scss", "a {b: 1 + 2}").create();
|
||||
|
||||
|
@ -8,6 +8,8 @@ import 'package:test/test.dart';
|
||||
import 'package:test_descriptor/test_descriptor.dart' as d;
|
||||
import 'package:test_process/test_process.dart';
|
||||
|
||||
import 'package:sass/src/util/path.dart';
|
||||
|
||||
/// Defines test that are shared between the Dart and Node.js CLI test suites.
|
||||
void sharedTests(Future<TestProcess> runSass(Iterable<String> arguments)) {
|
||||
test("compiles multiple sources to multiple destinations", () async {
|
||||
@ -27,6 +29,20 @@ void sharedTests(Future<TestProcess> runSass(Iterable<String> arguments)) {
|
||||
.validate();
|
||||
});
|
||||
|
||||
// On Windows, this verifies that we don't consider the colon after a drive
|
||||
// letter to be an `input:output` separator.
|
||||
test("compiles an absolute source to an absolute destination", () async {
|
||||
await d.file("test.scss", "a {b: c}").create();
|
||||
|
||||
var input = p.absolute(p.join(d.sandbox, 'test.scss'));
|
||||
var output = p.absolute(p.join(d.sandbox, 'out.css'));
|
||||
var sass = await runSass(["--no-source-map", "$input:$output"]);
|
||||
expect(sass.stdout, emitsDone);
|
||||
await sass.shouldExit(0);
|
||||
|
||||
await d.file("out.css", equalsIgnoringWhitespace("a { b: c; }")).validate();
|
||||
});
|
||||
|
||||
test("creates destination directories", () async {
|
||||
await d.file("test.scss", "a {b: c}").create();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user