2016-10-15 02:33:51 +02:00
|
|
|
// Copyright 2016 Google Inc. Use of this source code is governed by an
|
|
|
|
// MIT-style license that can be found in the LICENSE file or at
|
|
|
|
// https://opensource.org/licenses/MIT.
|
|
|
|
|
|
|
|
import 'dart:async';
|
|
|
|
import 'dart:isolate';
|
|
|
|
|
|
|
|
import 'package:args/args.dart';
|
|
|
|
import 'package:stack_trace/stack_trace.dart';
|
|
|
|
import 'package:path/path.dart' as p;
|
|
|
|
|
2016-10-15 03:24:50 +02:00
|
|
|
import '../sass.dart';
|
2016-10-15 02:33:51 +02:00
|
|
|
import 'exception.dart';
|
|
|
|
import 'io.dart';
|
|
|
|
|
2016-11-05 20:46:48 +01:00
|
|
|
main(List<String> args) async {
|
2016-10-15 02:33:51 +02:00
|
|
|
var argParser = new ArgParser(allowTrailingOptions: true)
|
|
|
|
..addOption('precision', hide: true)
|
|
|
|
..addOption('style',
|
|
|
|
abbr: 's',
|
|
|
|
help: 'Output style.',
|
|
|
|
allowed: ['expanded'],
|
|
|
|
defaultsTo: 'expanded')
|
2016-12-03 02:30:09 +01:00
|
|
|
..addFlag('color', abbr: 'c', help: 'Whether to emit terminal colors.')
|
2016-10-15 02:33:51 +02:00
|
|
|
..addFlag('trace', help: 'Print full Dart stack traces for exceptions.')
|
|
|
|
..addFlag('help',
|
|
|
|
abbr: 'h', help: 'Print this usage information.', negatable: false)
|
|
|
|
..addFlag('version',
|
|
|
|
help: 'Print the version of Dart Sass.', negatable: false);
|
|
|
|
var options = argParser.parse(args);
|
|
|
|
|
2016-10-29 00:23:14 +02:00
|
|
|
if (options['version'] as bool) {
|
2016-10-15 02:33:51 +02:00
|
|
|
_loadVersion().then((version) {
|
|
|
|
print(version);
|
2016-11-03 01:57:55 +01:00
|
|
|
exitCode = 0;
|
2016-10-15 02:33:51 +02:00
|
|
|
});
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-10-29 00:23:14 +02:00
|
|
|
if (options['help'] as bool || options.rest.isEmpty) {
|
2016-10-15 02:33:51 +02:00
|
|
|
print("Compile Sass to CSS.\n");
|
2016-10-31 22:51:25 +01:00
|
|
|
print("Usage: dart-sass <input>\n");
|
2016-10-15 02:33:51 +02:00
|
|
|
print(argParser.usage);
|
2016-11-03 01:57:55 +01:00
|
|
|
exitCode = 64;
|
|
|
|
return;
|
2016-10-15 02:33:51 +02:00
|
|
|
}
|
|
|
|
|
2016-12-03 02:30:09 +01:00
|
|
|
var color = (options['color'] as bool) ?? hasTerminal;
|
2016-10-15 02:33:51 +02:00
|
|
|
try {
|
2016-10-29 00:23:14 +02:00
|
|
|
var css = render(options.rest.first, color: color);
|
2016-10-15 02:33:51 +02:00
|
|
|
if (css.isNotEmpty) print(css);
|
|
|
|
} on SassException catch (error, stackTrace) {
|
2016-11-08 21:22:55 +01:00
|
|
|
stderr.writeln("Error: ${error.message}");
|
|
|
|
stderr.writeln(error.span.highlight(color: color));
|
|
|
|
|
|
|
|
var start = error.span.start;
|
|
|
|
if (error is SassRuntimeException) {
|
|
|
|
var firstFrame = error.trace.frames.first;
|
|
|
|
if (start.sourceUrl != firstFrame.uri ||
|
|
|
|
start.line + 1 != firstFrame.line ||
|
|
|
|
start.column + 1 != firstFrame.column) {
|
|
|
|
stderr.writeln(
|
|
|
|
" ${start.sourceUrl} ${start.line + 1}:${start.column + 1}");
|
|
|
|
}
|
|
|
|
|
|
|
|
for (var frame in error.trace.toString().split("\n")) {
|
|
|
|
if (frame.isEmpty) continue;
|
|
|
|
stderr.writeln(" $frame");
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
stderr.writeln(
|
|
|
|
" ${start.sourceUrl} ${start.line + 1}:${start.column + 1}");
|
|
|
|
}
|
2016-10-15 02:33:51 +02:00
|
|
|
|
2016-10-29 00:23:14 +02:00
|
|
|
if (options['trace'] as bool) {
|
2016-10-15 02:33:51 +02:00
|
|
|
stderr.writeln();
|
2016-10-19 23:53:46 +02:00
|
|
|
stderr.write(new Trace.from(stackTrace).terse.toString());
|
2016-10-15 02:33:51 +02:00
|
|
|
stderr.flush();
|
|
|
|
}
|
|
|
|
|
2016-10-19 02:12:04 +02:00
|
|
|
// Exit code 65 indicates invalid data per
|
|
|
|
// http://www.freebsd.org/cgi/man.cgi?query=sysexits.
|
2016-11-03 01:57:55 +01:00
|
|
|
exitCode = 65;
|
2016-10-19 23:53:46 +02:00
|
|
|
} catch (error, stackTrace) {
|
2016-10-29 00:23:14 +02:00
|
|
|
if (color) stderr.write('\u001b[31m\u001b[1m');
|
2016-10-19 23:53:46 +02:00
|
|
|
stderr.write('Unexpected exception:');
|
2016-10-29 00:23:14 +02:00
|
|
|
if (color) stderr.write('\u001b[0m');
|
2016-10-19 23:53:46 +02:00
|
|
|
stderr.writeln();
|
|
|
|
|
|
|
|
stderr.writeln(error);
|
|
|
|
stderr.writeln();
|
|
|
|
stderr.write(new Trace.from(stackTrace).terse.toString());
|
2016-11-05 20:46:48 +01:00
|
|
|
await stderr.flush();
|
2016-11-03 01:57:55 +01:00
|
|
|
exitCode = 255;
|
2016-10-15 02:33:51 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Loads and returns the current version of Sass.
|
|
|
|
Future<String> _loadVersion() async {
|
|
|
|
var version = const String.fromEnvironment('version');
|
2016-10-29 20:14:16 +02:00
|
|
|
if (const bool.fromEnvironment('node')) {
|
|
|
|
version += " compiled with dart2js "
|
|
|
|
"${const String.fromEnvironment('dart-version')}";
|
|
|
|
}
|
2016-10-15 02:33:51 +02:00
|
|
|
if (version != null) return version;
|
|
|
|
|
|
|
|
var libDir =
|
|
|
|
p.fromUri(await Isolate.resolvePackageUri(Uri.parse('package:sass/')));
|
2017-01-07 06:05:41 +01:00
|
|
|
var pubspec = readFileAsString(p.join(libDir, '..', 'pubspec.yaml'));
|
2016-10-15 02:33:51 +02:00
|
|
|
return pubspec
|
|
|
|
.split("\n")
|
|
|
|
.firstWhere((line) => line.startsWith('version: '))
|
|
|
|
.split(" ")
|
|
|
|
.last;
|
|
|
|
}
|