mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
116 lines
3.1 KiB
Dart
116 lines
3.1 KiB
Dart
// Copyright 2013 The Flutter Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
import 'dart:async';
|
|
import 'dart:io' as io;
|
|
|
|
import 'package:meta/meta.dart';
|
|
import 'package:path/path.dart' as path;
|
|
|
|
import 'environment.dart';
|
|
|
|
class FilePath {
|
|
FilePath.fromCwd(String relativePath)
|
|
: _absolutePath = path.absolute(relativePath);
|
|
FilePath.fromWebUi(String relativePath)
|
|
: _absolutePath = path.join(environment.webUiRootDir.path, relativePath);
|
|
|
|
final String _absolutePath;
|
|
|
|
String get absolute => _absolutePath;
|
|
String get relativeToCwd => path.relative(_absolutePath);
|
|
String get relativeToWebUi =>
|
|
path.relative(_absolutePath, from: environment.webUiRootDir.path);
|
|
|
|
@override
|
|
bool operator ==(dynamic other) {
|
|
return other is FilePath && _absolutePath == other._absolutePath;
|
|
}
|
|
|
|
@override
|
|
String toString() => _absolutePath;
|
|
}
|
|
|
|
/// Runs [executable] merging its output into the current process' standard out and standard error.
|
|
Future<int> runProcess(
|
|
String executable,
|
|
List<String> arguments, {
|
|
String workingDirectory,
|
|
bool mustSucceed: false,
|
|
}) async {
|
|
final io.Process process = await io.Process.start(
|
|
executable,
|
|
arguments,
|
|
workingDirectory: workingDirectory,
|
|
// Running the process in a system shell for Windows. Otherwise
|
|
// the process is not able to get Dart from path.
|
|
runInShell: io.Platform.isWindows,
|
|
mode: io.ProcessStartMode.inheritStdio,
|
|
);
|
|
final int exitCode = await process.exitCode;
|
|
if (mustSucceed && exitCode != 0) {
|
|
throw ProcessException(
|
|
description: 'Sub-process failed.',
|
|
executable: executable,
|
|
arguments: arguments,
|
|
workingDirectory: workingDirectory,
|
|
exitCode: exitCode,
|
|
);
|
|
}
|
|
return exitCode;
|
|
}
|
|
|
|
/// Runs [executable] and returns its standard output as a string.
|
|
///
|
|
/// If the process fails, throws a [ProcessException].
|
|
Future<String> evalProcess(
|
|
String executable,
|
|
List<String> arguments, {
|
|
String workingDirectory,
|
|
}) async {
|
|
final io.ProcessResult result = await io.Process.run(
|
|
executable,
|
|
arguments,
|
|
workingDirectory: workingDirectory,
|
|
);
|
|
if (result.exitCode != 0) {
|
|
throw ProcessException(
|
|
description: result.stderr,
|
|
executable: executable,
|
|
arguments: arguments,
|
|
workingDirectory: workingDirectory,
|
|
exitCode: result.exitCode,
|
|
);
|
|
}
|
|
return result.stdout;
|
|
}
|
|
|
|
@immutable
|
|
class ProcessException implements Exception {
|
|
ProcessException({
|
|
@required this.description,
|
|
@required this.executable,
|
|
@required this.arguments,
|
|
@required this.workingDirectory,
|
|
@required this.exitCode,
|
|
});
|
|
|
|
final String description;
|
|
final String executable;
|
|
final List<String> arguments;
|
|
final String workingDirectory;
|
|
final int exitCode;
|
|
|
|
@override
|
|
String toString() {
|
|
final StringBuffer message = StringBuffer();
|
|
message
|
|
..writeln(description)
|
|
..writeln('Command: $executable ${arguments.join(' ')}')
|
|
..writeln('Working directory: ${workingDirectory ?? io.Directory.current.path}')
|
|
..writeln('Exit code: $exitCode');
|
|
return '$message';
|
|
}
|
|
}
|