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
6a8f9041
Unverified
Commit
6a8f9041
authored
Jul 16, 2018
by
Sigurd Meldgaard
Committed by
GitHub
Jul 16, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Revert "Use FlutterProject to locate files (#18913)" (#19409)
This reverts commit
57d78cc7
.
parent
f93a65a7
Changes
25
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
25 changed files
with
392 additions
and
438 deletions
+392
-438
android_device.dart
packages/flutter_tools/lib/src/android/android_device.dart
+6
-8
apk.dart
packages/flutter_tools/lib/src/android/apk.dart
+3
-12
gradle.dart
packages/flutter_tools/lib/src/android/gradle.dart
+46
-39
application_package.dart
packages/flutter_tools/lib/src/application_package.dart
+33
-33
build_apk.dart
packages/flutter_tools/lib/src/commands/build_apk.dart
+1
-3
create.dart
packages/flutter_tools/lib/src/commands/create.dart
+31
-30
daemon.dart
packages/flutter_tools/lib/src/commands/daemon.dart
+1
-1
inject_plugins.dart
packages/flutter_tools/lib/src/commands/inject_plugins.dart
+5
-4
run.dart
packages/flutter_tools/lib/src/commands/run.dart
+1
-4
cocoapods.dart
packages/flutter_tools/lib/src/ios/cocoapods.dart
+30
-29
mac.dart
packages/flutter_tools/lib/src/ios/mac.dart
+10
-7
xcodeproj.dart
packages/flutter_tools/lib/src/ios/xcodeproj.dart
+23
-17
plugins.dart
packages/flutter_tools/lib/src/plugins.dart
+52
-43
project.dart
packages/flutter_tools/lib/src/project.dart
+9
-96
resident_runner.dart
packages/flutter_tools/lib/src/resident_runner.dart
+14
-8
run_cold.dart
packages/flutter_tools/lib/src/run_cold.dart
+1
-1
run_hot.dart
packages/flutter_tools/lib/src/run_hot.dart
+1
-1
flutter_tester.dart
packages/flutter_tools/lib/src/tester/flutter_tester.dart
+6
-6
gradle_test.dart
packages/flutter_tools/test/android/gradle_test.dart
+7
-14
application_package_test.dart
packages/flutter_tools/test/application_package_test.dart
+8
-8
cocoapods_test.dart
packages/flutter_tools/test/ios/cocoapods_test.dart
+70
-58
xcodeproj_test.dart
packages/flutter_tools/test/ios/xcodeproj_test.dart
+25
-14
project_test.dart
packages/flutter_tools/test/project_test.dart
+7
-0
mocks.dart
packages/flutter_tools/test/src/mocks.dart
+1
-1
flutter_tester_test.dart
packages/flutter_tools/test/tester/flutter_tester_test.dart
+1
-1
No files found.
packages/flutter_tools/lib/src/android/android_device.dart
View file @
6a8f9041
...
...
@@ -21,7 +21,6 @@ import '../base/utils.dart';
import
'../build_info.dart'
;
import
'../device.dart'
;
import
'../globals.dart'
;
import
'../project.dart'
;
import
'../protocol_discovery.dart'
;
import
'adb.dart'
;
...
...
@@ -242,7 +241,7 @@ class AndroidDevice extends Device {
String
_getSourceSha1
(
ApplicationPackage
app
)
{
final
AndroidApk
apk
=
app
;
final
File
shaFile
=
fs
.
file
(
'
${apk.
file.p
ath}
.sha1'
);
final
File
shaFile
=
fs
.
file
(
'
${apk.
apkP
ath}
.sha1'
);
return
shaFile
.
existsSync
()
?
shaFile
.
readAsStringSync
()
:
''
;
}
...
...
@@ -270,16 +269,16 @@ class AndroidDevice extends Device {
@override
Future
<
bool
>
installApp
(
ApplicationPackage
app
)
async
{
final
AndroidApk
apk
=
app
;
if
(!
apk
.
file
.
existsSync
(
))
{
printError
(
'"
${apk.
file.p
ath}
" does not exist.'
);
if
(!
fs
.
isFileSync
(
apk
.
apkPath
))
{
printError
(
'"
${apk.
apkP
ath}
" does not exist.'
);
return
false
;
}
if
(!
await
_checkForSupportedAdbVersion
()
||
!
await
_checkForSupportedAndroidVersion
())
return
false
;
final
Status
status
=
logger
.
startProgress
(
'Installing
${apk.
file.p
ath}
...'
,
expectSlowOperation:
true
);
final
RunResult
installResult
=
await
runAsync
(
adbCommandForDevice
(<
String
>[
'install'
,
'-t'
,
'-r'
,
apk
.
file
.
p
ath
]));
final
Status
status
=
logger
.
startProgress
(
'Installing
${apk.
apkP
ath}
...'
,
expectSlowOperation:
true
);
final
RunResult
installResult
=
await
runAsync
(
adbCommandForDevice
(<
String
>[
'install'
,
'-t'
,
'-r'
,
apk
.
apkP
ath
]));
status
.
stop
();
// Some versions of adb exit with exit code 0 even on failure :(
// Parsing the output to check for failures.
...
...
@@ -375,13 +374,12 @@ class AndroidDevice extends Device {
if
(!
prebuiltApplication
)
{
printTrace
(
'Building APK'
);
await
buildApk
(
project:
new
FlutterProject
(
fs
.
currentDirectory
),
target:
mainPath
,
buildInfo:
buildInfo
,
);
// Package has been built, so we can get the updated application ID and
// activity name from the .apk.
package
=
await
AndroidApk
.
from
AndroidProject
(
new
FlutterProject
(
fs
.
currentDirectory
).
android
);
package
=
await
AndroidApk
.
from
CurrentDirectory
(
);
}
printTrace
(
"Stopping app '
${package.name}
' on
$name
."
);
...
...
packages/flutter_tools/lib/src/android/apk.dart
View file @
6a8f9041
...
...
@@ -4,22 +4,17 @@
import
'dart:async'
;
import
'package:meta/meta.dart'
;
import
'../base/common.dart'
;
import
'../build_info.dart'
;
import
'../globals.dart'
;
import
'../project.dart'
;
import
'android_sdk.dart'
;
import
'gradle.dart'
;
Future
<
Null
>
buildApk
({
@required
FlutterProject
project
,
@required
String
target
,
String
target
,
BuildInfo
buildInfo
=
BuildInfo
.
debug
})
async
{
if
(!
project
.
android
.
is
UsingGradle
())
{
if
(!
isProject
UsingGradle
())
{
throwToolExit
(
'The build process for Android has changed, and the current project configuration
\n
'
'is no longer valid. Please consult
\n\n
'
...
...
@@ -38,9 +33,5 @@ Future<Null> buildApk({
throwToolExit
(
'Try re-installing or updating your Android SDK.'
);
}
return
buildGradleProject
(
project:
project
,
buildInfo:
buildInfo
,
target:
target
,
);
return
buildGradleProject
(
buildInfo
,
target
);
}
packages/flutter_tools/lib/src/android/gradle.dart
View file @
6a8f9041
...
...
@@ -4,8 +4,6 @@
import
'dart:async'
;
import
'package:meta/meta.dart'
;
import
'../android/android_sdk.dart'
;
import
'../artifacts.dart'
;
import
'../base/common.dart'
;
...
...
@@ -16,13 +14,16 @@ import '../base/platform.dart';
import
'../base/process.dart'
;
import
'../base/utils.dart'
;
import
'../build_info.dart'
;
import
'../bundle.dart'
as
bundle
;
import
'../cache.dart'
;
import
'../flutter_manifest.dart'
;
import
'../globals.dart'
;
import
'../project.dart'
;
import
'android_sdk.dart'
;
import
'android_studio.dart'
;
const
String
gradleManifestPath
=
'android/app/src/main/AndroidManifest.xml'
;
const
String
gradleAppOutV1
=
'android/app/build/outputs/apk/app-debug.apk'
;
const
String
gradleAppOutDirV1
=
'android/app/build/outputs/apk'
;
const
String
gradleVersion
=
'4.1'
;
final
RegExp
_assembleTaskPattern
=
new
RegExp
(
r'assemble([^:]+): task '
);
...
...
@@ -44,6 +45,9 @@ final RegExp ndkMessageFilter = new RegExp(r'^(?!NDK is missing a ".*" directory
r'|If you are using NDK, verify the ndk.dir is set to a valid NDK directory. It is currently set to .*)'
);
bool
isProjectUsingGradle
(
)
{
return
fs
.
isFileSync
(
'android/build.gradle'
);
}
FlutterPluginVersion
get
flutterPluginVersion
{
final
File
plugin
=
fs
.
file
(
'android/buildSrc/src/main/groovy/FlutterPlugin.groovy'
);
...
...
@@ -65,17 +69,18 @@ FlutterPluginVersion get flutterPluginVersion {
return
FlutterPluginVersion
.
none
;
}
/// Returns the apk file created by [buildGradleProject]
Future
<
File
>
getGradleAppOut
(
AndroidProject
androidProject
)
async
{
/// Returns the path to the apk file created by [buildGradleProject], relative
/// to current directory.
Future
<
String
>
getGradleAppOut
()
async
{
switch
(
flutterPluginVersion
)
{
case
FlutterPluginVersion
.
none
:
// Fall through. Pretend we're v1, and just go with it.
case
FlutterPluginVersion
.
v1
:
return
androidProject
.
gradleAppOutV1File
;
return
gradleAppOutV1
;
case
FlutterPluginVersion
.
managed
:
// Fall through. The managed plugin matches plugin v2 for now.
case
FlutterPluginVersion
.
v2
:
return
fs
.
file
((
await
_gradleProject
()).
apkDirectory
.
childFile
(
'app.apk'
));
return
fs
.
path
.
relative
(
fs
.
path
.
join
((
await
_gradleProject
()).
apkDirectory
,
'app.apk'
));
}
return
null
;
}
...
...
@@ -89,13 +94,12 @@ Future<GradleProject> _gradleProject() async {
// of calculating the app properties using Gradle. This may take minutes.
Future
<
GradleProject
>
_readGradleProject
()
async
{
final
String
gradle
=
await
_ensureGradle
();
final
FlutterProject
flutterProject
=
new
FlutterProject
(
fs
.
currentDirectory
);
await
updateLocalProperties
(
project:
flutterProject
);
await
updateLocalProperties
();
try
{
final
Status
status
=
logger
.
startProgress
(
'Resolving dependencies...'
,
expectSlowOperation:
true
);
final
RunResult
runResult
=
await
runCheckedAsync
(
<
String
>[
gradle
,
'app:properties'
],
workingDirectory:
flutterProject
.
android
.
directory
.
path
,
workingDirectory:
'android'
,
environment:
_gradleEnv
,
);
final
String
properties
=
runResult
.
stdout
.
trim
();
...
...
@@ -113,7 +117,7 @@ Future<GradleProject> _readGradleProject() async {
}
}
// Fall back to the default
return
new
GradleProject
(<
String
>[
'debug'
,
'profile'
,
'release'
],
<
String
>[],
flutterProject
.
android
.
gradleAppOutV1Directory
);
return
new
GradleProject
(<
String
>[
'debug'
,
'profile'
,
'release'
],
<
String
>[],
gradleAppOutDirV1
);
}
void
handleKnownGradleExceptions
(
String
exceptionString
)
{
...
...
@@ -195,19 +199,28 @@ distributionUrl=https\\://services.gradle.org/distributions/gradle-$gradleVersio
/// Overwrite android/local.properties in the specified Flutter project, if needed.
///
/// Throws, if `pubspec.yaml` or Android SDK cannot be located.
///
/// If [requireSdk] is `true` this will fail with a tool-exit if no Android Sdk
/// is found.
Future
<
void
>
updateLocalProperties
({
@required
FlutterProject
project
,
BuildInfo
buildInfo
,
bool
requireAndroidSdk
=
true
,
})
async
{
if
(
requireAndroidSdk
&&
androidSdk
==
null
)
{
Future
<
void
>
updateLocalProperties
({
String
projectPath
,
BuildInfo
buildInfo
})
async
{
final
Directory
android
=
(
projectPath
==
null
)
?
fs
.
directory
(
'android'
)
:
fs
.
directory
(
fs
.
path
.
join
(
projectPath
,
'android'
));
final
String
flutterManifest
=
(
projectPath
==
null
)
?
fs
.
path
.
join
(
bundle
.
defaultManifestPath
)
:
fs
.
path
.
join
(
projectPath
,
bundle
.
defaultManifestPath
);
if
(
androidSdk
==
null
)
{
throwToolExit
(
'Unable to locate Android SDK. Please run `flutter doctor` for more details.'
);
}
FlutterManifest
manifest
;
try
{
manifest
=
await
FlutterManifest
.
createFromPath
(
flutterManifest
);
}
catch
(
error
)
{
throwToolExit
(
'Failed to load pubspec.yaml:
$error
'
);
}
updateLocalPropertiesSync
(
android
,
manifest
,
buildInfo
);
}
final
File
localProperties
=
await
project
.
androidLocalPropertiesFile
;
/// Overwrite local.properties in the specified directory, if needed.
void
updateLocalPropertiesSync
(
Directory
android
,
FlutterManifest
manifest
,
[
BuildInfo
buildInfo
])
{
final
File
localProperties
=
android
.
childFile
(
'local.properties'
);
bool
changed
=
false
;
SettingsFile
settings
;
...
...
@@ -225,8 +238,6 @@ Future<void> updateLocalProperties({
}
}
final
FlutterManifest
manifest
=
await
project
.
manifest
;
if
(
androidSdk
!=
null
)
changeIfNecessary
(
'sdk.dir'
,
escapePath
(
androidSdk
.
directory
));
changeIfNecessary
(
'flutter.sdk'
,
escapePath
(
Cache
.
flutterRoot
));
...
...
@@ -243,11 +254,7 @@ Future<void> updateLocalProperties({
settings
.
writeContents
(
localProperties
);
}
Future
<
Null
>
buildGradleProject
({
@required
FlutterProject
project
,
@required
BuildInfo
buildInfo
,
@required
String
target
,
})
async
{
Future
<
Null
>
buildGradleProject
(
BuildInfo
buildInfo
,
String
target
)
async
{
// Update the local.properties file with the build mode, version name and code.
// FlutterPlugin v1 reads local.properties to determine build mode. Plugin v2
// uses the standard Android way to determine what to build, but we still
...
...
@@ -256,7 +263,7 @@ Future<Null> buildGradleProject({
// and can be overwritten with flutter build command.
// The default Gradle script reads the version name and number
// from the local.properties file.
await
updateLocalProperties
(
project:
project
,
buildInfo:
buildInfo
);
await
updateLocalProperties
(
buildInfo:
buildInfo
);
final
String
gradle
=
await
_ensureGradle
();
...
...
@@ -264,7 +271,7 @@ Future<Null> buildGradleProject({
case
FlutterPluginVersion
.
none
:
// Fall through. Pretend it's v1, and just go for it.
case
FlutterPluginVersion
.
v1
:
return
_buildGradleProjectV1
(
project
,
gradle
);
return
_buildGradleProjectV1
(
gradle
);
case
FlutterPluginVersion
.
managed
:
// Fall through. Managed plugin builds the same way as plugin v2.
case
FlutterPluginVersion
.
v2
:
...
...
@@ -272,7 +279,7 @@ Future<Null> buildGradleProject({
}
}
Future
<
Null
>
_buildGradleProjectV1
(
FlutterProject
project
,
String
gradle
)
async
{
Future
<
Null
>
_buildGradleProjectV1
(
String
gradle
)
async
{
// Run 'gradlew build'.
final
Status
status
=
logger
.
startProgress
(
'Running
\'
gradlew build
\'
...'
,
expectSlowOperation:
true
);
final
int
exitCode
=
await
runCommandAndStreamOutput
(
...
...
@@ -286,7 +293,7 @@ Future<Null> _buildGradleProjectV1(FlutterProject project, String gradle) async
if
(
exitCode
!=
0
)
throwToolExit
(
'Gradle build failed:
$exitCode
'
,
exitCode:
exitCode
);
printStatus
(
'Built
$
{fs.path.relative(project.android.gradleAppOutV1File.path)}
.'
);
printStatus
(
'Built
$
gradleAppOutV1
.'
);
}
Future
<
Null
>
_buildGradleProjectV2
(
String
gradle
,
BuildInfo
buildInfo
,
String
target
)
async
{
...
...
@@ -364,10 +371,10 @@ Future<Null> _buildGradleProjectV2(String gradle, BuildInfo buildInfo, String ta
if
(
apkFile
==
null
)
throwToolExit
(
'Gradle build failed to produce an Android package.'
);
// Copy the APK to app.apk, so `flutter run`, `flutter install`, etc. can find it.
apkFile
.
copySync
(
project
.
apkDirectory
.
childFile
(
'app.apk'
).
path
);
apkFile
.
copySync
(
fs
.
path
.
join
(
project
.
apkDirectory
,
'app.apk'
)
);
printTrace
(
'calculateSha:
${project.apkDirectory}
/app.apk'
);
final
File
apkShaFile
=
project
.
apkDirectory
.
childFile
(
'app.apk.sha1'
);
final
File
apkShaFile
=
fs
.
file
(
fs
.
path
.
join
(
project
.
apkDirectory
,
'app.apk.sha1'
)
);
apkShaFile
.
writeAsStringSync
(
calculateSha
(
apkFile
));
String
appSize
;
...
...
@@ -383,15 +390,15 @@ File _findApkFile(GradleProject project, BuildInfo buildInfo) {
final
String
apkFileName
=
project
.
apkFileFor
(
buildInfo
);
if
(
apkFileName
==
null
)
return
null
;
File
apkFile
=
fs
.
file
(
fs
.
path
.
join
(
project
.
apkDirectory
.
path
,
apkFileName
));
File
apkFile
=
fs
.
file
(
fs
.
path
.
join
(
project
.
apkDirectory
,
apkFileName
));
if
(
apkFile
.
existsSync
())
return
apkFile
;
apkFile
=
fs
.
file
(
fs
.
path
.
join
(
project
.
apkDirectory
.
path
,
buildInfo
.
modeName
,
apkFileName
));
apkFile
=
fs
.
file
(
fs
.
path
.
join
(
project
.
apkDirectory
,
buildInfo
.
modeName
,
apkFileName
));
if
(
apkFile
.
existsSync
())
return
apkFile
;
if
(
buildInfo
.
flavor
!=
null
)
{
// Android Studio Gradle plugin v3 adds flavor to path.
apkFile
=
fs
.
file
(
fs
.
path
.
join
(
project
.
apkDirectory
.
path
,
buildInfo
.
flavor
,
buildInfo
.
modeName
,
apkFileName
));
apkFile
=
fs
.
file
(
fs
.
path
.
join
(
project
.
apkDirectory
,
buildInfo
.
flavor
,
buildInfo
.
modeName
,
apkFileName
));
if
(
apkFile
.
existsSync
())
return
apkFile
;
}
...
...
@@ -446,13 +453,13 @@ class GradleProject {
return
new
GradleProject
(
buildTypes
.
toList
(),
productFlavors
.
toList
(),
fs
.
directory
(
fs
.
path
.
join
(
buildDir
,
'outputs'
,
'apk'
)),
fs
.
path
.
normalize
(
fs
.
path
.
join
(
buildDir
,
'outputs'
,
'apk'
)),
);
}
final
List
<
String
>
buildTypes
;
final
List
<
String
>
productFlavors
;
final
Directory
apkDirectory
;
final
String
apkDirectory
;
String
_buildTypeFor
(
BuildInfo
buildInfo
)
{
if
(
buildTypes
.
contains
(
buildInfo
.
modeName
))
...
...
packages/flutter_tools/lib/src/application_package.dart
View file @
6a8f9041
...
...
@@ -18,7 +18,6 @@ import 'globals.dart';
import
'ios/ios_workflow.dart'
;
import
'ios/plist_utils.dart'
as
plist
;
import
'ios/xcodeproj.dart'
;
import
'project.dart'
;
import
'tester/flutter_tester.dart'
;
abstract
class
ApplicationPackage
{
...
...
@@ -32,7 +31,7 @@ abstract class ApplicationPackage {
String
get
displayName
=>
name
;
File
get
packagesFile
=>
null
;
String
get
packagePath
=>
null
;
@override
String
toString
()
=>
displayName
;
...
...
@@ -40,21 +39,21 @@ abstract class ApplicationPackage {
class
AndroidApk
extends
ApplicationPackage
{
/// Path to the actual apk file.
final
File
file
;
final
String
apkPath
;
/// The path to the activity that should be launched.
final
String
launchActivity
;
AndroidApk
({
String
id
,
@required
this
.
file
,
@required
this
.
apkPath
,
@required
this
.
launchActivity
})
:
assert
(
file
!=
null
),
})
:
assert
(
apkPath
!=
null
),
assert
(
launchActivity
!=
null
),
super
(
id:
id
);
/// Creates a new AndroidApk from an existing APK.
factory
AndroidApk
.
fromApk
(
File
apk
)
{
factory
AndroidApk
.
fromApk
(
String
applicationBinary
)
{
final
String
aaptPath
=
androidSdk
?.
latestVersion
?.
aaptPath
;
if
(
aaptPath
==
null
)
{
printError
(
'Unable to locate the Android SDK; please run
\'
flutter doctor
\'
.'
);
...
...
@@ -65,7 +64,7 @@ class AndroidApk extends ApplicationPackage {
aaptPath
,
'dump'
,
'xmltree'
,
ap
k
.
path
,
ap
plicationBinary
,
'AndroidManifest.xml'
,
];
...
...
@@ -73,46 +72,47 @@ class AndroidApk extends ApplicationPackage {
.
parseFromXmlDump
(
runCheckedSync
(
aaptArgs
));
if
(
data
==
null
)
{
printError
(
'Unable to read manifest info from
$
{apk.path}
.'
);
printError
(
'Unable to read manifest info from
$
applicationBinary
.'
);
return
null
;
}
if
(
data
.
packageName
==
null
||
data
.
launchableActivityName
==
null
)
{
printError
(
'Unable to read manifest info from
$
{apk.path}
.'
);
printError
(
'Unable to read manifest info from
$
applicationBinary
.'
);
return
null
;
}
return
new
AndroidApk
(
id:
data
.
packageName
,
file:
apk
,
apkPath:
applicationBinary
,
launchActivity:
'
${data.packageName}
/
${data.launchableActivityName}
'
);
}
/// Creates a new AndroidApk based on the information in the Android manifest.
static
Future
<
AndroidApk
>
fromAndroidProject
(
AndroidProject
androidProject
)
async
{
File
apkFile
;
static
Future
<
AndroidApk
>
fromCurrentDirectory
()
async
{
String
manifestPath
;
String
apkPath
;
if
(
androidProject
.
is
UsingGradle
())
{
apk
File
=
await
getGradleAppOut
(
androidProject
);
if
(
apkFile
.
existsSync
())
{
if
(
isProject
UsingGradle
())
{
apk
Path
=
await
getGradleAppOut
(
);
if
(
fs
.
file
(
apkPath
)
.
existsSync
())
{
// Grab information from the .apk. The gradle build script might alter
// the application Id, so we need to look at what was actually built.
return
new
AndroidApk
.
fromApk
(
apk
File
);
return
new
AndroidApk
.
fromApk
(
apk
Path
);
}
// The .apk hasn't been built yet, so we work with what we have. The run
// command will grab a new AndroidApk after building, to get the updated
// IDs.
manifestPath
=
gradleManifestPath
;
}
else
{
apkFile
=
fs
.
file
(
fs
.
path
.
join
(
getAndroidBuildDirectory
(),
'app.apk'
));
manifestPath
=
fs
.
path
.
join
(
'android'
,
'AndroidManifest.xml'
);
apkPath
=
fs
.
path
.
join
(
getAndroidBuildDirectory
(),
'app.apk'
);
}
final
File
manifest
=
androidProject
.
gradleManifestFile
;
if
(!
manifest
.
existsSync
())
if
(!
fs
.
isFileSync
(
manifestPath
))
return
null
;
final
String
manifestString
=
manifest
.
readAsStringSync
();
final
String
manifestString
=
fs
.
file
(
manifestPath
)
.
readAsStringSync
();
final
xml
.
XmlDocument
document
=
xml
.
parse
(
manifestString
);
final
Iterable
<
xml
.
XmlElement
>
manifests
=
document
.
findElements
(
'manifest'
);
...
...
@@ -138,16 +138,16 @@ class AndroidApk extends ApplicationPackage {
return
new
AndroidApk
(
id:
packageId
,
file:
apkFile
,
apkPath:
apkPath
,
launchActivity:
launchActivity
);
}
@override
File
get
packagesFile
=>
file
;
String
get
packagePath
=>
apkPath
;
@override
String
get
name
=>
f
ile
.
basename
;
String
get
name
=>
f
s
.
path
.
basename
(
apkPath
)
;
}
/// Tests whether a [FileSystemEntity] is an iOS bundle directory
...
...
@@ -158,18 +158,18 @@ abstract class IOSApp extends ApplicationPackage {
IOSApp
({
@required
String
projectBundleId
})
:
super
(
id:
projectBundleId
);
/// Creates a new IOSApp from an existing app bundle or IPA.
factory
IOSApp
.
fromPrebuiltApp
(
File
applicationBinary
)
{
final
FileSystemEntityType
entityType
=
fs
.
typeSync
(
applicationBinary
.
path
);
factory
IOSApp
.
fromPrebuiltApp
(
String
applicationBinary
)
{
final
FileSystemEntityType
entityType
=
fs
.
typeSync
(
applicationBinary
);
if
(
entityType
==
FileSystemEntityType
.
notFound
)
{
printError
(
'File "
$
{applicationBinary.path}
" does not exist. Use an app bundle or an ipa.'
);
'File "
$
applicationBinary
" does not exist. Use an app bundle or an ipa.'
);
return
null
;
}
Directory
bundleDir
;
if
(
entityType
==
FileSystemEntityType
.
directory
)
{
final
Directory
directory
=
fs
.
directory
(
applicationBinary
);
if
(!
_isBundleDirectory
(
directory
))
{
printError
(
'Folder "
$
{applicationBinary.path}
" is not an app bundle.'
);
printError
(
'Folder "
$
applicationBinary
" is not an app bundle.'
);
return
null
;
}
bundleDir
=
fs
.
directory
(
applicationBinary
);
...
...
@@ -305,16 +305,16 @@ class PrebuiltIOSApp extends IOSApp {
String
get
_bundlePath
=>
bundleDir
.
path
;
}
Future
<
ApplicationPackage
>
getApplicationPackageForPlatform
(
TargetPlatform
platform
,
{
File
applicationBinary
})
async
{
Future
<
ApplicationPackage
>
getApplicationPackageForPlatform
(
TargetPlatform
platform
,
{
String
applicationBinary
})
async
{
switch
(
platform
)
{
case
TargetPlatform
.
android_arm
:
case
TargetPlatform
.
android_arm64
:
case
TargetPlatform
.
android_x64
:
case
TargetPlatform
.
android_x86
:
return
applicationBinary
==
null
?
await
AndroidApk
.
from
AndroidProject
(
new
FlutterProject
(
fs
.
currentDirectory
).
android
)
?
await
AndroidApk
.
from
CurrentDirectory
(
)
:
new
AndroidApk
.
fromApk
(
applicationBinary
);
case
TargetPlatform
.
ios
:
return
applicationBinary
==
null
...
...
@@ -344,7 +344,7 @@ class ApplicationPackageStore {
case
TargetPlatform
.
android_arm64
:
case
TargetPlatform
.
android_x64
:
case
TargetPlatform
.
android_x86
:
android
??=
await
AndroidApk
.
from
AndroidProject
(
new
FlutterProject
(
fs
.
currentDirectory
).
android
);
android
??=
await
AndroidApk
.
from
CurrentDirectory
(
);
return
android
;
case
TargetPlatform
.
ios
:
iOS
??=
new
IOSApp
.
fromCurrentDirectory
();
...
...
packages/flutter_tools/lib/src/commands/build_apk.dart
View file @
6a8f9041
...
...
@@ -5,8 +5,6 @@
import
'dart:async'
;
import
'../android/apk.dart'
;
import
'../base/file_system.dart'
;
import
'../project.dart'
;
import
'build.dart'
;
class
BuildApkCommand
extends
BuildSubCommand
{
...
...
@@ -46,6 +44,6 @@ class BuildApkCommand extends BuildSubCommand {
@override
Future
<
Null
>
runCommand
()
async
{
await
super
.
runCommand
();
await
buildApk
(
project:
new
FlutterProject
(
fs
.
currentDirectory
),
target:
targetFile
,
buildInfo:
getBuildInfo
()
);
await
buildApk
(
buildInfo:
getBuildInfo
(),
target:
targetFile
);
}
}
packages/flutter_tools/lib/src/commands/create.dart
View file @
6a8f9041
...
...
@@ -168,19 +168,20 @@ class CreateCommand extends FlutterCommand {
printStatus
(
'Creating project
${fs.path.relative(dirPath)}
...'
);
int
generatedFileCount
=
0
;
final
FlutterProject
project
=
new
FlutterProject
.
fromPath
(
dirPath
)
;
String
appPath
=
dirPath
;
switch
(
template
)
{
case
'app'
:
generatedFileCount
+=
await
_generateApp
(
project
,
templateContext
);
generatedFileCount
+=
await
_generateApp
(
dirPath
,
templateContext
);
break
;
case
'module'
:
generatedFileCount
+=
await
_generateModule
(
project
,
templateContext
);
generatedFileCount
+=
await
_generateModule
(
dirPath
,
templateContext
);
break
;
case
'package'
:
generatedFileCount
+=
await
_generatePackage
(
project
,
templateContext
);
generatedFileCount
+=
await
_generatePackage
(
dirPath
,
templateContext
);
break
;
case
'plugin'
:
generatedFileCount
+=
await
_generatePlugin
(
project
,
templateContext
);
appPath
=
fs
.
path
.
join
(
dirPath
,
'example'
);
generatedFileCount
+=
await
_generatePlugin
(
dirPath
,
appPath
,
templateContext
);
break
;
}
printStatus
(
'Wrote
$generatedFileCount
files.'
);
...
...
@@ -193,8 +194,7 @@ class CreateCommand extends FlutterCommand {
printStatus
(
'Your module code is in lib/main.dart in the
$relativePath
directory.'
);
}
else
{
// Run doctor; tell the user the next steps.
final
FlutterProject
app
=
project
.
hasExampleApp
?
project
.
example
:
project
;
final
String
relativeAppPath
=
fs
.
path
.
relative
(
app
.
directory
.
path
);
final
String
relativeAppPath
=
fs
.
path
.
relative
(
appPath
);
final
String
relativePluginPath
=
fs
.
path
.
relative
(
dirPath
);
if
(
doctor
.
canLaunchAnything
)
{
// Let them know a summary of the state of their tooling.
...
...
@@ -233,59 +233,60 @@ To edit platform code in an IDE see https://flutter.io/developing-packages/#edit
}
}
Future
<
int
>
_generateModule
(
FlutterProject
project
,
Map
<
String
,
dynamic
>
templateContext
)
async
{
Future
<
int
>
_generateModule
(
String
path
,
Map
<
String
,
dynamic
>
templateContext
)
async
{
int
generatedCount
=
0
;
final
String
description
=
argResults
.
wasParsed
(
'description'
)
?
argResults
[
'description'
]
:
'A new flutter module project.'
;
templateContext
[
'description'
]
=
description
;
generatedCount
+=
_renderTemplate
(
fs
.
path
.
join
(
'module'
,
'common'
),
p
roject
.
directory
,
templateContext
);
generatedCount
+=
_renderTemplate
(
fs
.
path
.
join
(
'module'
,
'common'
),
p
ath
,
templateContext
);
if
(
argResults
[
'pub'
])
{
await
pubGet
(
context:
PubContext
.
create
,
directory:
p
roject
.
directory
.
p
ath
,
directory:
path
,
offline:
argResults
[
'offline'
],
);
final
FlutterProject
project
=
new
FlutterProject
.
fromPath
(
path
);
await
project
.
ensureReadyForPlatformSpecificTooling
();
}
return
generatedCount
;
}
Future
<
int
>
_generatePackage
(
FlutterProject
project
,
Map
<
String
,
dynamic
>
templateContext
)
async
{
Future
<
int
>
_generatePackage
(
String
dirPath
,
Map
<
String
,
dynamic
>
templateContext
)
async
{
int
generatedCount
=
0
;
final
String
description
=
argResults
.
wasParsed
(
'description'
)
?
argResults
[
'description'
]
:
'A new flutter package project.'
;
templateContext
[
'description'
]
=
description
;
generatedCount
+=
_renderTemplate
(
'package'
,
project
.
directory
,
templateContext
);
generatedCount
+=
_renderTemplate
(
'package'
,
dirPath
,
templateContext
);
if
(
argResults
[
'pub'
])
{
await
pubGet
(
context:
PubContext
.
createPackage
,
directory:
project
.
directory
.
p
ath
,
directory:
dirP
ath
,
offline:
argResults
[
'offline'
],
);
}
return
generatedCount
;
}
Future
<
int
>
_generatePlugin
(
FlutterProject
project
,
Map
<
String
,
dynamic
>
templateContext
)
async
{
Future
<
int
>
_generatePlugin
(
String
dirPath
,
String
appPath
,
Map
<
String
,
dynamic
>
templateContext
)
async
{
int
generatedCount
=
0
;
final
String
description
=
argResults
.
wasParsed
(
'description'
)
?
argResults
[
'description'
]
:
'A new flutter plugin project.'
;
templateContext
[
'description'
]
=
description
;
generatedCount
+=
_renderTemplate
(
'plugin'
,
project
.
directory
,
templateContext
);
generatedCount
+=
_renderTemplate
(
'plugin'
,
dirPath
,
templateContext
);
if
(
argResults
[
'pub'
])
{
await
pubGet
(
context:
PubContext
.
createPlugin
,
directory:
project
.
directory
.
p
ath
,
directory:
dirP
ath
,
offline:
argResults
[
'offline'
],
);
}
if
(
android_sdk
.
androidSdk
!=
null
)
await
gradle
.
updateLocalProperties
(
project
:
project
);
await
gradle
.
updateLocalProperties
(
project
Path:
dirPath
);
final
String
projectName
=
templateContext
[
'projectName'
];
final
String
organization
=
templateContext
[
'organization'
];
...
...
@@ -298,27 +299,27 @@ To edit platform code in an IDE see https://flutter.io/developing-packages/#edit
templateContext
[
'pluginProjectName'
]
=
projectName
;
templateContext
[
'androidPluginIdentifier'
]
=
androidPluginIdentifier
;
generatedCount
+=
await
_generateApp
(
project
.
example
,
templateContext
);
generatedCount
+=
await
_generateApp
(
appPath
,
templateContext
);
return
generatedCount
;
}
Future
<
int
>
_generateApp
(
FlutterProject
project
,
Map
<
String
,
dynamic
>
templateContext
)
async
{
Future
<
int
>
_generateApp
(
String
projectPath
,
Map
<
String
,
dynamic
>
templateContext
)
async
{
int
generatedCount
=
0
;
generatedCount
+=
_renderTemplate
(
'create'
,
project
.
directory
,
templateContext
);
generatedCount
+=
_injectGradleWrapper
(
project
);
generatedCount
+=
_renderTemplate
(
'create'
,
project
Path
,
templateContext
);
generatedCount
+=
_injectGradleWrapper
(
project
Path
);
if
(
argResults
[
'with-driver-test'
])
{
final
Directory
testDirectory
=
project
.
directory
.
childDirectory
(
'test_driver'
);
generatedCount
+=
_renderTemplate
(
'driver'
,
test
Directory
,
templateContext
);
final
String
testPath
=
fs
.
path
.
join
(
projectPath
,
'test_driver'
);
generatedCount
+=
_renderTemplate
(
'driver'
,
test
Path
,
templateContext
);
}
if
(
argResults
[
'pub'
])
{
await
pubGet
(
context:
PubContext
.
create
,
directory:
project
.
directory
.
p
ath
,
offline:
argResults
[
'offline'
]);
await
project
.
ensureReadyForPlatformSpecificTooling
();
await
pubGet
(
context:
PubContext
.
create
,
directory:
project
P
ath
,
offline:
argResults
[
'offline'
]);
await
new
FlutterProject
.
fromPath
(
projectPath
)
.
ensureReadyForPlatformSpecificTooling
();
}
if
(
android_sdk
.
androidSdk
!=
null
)
await
gradle
.
updateLocalProperties
(
project
:
project
);
await
gradle
.
updateLocalProperties
(
project
Path:
projectPath
);
return
generatedCount
;
}
...
...
@@ -361,16 +362,16 @@ To edit platform code in an IDE see https://flutter.io/developing-packages/#edit
};
}
int
_renderTemplate
(
String
templateName
,
Directory
directory
,
Map
<
String
,
dynamic
>
context
)
{
int
_renderTemplate
(
String
templateName
,
String
dirPath
,
Map
<
String
,
dynamic
>
context
)
{
final
Template
template
=
new
Template
.
fromName
(
templateName
);
return
template
.
render
(
directory
,
context
,
overwriteExisting:
false
);
return
template
.
render
(
fs
.
directory
(
dirPath
)
,
context
,
overwriteExisting:
false
);
}
int
_injectGradleWrapper
(
FlutterProject
project
)
{
int
_injectGradleWrapper
(
String
projectDir
)
{
int
filesCreated
=
0
;
copyDirectorySync
(
cache
.
getArtifactDirectory
(
'gradle_wrapper'
),
project
.
android
.
directory
,
fs
.
directory
(
fs
.
path
.
join
(
projectDir
,
'android'
))
,
(
File
sourceFile
,
File
destinationFile
)
{
filesCreated
++;
final
String
modes
=
sourceFile
.
statSync
().
modeString
();
...
...
packages/flutter_tools/lib/src/commands/daemon.dart
View file @
6a8f9041
...
...
@@ -322,7 +322,7 @@ class AppDomain extends Domain {
Future
<
AppInstance
>
startApp
(
Device
device
,
String
projectDirectory
,
String
target
,
String
route
,
DebuggingOptions
options
,
bool
enableHotReload
,
{
File
applicationBinary
,
String
applicationBinary
,
@required
bool
trackWidgetCreation
,
String
projectRootPath
,
String
packagesFilePath
,
...
...
packages/flutter_tools/lib/src/commands/inject_plugins.dart
View file @
6a8f9041
...
...
@@ -5,9 +5,9 @@
import
'dart:async'
;
import
'../base/file_system.dart'
;
import
'../flutter_manifest.dart'
;
import
'../globals.dart'
;
import
'../plugins.dart'
;
import
'../project.dart'
;
import
'../runner/flutter_command.dart'
;
class
InjectPluginsCommand
extends
FlutterCommand
{
...
...
@@ -26,9 +26,10 @@ class InjectPluginsCommand extends FlutterCommand {
@override
Future
<
Null
>
runCommand
()
async
{
final
FlutterProject
project
=
new
FlutterProject
(
fs
.
currentDirectory
);
await
injectPlugins
(
project
);
final
bool
result
=
hasPlugins
(
project
);
final
String
projectPath
=
fs
.
currentDirectory
.
path
;
final
FlutterManifest
manifest
=
await
FlutterManifest
.
createFromPath
(
projectPath
);
injectPlugins
(
projectPath:
projectPath
,
manifest:
manifest
);
final
bool
result
=
hasPlugins
();
if
(
result
)
{
printStatus
(
'GeneratedPluginRegistrants successfully written.'
);
}
else
{
...
...
packages/flutter_tools/lib/src/commands/run.dart
View file @
6a8f9041
...
...
@@ -289,13 +289,10 @@ class RunCommand extends RunCommandBase {
notifyingLogger:
new
NotifyingLogger
(),
logToStdout:
true
);
AppInstance
app
;
try
{
final
String
applicationBinaryPath
=
argResults
[
'use-application-binary'
];
app
=
await
daemon
.
appDomain
.
startApp
(
devices
.
first
,
fs
.
currentDirectory
.
path
,
targetFile
,
route
,
_createDebuggingOptions
(),
hotMode
,
applicationBinary:
applicationBinaryPath
==
null
?
null
:
fs
.
file
(
applicationBinaryPath
),
applicationBinary:
argResults
[
'use-application-binary'
],
trackWidgetCreation:
argResults
[
'track-widget-creation'
],
projectRootPath:
argResults
[
'project-root'
],
packagesFilePath:
globalResults
[
'packages'
],
...
...
packages/flutter_tools/lib/src/ios/cocoapods.dart
View file @
6a8f9041
...
...
@@ -15,8 +15,8 @@ import '../base/process.dart';
import
'../base/process_manager.dart'
;
import
'../base/version.dart'
;
import
'../cache.dart'
;
import
'../flutter_manifest.dart'
;
import
'../globals.dart'
;
import
'../project.dart'
;
import
'xcodeproj.dart'
;
const
String
noCocoaPodsConsequence
=
'''
...
...
@@ -81,18 +81,18 @@ class CocoaPods {
Future
<
bool
>
get
isCocoaPodsInitialized
=>
fs
.
isDirectory
(
fs
.
path
.
join
(
homeDirPath
,
'.cocoapods'
,
'repos'
,
'master'
));
Future
<
bool
>
processPods
({
@required
IosProject
iosProject
,
@required
Directory
appIosDirectory
,
// For backward compatibility with previously created Podfile only.
@required
String
iosEngineDir
,
bool
isSwift
=
false
,
bool
dependenciesChanged
=
true
,
})
async
{
if
(!(
await
iosProject
.
podfile
.
exists
()))
{
if
(!(
await
appIosDirectory
.
childFile
(
'Podfile'
)
.
exists
()))
{
throwToolExit
(
'Podfile missing'
);
}
if
(
await
_checkPodCondition
())
{
if
(
_shouldRunPodInstall
(
iosProject
,
dependenciesChanged
))
{
await
_runPodInstall
(
iosProject
,
iosEngineDir
);
if
(
_shouldRunPodInstall
(
appIosDirectory
,
dependenciesChanged
))
{
await
_runPodInstall
(
appIosDirectory
,
iosEngineDir
);
return
true
;
}
}
...
...
@@ -151,18 +151,18 @@ class CocoaPods {
/// Ensures the `ios` sub-project of the Flutter project at [appDirectory]
/// contains a suitable `Podfile` and that its `Flutter/Xxx.xcconfig` files
/// include pods configuration.
void
setupPodfile
(
IosProject
iosProjec
t
)
{
void
setupPodfile
(
String
appDirectory
,
FlutterManifest
manifes
t
)
{
if
(!
xcodeProjectInterpreter
.
isInstalled
)
{
// Don't do anything for iOS when host platform doesn't support it.
return
;
}
if
(!
iosProject
.
directory
.
existsSync
())
{
if
(!
fs
.
directory
(
fs
.
path
.
join
(
appDirectory
,
'ios'
))
.
existsSync
())
{
return
;
}
final
File
podfile
=
iosProject
.
podfile
;
if
(!
podfile
.
existsSync
())
{
final
String
podfilePath
=
fs
.
path
.
join
(
appDirectory
,
'ios'
,
'Podfile'
)
;
if
(!
fs
.
file
(
podfilePath
)
.
existsSync
())
{
final
bool
isSwift
=
xcodeProjectInterpreter
.
getBuildSettings
(
iosProject
.
directory
.
childFile
(
'Runner.xcodeproj'
).
path
,
fs
.
path
.
join
(
appDirectory
,
'ios'
,
'Runner.xcodeproj'
)
,
'Runner'
,
).
containsKey
(
'SWIFT_VERSION'
);
final
File
podfileTemplate
=
fs
.
file
(
fs
.
path
.
join
(
...
...
@@ -173,14 +173,15 @@ class CocoaPods {
'cocoapods'
,
isSwift
?
'Podfile-swift'
:
'Podfile-objc'
,
));
podfileTemplate
.
copySync
(
podfile
.
p
ath
);
podfileTemplate
.
copySync
(
podfile
P
ath
);
}
_addPodsDependencyToFlutterXcconfig
(
iosProject
,
'Debug'
);
_addPodsDependencyToFlutterXcconfig
(
iosProject
,
'Release'
);
_addPodsDependencyToFlutterXcconfig
(
appDirectory
,
'Debug'
);
_addPodsDependencyToFlutterXcconfig
(
appDirectory
,
'Release'
);
}
void
_addPodsDependencyToFlutterXcconfig
(
IosProject
iosProject
,
String
mode
)
{
final
File
file
=
iosProject
.
xcodeConfigFor
(
mode
);
void
_addPodsDependencyToFlutterXcconfig
(
String
appDirectory
,
String
mode
)
{
final
File
file
=
fs
.
file
(
fs
.
path
.
join
(
appDirectory
,
'ios'
,
'Flutter'
,
'
$mode
.xcconfig'
)
);
if
(
file
.
existsSync
())
{
final
String
content
=
file
.
readAsStringSync
();
final
String
include
=
'#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.
${mode
...
...
@@ -191,11 +192,12 @@ class CocoaPods {
}
/// Ensures that pod install is deemed needed on next check.
void
invalidatePodInstallOutput
(
IosProject
iosProject
)
{
final
File
manifestLock
=
iosProject
.
podManifestLock
;
if
(
manifestLock
.
existsSync
())
{
manifestLock
.
deleteSync
();
}
void
invalidatePodInstallOutput
(
String
appDirectory
)
{
final
File
manifest
=
fs
.
file
(
fs
.
path
.
join
(
appDirectory
,
'ios'
,
'Pods'
,
'Manifest.lock'
),
);
if
(
manifest
.
existsSync
())
manifest
.
deleteSync
();
}
// Check if you need to run pod install.
...
...
@@ -204,25 +206,24 @@ class CocoaPods {
// 2. Podfile.lock doesn't exist or is older than Podfile
// 3. Pods/Manifest.lock doesn't exist (It is deleted when plugins change)
// 4. Podfile.lock doesn't match Pods/Manifest.lock.
bool
_shouldRunPodInstall
(
IosProject
iosProject
,
bool
dependenciesChanged
)
{
bool
_shouldRunPodInstall
(
Directory
appIosDirectory
,
bool
dependenciesChanged
)
{
if
(
dependenciesChanged
)
return
true
;
final
File
podfileFile
=
iosProject
.
podfile
;
final
File
podfileLockFile
=
iosProject
.
podfileLock
;
final
File
manifestLockFile
=
iosProject
.
podManifestLock
;
final
File
podfileFile
=
appIosDirectory
.
childFile
(
'Podfile'
);
final
File
podfileLockFile
=
appIosDirectory
.
childFile
(
'Podfile.lock'
);
final
File
manifestLockFile
=
appIosDirectory
.
childFile
(
fs
.
path
.
join
(
'Pods'
,
'Manifest.lock'
));
return
!
podfileLockFile
.
existsSync
()
||
!
manifestLockFile
.
existsSync
()
||
podfileLockFile
.
statSync
().
modified
.
isBefore
(
podfileFile
.
statSync
().
modified
)
||
podfileLockFile
.
readAsStringSync
()
!=
manifestLockFile
.
readAsStringSync
();
}
Future
<
Null
>
_runPodInstall
(
IosProject
iosProject
,
String
engineDirectory
)
async
{
Future
<
Null
>
_runPodInstall
(
Directory
appIosDirectory
,
String
engineDirectory
)
async
{
final
Status
status
=
logger
.
startProgress
(
'Running pod install...'
,
expectSlowOperation:
true
);
final
ProcessResult
result
=
await
processManager
.
run
(
<
String
>[
'pod'
,
'install'
,
'--verbose'
],
workingDirectory:
iosProject
.
d
irectory
.
path
,
workingDirectory:
appIosD
irectory
.
path
,
environment:
<
String
,
String
>{
// For backward compatibility with previously created Podfile only.
'FLUTTER_FRAMEWORK_DIR'
:
engineDirectory
,
...
...
@@ -243,7 +244,7 @@ class CocoaPods {
}
}
if
(
result
.
exitCode
!=
0
)
{
invalidatePodInstallOutput
(
iosProject
);
invalidatePodInstallOutput
(
appIosDirectory
.
parent
.
path
);
_diagnosePodInstallFailure
(
result
);
throwToolExit
(
'Error running pod install'
);
}
...
...
packages/flutter_tools/lib/src/ios/mac.dart
View file @
6a8f9041
...
...
@@ -20,9 +20,9 @@ import '../base/process.dart';
import
'../base/process_manager.dart'
;
import
'../base/utils.dart'
;
import
'../build_info.dart'
;
import
'../flutter_manifest.dart'
;
import
'../globals.dart'
;
import
'../plugins.dart'
;
import
'../project.dart'
;
import
'../services.dart'
;
import
'cocoapods.dart'
;
import
'code_signing.dart'
;
...
...
@@ -221,15 +221,18 @@ Future<XcodeBuildResult> buildXcodeProject({
final
Directory
appDirectory
=
fs
.
directory
(
app
.
appDirectory
);
await
_addServicesToBundle
(
appDirectory
);
final
FlutterProject
project
=
new
FlutterProject
(
fs
.
currentDirectory
);
await
updateGeneratedXcodeProperties
(
project:
project
,
final
FlutterManifest
manifest
=
await
FlutterManifest
.
createFromPath
(
fs
.
currentDirectory
.
childFile
(
'pubspec.yaml'
).
path
,
);
updateGeneratedXcodeProperties
(
projectPath:
fs
.
currentDirectory
.
path
,
buildInfo:
buildInfo
,
targetOverride:
targetOverride
,
previewDart2:
buildInfo
.
previewDart2
,
buildInfo:
buildInfo
,
manifest:
manifest
,
);
if
(
hasPlugins
(
project
))
{
if
(
hasPlugins
())
{
final
String
iosPath
=
fs
.
path
.
join
(
fs
.
currentDirectory
.
path
,
app
.
appDirectory
);
// If the Xcode project, Podfile, or Generated.xcconfig have changed since
// last run, pods should be updated.
...
...
@@ -243,7 +246,7 @@ Future<XcodeBuildResult> buildXcodeProject({
properties:
<
String
,
String
>{},
);
final
bool
didPodInstall
=
await
cocoaPods
.
processPods
(
iosProject:
project
.
ios
,
appIosDirectory:
appDirectory
,
iosEngineDir:
flutterFrameworkDir
(
buildInfo
.
mode
),
isSwift:
app
.
isSwift
,
dependenciesChanged:
!
await
fingerprinter
.
doesFingerprintMatch
()
...
...
packages/flutter_tools/lib/src/ios/xcodeproj.dart
View file @
6a8f9041
...
...
@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:async'
;
import
'package:meta/meta.dart'
;
import
'../artifacts.dart'
;
...
...
@@ -19,7 +17,6 @@ import '../bundle.dart' as bundle;
import
'../cache.dart'
;
import
'../flutter_manifest.dart'
;
import
'../globals.dart'
;
import
'../project.dart'
;
final
RegExp
_settingExpr
=
new
RegExp
(
r'(\w+)\s*=\s*(.*)$'
);
final
RegExp
_varExpr
=
new
RegExp
(
r'\$\((.*)\)'
);
...
...
@@ -28,18 +25,27 @@ String flutterFrameworkDir(BuildMode mode) {
return
fs
.
path
.
normalize
(
fs
.
path
.
dirname
(
artifacts
.
getArtifactPath
(
Artifact
.
flutterFramework
,
TargetPlatform
.
ios
,
mode
)));
}
String
_generatedXcodePropertiesPath
(
{
@required
String
projectPath
,
@required
FlutterManifest
manifest
})
{
if
(
manifest
.
isModule
)
{
return
fs
.
path
.
join
(
projectPath
,
'.ios'
,
'Flutter'
,
'Generated.xcconfig'
);
}
else
{
return
fs
.
path
.
join
(
projectPath
,
'ios'
,
'Flutter'
,
'Generated.xcconfig'
);
}
}
/// Writes default Xcode properties files in the Flutter project at [projectPath],
/// if project is an iOS project and such files are out of date or do not
/// already exist.
Future
<
void
>
generateXcodeProperties
({
FlutterProject
project
})
async
{
if
(
(
await
project
.
manifest
).
isModule
||
project
.
ios
.
directory
.
existsSync
())
{
if
(!
Cache
.
instance
.
fileOlderThanToolsStamp
(
await
project
.
generatedXcodeP
ropertiesFile
))
{
void
generateXcodeProperties
(
{
String
projectPath
,
FlutterManifest
manifest
})
{
if
(
manifest
.
isModule
||
fs
.
isDirectorySync
(
fs
.
path
.
join
(
projectPath
,
'ios'
)))
{
final
File
propertiesFile
=
fs
.
file
(
_generatedXcodePropertiesPath
(
projectPath:
projectPath
,
manifest:
manifest
));
if
(!
Cache
.
instance
.
fileOlderThanToolsStamp
(
p
ropertiesFile
))
{
return
;
}
await
updateGeneratedXcodeProperties
(
project:
project
,
updateGeneratedXcodeProperties
(
projectPath:
projectPath
,
manifest:
manifest
,
buildInfo:
BuildInfo
.
debug
,
targetOverride:
bundle
.
defaultMainPath
,
previewDart2:
true
,
...
...
@@ -51,12 +57,13 @@ Future<void> generateXcodeProperties({FlutterProject project}) async {
///
/// targetOverride: Optional parameter, if null or unspecified the default value
/// from xcode_backend.sh is used 'lib/main.dart'.
Future
<
void
>
updateGeneratedXcodeProperties
({
@required
FlutterProject
project
,
void
updateGeneratedXcodeProperties
(
{
@required
String
projectPath
,
@required
FlutterManifest
manifest
,
@required
BuildInfo
buildInfo
,
String
targetOverride
,
@required
bool
previewDart2
,
})
async
{
})
{
final
StringBuffer
localsBuffer
=
new
StringBuffer
();
localsBuffer
.
writeln
(
'// This is a generated file; do not edit or check into version control.'
);
...
...
@@ -65,7 +72,7 @@ Future<void> updateGeneratedXcodeProperties({
localsBuffer
.
writeln
(
'FLUTTER_ROOT=
$flutterRoot
'
);
// This holds because requiresProjectRoot is true for this command
localsBuffer
.
writeln
(
'FLUTTER_APPLICATION_PATH=
${fs.path.normalize(project
.directory.p
ath)}
'
);
localsBuffer
.
writeln
(
'FLUTTER_APPLICATION_PATH=
${fs.path.normalize(project
P
ath)}
'
);
// Relative to FLUTTER_APPLICATION_PATH, which is [Directory.current].
if
(
targetOverride
!=
null
)
...
...
@@ -79,7 +86,6 @@ Future<void> updateGeneratedXcodeProperties({
localsBuffer
.
writeln
(
'SYMROOT=
\
${SOURCE_ROOT}
/../
${getIosBuildDirectory()}
'
);
final
FlutterManifest
manifest
=
await
project
.
manifest
;
if
(!
manifest
.
isModule
)
{
// For module projects we do not want to write the FLUTTER_FRAMEWORK_DIR
// explicitly. Rather we rely on the xcode backend script and the Podfile
...
...
@@ -119,9 +125,9 @@ Future<void> updateGeneratedXcodeProperties({
localsBuffer
.
writeln
(
'TRACK_WIDGET_CREATION=true'
);
}
final
File
generatedXcodePropertiesFile
=
await
project
.
generatedXcodePropertiesFile
;
generatedXcodePropertie
sFile
.
createSync
(
recursive:
true
);
generatedXcodePropertie
sFile
.
writeAsStringSync
(
localsBuffer
.
toString
());
final
File
localsFile
=
fs
.
file
(
_generatedXcodePropertiesPath
(
projectPath:
projectPath
,
manifest:
manifest
))
;
local
sFile
.
createSync
(
recursive:
true
);
local
sFile
.
writeAsStringSync
(
localsBuffer
.
toString
());
}
XcodeProjectInterpreter
get
xcodeProjectInterpreter
=>
context
[
XcodeProjectInterpreter
];
...
...
packages/flutter_tools/lib/src/plugins.dart
View file @
6a8f9041
...
...
@@ -2,16 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:async'
;
import
'package:meta/meta.dart'
;
import
'package:mustache/mustache.dart'
as
mustache
;
import
'package:yaml/yaml.dart'
;
import
'base/file_system.dart'
;
import
'dart/package_map.dart'
;
import
'flutter_manifest.dart'
;
import
'globals.dart'
;
import
'ios/cocoapods.dart'
;
import
'project.dart'
;
void
_renderTemplateToFile
(
String
template
,
dynamic
context
,
String
filePath
)
{
final
String
renderedTemplate
=
...
...
@@ -70,11 +69,11 @@ Plugin _pluginFromPubspec(String name, Uri packageRoot) {
return
new
Plugin
.
fromYaml
(
name
,
packageRootPath
,
flutterConfig
[
'plugin'
]);
}
List
<
Plugin
>
findPlugins
(
FlutterProject
project
)
{
List
<
Plugin
>
findPlugins
(
String
directory
)
{
final
List
<
Plugin
>
plugins
=
<
Plugin
>[];
Map
<
String
,
Uri
>
packages
;
try
{
final
String
packagesFile
=
fs
.
path
.
join
(
project
.
directory
.
path
,
PackageMap
.
globalPackagesPath
);
final
String
packagesFile
=
fs
.
path
.
join
(
directory
,
PackageMap
.
globalPackagesPath
);
packages
=
new
PackageMap
(
packagesFile
).
map
;
}
on
FormatException
catch
(
e
)
{
printTrace
(
'Invalid .packages file:
$e
'
);
...
...
@@ -90,9 +89,9 @@ List<Plugin> findPlugins(FlutterProject project) {
}
/// Returns true if .flutter-plugins has changed, otherwise returns false.
bool
_writeFlutterPluginsList
(
FlutterProject
project
,
List
<
Plugin
>
plugins
)
{
final
File
pluginsFile
=
project
.
flutterPluginsFile
;
final
String
oldContents
=
_readFlutterPluginsList
(
project
);
bool
_writeFlutterPluginsList
(
String
directory
,
List
<
Plugin
>
plugins
)
{
final
File
pluginsFile
=
fs
.
file
(
fs
.
path
.
join
(
directory
,
'.flutter-plugins'
))
;
final
String
oldContents
=
_readFlutterPluginsList
(
directory
);
final
String
pluginManifest
=
plugins
.
map
((
Plugin
p
)
=>
'
${p.name}
=
${escapePath(p.path)}
'
).
join
(
'
\n
'
);
if
(
pluginManifest
.
isNotEmpty
)
{
...
...
@@ -101,16 +100,15 @@ bool _writeFlutterPluginsList(FlutterProject project, List<Plugin> plugins) {
if
(
pluginsFile
.
existsSync
())
pluginsFile
.
deleteSync
();
}
final
String
newContents
=
_readFlutterPluginsList
(
project
);
final
String
newContents
=
_readFlutterPluginsList
(
directory
);
return
oldContents
!=
newContents
;
}
/// Returns the contents of the `.flutter-plugins` file in [directory], or
/// null if that file does not exist.
String
_readFlutterPluginsList
(
FlutterProject
project
)
{
return
project
.
flutterPluginsFile
.
existsSync
()
?
project
.
flutterPluginsFile
.
readAsStringSync
()
:
null
;
String
_readFlutterPluginsList
(
String
directory
)
{
final
File
pluginsFile
=
fs
.
file
(
fs
.
path
.
join
(
directory
,
'.flutter-plugins'
));
return
pluginsFile
.
existsSync
()
?
pluginsFile
.
readAsStringSync
()
:
null
;
}
const
String
_androidPluginRegistryTemplate
=
'''package io.flutter.plugins;
...
...
@@ -144,7 +142,7 @@ public final class GeneratedPluginRegistrant {
}
'''
;
Future
<
void
>
_writeAndroidPluginRegistrant
(
FlutterProject
project
,
List
<
Plugin
>
plugins
)
async
{
void
_writeAndroidPluginRegistrant
(
String
directory
,
List
<
Plugin
>
plugins
)
{
final
List
<
Map
<
String
,
dynamic
>>
androidPlugins
=
plugins
.
where
((
Plugin
p
)
=>
p
.
androidPackage
!=
null
&&
p
.
pluginClass
!=
null
)
.
map
((
Plugin
p
)
=>
<
String
,
dynamic
>{
...
...
@@ -157,19 +155,8 @@ Future<void> _writeAndroidPluginRegistrant(FlutterProject project, List<Plugin>
'plugins'
:
androidPlugins
,
};
final
String
javaSourcePath
=
fs
.
path
.
join
(
(
await
project
.
androidPluginRegistrantHost
).
path
,
'src'
,
'main'
,
'java'
,
);
final
String
registryPath
=
fs
.
path
.
join
(
javaSourcePath
,
'io'
,
'flutter'
,
'plugins'
,
'GeneratedPluginRegistrant.java'
,
);
final
String
javaSourcePath
=
fs
.
path
.
join
(
directory
,
'src'
,
'main'
,
'java'
);
final
String
registryPath
=
fs
.
path
.
join
(
javaSourcePath
,
'io'
,
'flutter'
,
'plugins'
,
'GeneratedPluginRegistrant.java'
);
_renderTemplateToFile
(
_androidPluginRegistryTemplate
,
context
,
registryPath
);
}
...
...
@@ -234,7 +221,7 @@ Depends on all your plugins, and provides a function to register them.
end
''';
Future<void> _writeIOSPluginRegistrant(FlutterProject project, List<Plugin> plugins) async
{
void _writeIOSPluginRegistrant(String directory, FlutterManifest manifest, List<Plugin> plugins)
{
final List<Map<String, dynamic>> iosPlugins = plugins
.where((Plugin p) => p.pluginClass != null)
.map((Plugin p) => <String, dynamic>{
...
...
@@ -247,8 +234,10 @@ Future<void> _writeIOSPluginRegistrant(FlutterProject project, List<Plugin> plug
'plugins'
:
iosPlugins
,
};
final
String
registryDirectory
=
(
await
project
.
iosPluginRegistrantHost
).
path
;
if
((
await
project
.
manifest
).
isModule
)
{
if
(
manifest
.
isModule
)
{
// In a module create the GeneratedPluginRegistrant as a pod to be included
// from a hosting app.
final
String
registryDirectory
=
fs
.
path
.
join
(
directory
,
'Flutter'
,
'FlutterPluginRegistrant'
);
final
String
registryClassesDirectory
=
fs
.
path
.
join
(
registryDirectory
,
'Classes'
);
_renderTemplateToFile
(
_iosPluginRegistrantPodspecTemplate
,
...
...
@@ -266,37 +255,57 @@ Future<void> _writeIOSPluginRegistrant(FlutterProject project, List<Plugin> plug
fs
.
path
.
join
(
registryClassesDirectory
,
'GeneratedPluginRegistrant.m'
),
);
}
else
{
// For a non-module create the GeneratedPluginRegistrant as source files
// directly in the ios project.
final
String
runnerDirectory
=
fs
.
path
.
join
(
directory
,
'Runner'
);
_renderTemplateToFile
(
_iosPluginRegistryHeaderTemplate
,
context
,
fs
.
path
.
join
(
r
egistry
Directory
,
'GeneratedPluginRegistrant.h'
),
fs
.
path
.
join
(
r
unner
Directory
,
'GeneratedPluginRegistrant.h'
),
);
_renderTemplateToFile
(
_iosPluginRegistryImplementationTemplate
,
context
,
fs
.
path
.
join
(
r
egistry
Directory
,
'GeneratedPluginRegistrant.m'
),
fs
.
path
.
join
(
r
unner
Directory
,
'GeneratedPluginRegistrant.m'
),
);
}
}
/// Injects plugins found in `pubspec.yaml` into the platform-specific projects.
Future
<
void
>
injectPlugins
(
FlutterProject
project
)
async
{
final
List
<
Plugin
>
plugins
=
findPlugins
(
project
);
final
bool
changed
=
_writeFlutterPluginsList
(
project
,
plugins
);
await
_writeAndroidPluginRegistrant
(
project
,
plugins
);
await
_writeIOSPluginRegistrant
(
project
,
plugins
);
class
InjectPluginsResult
{
InjectPluginsResult
({
@required
this
.
hasPlugin
,
@required
this
.
hasChanged
,
});
/// True if any flutter plugin exists, otherwise false.
final
bool
hasPlugin
;
/// True if plugins have changed since last build.
final
bool
hasChanged
;
}
if
(
project
.
ios
.
directory
.
existsSync
())
{
/// Injects plugins found in `pubspec.yaml` into the platform-specific projects.
void
injectPlugins
(
{
@required
String
projectPath
,
@required
FlutterManifest
manifest
})
{
final
List
<
Plugin
>
plugins
=
findPlugins
(
projectPath
);
final
bool
changed
=
_writeFlutterPluginsList
(
projectPath
,
plugins
);
if
(
manifest
.
isModule
)
{
_writeAndroidPluginRegistrant
(
fs
.
path
.
join
(
projectPath
,
'.android'
,
'Flutter'
),
plugins
);
}
else
if
(
fs
.
isDirectorySync
(
fs
.
path
.
join
(
projectPath
,
'android'
,
'app'
)))
{
_writeAndroidPluginRegistrant
(
fs
.
path
.
join
(
projectPath
,
'android'
,
'app'
),
plugins
);
}
if
(
manifest
.
isModule
)
{
_writeIOSPluginRegistrant
(
fs
.
path
.
join
(
projectPath
,
'.ios'
),
manifest
,
plugins
);
}
else
if
(
fs
.
isDirectorySync
(
fs
.
path
.
join
(
projectPath
,
'ios'
)))
{
_writeIOSPluginRegistrant
(
fs
.
path
.
join
(
projectPath
,
'ios'
),
manifest
,
plugins
);
final
CocoaPods
cocoaPods
=
new
CocoaPods
();
if
(
plugins
.
isNotEmpty
)
cocoaPods
.
setupPodfile
(
project
.
ios
);
cocoaPods
.
setupPodfile
(
project
Path
,
manifest
);
if
(
changed
)
cocoaPods
.
invalidatePodInstallOutput
(
project
.
ios
);
cocoaPods
.
invalidatePodInstallOutput
(
project
Path
);
}
}
/// Returns whether the Flutter project at the specified [directory]
/// has any plugin dependencies.
bool
hasPlugins
(
FlutterProject
project
)
{
return
_readFlutterPluginsList
(
project
)
!=
null
;
bool
hasPlugins
(
{
String
directory
})
{
directory
??=
fs
.
currentDirectory
.
path
;
return
_readFlutterPluginsList
(
directory
)
!=
null
;
}
packages/flutter_tools/lib/src/project.dart
View file @
6a8f9041
...
...
@@ -5,6 +5,7 @@
import
'dart:async'
;
import
'dart:convert'
;
import
'android/gradle.dart'
as
gradle
;
import
'base/file_system.dart'
;
import
'bundle.dart'
as
bundle
;
...
...
@@ -66,57 +67,6 @@ class FlutterProject {
/// The generated IosModule sub project of this module project.
IosModuleProject
get
iosModule
=>
new
IosModuleProject
(
directory
.
childDirectory
(
'.ios'
));
Future
<
File
>
get
androidLocalPropertiesFile
{
return
_androidLocalPropertiesFile
??=
manifest
.
then
<
File
>((
FlutterManifest
manifest
)
{
return
directory
.
childDirectory
(
manifest
.
isModule
?
'.android'
:
'android'
)
.
childFile
(
'local.properties'
);
});
}
Future
<
File
>
_androidLocalPropertiesFile
;
Future
<
File
>
get
generatedXcodePropertiesFile
{
return
_generatedXcodeProperties
??=
manifest
.
then
<
File
>((
FlutterManifest
manifest
)
{
return
directory
.
childDirectory
(
manifest
.
isModule
?
'.ios'
:
'ios'
)
.
childDirectory
(
'Flutter'
)
.
childFile
(
'Generated.xcconfig'
);
});
}
Future
<
File
>
_generatedXcodeProperties
;
File
get
flutterPluginsFile
{
return
_flutterPluginsFile
??=
directory
.
childFile
(
'.flutter-plugins'
);
}
File
_flutterPluginsFile
;
Future
<
Directory
>
get
androidPluginRegistrantHost
async
{
return
_androidPluginRegistrantHost
??=
manifest
.
then
((
FlutterManifest
manifest
)
{
if
(
manifest
.
isModule
)
{
return
directory
.
childDirectory
(
'.android'
).
childDirectory
(
'Flutter'
);
}
else
{
return
directory
.
childDirectory
(
'android'
).
childDirectory
(
'app'
);
}
});
}
Future
<
Directory
>
_androidPluginRegistrantHost
;
Future
<
Directory
>
get
iosPluginRegistrantHost
async
{
return
_iosPluginRegistrantHost
??=
manifest
.
then
((
FlutterManifest
manifest
)
{
if
(
manifest
.
isModule
)
{
// In a module create the GeneratedPluginRegistrant as a pod to be included
// from a hosting app.
return
directory
.
childDirectory
(
'.ios'
)
.
childDirectory
(
'Flutter'
)
.
childDirectory
(
'FlutterPluginRegistrant'
);
}
else
{
// For a non-module create the GeneratedPluginRegistrant as source files
// directly in the iOS project.
return
directory
.
childDirectory
(
'ios'
).
childDirectory
(
'Runner'
);
}
});
}
Future
<
Directory
>
_iosPluginRegistrantHost
;
/// Returns true if this project has an example application
bool
get
hasExampleApp
=>
_exampleDirectory
.
childFile
(
'pubspec.yaml'
).
existsSync
();
...
...
@@ -136,11 +86,11 @@ class FlutterProject {
}
final
FlutterManifest
manifest
=
await
this
.
manifest
;
if
(
manifest
.
isModule
)
{
await
androidModule
.
ensureReadyForPlatformSpecificTooling
(
this
);
await
iosModule
.
ensureReadyForPlatformSpecificTooling
();
await
androidModule
.
ensureReadyForPlatformSpecificTooling
(
manifest
);
await
iosModule
.
ensureReadyForPlatformSpecificTooling
(
manifest
);
}
await
xcode
.
generateXcodeProperties
(
project:
this
);
await
injectPlugins
(
this
);
xcode
.
generateXcodeProperties
(
projectPath:
directory
.
path
,
manifest:
manifest
);
injectPlugins
(
projectPath:
directory
.
path
,
manifest:
manifest
);
}
}
...
...
@@ -151,20 +101,6 @@ class IosProject {
final
Directory
directory
;
/// The xcode config file for [mode].
File
xcodeConfigFor
(
String
mode
)
{
return
directory
.
childDirectory
(
'Flutter'
).
childFile
(
'
$mode
.xcconfig'
);
}
/// The 'Podfile'.
File
get
podfile
=>
directory
.
childFile
(
'Podfile'
);
/// The 'Podfile.lock'.
File
get
podfileLock
=>
directory
.
childFile
(
'Podfile.lock'
);
/// The 'Manifest.lock'.
File
get
podManifestLock
=>
directory
.
childDirectory
(
'Pods'
).
childFile
(
'Manifest.lock'
);
Future
<
String
>
productBundleIdentifier
()
{
final
File
projectFile
=
directory
.
childDirectory
(
'Runner.xcodeproj'
).
childFile
(
'project.pbxproj'
);
return
_firstMatchInFile
(
projectFile
,
_productBundleIdPattern
).
then
((
Match
match
)
=>
match
?.
group
(
1
));
...
...
@@ -178,7 +114,7 @@ class IosModuleProject {
final
Directory
directory
;
Future
<
void
>
ensureReadyForPlatformSpecificTooling
()
async
{
Future
<
void
>
ensureReadyForPlatformSpecificTooling
(
FlutterManifest
manifest
)
async
{
if
(
_shouldRegenerate
())
{
final
Template
template
=
new
Template
.
fromName
(
fs
.
path
.
join
(
'module'
,
'ios'
));
template
.
render
(
directory
,
<
String
,
dynamic
>{},
printStatusWhenWriting:
false
);
...
...
@@ -197,29 +133,6 @@ class AndroidProject {
AndroidProject
(
this
.
directory
);
File
get
gradleManifestFile
{
return
_gradleManifestFile
??=
isUsingGradle
()
?
fs
.
file
(
fs
.
path
.
join
(
directory
.
path
,
'app'
,
'src'
,
'main'
,
'AndroidManifest.xml'
))
:
directory
.
childFile
(
'AndroidManifest.xml'
);
}
File
_gradleManifestFile
;
File
get
gradleAppOutV1File
{
return
_gradleAppOutV1File
??=
gradleAppOutV1Directory
.
childFile
(
'app-debug.apk'
);
}
File
_gradleAppOutV1File
;
Directory
get
gradleAppOutV1Directory
{
return
_gradleAppOutV1Directory
??=
fs
.
directory
(
fs
.
path
.
join
(
directory
.
path
,
'app'
,
'build'
,
'outputs'
,
'apk'
));
}
Directory
_gradleAppOutV1Directory
;
bool
isUsingGradle
()
{
return
directory
.
childFile
(
'build.gradle'
).
existsSync
();
}
final
Directory
directory
;
Future
<
String
>
applicationId
()
{
...
...
@@ -240,15 +153,15 @@ class AndroidModuleProject {
final
Directory
directory
;
Future
<
void
>
ensureReadyForPlatformSpecificTooling
(
Flutter
Project
projec
t
)
async
{
Future
<
void
>
ensureReadyForPlatformSpecificTooling
(
Flutter
Manifest
manifes
t
)
async
{
if
(
_shouldRegenerate
())
{
final
Template
template
=
new
Template
.
fromName
(
fs
.
path
.
join
(
'module'
,
'android'
));
template
.
render
(
directory
,
<
String
,
dynamic
>{
'androidIdentifier'
:
(
await
project
.
manifest
)
.
moduleDescriptor
[
'androidPackage'
],
'androidIdentifier'
:
manifest
.
moduleDescriptor
[
'androidPackage'
],
},
printStatusWhenWriting:
false
);
gradle
.
injectGradleWrapper
(
directory
);
}
await
gradle
.
updateLocalProperties
(
project:
project
,
requireAndroidSdk:
false
);
gradle
.
updateLocalPropertiesSync
(
directory
,
manifest
);
}
bool
_shouldRegenerate
()
{
...
...
packages/flutter_tools/lib/src/resident_runner.dart
View file @
6a8f9041
...
...
@@ -6,6 +6,7 @@ import 'dart:async';
import
'package:meta/meta.dart'
;
import
'android/gradle.dart'
;
import
'application_package.dart'
;
import
'artifacts.dart'
;
import
'asset.dart'
;
...
...
@@ -23,7 +24,6 @@ import 'dependency_checker.dart';
import
'devfs.dart'
;
import
'device.dart'
;
import
'globals.dart'
;
import
'project.dart'
;
import
'run_cold.dart'
;
import
'run_hot.dart'
;
import
'vmservice.dart'
;
...
...
@@ -814,11 +814,15 @@ abstract class ResidentRunner {
new
DartDependencySetBuilder
(
mainPath
,
packagesFilePath
);
final
DependencyChecker
dependencyChecker
=
new
DependencyChecker
(
dartDependencySetBuilder
,
assetBundle
);
if
(
device
.
package
.
packagesFile
==
null
||
!
device
.
package
.
packagesFile
.
existsSync
())
{
final
String
path
=
device
.
package
.
packagePath
;
if
(
path
==
null
)
return
true
;
}
final
DateTime
lastBuildTime
=
device
.
package
.
packagesFile
.
statSync
().
modified
;
final
FileStat
stat
=
fs
.
file
(
path
).
statSync
();
if
(
stat
.
type
!=
FileSystemEntityType
.
FILE
)
// ignore: deprecated_member_use
return
true
;
if
(!
fs
.
file
(
path
).
existsSync
())
return
true
;
final
DateTime
lastBuildTime
=
stat
.
modified
;
return
dependencyChecker
.
check
(
lastBuildTime
);
}
...
...
@@ -902,9 +906,11 @@ String getMissingPackageHintForPlatform(TargetPlatform platform) {
case
TargetPlatform
.
android_arm64
:
case
TargetPlatform
.
android_x64
:
case
TargetPlatform
.
android_x86
:
final
FlutterProject
project
=
new
FlutterProject
(
fs
.
currentDirectory
);
final
String
manifestPath
=
fs
.
path
.
relative
(
project
.
android
.
gradleManifestFile
.
path
);
return
'Is your project missing an
$manifestPath
?
\n
Consider running "flutter create ." to create one.'
;
String
manifest
=
'android/AndroidManifest.xml'
;
if
(
isProjectUsingGradle
())
{
manifest
=
gradleManifestPath
;
}
return
'Is your project missing an
$manifest
?
\n
Consider running "flutter create ." to create one.'
;
case
TargetPlatform
.
ios
:
return
'Is your project missing an ios/Runner/Info.plist?
\n
Consider running "flutter create ." to create one.'
;
default
:
...
...
packages/flutter_tools/lib/src/run_cold.dart
View file @
6a8f9041
...
...
@@ -30,7 +30,7 @@ class ColdRunner extends ResidentRunner {
ipv6:
ipv6
);
final
bool
traceStartup
;
final
File
applicationBinary
;
final
String
applicationBinary
;
@override
Future
<
int
>
run
({
...
...
packages/flutter_tools/lib/src/run_hot.dart
View file @
6a8f9041
...
...
@@ -64,7 +64,7 @@ class HotRunner extends ResidentRunner {
ipv6:
ipv6
);
final
bool
benchmarkMode
;
final
File
applicationBinary
;
final
String
applicationBinary
;
final
bool
hostIsIde
;
Set
<
String
>
_dartDependencies
;
final
String
dillOutputPath
;
...
...
packages/flutter_tools/lib/src/tester/flutter_tester.dart
View file @
6a8f9041
...
...
@@ -22,21 +22,21 @@ import '../protocol_discovery.dart';
import
'../version.dart'
;
class
FlutterTesterApp
extends
ApplicationPackage
{
final
Directory
_directory
;
final
String
_directory
;
factory
FlutterTesterApp
.
fromCurrentDirectory
()
{
return
new
FlutterTesterApp
.
_
(
fs
.
currentDirectory
);
return
new
FlutterTesterApp
.
_
(
fs
.
currentDirectory
.
path
);
}
FlutterTesterApp
.
_
(
Directory
directory
)
FlutterTesterApp
.
_
(
String
directory
)
:
_directory
=
directory
,
super
(
id:
directory
.
path
);
super
(
id:
directory
);
@override
String
get
name
=>
_directory
.
basename
;
String
get
name
=>
fs
.
path
.
basename
(
_directory
)
;
@override
File
get
packagesFile
=>
_directory
.
childFile
(
'.packages'
);
String
get
packagePath
=>
fs
.
path
.
join
(
_directory
,
'.packages'
);
}
// TODO(scheglov): This device does not currently work with full restarts.
...
...
packages/flutter_tools/test/android/gradle_test.dart
View file @
6a8f9041
...
...
@@ -11,7 +11,6 @@ import 'package:flutter_tools/src/base/file_system.dart';
import
'package:flutter_tools/src/build_info.dart'
;
import
'package:flutter_tools/src/flutter_manifest.dart'
;
import
'package:flutter_tools/src/ios/xcodeproj.dart'
;
import
'package:flutter_tools/src/project.dart'
;
import
'package:mockito/mockito.dart'
;
import
'package:platform/platform.dart'
;
import
'package:process/process.dart'
;
...
...
@@ -32,7 +31,7 @@ void main() {
// This test is written to fail if our bots get Android SDKs in the future: shouldBeToolExit
// will be null and our expectation would fail. That would remind us to make these tests
// hermetic before adding Android SDKs to the bots.
await
updateLocalProperties
(
project:
new
FlutterProject
(
fs
.
currentDirectory
)
);
await
updateLocalProperties
();
}
on
Exception
catch
(
e
)
{
shouldBeToolExit
=
e
;
}
...
...
@@ -70,10 +69,7 @@ someProperty: someValue
buildDir: /Users/some/apps/hello/build/app
someOtherProperty: someOtherValue
'''
);
expect
(
fs
.
path
.
normalize
(
project
.
apkDirectory
.
path
),
fs
.
path
.
normalize
(
'/Users/some/apps/hello/build/app/outputs/apk'
),
);
expect
(
project
.
apkDirectory
,
fs
.
path
.
normalize
(
'/Users/some/apps/hello/build/app/outputs/apk'
));
});
test
(
'should extract default build variants from app properties'
,
()
{
final
GradleProject
project
=
projectFrom
(
'''
...
...
@@ -114,27 +110,27 @@ someOtherProperty: someOtherValue
expect
(
project
.
productFlavors
,
<
String
>[
'free'
,
'paid'
]);
});
test
(
'should provide apk file name for default build types'
,
()
{
final
GradleProject
project
=
new
GradleProject
(<
String
>[
'debug'
,
'profile'
,
'release'
],
<
String
>[],
fs
.
directory
(
'/some/dir'
)
);
final
GradleProject
project
=
new
GradleProject
(<
String
>[
'debug'
,
'profile'
,
'release'
],
<
String
>[],
'/some/dir'
);
expect
(
project
.
apkFileFor
(
BuildInfo
.
debug
),
'app-debug.apk'
);
expect
(
project
.
apkFileFor
(
BuildInfo
.
profile
),
'app-profile.apk'
);
expect
(
project
.
apkFileFor
(
BuildInfo
.
release
),
'app-release.apk'
);
expect
(
project
.
apkFileFor
(
const
BuildInfo
(
BuildMode
.
release
,
'unknown'
)),
isNull
);
});
test
(
'should provide apk file name for flavored build types'
,
()
{
final
GradleProject
project
=
new
GradleProject
(<
String
>[
'debug'
,
'profile'
,
'release'
],
<
String
>[
'free'
,
'paid'
],
fs
.
directory
(
'/some/dir'
)
);
final
GradleProject
project
=
new
GradleProject
(<
String
>[
'debug'
,
'profile'
,
'release'
],
<
String
>[
'free'
,
'paid'
],
'/some/dir'
);
expect
(
project
.
apkFileFor
(
const
BuildInfo
(
BuildMode
.
debug
,
'free'
)),
'app-free-debug.apk'
);
expect
(
project
.
apkFileFor
(
const
BuildInfo
(
BuildMode
.
release
,
'paid'
)),
'app-paid-release.apk'
);
expect
(
project
.
apkFileFor
(
const
BuildInfo
(
BuildMode
.
release
,
'unknown'
)),
isNull
);
});
test
(
'should provide assemble task name for default build types'
,
()
{
final
GradleProject
project
=
new
GradleProject
(<
String
>[
'debug'
,
'profile'
,
'release'
],
<
String
>[],
fs
.
directory
(
'/some/dir'
)
);
final
GradleProject
project
=
new
GradleProject
(<
String
>[
'debug'
,
'profile'
,
'release'
],
<
String
>[],
'/some/dir'
);
expect
(
project
.
assembleTaskFor
(
BuildInfo
.
debug
),
'assembleDebug'
);
expect
(
project
.
assembleTaskFor
(
BuildInfo
.
profile
),
'assembleProfile'
);
expect
(
project
.
assembleTaskFor
(
BuildInfo
.
release
),
'assembleRelease'
);
expect
(
project
.
assembleTaskFor
(
const
BuildInfo
(
BuildMode
.
release
,
'unknown'
)),
isNull
);
});
test
(
'should provide assemble task name for flavored build types'
,
()
{
final
GradleProject
project
=
new
GradleProject
(<
String
>[
'debug'
,
'profile'
,
'release'
],
<
String
>[
'free'
,
'paid'
],
fs
.
directory
(
'/some/dir'
)
);
final
GradleProject
project
=
new
GradleProject
(<
String
>[
'debug'
,
'profile'
,
'release'
],
<
String
>[
'free'
,
'paid'
],
'/some/dir'
);
expect
(
project
.
assembleTaskFor
(
const
BuildInfo
(
BuildMode
.
debug
,
'free'
)),
'assembleFreeDebug'
);
expect
(
project
.
assembleTaskFor
(
const
BuildInfo
(
BuildMode
.
release
,
'paid'
)),
'assemblePaidRelease'
);
expect
(
project
.
assembleTaskFor
(
const
BuildInfo
(
BuildMode
.
release
,
'unknown'
)),
isNull
);
...
...
@@ -189,10 +185,7 @@ someOtherProperty: someOtherValue
writeSchemaFile
(
fs
,
schemaData
);
try
{
await
updateLocalProperties
(
project:
new
FlutterProject
.
fromPath
(
'path/to/project'
),
buildInfo:
buildInfo
,
);
await
updateLocalProperties
(
projectPath:
'path/to/project'
,
buildInfo:
buildInfo
);
final
File
localPropertiesFile
=
fs
.
file
(
'path/to/project/android/local.properties'
);
expect
(
propertyFor
(
'flutter.versionName'
,
localPropertiesFile
),
expectedBuildName
);
...
...
packages/flutter_tools/test/application_package_test.dart
View file @
6a8f9041
...
...
@@ -57,7 +57,7 @@ void main() {
};
testUsingContext
(
'Error on non-existing file'
,
()
{
final
PrebuiltIOSApp
iosApp
=
new
IOSApp
.
fromPrebuiltApp
(
fs
.
file
(
'not_existing.ipa'
)
);
new
IOSApp
.
fromPrebuiltApp
(
'not_existing.ipa'
);
expect
(
iosApp
,
isNull
);
final
BufferLogger
logger
=
context
[
Logger
];
expect
(
...
...
@@ -68,7 +68,7 @@ void main() {
testUsingContext
(
'Error on non-app-bundle folder'
,
()
{
fs
.
directory
(
'regular_folder'
).
createSync
();
final
PrebuiltIOSApp
iosApp
=
new
IOSApp
.
fromPrebuiltApp
(
fs
.
file
(
'regular_folder'
)
);
new
IOSApp
.
fromPrebuiltApp
(
'regular_folder'
);
expect
(
iosApp
,
isNull
);
final
BufferLogger
logger
=
context
[
Logger
];
expect
(
...
...
@@ -76,7 +76,7 @@ void main() {
},
overrides:
overrides
);
testUsingContext
(
'Error on no info.plist'
,
()
{
fs
.
directory
(
'bundle.app'
).
createSync
();
final
PrebuiltIOSApp
iosApp
=
new
IOSApp
.
fromPrebuiltApp
(
fs
.
file
(
'bundle.app'
)
);
final
PrebuiltIOSApp
iosApp
=
new
IOSApp
.
fromPrebuiltApp
(
'bundle.app'
);
expect
(
iosApp
,
isNull
);
final
BufferLogger
logger
=
context
[
Logger
];
expect
(
...
...
@@ -87,7 +87,7 @@ void main() {
testUsingContext
(
'Error on bad info.plist'
,
()
{
fs
.
directory
(
'bundle.app'
).
createSync
();
fs
.
file
(
'bundle.app/Info.plist'
).
writeAsStringSync
(
badPlistData
);
final
PrebuiltIOSApp
iosApp
=
new
IOSApp
.
fromPrebuiltApp
(
fs
.
file
(
'bundle.app'
)
);
final
PrebuiltIOSApp
iosApp
=
new
IOSApp
.
fromPrebuiltApp
(
'bundle.app'
);
expect
(
iosApp
,
isNull
);
final
BufferLogger
logger
=
context
[
Logger
];
expect
(
...
...
@@ -99,7 +99,7 @@ void main() {
testUsingContext
(
'Success with app bundle'
,
()
{
fs
.
directory
(
'bundle.app'
).
createSync
();
fs
.
file
(
'bundle.app/Info.plist'
).
writeAsStringSync
(
plistData
);
final
PrebuiltIOSApp
iosApp
=
new
IOSApp
.
fromPrebuiltApp
(
fs
.
file
(
'bundle.app'
)
);
final
PrebuiltIOSApp
iosApp
=
new
IOSApp
.
fromPrebuiltApp
(
'bundle.app'
);
final
BufferLogger
logger
=
context
[
Logger
];
expect
(
logger
.
errorText
,
isEmpty
);
expect
(
iosApp
.
bundleDir
.
path
,
'bundle.app'
);
...
...
@@ -109,7 +109,7 @@ void main() {
testUsingContext
(
'Bad ipa zip-file, no payload dir'
,
()
{
fs
.
file
(
'app.ipa'
).
createSync
();
when
(
os
.
unzip
(
fs
.
file
(
'app.ipa'
),
any
)).
thenAnswer
((
Invocation
_
)
{});
final
PrebuiltIOSApp
iosApp
=
new
IOSApp
.
fromPrebuiltApp
(
fs
.
file
(
'app.ipa'
)
);
final
PrebuiltIOSApp
iosApp
=
new
IOSApp
.
fromPrebuiltApp
(
'app.ipa'
);
expect
(
iosApp
,
isNull
);
final
BufferLogger
logger
=
context
[
Logger
];
expect
(
...
...
@@ -132,7 +132,7 @@ void main() {
fs
.
directory
(
bundlePath1
).
createSync
(
recursive:
true
);
fs
.
directory
(
bundlePath2
).
createSync
(
recursive:
true
);
});
final
PrebuiltIOSApp
iosApp
=
new
IOSApp
.
fromPrebuiltApp
(
fs
.
file
(
'app.ipa'
)
);
final
PrebuiltIOSApp
iosApp
=
new
IOSApp
.
fromPrebuiltApp
(
'app.ipa'
);
expect
(
iosApp
,
isNull
);
final
BufferLogger
logger
=
context
[
Logger
];
expect
(
logger
.
errorText
,
...
...
@@ -153,7 +153,7 @@ void main() {
.
file
(
fs
.
path
.
join
(
bundleAppDir
.
path
,
'Info.plist'
))
.
writeAsStringSync
(
plistData
);
});
final
PrebuiltIOSApp
iosApp
=
new
IOSApp
.
fromPrebuiltApp
(
fs
.
file
(
'app.ipa'
)
);
final
PrebuiltIOSApp
iosApp
=
new
IOSApp
.
fromPrebuiltApp
(
'app.ipa'
);
final
BufferLogger
logger
=
context
[
Logger
];
expect
(
logger
.
errorText
,
isEmpty
);
expect
(
iosApp
.
bundleDir
.
path
,
endsWith
(
'bundle.app'
));
...
...
packages/flutter_tools/test/ios/cocoapods_test.dart
View file @
6a8f9041
This diff is collapsed.
Click to expand it.
packages/flutter_tools/test/ios/xcodeproj_test.dart
View file @
6a8f9041
...
...
@@ -289,9 +289,11 @@ Information about project "Runner":
previewDart2:
true
,
targetPlatform:
TargetPlatform
.
ios
,
);
final
FlutterProject
project
=
new
FlutterProject
.
fromPath
(
'path/to/project'
);
await
updateGeneratedXcodeProperties
(
project:
project
,
final
FlutterManifest
manifest
=
await
new
FlutterProject
.
fromPath
(
'path/to/project'
).
manifest
;
updateGeneratedXcodeProperties
(
projectPath:
'path/to/project'
,
manifest:
manifest
,
buildInfo:
buildInfo
,
previewDart2:
true
,
);
...
...
@@ -311,9 +313,11 @@ Information about project "Runner":
trackWidgetCreation:
true
,
targetPlatform:
TargetPlatform
.
ios
,
);
final
FlutterProject
project
=
new
FlutterProject
.
fromPath
(
'path/to/project'
);
await
updateGeneratedXcodeProperties
(
project:
project
,
final
FlutterManifest
manifest
=
await
new
FlutterProject
.
fromPath
(
'path/to/project'
).
manifest
;
updateGeneratedXcodeProperties
(
projectPath:
'path/to/project'
,
manifest:
manifest
,
buildInfo:
buildInfo
,
previewDart2:
true
,
);
...
...
@@ -332,9 +336,11 @@ Information about project "Runner":
previewDart2:
true
,
targetPlatform:
TargetPlatform
.
ios
,
);
final
FlutterProject
project
=
new
FlutterProject
.
fromPath
(
'path/to/project'
);
await
updateGeneratedXcodeProperties
(
project:
project
,
final
FlutterManifest
manifest
=
await
new
FlutterProject
.
fromPath
(
'path/to/project'
).
manifest
;
updateGeneratedXcodeProperties
(
projectPath:
'path/to/project'
,
manifest:
manifest
,
buildInfo:
buildInfo
,
previewDart2:
true
,
);
...
...
@@ -354,9 +360,11 @@ Information about project "Runner":
targetPlatform:
TargetPlatform
.
ios
,
);
final
FlutterProject
project
=
new
FlutterProject
.
fromPath
(
'path/to/project'
);
await
updateGeneratedXcodeProperties
(
project:
project
,
final
FlutterManifest
manifest
=
await
new
FlutterProject
.
fromPath
(
'path/to/project'
).
manifest
;
updateGeneratedXcodeProperties
(
projectPath:
'path/to/project'
,
manifest:
manifest
,
buildInfo:
buildInfo
,
previewDart2:
true
,
);
...
...
@@ -404,8 +412,11 @@ Information about project "Runner":
const
String
schemaData
=
'{}'
;
writeSchemaFile
(
fs
,
schemaData
);
await
updateGeneratedXcodeProperties
(
project:
new
FlutterProject
.
fromPath
(
'path/to/project'
),
final
FlutterManifest
manifest
=
await
new
FlutterProject
.
fromPath
(
'path/to/project'
).
manifest
;
updateGeneratedXcodeProperties
(
projectPath:
'path/to/project'
,
manifest:
manifest
,
buildInfo:
buildInfo
,
previewDart2:
false
,
);
...
...
packages/flutter_tools/test/project_test.dart
View file @
6a8f9041
...
...
@@ -129,6 +129,13 @@ void testInMemory(String description, Future<Null> testMethod()) {
);
}
void
addPubPackages
(
Directory
directory
)
{
directory
.
childFile
(
'pubspec.yaml'
)
..
createSync
(
recursive:
true
);
directory
.
childFile
(
'.packages'
)
..
createSync
(
recursive:
true
);
}
void
addIosWithBundleId
(
Directory
directory
,
String
id
)
{
directory
.
childDirectory
(
'ios'
)
...
...
packages/flutter_tools/test/src/mocks.dart
View file @
6a8f9041
...
...
@@ -25,7 +25,7 @@ class MockApplicationPackageStore extends ApplicationPackageStore {
MockApplicationPackageStore
()
:
super
(
android:
new
AndroidApk
(
id:
'io.flutter.android.mock'
,
file:
fs
.
file
(
'/mock/path/to/android/SkyShell.apk'
)
,
apkPath:
'/mock/path/to/android/SkyShell.apk'
,
launchActivity:
'io.flutter.android.mock.MockActivity'
),
iOS:
new
BuildableIOSApp
(
...
...
packages/flutter_tools/test/tester/flutter_tester_test.dart
View file @
6a8f9041
...
...
@@ -33,7 +33,7 @@ void main() {
final
FlutterTesterApp
app
=
new
FlutterTesterApp
.
fromCurrentDirectory
();
expect
(
app
.
name
,
'my_project'
);
expect
(
app
.
package
sFile
.
p
ath
,
fs
.
path
.
join
(
projectPath
,
'.packages'
));
expect
(
app
.
package
P
ath
,
fs
.
path
.
join
(
projectPath
,
'.packages'
));
},
overrides:
<
Type
,
Generator
>{
FileSystem:
()
=>
fs
,
});
...
...
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