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
18c8f577
Commit
18c8f577
authored
Mar 17, 2016
by
Devon Carew
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #2747 from devoncarew/refactor_build
Refactor the build commands
parents
67b3ce63
f8374cd9
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
174 additions
and
110 deletions
+174
-110
executable.dart
packages/flutter_tools/lib/executable.dart
+0
-2
build.dart
packages/flutter_tools/lib/src/commands/build.dart
+32
-56
build_apk.dart
packages/flutter_tools/lib/src/commands/build_apk.dart
+23
-25
build_flx.dart
packages/flutter_tools/lib/src/commands/build_flx.dart
+68
-0
drive.dart
packages/flutter_tools/lib/src/commands/drive.dart
+2
-2
refresh.dart
packages/flutter_tools/lib/src/commands/refresh.dart
+1
-1
run.dart
packages/flutter_tools/lib/src/commands/run.dart
+3
-5
flutter_command.dart
packages/flutter_tools/lib/src/runner/flutter_command.dart
+44
-18
mocks.dart
packages/flutter_tools/test/src/mocks.dart
+1
-1
No files found.
packages/flutter_tools/lib/executable.dart
View file @
18c8f577
...
...
@@ -12,7 +12,6 @@ import 'src/base/context.dart';
import
'src/base/logger.dart'
;
import
'src/base/process.dart'
;
import
'src/commands/analyze.dart'
;
import
'src/commands/apk.dart'
;
import
'src/commands/build.dart'
;
import
'src/commands/create.dart'
;
import
'src/commands/daemon.dart'
;
...
...
@@ -50,7 +49,6 @@ Future<Null> main(List<String> args) async {
FlutterCommandRunner
runner
=
new
FlutterCommandRunner
(
verboseHelp:
verboseHelp
)
..
addCommand
(
new
AnalyzeCommand
())
..
addCommand
(
new
ApkCommand
())
..
addCommand
(
new
BuildCommand
())
..
addCommand
(
new
CreateCommand
())
..
addCommand
(
new
DaemonCommand
(
hidden:
!
verboseHelp
))
...
...
packages/flutter_tools/lib/src/commands/build.dart
View file @
18c8f577
// Copyright 201
5
The Chromium Authors. All rights reserved.
// Copyright 201
6
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
'dart:async'
;
import
'dart:io'
;
import
'../flx.dart'
;
import
'../dart/pub.dart'
;
import
'../globals.dart'
;
import
'../runner/flutter_command.dart'
;
import
'../toolchain.dart'
;
import
'build_apk.dart'
;
import
'build_flx.dart'
;
class
BuildCommand
extends
FlutterCommand
{
BuildCommand
()
{
addSubcommand
(
new
BuildApkCommand
());
addSubcommand
(
new
BuildCleanCommand
());
addSubcommand
(
new
BuildFlxCommand
());
}
@override
final
String
name
=
'build'
;
@override
final
String
description
=
'Package your Flutter app into an FLX.'
;
BuildCommand
()
{
argParser
.
addFlag
(
'precompiled'
,
negatable:
false
);
// This option is still referenced by the iOS build scripts. We should
// remove it once we've updated those build scripts.
argParser
.
addOption
(
'asset-base'
,
help:
'Ignored. Will be removed.'
,
hide:
true
);
argParser
.
addOption
(
'compiler'
);
argParser
.
addOption
(
'manifest'
,
defaultsTo:
defaultManifestPath
);
argParser
.
addOption
(
'private-key'
,
defaultsTo:
defaultPrivateKeyPath
);
argParser
.
addOption
(
'output-file'
,
abbr:
'o'
,
defaultsTo:
defaultFlxOutputPath
);
argParser
.
addOption
(
'snapshot'
,
defaultsTo:
defaultSnapshotPath
);
argParser
.
addOption
(
'depfile'
,
defaultsTo:
defaultDepfilePath
);
argParser
.
addOption
(
'working-dir'
,
defaultsTo:
defaultWorkingDirPath
);
argParser
.
addFlag
(
'pub'
,
defaultsTo:
true
,
help:
'Whether to run "pub get" before building the app.'
);
addTargetOption
();
}
final
String
description
=
'Flutter build commands.'
;
@override
Future
<
int
>
run
()
async
{
if
(
argResults
[
'pub'
])
{
int
exitCode
=
await
pubGet
();
if
(
exitCode
!=
0
)
return
exitCode
;
}
return
await
super
.
run
();
}
Future
<
int
>
runInProject
()
=>
new
Future
<
int
>.
value
(
0
);
}
class
BuildCleanCommand
extends
FlutterCommand
{
@override
Future
<
int
>
runInProject
()
async
{
String
compilerPath
=
argResults
[
'compiler'
];
final
String
name
=
'clean'
;
if
(
compilerPath
==
null
)
await
downloadToolchain
();
else
toolchain
=
new
Toolchain
(
compiler:
new
Compiler
(
compilerPath
));
String
outputPath
=
argResults
[
'output-file'
];
@override
final
String
description
=
'Delete the build/ directory.'
;
return
await
build
(
toolchain
,
mainPath:
argResults
[
'target'
],
manifestPath:
argResults
[
'manifest'
],
outputPath:
outputPath
,
snapshotPath:
argResults
[
'snapshot'
],
depfilePath:
argResults
[
'depfile'
],
privateKeyPath:
argResults
[
'private-key'
],
workingDirPath:
argResults
[
'working-dir'
],
precompiledSnapshot:
argResults
[
'precompiled'
]
).
then
((
int
result
)
{
if
(
result
==
0
)
printStatus
(
'Built
$outputPath
.'
);
else
printError
(
'Error building
$outputPath
:
$result
.'
);
return
result
;
});
@override
Future
<
int
>
runInProject
()
async
{
Directory
buildDir
=
new
Directory
(
'build'
);
printStatus
(
"Deleting '
${buildDir.path}${Platform.pathSeparator}
'."
);
if
(!
buildDir
.
existsSync
())
return
0
;
try
{
buildDir
.
deleteSync
(
recursive:
true
);
return
0
;
}
catch
(
error
)
{
printError
(
error
.
toString
());
return
1
;
}
}
}
packages/flutter_tools/lib/src/commands/apk.dart
→
packages/flutter_tools/lib/src/commands/
build_
apk.dart
View file @
18c8f577
...
...
@@ -127,22 +127,19 @@ class _ApkComponents {
}
class
ApkKeystoreInfo
{
ApkKeystoreInfo
({
this
.
keystore
,
this
.
password
,
this
.
keyAlias
,
this
.
keyPassword
});
ApkKeystoreInfo
({
this
.
keystore
,
this
.
password
,
this
.
keyAlias
,
this
.
keyPassword
})
{
assert
(
keystore
!=
null
);
}
String
keystore
;
String
password
;
String
keyAlias
;
String
keyPassword
;
final
String
keystore
;
final
String
password
;
final
String
keyAlias
;
final
String
keyPassword
;
}
class
ApkCommand
extends
FlutterCommand
{
@override
final
String
name
=
'apk'
;
@override
final
String
description
=
'Build an Android APK package.'
;
ApkCommand
()
{
class
BuildApkCommand
extends
FlutterCommand
{
BuildApkCommand
()
{
usesTargetOption
();
argParser
.
addOption
(
'manifest'
,
abbr:
'm'
,
defaultsTo:
_kDefaultAndroidManifestPath
,
...
...
@@ -157,23 +154,24 @@ class ApkCommand extends FlutterCommand {
help:
'Output APK file.'
);
argParser
.
addOption
(
'flx'
,
abbr:
'f'
,
defaultsTo:
''
,
help:
'Path to the FLX file. If this is not provided, an FLX will be built.'
);
argParser
.
addOption
(
'keystore'
,
defaultsTo:
''
,
help:
'Path to the keystore used to sign the app.'
);
argParser
.
addOption
(
'keystore-password'
,
defaultsTo:
''
,
help:
'Password used to access the keystore.'
);
argParser
.
addOption
(
'keystore-key-alias'
,
defaultsTo:
''
,
help:
'Alias of the entry within the keystore.'
);
argParser
.
addOption
(
'keystore-key-password'
,
defaultsTo:
''
,
help:
'Password for the entry within the keystore.'
);
addTarget
Option
();
usesPub
Option
();
}
@override
final
String
name
=
'apk'
;
@override
final
String
description
=
'Build an Android APK file from your app.'
;
@override
Future
<
int
>
runInProject
()
async
{
// Validate that we can find an android sdk.
...
...
@@ -199,7 +197,7 @@ class ApkCommand extends FlutterCommand {
outputFile:
argResults
[
'output-file'
],
target:
argResults
[
'target'
],
flxPath:
argResults
[
'flx'
],
keystore:
argResults
[
'keystore'
]
.
isEmpty
?
null
:
new
ApkKeystoreInfo
(
keystore:
(
argResults
[
'keystore'
]
??
''
)
.
isEmpty
?
null
:
new
ApkKeystoreInfo
(
keystore:
argResults
[
'keystore'
],
password:
argResults
[
'keystore-password'
],
keyAlias:
argResults
[
'keystore-key-alias'
],
...
...
@@ -324,13 +322,13 @@ int _signApk(
keyPassword
=
_kDebugKeystorePassword
;
}
else
{
keystore
=
new
File
(
keystoreInfo
.
keystore
);
keystorePassword
=
keystoreInfo
.
password
;
keyAlias
=
keystoreInfo
.
keyAlias
;
keystorePassword
=
keystoreInfo
.
password
??
''
;
keyAlias
=
keystoreInfo
.
keyAlias
??
''
;
if
(
keystorePassword
.
isEmpty
||
keyAlias
.
isEmpty
)
{
printError
(
'Must provide a keystore password and a key alias.'
);
return
1
;
}
keyPassword
=
keystoreInfo
.
keyPassword
;
keyPassword
=
keystoreInfo
.
keyPassword
??
''
;
if
(
keyPassword
.
isEmpty
)
keyPassword
=
keystorePassword
;
}
...
...
@@ -375,7 +373,7 @@ Future<int> buildAndroid({
String
resources:
_kDefaultResourcesPath
,
String
outputFile:
_kDefaultOutputPath
,
String
target:
''
,
String
flxPath
:
''
,
String
flxPath
,
ApkKeystoreInfo
keystore
})
async
{
// Validate that we can find an android sdk.
...
...
@@ -405,7 +403,7 @@ Future<int> buildAndroid({
printStatus
(
'Building APK...'
);
if
(
flxPath
.
isNotEmpty
)
{
if
(
flxPath
!=
null
&&
flxPath
.
isNotEmpty
)
{
if
(!
FileSystemEntity
.
isFileSync
(
flxPath
))
{
printError
(
'FLX does not exist:
$flxPath
'
);
printError
(
'(Omit the --flx option to build the FLX automatically)'
);
...
...
packages/flutter_tools/lib/src/commands/build_flx.dart
0 → 100644
View file @
18c8f577
// Copyright 2015 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
'dart:async'
;
import
'../flx.dart'
;
import
'../globals.dart'
;
import
'../runner/flutter_command.dart'
;
import
'../toolchain.dart'
;
class
BuildFlxCommand
extends
FlutterCommand
{
BuildFlxCommand
()
{
usesTargetOption
();
argParser
.
addFlag
(
'precompiled'
,
negatable:
false
);
// This option is still referenced by the iOS build scripts. We should
// remove it once we've updated those build scripts.
argParser
.
addOption
(
'asset-base'
,
help:
'Ignored. Will be removed.'
,
hide:
true
);
argParser
.
addOption
(
'compiler'
);
argParser
.
addOption
(
'manifest'
,
defaultsTo:
defaultManifestPath
);
argParser
.
addOption
(
'private-key'
,
defaultsTo:
defaultPrivateKeyPath
);
argParser
.
addOption
(
'output-file'
,
abbr:
'o'
,
defaultsTo:
defaultFlxOutputPath
);
argParser
.
addOption
(
'snapshot'
,
defaultsTo:
defaultSnapshotPath
);
argParser
.
addOption
(
'depfile'
,
defaultsTo:
defaultDepfilePath
);
argParser
.
addOption
(
'working-dir'
,
defaultsTo:
defaultWorkingDirPath
);
usesPubOption
();
}
@override
final
String
name
=
'flx'
;
@override
final
String
description
=
'Build a Flutter FLX file from your app.'
;
@override
final
String
usageFooter
=
'FLX files are archives of your application code and resources; '
'they are used by some Flutter Android and iOS runtimes.'
;
@override
Future
<
int
>
runInProject
()
async
{
String
compilerPath
=
argResults
[
'compiler'
];
if
(
compilerPath
==
null
)
await
downloadToolchain
();
else
toolchain
=
new
Toolchain
(
compiler:
new
Compiler
(
compilerPath
));
String
outputPath
=
argResults
[
'output-file'
];
return
await
build
(
toolchain
,
mainPath:
argResults
[
'target'
],
manifestPath:
argResults
[
'manifest'
],
outputPath:
outputPath
,
snapshotPath:
argResults
[
'snapshot'
],
depfilePath:
argResults
[
'depfile'
],
privateKeyPath:
argResults
[
'private-key'
],
workingDirPath:
argResults
[
'working-dir'
],
precompiledSnapshot:
argResults
[
'precompiled'
]
).
then
((
int
result
)
{
if
(
result
==
0
)
printStatus
(
'Built
$outputPath
.'
);
else
printError
(
'Error building
$outputPath
:
$result
.'
);
return
result
;
});
}
}
packages/flutter_tools/lib/src/commands/drive.dart
View file @
18c8f577
...
...
@@ -15,7 +15,7 @@ import '../base/os.dart';
import
'../device.dart'
;
import
'../globals.dart'
;
import
'../ios/simulators.dart'
show
SimControl
,
IOSSimulatorUtils
;
import
'
apk.dart'
as
apk
;
import
'
build_apk.dart'
as
build_
apk
;
import
'run.dart'
;
/// Runs integration (a.k.a. end-to-end) tests.
...
...
@@ -244,7 +244,7 @@ Future<int> startApp(DriveCommand command) async {
if
(
command
.
device
is
AndroidDevice
)
{
printTrace
(
'Building an APK.'
);
int
result
=
await
apk
.
build
(
command
.
toolchain
,
command
.
buildConfigurations
,
int
result
=
await
build_
apk
.
build
(
command
.
toolchain
,
command
.
buildConfigurations
,
enginePath:
command
.
runner
.
enginePath
,
target:
command
.
target
);
if
(
result
!=
0
)
...
...
packages/flutter_tools/lib/src/commands/refresh.dart
View file @
18c8f577
...
...
@@ -19,7 +19,7 @@ class RefreshCommand extends FlutterCommand {
final
String
description
=
'Build and deploy the Dart code in a Flutter app (Android only).'
;
RefreshCommand
()
{
add
TargetOption
();
uses
TargetOption
();
}
@override
...
...
packages/flutter_tools/lib/src/commands/run.dart
View file @
18c8f577
...
...
@@ -15,7 +15,7 @@ import '../device.dart';
import
'../globals.dart'
;
import
'../runner/flutter_command.dart'
;
import
'../toolchain.dart'
;
import
'apk.dart'
;
import
'
build_
apk.dart'
;
import
'install.dart'
;
/// Given the value of the --target option, return the path of the Dart file
...
...
@@ -43,7 +43,7 @@ abstract class RunCommandBase extends FlutterCommand {
help:
'Start tracing during startup.'
);
argParser
.
addOption
(
'route'
,
help:
'Which route to load when starting the app.'
);
add
TargetOption
();
uses
TargetOption
();
}
bool
get
checked
=>
argResults
[
'checked'
];
...
...
@@ -73,12 +73,10 @@ class RunCommand extends RunCommandBase {
defaultsTo:
false
,
negatable:
false
,
help:
'Start in a paused mode and wait for a debugger to connect.'
);
argParser
.
addFlag
(
'pub'
,
defaultsTo:
true
,
help:
'Whether to run "pub get" before running the app.'
);
argParser
.
addOption
(
'debug-port'
,
defaultsTo:
observatoryDefaultPort
.
toString
(),
help:
'Listen to the given port for a debug connection.'
);
usesPubOption
();
}
@override
...
...
packages/flutter_tools/lib/src/runner/flutter_command.dart
View file @
18c8f577
...
...
@@ -7,6 +7,7 @@ import 'dart:io';
import
'package:args/command_runner.dart'
;
import
'../dart/pub.dart'
;
import
'../application_package.dart'
;
import
'../build_configuration.dart'
;
import
'../device.dart'
;
...
...
@@ -18,6 +19,10 @@ import 'flutter_command_runner.dart';
typedef
bool
Validator
(
);
abstract
class
FlutterCommand
extends
Command
{
FlutterCommand
()
{
commandValidator
=
_commandValidator
;
}
@override
FlutterCommandRunner
get
runner
=>
super
.
runner
;
...
...
@@ -30,12 +35,28 @@ abstract class FlutterCommand extends Command {
/// Whether this command only applies to Android devices.
bool
get
androidOnly
=>
false
;
/// Whether this command allows usage of the 'target' option.
bool
get
allowsTarget
=>
_targetOptionSpecified
;
bool
_targetOptionSpecified
=
false
;
/// Whether this command uses the 'target' option.
bool
_usesTargetOption
=
false
;
bool
_usesPubOption
=
false
;
List
<
BuildConfiguration
>
get
buildConfigurations
=>
runner
.
buildConfigurations
;
void
usesTargetOption
()
{
argParser
.
addOption
(
'target'
,
abbr:
't'
,
defaultsTo:
flx
.
defaultMainPath
,
help:
'Target app path / main entry-point file.'
);
_usesTargetOption
=
true
;
}
void
usesPubOption
()
{
argParser
.
addFlag
(
'pub'
,
defaultsTo:
true
,
help:
'Whether to run "pub get" before executing this command.'
);
_usesPubOption
=
true
;
}
Future
<
Null
>
downloadToolchain
()
async
{
toolchain
??=
await
Toolchain
.
forConfigs
(
buildConfigurations
);
}
...
...
@@ -56,8 +77,7 @@ abstract class FlutterCommand extends Command {
}
Future
<
int
>
_run
()
async
{
bool
_checkRoot
=
requiresProjectRoot
&&
allowsTarget
&&
!
_targetSpecified
;
if
(
_checkRoot
&&
!
projectRootValidator
())
if
(
requiresProjectRoot
&&
!
commandValidator
())
return
1
;
// Ensure at least one toolchain is installed.
...
...
@@ -99,19 +119,36 @@ abstract class FlutterCommand extends Command {
}
}
if
(
_usesPubOption
&&
argResults
[
'pub'
])
{
int
exitCode
=
await
pubGet
();
if
(
exitCode
!=
0
)
return
exitCode
;
}
return
await
runInProject
();
}
// This is a field so that you can modify the value for testing.
Validator
projectRootValidator
=
()
{
Validator
commandValidator
;
bool
_commandValidator
()
{
if
(!
FileSystemEntity
.
isFileSync
(
'pubspec.yaml'
))
{
printError
(
'Error: No pubspec.yaml file found.
\n
'
'This command should be run from the root of your Flutter project.
\n
'
'Do not run this command from the root of your git clone of Flutter.'
);
return
false
;
}
if
(
_usesTargetOption
)
{
String
targetPath
=
argResults
[
'target'
];
if
(!
FileSystemEntity
.
isFileSync
(
targetPath
))
{
printError
(
'Target file "
$targetPath
" not found.'
);
return
false
;
}
}
return
true
;
}
;
}
Future
<
int
>
runInProject
();
...
...
@@ -122,15 +159,4 @@ abstract class FlutterCommand extends Command {
ApplicationPackageStore
applicationPackages
;
Toolchain
toolchain
;
bool
_targetSpecified
=
false
;
void
addTargetOption
()
{
argParser
.
addOption
(
'target'
,
abbr:
't'
,
callback:
(
dynamic
val
)
=>
_targetSpecified
=
true
,
defaultsTo:
flx
.
defaultMainPath
,
help:
'Target app path / main entry-point file.'
);
_targetOptionSpecified
=
true
;
}
}
packages/flutter_tools/test/src/mocks.dart
View file @
18c8f577
...
...
@@ -101,5 +101,5 @@ void applyMocksToCommand(FlutterCommand command) {
command
..
applicationPackages
=
new
MockApplicationPackageStore
()
..
toolchain
=
new
MockToolchain
()
..
projectRoot
Validator
=
()
=>
true
;
..
command
Validator
=
()
=>
true
;
}
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