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
ac36e442
Unverified
Commit
ac36e442
authored
Apr 19, 2019
by
Jonah Williams
Committed by
GitHub
Apr 19, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add flutter run support for linux and windows (#31229)
parent
65f45999
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
514 additions
and
132 deletions
+514
-132
application_package.dart
packages/flutter_tools/lib/src/application_package.dart
+10
-2
build_linux.dart
packages/flutter_tools/lib/src/commands/build_linux.dart
+2
-22
build_windows.dart
packages/flutter_tools/lib/src/commands/build_windows.dart
+2
-22
desktop.dart
packages/flutter_tools/lib/src/desktop.dart
+35
-0
application_package.dart
...ages/flutter_tools/lib/src/linux/application_package.dart
+74
-0
build_linux.dart
packages/flutter_tools/lib/src/linux/build_linux.dart
+44
-0
linux_device.dart
packages/flutter_tools/lib/src/linux/linux_device.dart
+62
-17
macos_device.dart
packages/flutter_tools/lib/src/macos/macos_device.dart
+3
-31
project.dart
packages/flutter_tools/lib/src/project.dart
+1
-1
application_package.dart
...es/flutter_tools/lib/src/windows/application_package.dart
+76
-0
build_windows.dart
packages/flutter_tools/lib/src/windows/build_windows.dart
+44
-0
windows_device.dart
packages/flutter_tools/lib/src/windows/windows_device.dart
+95
-17
linux_device_test.dart
packages/flutter_tools/test/linux/linux_device_test.dart
+33
-10
windows_device_test.dart
packages/flutter_tools/test/windows/windows_device_test.dart
+33
-10
No files found.
packages/flutter_tools/lib/src/application_package.dart
View file @
ac36e442
...
...
@@ -20,10 +20,12 @@ import 'build_info.dart';
import
'globals.dart'
;
import
'ios/ios_workflow.dart'
;
import
'ios/plist_utils.dart'
as
plist
;
import
'linux/application_package.dart'
;
import
'macos/application_package.dart'
;
import
'project.dart'
;
import
'tester/flutter_tester.dart'
;
import
'web/web_device.dart'
;
import
'windows/application_package.dart'
;
class
ApplicationPackageFactory
{
static
ApplicationPackageFactory
get
instance
=>
context
[
ApplicationPackageFactory
];
...
...
@@ -51,12 +53,18 @@ class ApplicationPackageFactory {
return
FlutterTesterApp
.
fromCurrentDirectory
();
case
TargetPlatform
.
darwin_x64
:
return
applicationBinary
==
null
?
MacOSApp
.
fromMacOSProject
((
await
FlutterProject
.
current
()).
macos
)
:
MacOSApp
.
fromPrebuiltApp
(
applicationBinary
);
?
MacOSApp
.
fromMacOSProject
((
await
FlutterProject
.
current
()).
macos
)
:
MacOSApp
.
fromPrebuiltApp
(
applicationBinary
);
case
TargetPlatform
.
web
:
return
WebApplicationPackage
(
await
FlutterProject
.
current
());
case
TargetPlatform
.
linux_x64
:
return
applicationBinary
==
null
?
LinuxApp
.
fromLinuxProject
((
await
FlutterProject
.
current
()).
linux
)
:
LinuxApp
.
fromPrebuiltApp
(
applicationBinary
);
case
TargetPlatform
.
windows_x64
:
return
applicationBinary
==
null
?
WindowsApp
.
fromWindowsProject
((
await
FlutterProject
.
current
()).
windows
)
:
WindowsApp
.
fromPrebuiltApp
(
applicationBinary
);
case
TargetPlatform
.
fuchsia
:
return
null
;
}
...
...
packages/flutter_tools/lib/src/commands/build_linux.dart
View file @
ac36e442
...
...
@@ -5,13 +5,10 @@
import
'dart:async'
;
import
'../base/common.dart'
;
import
'../base/io.dart'
;
import
'../base/platform.dart'
;
import
'../base/process_manager.dart'
;
import
'../build_info.dart'
;
import
'../cache.dart'
;
import
'../convert.dart'
;
import
'../globals.dart'
;
import
'../linux/build_linux.dart'
;
import
'../project.dart'
;
import
'../runner/flutter_command.dart'
show
FlutterCommandResult
;
import
'build.dart'
;
...
...
@@ -62,24 +59,7 @@ class BuildLinuxCommand extends BuildSubCommand {
if
(!
flutterProject
.
linux
.
existsSync
())
{
throwToolExit
(
'No Linux desktop project configured.'
);
}
final
Process
process
=
await
processManager
.
start
(<
String
>[
flutterProject
.
linux
.
buildScript
.
path
,
Cache
.
flutterRoot
,
buildInfo
.
isDebug
?
'debug'
:
'release'
,
buildInfo
?.
trackWidgetCreation
==
true
?
'track-widget-creation'
:
'no-track-widget-creation'
,
],
runInShell:
true
);
process
.
stderr
.
transform
(
utf8
.
decoder
)
.
transform
(
const
LineSplitter
())
.
listen
(
printError
);
process
.
stdout
.
transform
(
utf8
.
decoder
)
.
transform
(
const
LineSplitter
())
.
listen
(
printStatus
);
final
int
result
=
await
process
.
exitCode
;
if
(
result
!=
0
)
{
throwToolExit
(
'Build process failed'
);
}
await
buildLinux
(
flutterProject
.
linux
,
buildInfo
);
return
null
;
}
}
packages/flutter_tools/lib/src/commands/build_windows.dart
View file @
ac36e442
...
...
@@ -5,15 +5,12 @@
import
'dart:async'
;
import
'../base/common.dart'
;
import
'../base/io.dart'
;
import
'../base/platform.dart'
;
import
'../base/process_manager.dart'
;
import
'../build_info.dart'
;
import
'../cache.dart'
;
import
'../convert.dart'
;
import
'../globals.dart'
;
import
'../project.dart'
;
import
'../runner/flutter_command.dart'
show
FlutterCommandResult
;
import
'../windows/build_windows.dart'
;
import
'build.dart'
;
/// A command to build a windows desktop target through a build shell script.
...
...
@@ -62,24 +59,7 @@ class BuildWindowsCommand extends BuildSubCommand {
if
(!
flutterProject
.
windows
.
existsSync
())
{
throwToolExit
(
'No Windows desktop project configured.'
);
}
final
Process
process
=
await
processManager
.
start
(<
String
>[
flutterProject
.
windows
.
buildScript
.
path
,
Cache
.
flutterRoot
,
buildInfo
.
isDebug
?
'debug'
:
'release'
,
buildInfo
?.
trackWidgetCreation
==
true
?
'track-widget-creation'
:
'no-track-widget-creation'
,
],
runInShell:
true
);
process
.
stderr
.
transform
(
utf8
.
decoder
)
.
transform
(
const
LineSplitter
())
.
listen
(
printError
);
process
.
stdout
.
transform
(
utf8
.
decoder
)
.
transform
(
const
LineSplitter
())
.
listen
(
printStatus
);
final
int
result
=
await
process
.
exitCode
;
if
(
result
!=
0
)
{
throwToolExit
(
'Build process failed'
);
}
await
buildWindows
(
flutterProject
.
windows
,
buildInfo
);
return
null
;
}
}
packages/flutter_tools/lib/src/desktop.dart
View file @
ac36e442
...
...
@@ -2,7 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'base/io.dart'
;
import
'base/platform.dart'
;
import
'base/process_manager.dart'
;
import
'version.dart'
;
// Only launch or display desktop embedding devices if
...
...
@@ -12,3 +14,36 @@ bool get flutterDesktopEnabled {
return
_flutterDesktopEnabled
&&
!
FlutterVersion
.
instance
.
isStable
;
}
bool
_flutterDesktopEnabled
;
/// Kills a process on linux or macOS.
Future
<
bool
>
killProcess
(
String
executable
)
async
{
final
RegExp
whitespace
=
RegExp
(
r'\s+'
);
bool
succeeded
=
true
;
try
{
final
ProcessResult
result
=
await
processManager
.
run
(<
String
>[
'ps'
,
'aux'
,
]);
if
(
result
.
exitCode
!=
0
)
{
return
false
;
}
final
List
<
String
>
lines
=
result
.
stdout
.
split
(
'
\n
'
);
for
(
String
line
in
lines
)
{
if
(!
line
.
contains
(
executable
))
{
continue
;
}
final
List
<
String
>
values
=
line
.
split
(
whitespace
);
if
(
values
.
length
<
2
)
{
continue
;
}
final
String
pid
=
values
[
1
];
final
ProcessResult
killResult
=
await
processManager
.
run
(<
String
>[
'kill'
,
pid
,
]);
succeeded
&=
killResult
.
exitCode
==
0
;
}
return
true
;
}
on
ArgumentError
{
succeeded
=
false
;
}
return
succeeded
;
}
packages/flutter_tools/lib/src/linux/application_package.dart
0 → 100644
View file @
ac36e442
// Copyright 2019 The Chromium 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
'package:meta/meta.dart'
;
import
'../application_package.dart'
;
import
'../base/common.dart'
;
import
'../base/file_system.dart'
;
import
'../base/io.dart'
;
import
'../base/process_manager.dart'
;
import
'../build_info.dart'
;
import
'../project.dart'
;
abstract
class
LinuxApp
extends
ApplicationPackage
{
LinuxApp
({
@required
String
projectBundleId
})
:
super
(
id:
projectBundleId
);
/// Creates a new [LinuxApp] from a linux sub project.
factory
LinuxApp
.
fromLinuxProject
(
LinuxProject
project
)
{
return
BuildableLinuxApp
(
project:
project
,
);
}
/// Creates a new [LinuxApp] from an existing executable.
///
/// `applicationBinary` is the path to the executable.
factory
LinuxApp
.
fromPrebuiltApp
(
FileSystemEntity
applicationBinary
)
{
return
PrebuiltLinuxApp
(
executable:
applicationBinary
.
path
,
);
}
@override
String
get
displayName
=>
id
;
String
executable
(
BuildMode
buildMode
);
}
class
PrebuiltLinuxApp
extends
LinuxApp
{
PrebuiltLinuxApp
({
@required
String
executable
,
})
:
_executable
=
executable
,
super
(
projectBundleId:
executable
);
final
String
_executable
;
@override
String
executable
(
BuildMode
buildMode
)
=>
_executable
;
@override
String
get
name
=>
_executable
;
}
class
BuildableLinuxApp
extends
LinuxApp
{
BuildableLinuxApp
({
this
.
project
})
:
super
(
projectBundleId:
project
.
project
.
manifest
.
appName
);
final
LinuxProject
project
;
@override
String
executable
(
BuildMode
buildMode
)
{
final
ProcessResult
result
=
processManager
.
runSync
(<
String
>[
project
.
nameScript
.
path
,
buildMode
==
BuildMode
.
debug
?
'debug'
:
'release'
,
]);
if
(
result
.
exitCode
!=
0
)
{
throwToolExit
(
'Failed to find Linux project name'
);
}
return
result
.
stdout
.
toString
().
trim
();
}
@override
String
get
name
=>
project
.
project
.
manifest
.
appName
;
}
packages/flutter_tools/lib/src/linux/build_linux.dart
0 → 100644
View file @
ac36e442
// Copyright 2019 The Chromium 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
'../base/common.dart'
;
import
'../base/io.dart'
;
import
'../base/logger.dart'
;
import
'../base/process_manager.dart'
;
import
'../build_info.dart'
;
import
'../cache.dart'
;
import
'../convert.dart'
;
import
'../globals.dart'
;
import
'../project.dart'
;
/// Builds the Linux project through the project shell script.
Future
<
void
>
buildLinux
(
LinuxProject
linuxProject
,
BuildInfo
buildInfo
)
async
{
final
Process
process
=
await
processManager
.
start
(<
String
>[
linuxProject
.
buildScript
.
path
,
Cache
.
flutterRoot
,
buildInfo
?.
isDebug
==
true
?
'debug'
:
'release'
,
buildInfo
?.
trackWidgetCreation
==
true
?
'track-widget-creation'
:
'no-track-widget-creation'
,
],
runInShell:
true
);
final
Status
status
=
logger
.
startProgress
(
'Building Linux application...'
,
timeout:
null
,
);
int
result
;
try
{
process
.
stderr
.
transform
(
utf8
.
decoder
)
.
transform
(
const
LineSplitter
())
.
listen
(
printError
);
process
.
stdout
.
transform
(
utf8
.
decoder
)
.
transform
(
const
LineSplitter
())
.
listen
(
printTrace
);
result
=
await
process
.
exitCode
;
}
finally
{
status
.
cancel
();
}
if
(
result
!=
0
)
{
throwToolExit
(
'Build process failed'
);
}
}
packages/flutter_tools/lib/src/linux/linux_device.dart
View file @
ac36e442
...
...
@@ -3,10 +3,19 @@
// found in the LICENSE file.
import
'../application_package.dart'
;
import
'../base/io.dart'
;
import
'../base/os.dart'
;
import
'../base/platform.dart'
;
import
'../base/process_manager.dart'
;
import
'../build_info.dart'
;
import
'../convert.dart'
;
import
'../desktop.dart'
;
import
'../device.dart'
;
import
'../globals.dart'
;
import
'../project.dart'
;
import
'../protocol_discovery.dart'
;
import
'application_package.dart'
;
import
'build_linux.dart'
;
import
'linux_workflow.dart'
;
/// A device that represents a desktop Linux target.
...
...
@@ -19,20 +28,20 @@ class LinuxDevice extends Device {
@override
DeviceLogReader
getLogReader
({
ApplicationPackage
app
})
=>
NoOpDeviceLogReader
(
'linux'
);
// Since the host and target devices are the same, no work needs to be done
// to install the application.
@override
Future
<
bool
>
installApp
(
ApplicationPackage
app
)
{
throw
UnimplementedError
();
}
Future
<
bool
>
installApp
(
ApplicationPackage
app
)
async
=>
true
;
// Since the host and target devices are the same, no work needs to be done
// to install the application.
@override
Future
<
bool
>
isAppInstalled
(
ApplicationPackage
app
)
{
throw
UnimplementedError
();
}
Future
<
bool
>
isAppInstalled
(
ApplicationPackage
app
)
async
=>
true
;
// Since the host and target devices are the same, no work needs to be done
// to install the application.
@override
Future
<
bool
>
isLatestBuildInstalled
(
ApplicationPackage
app
)
{
throw
UnimplementedError
();
}
Future
<
bool
>
isLatestBuildInstalled
(
ApplicationPackage
app
)
async
=>
true
;
@override
Future
<
bool
>
get
isLocalEmulator
async
=>
false
;
...
...
@@ -51,7 +60,7 @@ class LinuxDevice extends Device {
@override
Future
<
LaunchResult
>
startApp
(
ApplicationPackage
package
,
{
covariant
LinuxApp
package
,
{
String
mainPath
,
String
route
,
DebuggingOptions
debuggingOptions
,
...
...
@@ -59,22 +68,43 @@ class LinuxDevice extends Device {
bool
prebuiltApplication
=
false
,
bool
usesTerminalUi
=
true
,
bool
ipv6
=
false
,
})
{
throw
UnimplementedError
();
})
async
{
if
(!
prebuiltApplication
)
{
await
buildLinux
((
await
FlutterProject
.
current
()).
linux
,
debuggingOptions
.
buildInfo
);
}
await
stopApp
(
package
);
final
Process
process
=
await
processManager
.
start
(<
String
>[
package
.
executable
(
debuggingOptions
?.
buildInfo
?.
mode
)
]);
if
(
debuggingOptions
?.
buildInfo
?.
isRelease
==
true
)
{
return
LaunchResult
.
succeeded
();
}
final
LinuxLogReader
logReader
=
LinuxLogReader
(
package
,
process
);
final
ProtocolDiscovery
observatoryDiscovery
=
ProtocolDiscovery
.
observatory
(
logReader
);
try
{
final
Uri
observatoryUri
=
await
observatoryDiscovery
.
uri
;
return
LaunchResult
.
succeeded
(
observatoryUri:
observatoryUri
);
}
catch
(
error
)
{
printError
(
'Error waiting for a debug connection:
$error
'
);
return
LaunchResult
.
failed
();
}
finally
{
await
observatoryDiscovery
.
cancel
();
}
}
@override
Future
<
bool
>
stopApp
(
ApplicationPackage
app
)
{
throw
UnimplementedError
();
Future
<
bool
>
stopApp
(
covariant
LinuxApp
app
)
async
{
// Assume debug for now.
return
killProcess
(
app
.
executable
(
BuildMode
.
debug
));
}
@override
Future
<
TargetPlatform
>
get
targetPlatform
async
=>
TargetPlatform
.
linux_x64
;
// Since the host and target devices are the same, no work needs to be done
// to uninstall the application.
@override
Future
<
bool
>
uninstallApp
(
ApplicationPackage
app
)
{
throw
UnimplementedError
();
}
Future
<
bool
>
uninstallApp
(
ApplicationPackage
app
)
async
=>
true
;
}
class
LinuxDevices
extends
PollingDeviceDiscovery
{
...
...
@@ -99,3 +129,18 @@ class LinuxDevices extends PollingDeviceDiscovery {
@override
Future
<
List
<
String
>>
getDiagnostics
()
async
=>
const
<
String
>[];
}
class
LinuxLogReader
extends
DeviceLogReader
{
LinuxLogReader
(
this
.
linuxApp
,
this
.
process
);
final
LinuxApp
linuxApp
;
final
Process
process
;
@override
Stream
<
String
>
get
logLines
{
return
process
.
stdout
.
transform
(
utf8
.
decoder
);
}
@override
String
get
name
=>
linuxApp
.
displayName
;
}
packages/flutter_tools/lib/src/macos/macos_device.dart
View file @
ac36e442
...
...
@@ -10,6 +10,7 @@ import '../base/process_manager.dart';
import
'../build_info.dart'
;
import
'../cache.dart'
;
import
'../convert.dart'
;
import
'../desktop.dart'
;
import
'../device.dart'
;
import
'../globals.dart'
;
import
'../macos/application_package.dart'
;
...
...
@@ -103,37 +104,8 @@ class MacOSDevice extends Device {
// currently we rely on killing the isolate taking down the application.
@override
Future
<
bool
>
stopApp
(
covariant
MacOSApp
app
)
async
{
final
RegExp
whitespace
=
RegExp
(
r'\s+'
);
bool
succeeded
=
true
;
// assume debug for now.
final
String
executable
=
app
.
executable
(
BuildMode
.
debug
);
try
{
final
ProcessResult
result
=
await
processManager
.
run
(<
String
>[
'ps'
,
'aux'
,
]);
if
(
result
.
exitCode
!=
0
)
{
return
false
;
}
final
List
<
String
>
lines
=
result
.
stdout
.
split
(
'
\n
'
);
for
(
String
line
in
lines
)
{
if
(!
line
.
contains
(
executable
))
{
continue
;
}
final
List
<
String
>
values
=
line
.
split
(
whitespace
);
if
(
values
.
length
<
2
)
{
continue
;
}
final
String
pid
=
values
[
1
];
final
ProcessResult
killResult
=
await
processManager
.
run
(<
String
>[
'kill'
,
pid
,
]);
succeeded
&=
killResult
.
exitCode
==
0
;
}
return
true
;
}
on
ArgumentError
{
succeeded
=
false
;
}
return
succeeded
;
// Assume debug for now.
return
killProcess
(
app
.
executable
(
BuildMode
.
debug
));
}
@override
...
...
packages/flutter_tools/lib/src/project.dart
View file @
ac36e442
...
...
@@ -555,7 +555,7 @@ class WindowsProject {
File
get
buildScript
=>
project
.
directory
.
childDirectory
(
'windows'
).
childFile
(
'build.bat'
);
// Note: The name script file exists as a temporary shim.
File
get
nameScript
=>
project
.
directory
.
childDirectory
(
'windows'
).
childFile
(
'name_output.
sh
'
);
File
get
nameScript
=>
project
.
directory
.
childDirectory
(
'windows'
).
childFile
(
'name_output.
bat
'
);
}
/// The Linux sub project.
...
...
packages/flutter_tools/lib/src/windows/application_package.dart
0 → 100644
View file @
ac36e442
// Copyright 2019 The Chromium 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
'package:meta/meta.dart'
;
import
'../application_package.dart'
;
import
'../base/common.dart'
;
import
'../base/file_system.dart'
;
import
'../base/io.dart'
;
import
'../base/process_manager.dart'
;
import
'../build_info.dart'
;
import
'../project.dart'
;
abstract
class
WindowsApp
extends
ApplicationPackage
{
WindowsApp
({
@required
String
projectBundleId
})
:
super
(
id:
projectBundleId
);
/// Creates a new [WindowsApp] from a windows sub project.
factory
WindowsApp
.
fromWindowsProject
(
WindowsProject
project
)
{
return
BuildableWindowsApp
(
project:
project
,
);
}
/// Creates a new [WindowsApp] from an existing executable.
///
/// `applicationBinary` is the path to the executable.
factory
WindowsApp
.
fromPrebuiltApp
(
FileSystemEntity
applicationBinary
)
{
return
PrebuiltWindowsApp
(
executable:
applicationBinary
.
path
,
);
}
@override
String
get
displayName
=>
id
;
String
executable
(
BuildMode
buildMode
);
}
class
PrebuiltWindowsApp
extends
WindowsApp
{
PrebuiltWindowsApp
({
@required
String
executable
,
})
:
_executable
=
executable
,
super
(
projectBundleId:
executable
);
final
String
_executable
;
@override
String
executable
(
BuildMode
buildMode
)
=>
_executable
;
@override
String
get
name
=>
_executable
;
}
class
BuildableWindowsApp
extends
WindowsApp
{
BuildableWindowsApp
({
@required
this
.
project
,
})
:
super
(
projectBundleId:
project
.
project
.
manifest
.
appName
);
final
WindowsProject
project
;
@override
String
executable
(
BuildMode
buildMode
)
{
final
ProcessResult
result
=
processManager
.
runSync
(<
String
>[
project
.
nameScript
.
path
,
buildMode
==
BuildMode
.
debug
?
'debug'
:
'release'
,
]);
if
(
result
.
exitCode
!=
0
)
{
throwToolExit
(
'Failed to find Windows project name'
);
}
return
result
.
stdout
.
toString
().
trim
();
}
@override
String
get
name
=>
project
.
project
.
manifest
.
appName
;
}
packages/flutter_tools/lib/src/windows/build_windows.dart
0 → 100644
View file @
ac36e442
// Copyright 2019 The Chromium 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
'../base/common.dart'
;
import
'../base/io.dart'
;
import
'../base/logger.dart'
;
import
'../base/process_manager.dart'
;
import
'../build_info.dart'
;
import
'../cache.dart'
;
import
'../convert.dart'
;
import
'../globals.dart'
;
import
'../project.dart'
;
/// Builds the Windows project through the project bat script.
Future
<
void
>
buildWindows
(
WindowsProject
windowsProject
,
BuildInfo
buildInfo
)
async
{
final
Process
process
=
await
processManager
.
start
(<
String
>[
windowsProject
.
buildScript
.
path
,
Cache
.
flutterRoot
,
buildInfo
.
isDebug
?
'debug'
:
'release'
,
buildInfo
?.
trackWidgetCreation
==
true
?
'track-widget-creation'
:
'no-track-widget-creation'
,
],
runInShell:
true
);
final
Status
status
=
logger
.
startProgress
(
'Building Windows application...'
,
timeout:
null
,
);
int
result
;
try
{
process
.
stderr
.
transform
(
utf8
.
decoder
)
.
transform
(
const
LineSplitter
())
.
listen
(
printError
);
process
.
stdout
.
transform
(
utf8
.
decoder
)
.
transform
(
const
LineSplitter
())
.
listen
(
printTrace
);
result
=
await
process
.
exitCode
;
}
finally
{
status
.
cancel
();
}
if
(
result
!=
0
)
{
throwToolExit
(
'Build process failed'
);
}
}
packages/flutter_tools/lib/src/windows/windows_device.dart
View file @
ac36e442
...
...
@@ -2,11 +2,21 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'package:meta/meta.dart'
;
import
'../application_package.dart'
;
import
'../base/io.dart'
;
import
'../base/os.dart'
;
import
'../base/platform.dart'
;
import
'../base/process_manager.dart'
;
import
'../build_info.dart'
;
import
'../convert.dart'
;
import
'../device.dart'
;
import
'../globals.dart'
;
import
'../project.dart'
;
import
'../protocol_discovery.dart'
;
import
'application_package.dart'
;
import
'build_windows.dart'
;
import
'windows_workflow.dart'
;
/// A device that represents a desktop Windows target.
...
...
@@ -19,20 +29,20 @@ class WindowsDevice extends Device {
@override
DeviceLogReader
getLogReader
({
ApplicationPackage
app
})
=>
NoOpDeviceLogReader
(
'windows'
);
// Since the host and target devices are the same, no work needs to be done
// to install the application.
@override
Future
<
bool
>
installApp
(
ApplicationPackage
app
)
{
throw
UnimplementedError
();
}
Future
<
bool
>
installApp
(
ApplicationPackage
app
)
async
=>
true
;
// Since the host and target devices are the same, no work needs to be done
// to install the application.
@override
Future
<
bool
>
isAppInstalled
(
ApplicationPackage
app
)
{
throw
UnimplementedError
();
}
Future
<
bool
>
isAppInstalled
(
ApplicationPackage
app
)
async
=>
true
;
// Since the host and target devices are the same, no work needs to be done
// to install the application.
@override
Future
<
bool
>
isLatestBuildInstalled
(
ApplicationPackage
app
)
{
throw
UnimplementedError
();
}
Future
<
bool
>
isLatestBuildInstalled
(
ApplicationPackage
app
)
async
=>
true
;
@override
Future
<
bool
>
get
isLocalEmulator
async
=>
false
;
...
...
@@ -51,7 +61,7 @@ class WindowsDevice extends Device {
@override
Future
<
LaunchResult
>
startApp
(
ApplicationPackage
package
,
{
covariant
WindowsApp
package
,
{
String
mainPath
,
String
route
,
DebuggingOptions
debuggingOptions
,
...
...
@@ -59,22 +69,48 @@ class WindowsDevice extends Device {
bool
prebuiltApplication
=
false
,
bool
usesTerminalUi
=
true
,
bool
ipv6
=
false
,
})
{
throw
UnimplementedError
();
})
async
{
if
(!
prebuiltApplication
)
{
await
buildWindows
((
await
FlutterProject
.
current
()).
windows
,
debuggingOptions
.
buildInfo
);
}
await
stopApp
(
package
);
final
Process
process
=
await
processManager
.
start
(<
String
>[
package
.
executable
(
debuggingOptions
?.
buildInfo
?.
mode
)
]);
if
(
debuggingOptions
?.
buildInfo
?.
isRelease
==
true
)
{
return
LaunchResult
.
succeeded
();
}
final
WindowsLogReader
logReader
=
WindowsLogReader
(
package
,
process
);
final
ProtocolDiscovery
observatoryDiscovery
=
ProtocolDiscovery
.
observatory
(
logReader
);
try
{
final
Uri
observatoryUri
=
await
observatoryDiscovery
.
uri
;
return
LaunchResult
.
succeeded
(
observatoryUri:
observatoryUri
);
}
catch
(
error
)
{
printError
(
'Error waiting for a debug connection:
$error
'
);
return
LaunchResult
.
failed
();
}
finally
{
await
observatoryDiscovery
.
cancel
();
}
}
@override
Future
<
bool
>
stopApp
(
ApplicationPackage
app
)
{
throw
UnimplementedError
();
Future
<
bool
>
stopApp
(
covariant
WindowsApp
app
)
async
{
// Assume debug for now.
final
List
<
String
>
process
=
runningProcess
(
app
.
executable
(
BuildMode
.
debug
));
if
(
process
==
null
)
{
return
false
;
}
final
ProcessResult
result
=
await
processManager
.
run
(<
String
>[
'Taskkill'
,
'/PID'
,
process
.
first
,
'/F'
]);
return
result
.
exitCode
==
0
;
}
@override
Future
<
TargetPlatform
>
get
targetPlatform
async
=>
TargetPlatform
.
windows_x64
;
// Since the host and target devices are the same, no work needs to be done
// to uninstall the application.
@override
Future
<
bool
>
uninstallApp
(
ApplicationPackage
app
)
{
throw
UnimplementedError
();
}
Future
<
bool
>
uninstallApp
(
ApplicationPackage
app
)
async
=>
true
;
}
class
WindowsDevices
extends
PollingDeviceDiscovery
{
...
...
@@ -99,3 +135,45 @@ class WindowsDevices extends PollingDeviceDiscovery {
@override
Future
<
List
<
String
>>
getDiagnostics
()
async
=>
const
<
String
>[];
}
final
RegExp
_whitespace
=
RegExp
(
r'\w+'
);
/// Returns the running process matching `process` name.
///
/// This list contains the process name and id.
@visibleForTesting
List
<
String
>
runningProcess
(
String
processName
)
{
// TODO(jonahwilliams): find a way to do this without powershell.
final
ProcessResult
result
=
processManager
.
runSync
(<
String
>[
'powershell'
,
'-script="Get-CimInstance Win32_Process"'
]);
if
(
result
.
exitCode
!=
0
)
{
return
null
;
}
for
(
String
rawProcess
in
result
.
stdout
.
split
(
'
\n
'
))
{
final
String
process
=
rawProcess
.
trim
();
if
(!
process
.
contains
(
processName
))
{
continue
;
}
final
List
<
String
>
parts
=
process
.
split
(
_whitespace
);
final
List
<
String
>
data
=
<
String
>[
parts
[
0
],
// ID
parts
[
1
],
// Name
];
return
data
;
}
return
null
;
}
class
WindowsLogReader
extends
DeviceLogReader
{
WindowsLogReader
(
this
.
windowsApp
,
this
.
process
);
final
WindowsApp
windowsApp
;
final
Process
process
;
@override
Stream
<
String
>
get
logLines
{
return
process
.
stdout
.
transform
(
utf8
.
decoder
);
}
@override
String
get
name
=>
windowsApp
.
displayName
;
}
packages/flutter_tools/test/linux/linux_device_test.dart
View file @
ac36e442
...
...
@@ -2,11 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
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/build_info.dart'
;
import
'package:flutter_tools/src/linux/application_package.dart'
;
import
'package:flutter_tools/src/linux/linux_device.dart'
;
import
'package:flutter_tools/src/device.dart'
;
import
'package:mockito/mockito.dart'
;
import
'package:process/process.dart'
;
import
'../src/common.dart'
;
import
'../src/context.dart'
;
...
...
@@ -15,21 +19,30 @@ void main() {
group
(
LinuxDevice
,
()
{
final
LinuxDevice
device
=
LinuxDevice
();
final
MockPlatform
notLinux
=
MockPlatform
();
final
MockProcessManager
mockProcessManager
=
MockProcessManager
();
when
(
notLinux
.
isLinux
).
thenReturn
(
false
);
when
(
notLinux
.
environment
).
thenReturn
(
const
<
String
,
String
>{});
when
(
mockProcessManager
.
run
(<
String
>[
'ps'
,
'aux'
,
])).
thenAnswer
((
Invocation
invocation
)
async
{
final
MockProcessResult
result
=
MockProcessResult
();
when
(
result
.
exitCode
).
thenReturn
(
0
);
when
<
String
>(
result
.
stdout
).
thenReturn
(
''
);
return
result
;
});
test
(
'defaults'
,
()
async
{
testUsingContext
(
'defaults'
,
()
async
{
final
PrebuiltLinuxApp
linuxApp
=
PrebuiltLinuxApp
(
executable:
'foo'
);
expect
(
await
device
.
targetPlatform
,
TargetPlatform
.
linux_x64
);
expect
(
device
.
name
,
'Linux'
);
});
test
(
'unimplemented methods'
,
()
{
expect
(()
=>
device
.
installApp
(
null
),
throwsA
(
isInstanceOf
<
UnimplementedError
>()));
expect
(()
=>
device
.
uninstallApp
(
null
),
throwsA
(
isInstanceOf
<
UnimplementedError
>()));
expect
(()
=>
device
.
isLatestBuildInstalled
(
null
),
throwsA
(
isInstanceOf
<
UnimplementedError
>()));
expect
(()
=>
device
.
startApp
(
null
),
throwsA
(
isInstanceOf
<
UnimplementedError
>()));
expect
(()
=>
device
.
stopApp
(
null
),
throwsA
(
isInstanceOf
<
UnimplementedError
>()));
expect
(()
=>
device
.
isAppInstalled
(
null
),
throwsA
(
isInstanceOf
<
UnimplementedError
>()));
expect
(
await
device
.
installApp
(
linuxApp
),
true
);
expect
(
await
device
.
uninstallApp
(
linuxApp
),
true
);
expect
(
await
device
.
isLatestBuildInstalled
(
linuxApp
),
true
);
expect
(
await
device
.
isAppInstalled
(
linuxApp
),
true
);
expect
(
await
device
.
stopApp
(
linuxApp
),
true
);
},
overrides:
<
Type
,
Generator
>{
ProcessManager:
()
=>
mockProcessManager
,
});
test
(
'noop port forwarding'
,
()
async
{
...
...
@@ -49,3 +62,13 @@ void main() {
}
class
MockPlatform
extends
Mock
implements
Platform
{}
class
MockFileSystem
extends
Mock
implements
FileSystem
{}
class
MockFile
extends
Mock
implements
File
{}
class
MockProcessManager
extends
Mock
implements
ProcessManager
{}
class
MockProcess
extends
Mock
implements
Process
{}
class
MockProcessResult
extends
Mock
implements
ProcessResult
{}
\ No newline at end of file
packages/flutter_tools/test/windows/windows_device_test.dart
View file @
ac36e442
...
...
@@ -2,11 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
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/build_info.dart'
;
import
'package:flutter_tools/src/windows/application_package.dart'
;
import
'package:flutter_tools/src/windows/windows_device.dart'
;
import
'package:flutter_tools/src/device.dart'
;
import
'package:mockito/mockito.dart'
;
import
'package:process/process.dart'
;
import
'../src/common.dart'
;
import
'../src/context.dart'
;
...
...
@@ -15,21 +19,30 @@ void main() {
group
(
WindowsDevice
,
()
{
final
WindowsDevice
device
=
WindowsDevice
();
final
MockPlatform
notWindows
=
MockPlatform
();
final
MockProcessManager
mockProcessManager
=
MockProcessManager
();
when
(
notWindows
.
isWindows
).
thenReturn
(
false
);
when
(
notWindows
.
environment
).
thenReturn
(
const
<
String
,
String
>{});
when
(
mockProcessManager
.
runSync
(<
String
>[
'powershell'
,
'-script="Get-CimInstance Win32_Process"'
])).
thenAnswer
((
Invocation
invocation
)
{
final
MockProcessResult
result
=
MockProcessResult
();
when
(
result
.
exitCode
).
thenReturn
(
0
);
when
<
String
>(
result
.
stdout
).
thenReturn
(
''
);
return
result
;
});
test
(
'defaults'
,
()
async
{
testUsingContext
(
'defaults'
,
()
async
{
final
PrebuiltWindowsApp
windowsApp
=
PrebuiltWindowsApp
(
executable:
'foo'
);
expect
(
await
device
.
targetPlatform
,
TargetPlatform
.
windows_x64
);
expect
(
device
.
name
,
'Windows'
);
});
test
(
'unimplemented methods'
,
()
{
expect
(()
=>
device
.
installApp
(
null
),
throwsA
(
isInstanceOf
<
UnimplementedError
>()));
expect
(()
=>
device
.
uninstallApp
(
null
),
throwsA
(
isInstanceOf
<
UnimplementedError
>()));
expect
(()
=>
device
.
isLatestBuildInstalled
(
null
),
throwsA
(
isInstanceOf
<
UnimplementedError
>()));
expect
(()
=>
device
.
startApp
(
null
),
throwsA
(
isInstanceOf
<
UnimplementedError
>()));
expect
(()
=>
device
.
stopApp
(
null
),
throwsA
(
isInstanceOf
<
UnimplementedError
>()));
expect
(()
=>
device
.
isAppInstalled
(
null
),
throwsA
(
isInstanceOf
<
UnimplementedError
>()));
expect
(
await
device
.
installApp
(
windowsApp
),
true
);
expect
(
await
device
.
uninstallApp
(
windowsApp
),
true
);
expect
(
await
device
.
isLatestBuildInstalled
(
windowsApp
),
true
);
expect
(
await
device
.
isAppInstalled
(
windowsApp
),
true
);
expect
(
await
device
.
stopApp
(
windowsApp
),
false
);
},
overrides:
<
Type
,
Generator
>{
ProcessManager:
()
=>
mockProcessManager
,
});
test
(
'noop port forwarding'
,
()
async
{
...
...
@@ -49,3 +62,13 @@ void main() {
}
class
MockPlatform
extends
Mock
implements
Platform
{}
class
MockFileSystem
extends
Mock
implements
FileSystem
{}
class
MockFile
extends
Mock
implements
File
{}
class
MockProcessManager
extends
Mock
implements
ProcessManager
{}
class
MockProcess
extends
Mock
implements
Process
{}
class
MockProcessResult
extends
Mock
implements
ProcessResult
{}
\ No newline at end of file
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