Commit 7ad1e38e authored by Devon Carew's avatar Devon Carew

Fix windows crash (#3236)

* better messaging about windows support

* fix lints
parent 26906240
...@@ -34,7 +34,7 @@ GOTO :after_snapshot ...@@ -34,7 +34,7 @@ GOTO :after_snapshot
CD "%flutter_tools_dir%" CD "%flutter_tools_dir%"
ECHO Updating flutter tool... ECHO Updating flutter tool...
CALL pub.bat get CALL pub.bat get
CD "%flutter_dir" CD "%flutter_dir%"
REM Allows us to check if sky_engine's REVISION is correct REM Allows us to check if sky_engine's REVISION is correct
CALL pub.bat get CALL pub.bat get
CD "%flutter_root%" CD "%flutter_root%"
......
...@@ -6,7 +6,6 @@ import 'dart:io'; ...@@ -6,7 +6,6 @@ import 'dart:io';
import 'package:path/path.dart' as path; import 'package:path/path.dart' as path;
import 'base/process.dart';
import 'build_configuration.dart'; import 'build_configuration.dart';
import 'globals.dart'; import 'globals.dart';
...@@ -216,10 +215,12 @@ class ArtifactStore { ...@@ -216,10 +215,12 @@ class ArtifactStore {
File cachedFile = new File( File cachedFile = new File(
path.join(_getBaseCacheDir().path, 'engine', artifact.platform, artifact.fileName) path.join(_getBaseCacheDir().path, 'engine', artifact.platform, artifact.fileName)
); );
if (!cachedFile.existsSync()) { if (!cachedFile.existsSync()) {
printError('File not found in the platform artifacts: ${cachedFile.path}'); printError('File not found in the platform artifacts: ${cachedFile.path}');
throw new ProcessExit(2); return null;
} else {
return cachedFile.path;
} }
return cachedFile.path;
} }
} }
...@@ -6,10 +6,13 @@ import 'dart:async'; ...@@ -6,10 +6,13 @@ import 'dart:async';
import 'dart:io'; import 'dart:io';
final _AnsiTerminal _terminal = new _AnsiTerminal(); final _AnsiTerminal _terminal = new _AnsiTerminal();
final String _sep = Platform.isWindows ? '-' : '•';
abstract class Logger { abstract class Logger {
bool get isVerbose => false; bool get isVerbose => false;
String get separator => _sep;
/// Display an error level message to the user. Commands should use this if they /// Display an error level message to the user. Commands should use this if they
/// fail in some way. /// fail in some way.
void printError(String message, [StackTrace stackTrace]); void printError(String message, [StackTrace stackTrace]);
...@@ -34,7 +37,7 @@ class Status { ...@@ -34,7 +37,7 @@ class Status {
void cancel() { } void cancel() { }
} }
class StdoutLogger implements Logger { class StdoutLogger extends Logger {
Status _status; Status _status;
@override @override
...@@ -79,7 +82,7 @@ class StdoutLogger implements Logger { ...@@ -79,7 +82,7 @@ class StdoutLogger implements Logger {
void flush() { } void flush() { }
} }
class BufferLogger implements Logger { class BufferLogger extends Logger {
@override @override
bool get isVerbose => false; bool get isVerbose => false;
...@@ -110,7 +113,7 @@ class BufferLogger implements Logger { ...@@ -110,7 +113,7 @@ class BufferLogger implements Logger {
void flush() { } void flush() { }
} }
class VerboseLogger implements Logger { class VerboseLogger extends Logger {
_LogMessage lastMessage; _LogMessage lastMessage;
@override @override
...@@ -170,10 +173,10 @@ class _LogMessage { ...@@ -170,10 +173,10 @@ class _LogMessage {
stopwatch.stop(); stopwatch.stop();
int millis = stopwatch.elapsedMilliseconds; int millis = stopwatch.elapsedMilliseconds;
String prefix = '${millis.toString().padLeft(4)} ms '; String prefix = '${millis.toString().padLeft(4)} ms $_sep ';
String indent = ''.padLeft(prefix.length); String indent = ''.padLeft(prefix.length);
if (millis >= 100) if (millis >= 100)
prefix = _terminal.writeBold(prefix.substring(0, prefix.length - 3)) + ' '; prefix = _terminal.writeBold(prefix.substring(0, prefix.length - 3)) + ' $_sep ';
String indentMessage = message.replaceAll('\n', '\n$indent'); String indentMessage = message.replaceAll('\n', '\n$indent');
if (type == _LogType.error) { if (type == _LogType.error) {
...@@ -190,6 +193,7 @@ class _LogMessage { ...@@ -190,6 +193,7 @@ class _LogMessage {
class _AnsiTerminal { class _AnsiTerminal {
_AnsiTerminal() { _AnsiTerminal() {
// TODO(devoncarew): This detection does not work for Windows.
String term = Platform.environment['TERM']; String term = Platform.environment['TERM'];
_supportsColor = term != null && term != 'dumb'; _supportsColor = term != null && term != 'dumb';
} }
......
...@@ -5,10 +5,16 @@ ...@@ -5,10 +5,16 @@
import 'dart:async'; import 'dart:async';
import 'dart:io'; import 'dart:io';
import 'package:archive/archive.dart';
import 'package:path/path.dart' as path;
import 'context.dart'; import 'context.dart';
import 'process.dart';
/// Returns [OperatingSystemUtils] active in the current app context (i.e. zone). /// Returns [OperatingSystemUtils] active in the current app context (i.e. zone).
OperatingSystemUtils get os => context[OperatingSystemUtils] ?? (context[OperatingSystemUtils] = new OperatingSystemUtils._()); OperatingSystemUtils get os {
return context[OperatingSystemUtils] ?? (context[OperatingSystemUtils] = new OperatingSystemUtils._());
}
abstract class OperatingSystemUtils { abstract class OperatingSystemUtils {
factory OperatingSystemUtils._() { factory OperatingSystemUtils._() {
...@@ -33,6 +39,8 @@ abstract class OperatingSystemUtils { ...@@ -33,6 +39,8 @@ abstract class OperatingSystemUtils {
/// Return the path (with symlinks resolved) to the given executable, or `null` /// Return the path (with symlinks resolved) to the given executable, or `null`
/// if `which` was not able to locate the binary. /// if `which` was not able to locate the binary.
File which(String execName); File which(String execName);
void unzip(File file, Directory targetDirectory);
} }
class _PosixUtils extends OperatingSystemUtils { class _PosixUtils extends OperatingSystemUtils {
...@@ -53,6 +61,12 @@ class _PosixUtils extends OperatingSystemUtils { ...@@ -53,6 +61,12 @@ class _PosixUtils extends OperatingSystemUtils {
String path = result.stdout.trim().split('\n').first.trim(); String path = result.stdout.trim().split('\n').first.trim();
return new File(new File(path).resolveSymbolicLinksSync()); return new File(new File(path).resolveSymbolicLinksSync());
} }
// unzip -o -q zipfile -d dest
@override
void unzip(File file, Directory targetDirectory) {
runSync(<String>['unzip', '-o', '-q', file.path, '-d', targetDirectory.path]);
}
} }
class _WindowsUtils extends OperatingSystemUtils { class _WindowsUtils extends OperatingSystemUtils {
...@@ -66,7 +80,26 @@ class _WindowsUtils extends OperatingSystemUtils { ...@@ -66,7 +80,26 @@ class _WindowsUtils extends OperatingSystemUtils {
@override @override
File which(String execName) { File which(String execName) {
throw new UnimplementedError('_WindowsUtils.which'); ProcessResult result = Process.runSync('where', <String>[execName]);
if (result.exitCode != 0)
return null;
return new File(result.stdout.trim().split('\n').first.trim());
}
@override
void unzip(File file, Directory targetDirectory) {
Archive archive = new ZipDecoder().decodeBytes(file.readAsBytesSync());
for (ArchiveFile archiveFile in archive.files) {
// The archive package doesn't correctly set isFile.
if (!archiveFile.isFile || archiveFile.name.endsWith('/'))
continue;
File destFile = new File(path.join(targetDirectory.path, archiveFile.name));
if (!destFile.parent.existsSync())
destFile.parent.createSync(recursive: true);
destFile.writeAsBytesSync(archiveFile.content);
}
} }
} }
......
...@@ -11,7 +11,6 @@ import 'artifacts.dart'; ...@@ -11,7 +11,6 @@ import 'artifacts.dart';
import 'base/context.dart'; import 'base/context.dart';
import 'base/logger.dart'; import 'base/logger.dart';
import 'base/os.dart'; import 'base/os.dart';
import 'base/process.dart';
import 'globals.dart'; import 'globals.dart';
/// A warpper around the `bin/cache/` directory. /// A warpper around the `bin/cache/` directory.
...@@ -129,8 +128,7 @@ class Cache { ...@@ -129,8 +128,7 @@ class Cache {
File tempFile = new File(path.join(Directory.systemTemp.path, '${url.toString().hashCode}.zip')); File tempFile = new File(path.join(Directory.systemTemp.path, '${url.toString().hashCode}.zip'));
tempFile.writeAsBytesSync(fileBytes, flush: true); tempFile.writeAsBytesSync(fileBytes, flush: true);
// unzip -o -q zipfile -d dest os.unzip(tempFile, location);
runSync(<String>['unzip', '-o', '-q', tempFile.path, '-d', location.path]);
tempFile.deleteSync(); tempFile.deleteSync();
} else { } else {
(location as File).writeAsBytesSync(fileBytes, flush: true); (location as File).writeAsBytesSync(fileBytes, flush: true);
......
...@@ -527,7 +527,7 @@ class AnalyzeCommand extends FlutterCommand { ...@@ -527,7 +527,7 @@ class AnalyzeCommand extends FlutterCommand {
String files = '${analyzedPaths.length} ${pluralize('file', analyzedPaths.length)}'; String files = '${analyzedPaths.length} ${pluralize('file', analyzedPaths.length)}';
String seconds = (analysisTimer.elapsedMilliseconds / 1000.0).toStringAsFixed(2); String seconds = (analysisTimer.elapsedMilliseconds / 1000.0).toStringAsFixed(2);
printStatus('$errorsMessage analyzed $files, $seconds seconds'); printStatus('$errorsMessage ${logger.separator} analyzed $files, $seconds seconds');
firstAnalysis = false; firstAnalysis = false;
} }
...@@ -807,6 +807,7 @@ class AnalysisError implements Comparable<AnalysisError> { ...@@ -807,6 +807,7 @@ class AnalysisError implements Comparable<AnalysisError> {
@override @override
String toString() { String toString() {
String relativePath = path.relative(file); String relativePath = path.relative(file);
return '${severity.toLowerCase().padLeft(7)}$message$relativePath:$startLine:$startColumn'; String sep = logger.separator;
return '${severity.toLowerCase().padLeft(7)} $sep $message $sep $relativePath:$startLine:$startColumn';
} }
} }
...@@ -223,8 +223,8 @@ abstract class Device { ...@@ -223,8 +223,8 @@ abstract class Device {
for (Device device in devices) { for (Device device in devices) {
String supportIndicator = device.isSupported() ? '' : ' (unsupported)'; String supportIndicator = device.isSupported() ? '' : ' (unsupported)';
printStatus('${device.name.padRight(nameWidth)} ' printStatus('${device.name.padRight(nameWidth)} ${logger.separator} '
'${device.id.padRight(idWidth)} ' '${device.id.padRight(idWidth)} ${logger.separator} '
'${getNameForTargetPlatform(device.platform)}$supportIndicator'); '${getNameForTargetPlatform(device.platform)}$supportIndicator');
} }
} }
......
...@@ -109,11 +109,13 @@ class Doctor { ...@@ -109,11 +109,13 @@ class Doctor {
else else
printStatus('${result.leadingBox} ${validator.title}'); printStatus('${result.leadingBox} ${validator.title}');
final String separator = Platform.isWindows ? ' ' : logger.separator;
for (ValidationMessage message in result.messages) { for (ValidationMessage message in result.messages) {
if (message.isError) { if (message.isError) {
printStatus(' x ${message.message.replaceAll('\n', '\n ')}'); printStatus(' x ${message.message.replaceAll('\n', '\n ')}');
} else { } else {
printStatus(' ${message.message.replaceAll('\n', '\n ')}'); printStatus(' $separator ${message.message.replaceAll('\n', '\n ')}');
} }
} }
} }
...@@ -160,9 +162,9 @@ class ValidationResult { ...@@ -160,9 +162,9 @@ class ValidationResult {
String get leadingBox { String get leadingBox {
if (type == ValidationType.missing) if (type == ValidationType.missing)
return '[ ]'; return '[x]';
else if (type == ValidationType.installed) else if (type == ValidationType.installed)
return '[✓]'; return Platform.isWindows ? '[+]' : '[✓]';
else else
return '[-]'; return '[-]';
} }
...@@ -185,6 +187,7 @@ class _FlutterValidator extends DoctorValidator { ...@@ -185,6 +187,7 @@ class _FlutterValidator extends DoctorValidator {
@override @override
ValidationResult validate() { ValidationResult validate() {
List<ValidationMessage> messages = <ValidationMessage>[]; List<ValidationMessage> messages = <ValidationMessage>[];
ValidationType valid = ValidationType.installed;
FlutterVersion version = FlutterVersion.getVersion(); FlutterVersion version = FlutterVersion.getVersion();
...@@ -195,7 +198,16 @@ class _FlutterValidator extends DoctorValidator { ...@@ -195,7 +198,16 @@ class _FlutterValidator extends DoctorValidator {
'engine revision ${version.engineRevisionShort}' 'engine revision ${version.engineRevisionShort}'
)); ));
return new ValidationResult(ValidationType.installed, messages, if (Platform.isWindows) {
valid = ValidationType.missing;
messages.add(new ValidationMessage.error(
'Flutter tools are not (yet) supported on Windows: '
'https://github.com/flutter/flutter/issues/138.'
));
}
return new ValidationResult(valid, messages,
statusInfo: 'on ${osName()}, channel ${version.channel}'); statusInfo: 'on ${osName()}, channel ${version.channel}');
} }
} }
...@@ -247,7 +259,9 @@ class _AtomValidator extends DoctorValidator { ...@@ -247,7 +259,9 @@ class _AtomValidator extends DoctorValidator {
} }
return new ValidationResult( return new ValidationResult(
installCount == 2 ? ValidationType.installed : installCount == 1 ? ValidationType.partial : ValidationType.missing, installCount == 2
? ValidationType.installed
: installCount == 1 ? ValidationType.partial : ValidationType.missing,
messages messages
); );
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment