Skip to content

Commit

Permalink
Merge branch 'master' into feature.hwb
Browse files Browse the repository at this point in the history
  • Loading branch information
nex3 committed Oct 28, 2020
2 parents 6c679e1 + 5c3f550 commit 093ff58
Show file tree
Hide file tree
Showing 17 changed files with 120 additions and 181 deletions.
21 changes: 18 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,10 @@ jobs:
# They next need to be rotated April 2021. See
# https://github.com/nodejs/Release.
- &node-tests
name: Node tests | Dart stable | Node stable
# Run on Node 14 until laverdet/node-fibers#445 is fixed.
name: Node tests | Dart stable | Node 14
language: node_js
node_js: node
node_js: v14
install: pub run grinder before-test
script: tool/travis/task/node_tests.sh
- <<: *node-tests
Expand All @@ -90,7 +91,7 @@ jobs:
- <<: *node-tests
os: osx
- <<: *node-tests
name: Node tests | Dart dev | Node stable
name: Node tests | Dart dev | Node 14
env: DART_CHANNEL=dev

# Miscellaneous checks.
Expand Down Expand Up @@ -181,6 +182,20 @@ jobs:
skip_cleanup: true
on: {tags: true}

# Deploy to Chocolatey.
- name: Chocolatey
if: *deploy-if
os: windows
env:
# CHOCOLATEY_TOKEN="..."
- secure: "EnII3YAGESEl9g9rQDcrL1Sw9eww80VJP0qZHz8Da07GB0hUrDQBJ372Zs2A4qaH/GOm7cknszEPOnkE4w3IBwe5idj31Q+WJbcvqqAB1gex3bLYyStdHeohculqmPgpuEPD3yVT59viJIn6L9+GEKNtnCygDpgxMilXzDIXi6vtLqovJc6q09i7XCSnf2IVjzKv0VBSUV0lU9QOZui5/zLN0sCSzE8QKYj0QSoQ8Th3ZTuWn3/CtRYhIaw4/12oepHyXRvieMeNGnhv8O4d1lAOiXKn28COJWA+xvCOZSxIrBCc0k8VzanYftTcp1Zf0Lxkm0ObmFXWaoHATFWjkvW6G34kQrzRpUlWUMmxIxBukHc2ZFuGnVi6pL9ANI8BVh6m8M1ojRqtKCFvBbgDDdxD7qqBQSfdtssEL+m6O0U9A5/xnQxHPbuyL/Y9ww9p/ohEFaaF3MK/qjiWKQJR+TXspmNDBhFC+w2vQ6zetEx787V6POS8ma5MX1+WWOecDtaDuEMv4bzjkTuYk9tuBC4GR/KrdUNbFtcNXCk5To4Du4FBdOW/+yoVg+ZHtgOzSDehgMJMeFM2fTYNt55iwmjwDyS4XcqsWoHHCDMEhIcuXL5XV5VBENFgs98EGofja70Lp05oLH2W7100OuyG0H18lpECx15OXSFnHQh+91g="
script: skip
deploy:
provider: script
script: pub run grinder pkg-chocolatey-deploy
skip_cleanup: true
on: {tags: true}

# Redeploy sass-lang.com.
- name: sass-lang.com
if: *deploy-if
Expand Down
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,18 @@

[HWB]: https://en.wikipedia.org/wiki/HWB_color_model

## 1.27.1

* **Potentially breaking bug fix:** `meta.load-css()` now correctly uses the
name `$url` for its first argument, rather than `$module`.

* Don't crash when using `Infinity` or `NaN` as a key in a map.

* Emit a proper parse error for a `=` with no right-hand side in a function.

* Avoid going exponential on certain recursive `@extend` edge cases.
>>>>>>> master
## 1.27.0

* Adds an overload to `map.merge()` that supports merging a nested map.
Expand Down
18 changes: 14 additions & 4 deletions lib/src/extend/extender.dart
Original file line number Diff line number Diff line change
Expand Up @@ -684,10 +684,20 @@ class Extender {
.toList();
});

return unifiedPaths
.where((complexes) => complexes != null)
.expand((l) => l)
.toList();
// If we're preserving the original selector, mark the first unification as
// such so [_trim] doesn't get rid of it.
var isOriginal = (ComplexSelector _) => false;
if (inOriginal && _mode != ExtendMode.replace) {
var original = unifiedPaths.first.first;
isOriginal = (complex) => complex == original;
}

return _trim(
unifiedPaths
.where((complexes) => complexes != null)
.expand((l) => l)
.toList(),
isOriginal);
}

Iterable<List<Extension>> _extendSimple(
Expand Down
134 changes: 34 additions & 100 deletions lib/src/io/node.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,63 +7,16 @@ import 'dart:convert';
import 'dart:js_util';

import 'package:js/js.dart';
import 'package:node_interop/fs.dart';
import 'package:node_interop/node_interop.dart';
import 'package:node_interop/stream.dart';
import 'package:path/path.dart' as p;
import 'package:source_span/source_span.dart';
import 'package:watcher/watcher.dart';

import '../exception.dart';
import '../node/chokidar.dart';

@JS()
class _FS {
external Object readFileSync(String path, [String encoding]);
external void writeFileSync(String path, String data);
external bool existsSync(String path);
external void mkdirSync(String path);
external _Stat statSync(String path);
external void unlinkSync(String path);
external List<Object> readdirSync(String path);
}

@JS()
class _Stat {
external bool isFile();
external bool isDirectory();
external _Date get mtime;
}

@JS()
class _Date {
external int getTime();
}

@JS()
class _Stderr {
external void write(String text);
}

@JS()
class _Stdin {
external String read();

external void on(String event, void callback([Object object]));
}

@JS()
class _SystemError {
external String get message;
external String get code;
external String get syscall;
external String get path;
}

@JS()
class _Process {
external String get platform;
external Object get env;
external String cwd();
}

class FileSystemException {
final String message;
final String path;
Expand All @@ -74,7 +27,7 @@ class FileSystemException {
}

class Stderr {
final _Stderr _stderr;
final Writable _stderr;

Stderr(this._stderr);

Expand All @@ -87,12 +40,6 @@ class Stderr {
void flush() {}
}

@JS("fs")
external _FS get _fs;

@JS("process")
external _Process get _process;

String readFile(String path) {
// TODO(nweiz): explicitly decode the bytes as UTF-8 like we do in the VM when
// it doesn't cause a substantial performance degradation for large files. See
Expand All @@ -112,13 +59,13 @@ String readFile(String path) {

/// Wraps `fs.readFileSync` to throw a [FileSystemException].
Object _readFile(String path, [String encoding]) =>
_systemErrorToFileSystemException(() => _fs.readFileSync(path, encoding));
_systemErrorToFileSystemException(() => fs.readFileSync(path, encoding));

void writeFile(String path, String contents) =>
_systemErrorToFileSystemException(() => _fs.writeFileSync(path, contents));
_systemErrorToFileSystemException(() => fs.writeFileSync(path, contents));

void deleteFile(String path) =>
_systemErrorToFileSystemException(() => _fs.unlinkSync(path));
_systemErrorToFileSystemException(() => fs.unlinkSync(path));

Future<String> readStdin() async {
var completer = Completer<String>();
Expand All @@ -129,16 +76,16 @@ Future<String> readStdin() async {
});
// Node defaults all buffers to 'utf8'.
var sink = utf8.decoder.startChunkedConversion(innerSink);
_stdin.on('data', allowInterop(([chunk]) {
process.stdin.on('data', allowInterop(([Object chunk]) {
assert(chunk != null);
sink.add(chunk as List<int>);
}));
_stdin.on('end', allowInterop(([_]) {
process.stdin.on('end', allowInterop(([Object _]) {
// Callback for 'end' receives no args.
assert(_ == null);
sink.close();
}));
_stdin.on('error', allowInterop(([e]) {
process.stdin.on('error', allowInterop(([Object e]) {
assert(e != null);
stderr.writeln('Failed to read from stdin');
stderr.writeln(e);
Expand All @@ -148,7 +95,7 @@ Future<String> readStdin() async {
}

/// Cleans up a Node system error's message.
String _cleanErrorMessage(_SystemError error) {
String _cleanErrorMessage(JsSystemError error) {
// The error message is of the form "$code: $text, $syscall '$path'". We just
// want the text.
return error.message.substring("${error.code}: ".length,
Expand All @@ -161,12 +108,12 @@ bool fileExists(String path) {
// whether the entity in question is a file or a directory. Since false
// negatives are much more common than false positives, it works out in our
// favor to check this first.
if (!_fs.existsSync(path)) return false;
if (!fs.existsSync(path)) return false;

try {
return _fs.statSync(path).isFile();
return fs.statSync(path).isFile();
} catch (error) {
var systemError = error as _SystemError;
var systemError = error as JsSystemError;
if (systemError.code == 'ENOENT') return false;
rethrow;
}
Expand All @@ -179,12 +126,12 @@ bool dirExists(String path) {
// whether the entity in question is a file or a directory. Since false
// negatives are much more common than false positives, it works out in our
// favor to check this first.
if (!_fs.existsSync(path)) return false;
if (!fs.existsSync(path)) return false;

try {
return _fs.statSync(path).isDirectory();
return fs.statSync(path).isDirectory();
} catch (error) {
var systemError = error as _SystemError;
var systemError = error as JsSystemError;
if (systemError.code == 'ENOENT') return false;
rethrow;
}
Expand All @@ -194,27 +141,27 @@ bool dirExists(String path) {
void ensureDir(String path) {
return _systemErrorToFileSystemException(() {
try {
_fs.mkdirSync(path);
fs.mkdirSync(path);
} catch (error) {
var systemError = error as _SystemError;
var systemError = error as JsSystemError;
if (systemError.code == 'EEXIST') return;
if (systemError.code != 'ENOENT') rethrow;
ensureDir(p.dirname(path));
_fs.mkdirSync(path);
fs.mkdirSync(path);
}
});
}

Iterable<String> listDir(String path, {bool recursive = false}) {
return _systemErrorToFileSystemException(() {
if (!recursive) {
return _fs
return fs
.readdirSync(path)
.map((child) => p.join(path, child as String))
.where((child) => !dirExists(child));
} else {
Iterable<String> list(String parent) =>
_fs.readdirSync(parent).expand((child) {
fs.readdirSync(parent).expand((child) {
var path = p.join(parent, child as String);
return dirExists(path) ? list(path) : [path];
});
Expand All @@ -225,55 +172,42 @@ Iterable<String> listDir(String path, {bool recursive = false}) {
}

DateTime modificationTime(String path) =>
_systemErrorToFileSystemException(() => DateTime.fromMillisecondsSinceEpoch(
_fs.statSync(path).mtime.getTime()));
_systemErrorToFileSystemException(() =>
DateTime.fromMillisecondsSinceEpoch(fs.statSync(path).mtime.getTime()));

String getEnvironmentVariable(String name) =>
getProperty(_process.env, name) as String;
getProperty(process.env, name) as String;

/// Runs callback and converts any [_SystemError]s it throws into
/// Runs callback and converts any [JsSystemError]s it throws into
/// [FileSystemException]s.
T _systemErrorToFileSystemException<T>(T callback()) {
try {
return callback();
} catch (error) {
var systemError = error as _SystemError;
var systemError = error as JsSystemError;
throw FileSystemException._(
_cleanErrorMessage(systemError), systemError.path);
}
}

@JS("process.stderr")
external _Stderr get _stderr;

final stderr = Stderr(_stderr);
final stderr = Stderr(process.stderr);

@JS("process.stdin")
external _Stdin get _stdin;
bool get hasTerminal => process.stdout.isTTY ?? false;

bool get hasTerminal => _hasTerminal ?? false;
bool get isWindows => process.platform == 'win32';

bool get isWindows => _process.platform == 'win32';

bool get isMacOS => _process.platform == 'darwin';
bool get isMacOS => process.platform == 'darwin';

bool get isNode => true;

// Node seems to support ANSI escapes on all terminals.
bool get supportsAnsiEscapes => hasTerminal;

String get currentPath => _process.cwd();

@JS("process.stdout.isTTY")
external bool get _hasTerminal;
String get currentPath => process.cwd();

@JS("process.exitCode")
external int get exitCode;
int get exitCode => process.exitCode;

// TODO(nweiz): remove this ignore when dart-lang/sdk#39250 is fixed.
// ignore: inference_failure_on_function_return_type
@JS("process.exitCode")
external set exitCode(int code);
set exitCode(int code) => process.exitCode = code;

Future<Stream<WatchEvent>> watchDir(String path, {bool poll = false}) {
var watcher = chokidar.watch(
Expand Down
Loading

0 comments on commit 093ff58

Please sign in to comment.