Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
354e2a57
Unverified
Commit
354e2a57
authored
Oct 12, 2020
by
Jonah Williams
Committed by
GitHub
Oct 12, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Revert "[flutter_tools] fold executable resolution into flutter (#67669)" (#67954)
This reverts commit
10c78c26
.
parent
10c78c26
Changes
15
Show whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
158 additions
and
560 deletions
+158
-560
error_handling_io.dart
packages/flutter_tools/lib/src/base/error_handling_io.dart
+36
-175
os.dart
packages/flutter_tools/lib/src/base/os.dart
+2
-8
process.dart
packages/flutter_tools/lib/src/base/process.dart
+0
-9
context_runner.dart
packages/flutter_tools/lib/src/context_runner.dart
+1
-2
ios_deploy.dart
packages/flutter_tools/lib/src/ios/ios_deploy.dart
+4
-0
build_linux.dart
packages/flutter_tools/lib/src/linux/build_linux.dart
+2
-9
linux_doctor.dart
packages/flutter_tools/lib/src/linux/linux_doctor.dart
+2
-9
xcode.dart
packages/flutter_tools/lib/src/macos/xcode.dart
+8
-0
chrome.dart
packages/flutter_tools/lib/src/web/chrome.dart
+5
-1
build_windows.dart
packages/flutter_tools/lib/src/windows/build_windows.dart
+2
-9
visual_studio.dart
packages/flutter_tools/lib/src/windows/visual_studio.dart
+4
-0
build_linux_test.dart
..._tools/test/commands.shard/hermetic/build_linux_test.dart
+2
-3
error_handling_io_test.dart
...tools/test/general.shard/base/error_handling_io_test.dart
+85
-330
os_test.dart
packages/flutter_tools/test/general.shard/base/os_test.dart
+4
-4
xcode_test.dart
...es/flutter_tools/test/general.shard/macos/xcode_test.dart
+1
-1
No files found.
packages/flutter_tools/lib/src/base/error_handling_io.dart
View file @
354e2a57
...
...
@@ -11,10 +11,7 @@ import 'package:path/path.dart' as p; // ignore: package_path_import
import
'package:process/process.dart'
;
import
'common.dart'
show
throwToolExit
;
import
'io.dart'
;
import
'logger.dart'
;
import
'platform.dart'
;
import
'process.dart'
;
// The Flutter tool hits file system and process errors that only the end-user can address.
// We would like these errors to not hit crash logging. In these cases, we
...
...
@@ -56,11 +53,11 @@ class ErrorHandlingFileSystem extends ForwardingFileSystem {
/// This can be used to bypass the [ErrorHandlingFileSystem] permission exit
/// checks for situations where failure is acceptable, such as the flutter
/// persistent settings cache.
static
T
noExitOnFailure
<
T
>(
T
Function
()
operation
)
{
static
void
noExitOnFailure
(
void
Function
()
operation
)
{
final
bool
previousValue
=
ErrorHandlingFileSystem
.
_noExitOnFailure
;
try
{
ErrorHandlingFileSystem
.
_noExitOnFailure
=
true
;
return
operation
();
operation
();
}
finally
{
ErrorHandlingFileSystem
.
_noExitOnFailure
=
previousValue
;
}
...
...
@@ -504,44 +501,6 @@ T _runSync<T>(T Function() op, {
}
}
/// Type signature for [io.Process.killPid].
typedef
ProcessKillPid
=
bool
Function
(
int
pid
,
[
io
.
ProcessSignal
signal
]);
/// Type signature for [io.Process.run].
typedef
ProcessRun
=
Future
<
io
.
ProcessResult
>
Function
(
String
executable
,
List
<
String
>
arguments
,
{
String
workingDirectory
,
Map
<
String
,
String
>
environment
,
bool
includeParentEnvironment
,
bool
runInShell
,
Encoding
stdoutEncoding
,
Encoding
stderrEncoding
,
});
/// Type signature for [io.Process.runSync].
typedef
ProcessRunSync
=
io
.
ProcessResult
Function
(
String
executable
,
List
<
String
>
arguments
,
{
String
workingDirectory
,
Map
<
String
,
String
>
environment
,
bool
includeParentEnvironment
,
bool
runInShell
,
Encoding
stdoutEncoding
,
Encoding
stderrEncoding
,
});
/// Type signature for [io.Process.start].
typedef
ProcessStart
=
Future
<
io
.
Process
>
Function
(
String
executable
,
List
<
String
>
arguments
,
{
String
workingDirectory
,
Map
<
String
,
String
>
environment
,
bool
includeParentEnvironment
,
bool
runInShell
,
io
.
ProcessStartMode
mode
,
});
/// A [ProcessManager] that throws a [ToolExit] on certain errors.
///
/// If a [ProcessException] is not caused by the Flutter tool, and can only be
...
...
@@ -552,45 +511,26 @@ typedef ProcessStart = Future<io.Process> Function(
/// * [ErrorHandlingFileSystem], for a similar file system strategy.
class
ErrorHandlingProcessManager
extends
ProcessManager
{
ErrorHandlingProcessManager
({
@required
ProcessManager
delegate
,
@required
Platform
platform
,
@required
FileSystem
fileSystem
,
@required
Logger
logger
,
@visibleForTesting
ProcessKillPid
killPid
=
io
.
Process
.
killPid
,
@visibleForTesting
ProcessRun
run
=
io
.
Process
.
run
,
@visibleForTesting
ProcessRunSync
runSync
=
io
.
Process
.
runSync
,
@visibleForTesting
ProcessStart
start
=
io
.
Process
.
start
,
})
:
_platform
=
platform
,
_fileSytem
=
fileSystem
,
_logger
=
logger
,
_killPid
=
killPid
,
_processRun
=
run
,
_processRunSync
=
runSync
,
_processStart
=
start
;
final
Logger
_logger
;
final
FileSystem
_fileSytem
;
final
Platform
_platform
;
final
ProcessKillPid
_killPid
;
final
ProcessRun
_processRun
;
final
ProcessRunSync
_processRunSync
;
final
ProcessStart
_processStart
;
})
:
_delegate
=
delegate
,
_platform
=
platform
;
// Cached executable paths, the first is the working directory, the next is a map from
// executable name to actual path.
final
Map
<
String
,
Map
<
String
,
String
>>
_resolvedExecutables
=
<
String
,
Map
<
String
,
String
>>{};
final
ProcessManager
_delegate
;
final
Platform
_platform
;
@override
bool
canRun
(
dynamic
executable
,
{
String
workingDirectory
})
{
return
_runSync
<
bool
>
(
()
=>
_
getCommandPath
(<
dynamic
>[
executable
],
workingDirectory
,
strict:
true
)
!=
null
,
return
_runSync
(
()
=>
_
delegate
.
canRun
(
executable
,
workingDirectory:
workingDirectory
)
,
platform:
_platform
,
);
}
@override
bool
killPid
(
int
pid
,
[
io
.
ProcessSignal
signal
=
io
.
ProcessSignal
.
sigterm
])
{
return
_runSync
<
bool
>
(
()
=>
_killPid
(
pid
,
signal
),
return
_runSync
(
()
=>
_
delegate
.
killPid
(
pid
,
signal
),
platform:
_platform
,
);
}
...
...
@@ -605,18 +545,15 @@ class ErrorHandlingProcessManager extends ProcessManager {
Encoding
stdoutEncoding
=
io
.
systemEncoding
,
Encoding
stderrEncoding
=
io
.
systemEncoding
,
})
{
return
_run
(()
{
return
_processRun
(
_getCommandPath
(
command
,
workingDirectory
),
_getArguments
(
command
),
return
_run
(()
=>
_delegate
.
run
(
command
,
workingDirectory:
workingDirectory
,
environment:
environment
,
includeParentEnvironment:
includeParentEnvironment
,
runInShell:
runInShell
,
stdoutEncoding:
stdoutEncoding
,
stderrEncoding:
stderrEncoding
,
);
},
platform:
_platform
);
),
platform:
_platform
);
}
@override
...
...
@@ -628,16 +565,13 @@ class ErrorHandlingProcessManager extends ProcessManager {
bool
runInShell
=
false
,
io
.
ProcessStartMode
mode
=
io
.
ProcessStartMode
.
normal
,
})
{
return
_run
(()
{
return
_processStart
(
_getCommandPath
(
command
,
workingDirectory
),
_getArguments
(
command
),
return
_run
(()
=>
_delegate
.
start
(
command
,
workingDirectory:
workingDirectory
,
environment:
environment
,
includeParentEnvironment:
includeParentEnvironment
,
runInShell:
runInShell
,
);
},
platform:
_platform
);
),
platform:
_platform
);
}
@override
...
...
@@ -650,88 +584,15 @@ class ErrorHandlingProcessManager extends ProcessManager {
Encoding
stdoutEncoding
=
io
.
systemEncoding
,
Encoding
stderrEncoding
=
io
.
systemEncoding
,
})
{
return
_runSync
(()
{
return
_processRunSync
(
_getCommandPath
(
command
,
workingDirectory
),
_getArguments
(
command
),
return
_runSync
(()
=>
_delegate
.
runSync
(
command
,
workingDirectory:
workingDirectory
,
environment:
environment
,
includeParentEnvironment:
includeParentEnvironment
,
runInShell:
runInShell
,
stdoutEncoding:
stdoutEncoding
,
stderrEncoding:
stderrEncoding
,
);
},
platform:
_platform
);
}
/// Resolve the first item of [command] to a file or link.
///
/// This function will cache each raw command string per working directory,
/// so that repeated lookups for the same command will resolve to the same
/// executable. If a new executable is installed in a higher priority
/// location after a command has already been cached, the older executable
/// will be used until the tool restarts.
///
/// If the entity cannot be found, return the raw command as is and do not
/// cache it.
String
_getCommandPath
(
List
<
dynamic
>
command
,
String
workingDirectory
,
{
bool
strict
=
false
})
{
final
String
executable
=
command
.
first
.
toString
();
final
Map
<
String
,
String
>
workingDirectoryCache
=
_resolvedExecutables
[
workingDirectory
]
??=
<
String
,
String
>{};
final
String
resolvedExecutable
=
workingDirectoryCache
[
executable
]
??
_which
(
executable
,
workingDirectory
);
if
(
resolvedExecutable
!=
executable
)
{
workingDirectoryCache
[
executable
]
=
resolvedExecutable
;
}
return
resolvedExecutable
;
}
String
_which
(
String
execName
,
String
workingDirectory
)
{
// `where` always returns all matches, not just the first one.
ProcessResult
result
;
try
{
result
=
_processRunSync
(
_platform
.
isWindows
?
'where'
:
'which'
,
<
String
>[
execName
],
workingDirectory:
workingDirectory
,
);
}
on
ProcessException
catch
(
err
)
{
if
(!
isMissingExecutableException
(
err
)
||
!
_platform
.
isWindows
)
{
rethrow
;
}
// `where` could be missing if system32 is not on the PATH.
throwToolExit
(
'Cannot find the executable for `where`. This can happen if the System32 '
'folder (e.g. C:
\\
Windows
\\
System32 ) is removed from the PATH environment '
'variable. Ensure that this is present and then try again after restarting '
'the terminal and/or IDE.'
);
}
if
(
result
.
exitCode
!=
0
)
{
return
execName
;
}
final
List
<
String
>
lines
=
(
result
.
stdout
as
String
).
trim
().
split
(
'
\n
'
);
for
(
final
String
line
in
lines
)
{
final
String
resolvedPath
=
line
.
trim
();
try
{
final
String
candidate
=
ErrorHandlingFileSystem
.
noExitOnFailure
(()
{
if
(
_fileSytem
.
isFileSync
(
resolvedPath
))
{
return
resolvedPath
;
}
return
null
;
});
if
(
candidate
!=
null
)
{
return
candidate
;
}
}
on
Exception
{
// Do nothing and prevent permission issues from causing a tool exit.
}
}
_logger
.
printTrace
(
'Could not resolve executable for
$execName
in
$workingDirectory
.'
);
return
execName
;
}
List
<
String
>
_getArguments
(
List
<
dynamic
>
command
)
{
return
<
String
>[
for
(
dynamic
arg
in
command
.
skip
(
1
))
arg
.
toString
()];
),
platform:
_platform
);
}
}
...
...
packages/flutter_tools/lib/src/base/os.dart
View file @
354e2a57
...
...
@@ -213,10 +213,7 @@ class _PosixUtils extends OperatingSystemUtils {
throwOnError:
true
,
verboseExceptions:
true
,
);
}
on
ProcessException
catch
(
err
)
{
if
(!
isMissingExecutableException
(
err
))
{
rethrow
;
}
}
on
ArgumentError
{
// unzip is not available. this error message is modeled after the download
// error in bin/internal/update_dart_sdk.sh
String
message
=
'Please install unzip.'
;
...
...
@@ -300,10 +297,7 @@ class _WindowsUtils extends OperatingSystemUtils {
ProcessResult
result
;
try
{
result
=
_processManager
.
runSync
(<
String
>[
'where'
,
execName
]);
}
on
ProcessException
catch
(
err
)
{
if
(!
isMissingExecutableException
(
err
))
{
rethrow
;
}
}
on
ArgumentError
{
// `where` could be missing if system32 is not on the PATH.
throwToolExit
(
'Cannot find the executable for `where`. This can happen if the System32 '
...
...
packages/flutter_tools/lib/src/base/process.dart
View file @
354e2a57
...
...
@@ -610,12 +610,3 @@ class _DefaultProcessUtils implements ProcessUtils {
}
}
}
/// Whether the process exception was thrown due to a mising executable.
///
/// On macOS, Linux, and Windows error code 2 indicates a missing file, which
/// means that the process resolution failed to locate the correct
/// executable.
bool
isMissingExecutableException
(
ProcessException
processException
)
{
return
processException
.
errorCode
==
2
;
}
packages/flutter_tools/lib/src/context_runner.dart
View file @
354e2a57
...
...
@@ -223,9 +223,8 @@ Future<T> runInContext<T>(
),
ProcessInfo:
()
=>
ProcessInfo
(),
ProcessManager:
()
=>
ErrorHandlingProcessManager
(
delegate:
const
LocalProcessManager
(),
platform:
globals
.
platform
,
fileSystem:
globals
.
fs
,
logger:
globals
.
logger
,
),
ProcessUtils:
()
=>
ProcessUtils
(
processManager:
globals
.
processManager
,
...
...
packages/flutter_tools/lib/src/ios/ios_deploy.dart
View file @
354e2a57
...
...
@@ -361,6 +361,10 @@ class IOSDeployDebugger {
_logger
.
printTrace
(
'ios-deploy failed:
$exception
'
);
_debuggerState
=
_IOSDeployDebuggerState
.
detached
;
_debuggerOutput
.
addError
(
exception
,
stackTrace
);
}
on
ArgumentError
catch
(
exception
,
stackTrace
)
{
_logger
.
printTrace
(
'ios-deploy failed:
$exception
'
);
_debuggerState
=
_IOSDeployDebuggerState
.
detached
;
_debuggerOutput
.
addError
(
exception
,
stackTrace
);
}
// Wait until the debugger attaches, or the attempt fails.
return
debuggerCompleter
.
future
;
...
...
packages/flutter_tools/lib/src/linux/build_linux.dart
View file @
354e2a57
...
...
@@ -6,7 +6,6 @@ import '../artifacts.dart';
import
'../base/analyze_size.dart'
;
import
'../base/common.dart'
;
import
'../base/file_system.dart'
;
import
'../base/io.dart'
;
import
'../base/logger.dart'
;
import
'../base/process.dart'
;
import
'../base/utils.dart'
;
...
...
@@ -105,10 +104,7 @@ Future<void> _runCmake(String buildModeName, Directory sourceDir, Directory buil
},
trace:
true
,
);
}
on
ProcessException
catch
(
err
)
{
if
(!
isMissingExecutableException
(
err
))
{
rethrow
;
}
}
on
ArgumentError
{
throwToolExit
(
"cmake not found. Run 'flutter doctor' for more information."
);
}
if
(
result
!=
0
)
{
...
...
@@ -135,10 +131,7 @@ Future<void> _runBuild(Directory buildDir) async {
},
trace:
true
,
);
}
on
ProcessException
catch
(
err
)
{
if
(!
isMissingExecutableException
(
err
))
{
rethrow
;
}
}
on
ArgumentError
{
throwToolExit
(
"ninja not found. Run 'flutter doctor' for more information."
);
}
if
(
result
!=
0
)
{
...
...
packages/flutter_tools/lib/src/linux/linux_doctor.dart
View file @
354e2a57
...
...
@@ -6,7 +6,6 @@ import 'package:meta/meta.dart';
import
'package:process/process.dart'
;
import
'../base/io.dart'
;
import
'../base/process.dart'
;
import
'../base/user_messages.dart'
;
import
'../base/version.dart'
;
import
'../doctor.dart'
;
...
...
@@ -169,10 +168,7 @@ class LinuxDoctorValidator extends DoctorValidator {
binary
,
'--version'
,
]);
}
on
ProcessException
catch
(
err
)
{
if
(!
isMissingExecutableException
(
err
))
{
rethrow
;
}
}
on
ArgumentError
{
// ignore error.
}
if
(
result
==
null
||
result
.
exitCode
!=
0
)
{
...
...
@@ -191,10 +187,7 @@ class LinuxDoctorValidator extends DoctorValidator {
'--exists'
,
library
,
]);
}
on
ProcessException
catch
(
err
)
{
if
(!
isMissingExecutableException
(
err
))
{
rethrow
;
}
}
on
ArgumentError
{
// ignore error.
}
return
(
result
?.
exitCode
??
1
)
==
0
;
...
...
packages/flutter_tools/lib/src/macos/xcode.dart
View file @
354e2a57
...
...
@@ -84,6 +84,8 @@ class Xcode {
).
stdout
.
trim
();
}
on
ProcessException
{
// Ignored, return null below.
}
on
ArgumentError
{
// Ignored, return null below.
}
}
return
_xcodeSelectPath
;
...
...
@@ -274,6 +276,8 @@ class XCDevice {
).
stdout
.
trim
();
}
on
ProcessException
catch
(
exception
)
{
_logger
.
printTrace
(
'Process exception finding xcdevice:
\n
$exception
'
);
}
on
ArgumentError
catch
(
exception
)
{
_logger
.
printTrace
(
'Argument exception finding xcdevice:
\n
$exception
'
);
}
}
return
_xcdevicePath
;
...
...
@@ -310,6 +314,8 @@ class XCDevice {
_logger
.
printTrace
(
'xcdevice returned an error:
\n
${result.stderr}
'
);
}
on
ProcessException
catch
(
exception
)
{
_logger
.
printTrace
(
'Process exception running xcdevice list:
\n
$exception
'
);
}
on
ArgumentError
catch
(
exception
)
{
_logger
.
printTrace
(
'Argument exception running xcdevice list:
\n
$exception
'
);
}
return
null
;
...
...
@@ -402,6 +408,8 @@ class XCDevice {
}));
}
on
ProcessException
catch
(
exception
,
stackTrace
)
{
_deviceIdentifierByEvent
.
addError
(
exception
,
stackTrace
);
}
on
ArgumentError
catch
(
exception
,
stackTrace
)
{
_deviceIdentifierByEvent
.
addError
(
exception
,
stackTrace
);
}
}
...
...
packages/flutter_tools/lib/src/web/chrome.dart
View file @
354e2a57
...
...
@@ -150,7 +150,11 @@ class ChromiumLauncher {
/// Whether we can locate the chrome executable.
bool
canFindExecutable
()
{
final
String
chrome
=
_browserFinder
(
_platform
,
_fileSystem
);
try
{
return
_processManager
.
canRun
(
chrome
);
}
on
ArgumentError
{
return
false
;
}
}
/// The executable this launcher will use.
...
...
packages/flutter_tools/lib/src/windows/build_windows.dart
View file @
354e2a57
...
...
@@ -6,7 +6,6 @@ import '../artifacts.dart';
import
'../base/analyze_size.dart'
;
import
'../base/common.dart'
;
import
'../base/file_system.dart'
;
import
'../base/io.dart'
;
import
'../base/logger.dart'
;
import
'../base/process.dart'
;
import
'../base/utils.dart'
;
...
...
@@ -108,10 +107,7 @@ Future<void> _runCmakeGeneration(String cmakePath, Directory buildDir, Directory
],
trace:
true
,
);
}
on
ProcessException
catch
(
err
)
{
if
(!
isMissingExecutableException
(
err
))
{
rethrow
;
}
}
on
ArgumentError
{
throwToolExit
(
"cmake not found. Run 'flutter doctor' for more information."
);
}
if
(
result
!=
0
)
{
...
...
@@ -148,10 +144,7 @@ Future<void> _runBuild(String cmakePath, Directory buildDir, String buildModeNam
trace:
true
,
stdoutErrorMatcher:
errorMatcher
,
);
}
on
ProcessException
catch
(
err
)
{
if
(!
isMissingExecutableException
(
err
))
{
rethrow
;
}
}
on
ArgumentError
{
throwToolExit
(
"cmake not found. Run 'flutter doctor' for more information."
);
}
if
(
result
!=
0
)
{
...
...
packages/flutter_tools/lib/src/windows/visual_studio.dart
View file @
354e2a57
...
...
@@ -303,6 +303,8 @@ class VisualStudio {
return
installations
[
0
];
}
}
}
on
ArgumentError
{
// Thrown if vswhere doesn't exist; ignore and return null below.
}
on
ProcessException
{
// Ignored, return null below.
}
on
FormatException
{
...
...
@@ -418,6 +420,8 @@ class VisualStudio {
return
match
.
group
(
1
).
trim
();
}
}
}
on
ArgumentError
{
// Thrown if reg somehow doesn't exist; ignore and return null below.
}
on
ProcessException
{
// Ignored, return null below.
}
...
...
packages/flutter_tools/test/commands.shard/hermetic/build_linux_test.dart
View file @
354e2a57
...
...
@@ -6,7 +6,6 @@ import 'package:args/command_runner.dart';
import
'package:file/memory.dart'
;
import
'package:file_testing/file_testing.dart'
;
import
'package:flutter_tools/src/base/file_system.dart'
;
import
'package:flutter_tools/src/base/io.dart'
;
import
'package:flutter_tools/src/base/platform.dart'
;
import
'package:flutter_tools/src/base/utils.dart'
;
import
'package:flutter_tools/src/cache.dart'
;
...
...
@@ -153,7 +152,7 @@ void main() {
setUpMockProjectFilesForBuild
();
processManager
=
FakeProcessManager
.
list
(<
FakeCommand
>[
cmakeCommand
(
'release'
,
onRun:
()
{
throw
const
ProcessException
(
'cmake'
,
<
String
>[],
''
,
2
);
throw
ArgumentError
(
);
}),
]);
...
...
@@ -173,7 +172,7 @@ void main() {
processManager
=
FakeProcessManager
.
list
(<
FakeCommand
>[
cmakeCommand
(
'release'
),
ninjaCommand
(
'release'
,
onRun:
()
{
throw
const
ProcessException
(
'ninja'
,
<
String
>[],
''
,
2
);
throw
ArgumentError
(
);
}),
]);
...
...
packages/flutter_tools/test/general.shard/base/error_handling_io_test.dart
View file @
354e2a57
...
...
@@ -2,16 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:io'
as
io
;
// ignore: dart_io_import
import
'package:file/file.dart'
;
import
'package:file/memory.dart'
;
import
'package:flutter_tools/src/base/common.dart'
;
import
'package:flutter_tools/src/base/error_handling_io.dart'
;
import
'package:flutter_tools/src/base/file_system.dart'
;
import
'package:flutter_tools/src/base/io.dart'
;
import
'package:flutter_tools/src/base/logger.dart'
;
import
'package:flutter_tools/src/base/platform.dart'
;
import
'package:flutter_tools/src/convert.dart'
;
import
'package:mockito/mockito.dart'
;
import
'package:path/path.dart'
as
path
;
// ignore: package_path_import
...
...
@@ -25,24 +21,17 @@ class MockDirectory extends Mock implements Directory {}
final
Platform
windowsPlatform
=
FakePlatform
(
operatingSystem:
'windows'
,
environment:
<
String
,
String
>{
'PATH'
:
''
,
'PATHEXT'
:
''
,
}
environment:
<
String
,
String
>{}
);
final
Platform
linuxPlatform
=
FakePlatform
(
operatingSystem:
'linux'
,
environment:
<
String
,
String
>{
'PATH'
:
''
,
}
environment:
<
String
,
String
>{}
);
final
Platform
macOSPlatform
=
FakePlatform
(
operatingSystem:
'macos'
,
environment:
<
String
,
String
>{
'PATH'
:
''
,
}
environment:
<
String
,
String
>{}
);
void
setupWriteMocks
(
{
...
...
@@ -642,13 +631,16 @@ void main() {
const
int
kUserPermissionDenied
=
5
;
test
(
'when the device is full'
,
()
{
final
ProcessManager
processManager
=
setUpCrashingProcessManager
(
windowsPlatform
,
kDeviceFull
,
final
MockProcessManager
mockProcessManager
=
MockProcessManager
();
final
ProcessManager
processManager
=
ErrorHandlingProcessManager
(
delegate:
mockProcessManager
,
platform:
windowsPlatform
,
);
setupProcessManagerMocks
(
mockProcessManager
,
kDeviceFull
);
const
String
expectedMessage
=
'The target device is full'
;
expect
(()
=>
processManager
.
canRun
(
'foo'
),
throwsToolExit
(
message:
expectedMessage
));
expect
(()
=>
processManager
.
killPid
(
1
),
throwsToolExit
(
message:
expectedMessage
));
expect
(()
async
=>
await
processManager
.
start
(<
String
>[
'foo'
]),
...
...
@@ -660,13 +652,16 @@ void main() {
});
test
(
'when the file is being used by another program'
,
()
{
final
ProcessManager
processManager
=
setUpCrashingProcessManager
(
windowsPlatform
,
kUserMappedSectionOpened
,
final
MockProcessManager
mockProcessManager
=
MockProcessManager
();
final
ProcessManager
processManager
=
ErrorHandlingProcessManager
(
delegate:
mockProcessManager
,
platform:
windowsPlatform
,
);
setupProcessManagerMocks
(
mockProcessManager
,
kUserMappedSectionOpened
);
const
String
expectedMessage
=
'The file is being used by another program'
;
expect
(()
=>
processManager
.
canRun
(
'foo'
),
throwsToolExit
(
message:
expectedMessage
));
expect
(()
=>
processManager
.
killPid
(
1
),
throwsToolExit
(
message:
expectedMessage
));
expect
(()
async
=>
await
processManager
.
start
(<
String
>[
'foo'
]),
...
...
@@ -678,13 +673,16 @@ void main() {
});
test
(
'when permissions are denied'
,
()
{
final
ProcessManager
processManager
=
setUpCrashingProcessManager
(
windowsPlatform
,
kUserPermissionDenied
,
final
MockProcessManager
mockProcessManager
=
MockProcessManager
();
final
ProcessManager
processManager
=
ErrorHandlingProcessManager
(
delegate:
mockProcessManager
,
platform:
windowsPlatform
,
);
setupProcessManagerMocks
(
mockProcessManager
,
kUserPermissionDenied
);
const
String
expectedMessage
=
'The flutter tool cannot access the file'
;
expect
(()
=>
processManager
.
canRun
(
'foo'
),
throwsToolExit
(
message:
expectedMessage
));
expect
(()
=>
processManager
.
killPid
(
1
),
throwsToolExit
(
message:
expectedMessage
));
expect
(()
async
=>
await
processManager
.
start
(<
String
>[
'foo'
]),
...
...
@@ -701,13 +699,16 @@ void main() {
const
int
eacces
=
13
;
test
(
'when writing to a full device'
,
()
{
final
ProcessManager
processManager
=
setUpCrashingProcessManager
(
linuxPlatform
,
enospc
,
final
MockProcessManager
mockProcessManager
=
MockProcessManager
();
final
ProcessManager
processManager
=
ErrorHandlingProcessManager
(
delegate:
mockProcessManager
,
platform:
linuxPlatform
,
);
setupProcessManagerMocks
(
mockProcessManager
,
enospc
);
const
String
expectedMessage
=
'The target device is full'
;
expect
(()
=>
processManager
.
canRun
(
'foo'
),
throwsToolExit
(
message:
expectedMessage
));
expect
(()
=>
processManager
.
killPid
(
1
),
throwsToolExit
(
message:
expectedMessage
));
expect
(()
async
=>
await
processManager
.
start
(<
String
>[
'foo'
]),
...
...
@@ -719,13 +720,16 @@ void main() {
});
test
(
'when permissions are denied'
,
()
{
final
ProcessManager
processManager
=
setUpCrashingProcessManager
(
linuxPlatform
,
eacces
,
final
MockProcessManager
mockProcessManager
=
MockProcessManager
();
final
ProcessManager
processManager
=
ErrorHandlingProcessManager
(
delegate:
mockProcessManager
,
platform:
linuxPlatform
,
);
setupProcessManagerMocks
(
mockProcessManager
,
eacces
);
const
String
expectedMessage
=
'The flutter tool cannot access the file'
;
expect
(()
=>
processManager
.
canRun
(
'foo'
),
throwsToolExit
(
message:
expectedMessage
));
expect
(()
=>
processManager
.
killPid
(
1
),
throwsToolExit
(
message:
expectedMessage
));
expect
(()
async
=>
await
processManager
.
start
(<
String
>[
'foo'
]),
...
...
@@ -742,13 +746,16 @@ void main() {
const
int
eacces
=
13
;
test
(
'when writing to a full device'
,
()
{
final
ProcessManager
processManager
=
setUpCrashingProcessManager
(
macOSPlatform
,
enospc
,
final
MockProcessManager
mockProcessManager
=
MockProcessManager
();
final
ProcessManager
processManager
=
ErrorHandlingProcessManager
(
delegate:
mockProcessManager
,
platform:
macOSPlatform
,
);
setupProcessManagerMocks
(
mockProcessManager
,
enospc
);
const
String
expectedMessage
=
'The target device is full'
;
expect
(()
=>
processManager
.
canRun
(
'foo'
),
throwsToolExit
(
message:
expectedMessage
));
expect
(()
=>
processManager
.
killPid
(
1
),
throwsToolExit
(
message:
expectedMessage
));
expect
(()
async
=>
await
processManager
.
start
(<
String
>[
'foo'
]),
...
...
@@ -760,13 +767,16 @@ void main() {
});
test
(
'when permissions are denied'
,
()
{
final
ProcessManager
processManager
=
setUpCrashingProcessManager
(
macOSPlatform
,
eacces
,
final
MockProcessManager
mockProcessManager
=
MockProcessManager
();
final
ProcessManager
processManager
=
ErrorHandlingProcessManager
(
delegate:
mockProcessManager
,
platform:
linuxPlatform
,
);
setupProcessManagerMocks
(
mockProcessManager
,
eacces
);
const
String
expectedMessage
=
'The flutter tool cannot access the file'
;
expect
(()
=>
processManager
.
canRun
(
'foo'
),
throwsToolExit
(
message:
expectedMessage
));
expect
(()
=>
processManager
.
killPid
(
1
),
throwsToolExit
(
message:
expectedMessage
));
expect
(()
async
=>
await
processManager
.
start
(<
String
>[
'foo'
]),
...
...
@@ -777,296 +787,41 @@ void main() {
throwsToolExit
(
message:
expectedMessage
));
});
});
testWithoutContext
(
'Process manager uses which on Linux to resolve executables'
,
()
{
final
FileSystem
fileSystem
=
MemoryFileSystem
.
test
();
final
ProcessManager
processManager
=
setUpProcessManager
(
linuxPlatform
,
fileSystem
,
(
String
executable
,
List
<
String
>
arguments
,
{
Map
<
String
,
String
>
environment
,
bool
includeParentEnvironment
,
bool
runInShell
,
Encoding
stderrEncoding
,
Encoding
stdoutEncoding
,
String
workingDirectory
,
})
{
if
(
executable
==
'which'
)
{
return
ProcessResult
(
0
,
0
,
'fizz/foo
\n
'
,
''
);
}
if
(
executable
==
'fizz/foo'
)
{
return
ProcessResult
(
0
,
0
,
''
,
''
);
}
throw
ProcessException
(
executable
,
arguments
,
''
,
2
);
},
);
fileSystem
.
file
(
'fizz/foo'
).
createSync
(
recursive:
true
);
final
ProcessResult
result
=
processManager
.
runSync
(<
String
>[
'foo'
]);
expect
(
result
.
exitCode
,
0
);
});
testWithoutContext
(
'Process manager uses which on macOS to resolve executables'
,
()
{
final
FileSystem
fileSystem
=
MemoryFileSystem
.
test
();
final
ProcessManager
processManager
=
setUpProcessManager
(
macOSPlatform
,
fileSystem
,
(
String
executable
,
List
<
String
>
arguments
,
{
Map
<
String
,
String
>
environment
,
bool
includeParentEnvironment
,
bool
runInShell
,
Encoding
stderrEncoding
,
Encoding
stdoutEncoding
,
String
workingDirectory
,
})
{
if
(
executable
==
'which'
)
{
return
ProcessResult
(
0
,
0
,
'fizz/foo
\n
'
,
''
);
}
if
(
executable
==
'fizz/foo'
)
{
return
ProcessResult
(
0
,
0
,
''
,
''
);
}
throw
ProcessException
(
executable
,
arguments
,
''
,
2
);
},
);
fileSystem
.
file
(
'fizz/foo'
).
createSync
(
recursive:
true
);
final
ProcessResult
result
=
processManager
.
runSync
(<
String
>[
'foo'
]);
expect
(
result
.
exitCode
,
0
);
});
testWithoutContext
(
'Process manager uses where on Windows to resolve executables'
,
()
{
final
FileSystem
fileSystem
=
MemoryFileSystem
.
test
(
style:
FileSystemStyle
.
windows
);
final
ProcessManager
processManager
=
setUpProcessManager
(
windowsPlatform
,
fileSystem
,
(
String
executable
,
List
<
String
>
arguments
,
{
Map
<
String
,
String
>
environment
,
bool
includeParentEnvironment
,
bool
runInShell
,
Encoding
stderrEncoding
,
Encoding
stdoutEncoding
,
String
workingDirectory
,
})
{
if
(
executable
==
'where'
)
{
return
ProcessResult
(
0
,
0
,
'C:
\\
fizz
\\
foo.exe
\n
'
,
''
);
}
if
(
executable
==
'C:
\\
fizz
\\
foo.exe'
)
{
return
ProcessResult
(
0
,
0
,
''
,
''
);
}
throw
ProcessException
(
executable
,
arguments
,
''
,
2
);
},
);
fileSystem
.
file
(
'C:
\\
fizz
\\
foo.exe'
).
createSync
(
recursive:
true
);
final
ProcessResult
result
=
processManager
.
runSync
(<
String
>[
'foo'
]);
expect
(
result
.
exitCode
,
0
);
});
testWithoutContext
(
'Process manager will exit if where returns exit code 2 on Windows'
,
()
{
final
FileSystem
fileSystem
=
MemoryFileSystem
.
test
(
style:
FileSystemStyle
.
windows
);
final
ProcessManager
processManager
=
setUpProcessManager
(
windowsPlatform
,
fileSystem
,
(
String
executable
,
List
<
String
>
arguments
,
{
Map
<
String
,
String
>
environment
,
bool
includeParentEnvironment
,
bool
runInShell
,
Encoding
stderrEncoding
,
Encoding
stdoutEncoding
,
String
workingDirectory
,
})
{
throw
ProcessException
(
executable
,
arguments
,
''
,
2
);
},
);
expect
(()
=>
processManager
.
runSync
(<
String
>[
'any'
]),
throwsToolExit
());
});
testWithoutContext
(
'Process manager will rethrow process exception if exit code on Linux'
,
()
{
final
FileSystem
fileSystem
=
MemoryFileSystem
.
test
();
final
ProcessManager
processManager
=
setUpProcessManager
(
linuxPlatform
,
fileSystem
,
(
String
executable
,
List
<
String
>
arguments
,
{
Map
<
String
,
String
>
environment
,
bool
includeParentEnvironment
,
bool
runInShell
,
Encoding
stderrEncoding
,
Encoding
stdoutEncoding
,
String
workingDirectory
,
})
{
throw
ProcessException
(
executable
,
arguments
,
''
,
2
);
},
);
expect
(()
=>
processManager
.
runSync
(<
String
>[
'any'
]),
throwsA
(
isA
<
ProcessException
>()));
});
testWithoutContext
(
'Process manager will return first executable that exists'
,
()
{
final
FileSystem
fileSystem
=
MemoryFileSystem
.
test
();
final
ProcessManager
processManager
=
setUpProcessManager
(
linuxPlatform
,
fileSystem
,
(
String
executable
,
List
<
String
>
arguments
,
{
Map
<
String
,
String
>
environment
,
bool
includeParentEnvironment
,
bool
runInShell
,
Encoding
stderrEncoding
,
Encoding
stdoutEncoding
,
String
workingDirectory
,
})
{
if
(
executable
==
'which'
)
{
return
ProcessResult
(
0
,
0
,
'fizz/foo
\n
bar/foo
\n
'
,
''
);
}
if
(
executable
==
'bar/foo'
)
{
return
ProcessResult
(
0
,
0
,
''
,
''
);
}
throw
ProcessException
(
executable
,
arguments
,
''
,
2
);
},
);
fileSystem
.
file
(
'bar/foo'
).
createSync
(
recursive:
true
);
final
ProcessResult
result
=
processManager
.
runSync
(<
String
>[
'foo'
]);
expect
(
result
.
exitCode
,
0
);
});
testWithoutContext
(
'Process manager will cache executable resolution'
,
()
{
int
whichCalled
=
0
;
final
FileSystem
fileSystem
=
MemoryFileSystem
.
test
();
final
ProcessManager
processManager
=
setUpProcessManager
(
linuxPlatform
,
fileSystem
,
(
String
executable
,
List
<
String
>
arguments
,
{
Map
<
String
,
String
>
environment
,
bool
includeParentEnvironment
,
bool
runInShell
,
Encoding
stderrEncoding
,
Encoding
stdoutEncoding
,
String
workingDirectory
,
})
{
if
(
executable
==
'which'
)
{
whichCalled
+=
1
;
return
ProcessResult
(
0
,
0
,
'fizz/foo
\n
'
,
''
);
}
if
(
executable
==
'fizz/foo'
)
{
return
ProcessResult
(
0
,
0
,
''
,
''
);
}
throw
ProcessException
(
executable
,
arguments
,
''
,
2
);
},
);
fileSystem
.
file
(
'fizz/foo'
).
createSync
(
recursive:
true
);
processManager
.
runSync
(<
String
>[
'foo'
]);
processManager
.
runSync
(<
String
>[
'foo'
]);
expect
(
whichCalled
,
1
);
});
testWithoutContext
(
'Process manager will not cache executable resolution if the process fails'
,
()
{
int
whichCalled
=
0
;
final
FileSystem
fileSystem
=
MemoryFileSystem
.
test
();
final
ProcessManager
processManager
=
setUpProcessManager
(
linuxPlatform
,
fileSystem
,
(
String
executable
,
List
<
String
>
arguments
,
{
Map
<
String
,
String
>
environment
,
bool
includeParentEnvironment
,
bool
runInShell
,
Encoding
stderrEncoding
,
Encoding
stdoutEncoding
,
String
workingDirectory
,
})
{
if
(
executable
==
'which'
)
{
whichCalled
+=
1
;
return
ProcessResult
(
0
,
0
,
''
,
''
);
}
if
(
executable
==
'foo'
)
{
return
ProcessResult
(
0
,
0
,
''
,
''
);
}
throw
ProcessException
(
executable
,
arguments
,
''
,
2
);
},
);
processManager
.
runSync
(<
String
>[
'foo'
]);
processManager
.
runSync
(<
String
>[
'foo'
]);
expect
(
whichCalled
,
2
);
});
}
ProcessManager
setUpProcessManager
(
Platform
platform
,
FileSystem
fileSystem
,
ProcessRunSync
processRunSync
,
void
setupProcessManagerMocks
(
MockProcessManager
processManager
,
int
errorCode
,
)
{
return
ErrorHandlingProcessManager
(
fileSystem:
fileSystem
,
logger:
BufferLogger
.
test
(),
platform:
platform
,
runSync:
processRunSync
,
);
when
(
processManager
.
canRun
(
any
,
workingDirectory:
anyNamed
(
'workingDirectory'
)))
.
thenThrow
(
ProcessException
(
''
,
<
String
>[],
''
,
errorCode
));
when
(
processManager
.
killPid
(
any
,
any
))
.
thenThrow
(
ProcessException
(
''
,
<
String
>[],
''
,
errorCode
));
when
(
processManager
.
runSync
(
any
,
environment:
anyNamed
(
'environment'
),
includeParentEnvironment:
anyNamed
(
'includeParentEnvironment'
),
runInShell:
anyNamed
(
'runInShell'
),
workingDirectory:
anyNamed
(
'workingDirectory'
),
stdoutEncoding:
anyNamed
(
'stdoutEncoding'
),
stderrEncoding:
anyNamed
(
'stderrEncoding'
),
)).
thenThrow
(
ProcessException
(
''
,
<
String
>[],
''
,
errorCode
));
when
(
processManager
.
run
(
any
,
environment:
anyNamed
(
'environment'
),
includeParentEnvironment:
anyNamed
(
'includeParentEnvironment'
),
runInShell:
anyNamed
(
'runInShell'
),
workingDirectory:
anyNamed
(
'workingDirectory'
),
stdoutEncoding:
anyNamed
(
'stdoutEncoding'
),
stderrEncoding:
anyNamed
(
'stderrEncoding'
),
)).
thenThrow
(
ProcessException
(
''
,
<
String
>[],
''
,
errorCode
));
when
(
processManager
.
start
(
any
,
environment:
anyNamed
(
'environment'
),
includeParentEnvironment:
anyNamed
(
'includeParentEnvironment'
),
runInShell:
anyNamed
(
'runInShell'
),
workingDirectory:
anyNamed
(
'workingDirectory'
),
)).
thenThrow
(
ProcessException
(
''
,
<
String
>[],
''
,
errorCode
));
}
ProcessManager
setUpCrashingProcessManager
(
Platform
platform
,
int
osError
,
)
{
return
ErrorHandlingProcessManager
(
fileSystem:
MemoryFileSystem
.
test
(
style:
platform
.
isWindows
?
FileSystemStyle
.
windows
:
FileSystemStyle
.
posix
,
),
logger:
BufferLogger
.
test
(),
platform:
platform
,
killPid:
(
int
pid
,
[
io
.
ProcessSignal
signal
])
{
throw
ProcessException
(
'executable'
,
<
String
>[],
''
,
osError
);
},
run:
(
String
executable
,
List
<
String
>
arguments
,
{
Map
<
String
,
String
>
environment
,
bool
includeParentEnvironment
,
bool
runInShell
,
Encoding
stderrEncoding
,
Encoding
stdoutEncoding
,
String
workingDirectory
,
})
{
throw
ProcessException
(
executable
,
arguments
,
''
,
osError
);
},
runSync:
(
String
executable
,
List
<
String
>
arguments
,
{
Map
<
String
,
String
>
environment
,
bool
includeParentEnvironment
,
bool
runInShell
,
Encoding
stderrEncoding
,
Encoding
stdoutEncoding
,
String
workingDirectory
,
})
{
throw
ProcessException
(
executable
,
arguments
,
''
,
osError
);
},
start:
(
String
executable
,
List
<
String
>
arguments
,
{
Map
<
String
,
String
>
environment
,
bool
includeParentEnvironment
,
bool
runInShell
,
String
workingDirectory
,
ProcessStartMode
mode
,
})
{
throw
ProcessException
(
executable
,
arguments
,
''
,
osError
);
},
);
}
class
MockProcessManager
extends
Mock
implements
ProcessManager
{}
packages/flutter_tools/test/general.shard/base/os_test.dart
View file @
354e2a57
...
...
@@ -63,9 +63,9 @@ void main() {
});
group
(
'which on Windows'
,
()
{
testWithoutContext
(
'throws tool exit if where throws a
process exception with code 2
'
,
()
async
{
testWithoutContext
(
'throws tool exit if where throws a
n argument error
'
,
()
async
{
when
(
mockProcessManager
.
runSync
(<
String
>[
'where'
,
kExecutable
]))
.
thenThrow
(
const
ProcessException
(
'where'
,
<
String
>[],
'Cannot find executable for where'
,
2
));
.
thenThrow
(
ArgumentError
(
'Cannot find executable for where'
));
final
OperatingSystemUtils
utils
=
createOSUtils
(
FakePlatform
(
operatingSystem:
'windows'
));
expect
(()
=>
utils
.
which
(
kExecutable
),
throwsA
(
isA
<
ToolExit
>()));
...
...
@@ -143,11 +143,11 @@ void main() {
);
});
testWithoutContext
(
'If unzip throws a
ProcessException with code 2
, display an install message'
,
()
{
testWithoutContext
(
'If unzip throws a
n ArgumentError
, display an install message'
,
()
{
final
FileSystem
fileSystem
=
MemoryFileSystem
.
test
();
when
(
mockProcessManager
.
runSync
(
<
String
>[
'unzip'
,
'-o'
,
'-q'
,
'foo.zip'
,
'-d'
,
fileSystem
.
currentDirectory
.
path
],
)).
thenThrow
(
const
ProcessException
(
'unzip'
,
<
String
>[
'-o'
,
'-q'
,
'foo.zip'
,
'-d'
],
''
,
2
));
)).
thenThrow
(
ArgumentError
(
));
final
OperatingSystemUtils
linuxOsUtils
=
OperatingSystemUtils
(
fileSystem:
fileSystem
,
...
...
packages/flutter_tools/test/general.shard/macos/xcode_test.dart
View file @
354e2a57
...
...
@@ -55,7 +55,7 @@ void main() {
.
thenThrow
(
const
ProcessException
(
'/usr/bin/xcode-select'
,
<
String
>[
'--print-path'
]));
expect
(
xcode
.
xcodeSelectPath
,
isNull
);
when
(
processManager
.
runSync
(<
String
>[
'/usr/bin/xcode-select'
,
'--print-path'
]))
.
thenThrow
(
const
ProcessException
(
'/usr/bin/xcode-select'
,
<
String
>[
'--print-path'
],
''
,
2
));
.
thenThrow
(
ArgumentError
(
'Invalid argument(s): Cannot find executable for /usr/bin/xcode-select'
));
expect
(
xcode
.
xcodeSelectPath
,
isNull
);
});
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment