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
4a1c62c2
Unverified
Commit
4a1c62c2
authored
Aug 28, 2019
by
Emmanuel Garcia
Committed by
GitHub
Aug 28, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add missing files in the Gradle wrapper directory (#39145)
parent
ddd31bce
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
227 additions
and
23 deletions
+227
-23
gradle.dart
packages/flutter_tools/lib/src/android/gradle.dart
+26
-15
file_system.dart
packages/flutter_tools/lib/src/base/file_system.dart
+19
-5
create.dart
packages/flutter_tools/lib/src/commands/create.dart
+1
-1
project.dart
packages/flutter_tools/lib/src/project.dart
+2
-2
gradle_test.dart
...flutter_tools/test/general.shard/android/gradle_test.dart
+144
-0
application_package_test.dart
...er_tools/test/general.shard/application_package_test.dart
+12
-0
file_system_test.dart
...utter_tools/test/general.shard/base/file_system_test.dart
+23
-0
No files found.
packages/flutter_tools/lib/src/android/gradle.dart
View file @
4a1c62c2
...
...
@@ -268,13 +268,10 @@ String _locateGradlewExecutable(Directory directory) {
final
File
gradle
=
directory
.
childFile
(
platform
.
isWindows
?
'gradlew.bat'
:
'gradlew'
,
);
if
(
gradle
.
existsSync
())
{
os
.
makeExecutable
(
gradle
);
return
gradle
.
absolute
.
path
;
}
else
{
return
null
;
}
return
null
;
}
Future
<
String
>
_ensureGradle
(
FlutterProject
project
)
async
{
...
...
@@ -286,12 +283,12 @@ Future<String> _ensureGradle(FlutterProject project) async {
// of validating the Gradle executable. This may take several seconds.
Future
<
String
>
_initializeGradle
(
FlutterProject
project
)
async
{
final
Directory
android
=
project
.
android
.
hostAppGradleRoot
;
final
Status
status
=
logger
.
startProgress
(
'Initializing gradle...'
,
timeout:
timeoutConfiguration
.
slowOperation
);
String
gradle
=
_locateGradlewExecutable
(
android
);
if
(
gradle
==
null
)
{
injectGradleWrapper
(
android
);
gradle
=
_locateGradlewExecutable
(
android
);
}
final
Status
status
=
logger
.
startProgress
(
'Initializing gradle...'
,
timeout:
timeoutConfiguration
.
slowOperation
);
injectGradleWrapperIfNeeded
(
android
);
final
String
gradle
=
_locateGradlewExecutable
(
android
);
if
(
gradle
==
null
)
throwToolExit
(
'Unable to locate gradlew script'
);
printTrace
(
'Using gradle from
$gradle
.'
);
...
...
@@ -302,11 +299,25 @@ Future<String> _initializeGradle(FlutterProject project) async {
return
gradle
;
}
/// Injects the Gradle wrapper into the specified directory.
void
injectGradleWrapper
(
Directory
directory
)
{
copyDirectorySync
(
cache
.
getArtifactDirectory
(
'gradle_wrapper'
),
directory
);
_locateGradlewExecutable
(
directory
);
final
File
propertiesFile
=
directory
.
childFile
(
fs
.
path
.
join
(
'gradle'
,
'wrapper'
,
'gradle-wrapper.properties'
));
/// Injects the Gradle wrapper files if any of these files don't exist in [directory].
void
injectGradleWrapperIfNeeded
(
Directory
directory
)
{
copyDirectorySync
(
cache
.
getArtifactDirectory
(
'gradle_wrapper'
),
directory
,
shouldCopyFile:
(
File
sourceFile
,
File
destinationFile
)
{
// Don't override the existing files in the project.
return
!
destinationFile
.
existsSync
();
},
onFileCopied:
(
File
sourceFile
,
File
destinationFile
)
{
final
String
modes
=
sourceFile
.
statSync
().
modeString
();
if
(
modes
!=
null
&&
modes
.
contains
(
'x'
))
{
os
.
makeExecutable
(
destinationFile
);
}
},
);
// Add the `gradle-wrapper.properties` file if it doesn't exist.
final
File
propertiesFile
=
directory
.
childFile
(
fs
.
path
.
join
(
'gradle'
,
'wrapper'
,
'gradle-wrapper.properties'
));
if
(!
propertiesFile
.
existsSync
())
{
final
String
gradleVersion
=
getGradleVersionForAndroidPlugin
(
directory
);
propertiesFile
.
writeAsStringSync
(
'''
...
...
packages/flutter_tools/lib/src/base/file_system.dart
View file @
4a1c62c2
...
...
@@ -64,11 +64,18 @@ void ensureDirectoryExists(String filePath) {
}
}
///
Recursively copies `srcDir` to `destDir`, invoking [onFileCopied] if
///
specified
for each source/destination file pair.
///
Creates `destDir` if needed, then recursively copies `srcDir` to `destDir`,
///
invoking [onFileCopied], if specified,
for each source/destination file pair.
///
/// Creates `destDir` if needed.
void
copyDirectorySync
(
Directory
srcDir
,
Directory
destDir
,
[
void
onFileCopied
(
File
srcFile
,
File
destFile
)
])
{
/// Skips files if [shouldCopyFile] returns `false`.
void
copyDirectorySync
(
Directory
srcDir
,
Directory
destDir
,
{
bool
shouldCopyFile
(
File
srcFile
,
File
destFile
),
void
onFileCopied
(
File
srcFile
,
File
destFile
),
}
)
{
if
(!
srcDir
.
existsSync
())
throw
Exception
(
'Source directory "
${srcDir.path}
" does not exist, nothing to copy'
);
...
...
@@ -79,11 +86,18 @@ void copyDirectorySync(Directory srcDir, Directory destDir, [ void onFileCopied(
final
String
newPath
=
destDir
.
fileSystem
.
path
.
join
(
destDir
.
path
,
entity
.
basename
);
if
(
entity
is
File
)
{
final
File
newFile
=
destDir
.
fileSystem
.
file
(
newPath
);
if
(
shouldCopyFile
!=
null
&&
!
shouldCopyFile
(
entity
,
newFile
))
{
continue
;
}
newFile
.
writeAsBytesSync
(
entity
.
readAsBytesSync
());
onFileCopied
?.
call
(
entity
,
newFile
);
}
else
if
(
entity
is
Directory
)
{
copyDirectorySync
(
entity
,
destDir
.
fileSystem
.
directory
(
newPath
));
entity
,
destDir
.
fileSystem
.
directory
(
newPath
),
shouldCopyFile:
shouldCopyFile
,
onFileCopied:
onFileCopied
,
);
}
else
{
throw
Exception
(
'
${entity.path}
is neither File nor Directory'
);
}
...
...
packages/flutter_tools/lib/src/commands/create.dart
View file @
4a1c62c2
...
...
@@ -628,7 +628,7 @@ To edit platform code in an IDE see https://flutter.dev/developing-packages/#edi
copyDirectorySync
(
cache
.
getArtifactDirectory
(
'gradle_wrapper'
),
project
.
android
.
hostAppGradleRoot
,
(
File
sourceFile
,
File
destinationFile
)
{
onFileCopied:
(
File
sourceFile
,
File
destinationFile
)
{
filesCreated
++;
final
String
modes
=
sourceFile
.
statSync
().
modeString
();
if
(
modes
!=
null
&&
modes
.
contains
(
'x'
))
{
...
...
packages/flutter_tools/lib/src/project.dart
View file @
4a1c62c2
...
...
@@ -580,7 +580,7 @@ class AndroidProject {
_overwriteFromTemplate
(
fs
.
path
.
join
(
'module'
,
'android'
,
'host_app_common'
),
_editableHostAppDirectory
);
_overwriteFromTemplate
(
fs
.
path
.
join
(
'module'
,
'android'
,
'host_app_editable'
),
_editableHostAppDirectory
);
_overwriteFromTemplate
(
fs
.
path
.
join
(
'module'
,
'android'
,
'gradle'
),
_editableHostAppDirectory
);
gradle
.
injectGradleWrapper
(
_editableHostAppDirectory
);
gradle
.
injectGradleWrapper
IfNeeded
(
_editableHostAppDirectory
);
gradle
.
writeLocalProperties
(
_editableHostAppDirectory
.
childFile
(
'local.properties'
));
await
injectPlugins
(
parent
);
}
...
...
@@ -593,7 +593,7 @@ class AndroidProject {
_deleteIfExistsSync
(
ephemeralDirectory
);
_overwriteFromTemplate
(
fs
.
path
.
join
(
'module'
,
'android'
,
'library'
),
ephemeralDirectory
);
_overwriteFromTemplate
(
fs
.
path
.
join
(
'module'
,
'android'
,
'gradle'
),
ephemeralDirectory
);
gradle
.
injectGradleWrapper
(
ephemeralDirectory
);
gradle
.
injectGradleWrapper
IfNeeded
(
ephemeralDirectory
);
}
void
_overwriteFromTemplate
(
String
path
,
Directory
target
)
{
...
...
packages/flutter_tools/test/general.shard/android/gradle_test.dart
View file @
4a1c62c2
...
...
@@ -13,6 +13,7 @@ import 'package:flutter_tools/src/base/logger.dart';
import
'package:flutter_tools/src/artifacts.dart'
;
import
'package:flutter_tools/src/base/common.dart'
;
import
'package:flutter_tools/src/base/file_system.dart'
;
import
'package:flutter_tools/src/base/os.dart'
;
import
'package:flutter_tools/src/build_info.dart'
;
import
'package:flutter_tools/src/cache.dart'
;
import
'package:flutter_tools/src/ios/xcodeproj.dart'
;
...
...
@@ -848,6 +849,125 @@ flutter:
});
});
group
(
'injectGradleWrapperIfNeeded'
,
()
{
MemoryFileSystem
memoryFileSystem
;
Directory
tempDir
;
Directory
gradleWrapperDirectory
;
setUp
(()
{
memoryFileSystem
=
MemoryFileSystem
();
tempDir
=
memoryFileSystem
.
systemTempDirectory
.
createTempSync
(
'artifacts_test.'
);
gradleWrapperDirectory
=
memoryFileSystem
.
directory
(
memoryFileSystem
.
path
.
join
(
tempDir
.
path
,
'bin'
,
'cache'
,
'artifacts'
,
'gradle_wrapper'
));
gradleWrapperDirectory
.
createSync
(
recursive:
true
);
gradleWrapperDirectory
.
childFile
(
'gradlew'
)
.
writeAsStringSync
(
'irrelevant'
);
gradleWrapperDirectory
.
childDirectory
(
'gradle'
)
.
childDirectory
(
'wrapper'
)
.
createSync
(
recursive:
true
);
gradleWrapperDirectory
.
childDirectory
(
'gradle'
)
.
childDirectory
(
'wrapper'
)
.
childFile
(
'gradle-wrapper.jar'
)
.
writeAsStringSync
(
'irrelevant'
);
});
testUsingContext
(
'Inject the wrapper when all files are missing'
,
()
{
final
Directory
sampleAppAndroid
=
fs
.
directory
(
'/sample-app/android'
);
sampleAppAndroid
.
createSync
(
recursive:
true
);
injectGradleWrapperIfNeeded
(
sampleAppAndroid
);
expect
(
sampleAppAndroid
.
childFile
(
'gradlew'
).
existsSync
(),
isTrue
);
expect
(
sampleAppAndroid
.
childDirectory
(
'gradle'
)
.
childDirectory
(
'wrapper'
)
.
childFile
(
'gradle-wrapper.jar'
)
.
existsSync
(),
isTrue
);
expect
(
sampleAppAndroid
.
childDirectory
(
'gradle'
)
.
childDirectory
(
'wrapper'
)
.
childFile
(
'gradle-wrapper.properties'
)
.
existsSync
(),
isTrue
);
expect
(
sampleAppAndroid
.
childDirectory
(
'gradle'
)
.
childDirectory
(
'wrapper'
)
.
childFile
(
'gradle-wrapper.properties'
)
.
readAsStringSync
(),
'distributionBase=GRADLE_USER_HOME
\n
'
'distributionPath=wrapper/dists
\n
'
'zipStoreBase=GRADLE_USER_HOME
\n
'
'zipStorePath=wrapper/dists
\n
'
'distributionUrl=https
\\
://services.gradle.org/distributions/gradle-4.10.2-all.zip
\n
'
);
},
overrides:
<
Type
,
Generator
>{
Cache:
()
=>
Cache
(
rootOverride:
tempDir
),
FileSystem:
()
=>
memoryFileSystem
,
});
testUsingContext
(
'Inject the wrapper when some files are missing'
,
()
{
final
Directory
sampleAppAndroid
=
fs
.
directory
(
'/sample-app/android'
);
sampleAppAndroid
.
createSync
(
recursive:
true
);
// There's an existing gradlew
sampleAppAndroid
.
childFile
(
'gradlew'
).
writeAsStringSync
(
'existing gradlew'
);
injectGradleWrapperIfNeeded
(
sampleAppAndroid
);
expect
(
sampleAppAndroid
.
childFile
(
'gradlew'
).
existsSync
(),
isTrue
);
expect
(
sampleAppAndroid
.
childFile
(
'gradlew'
).
readAsStringSync
(),
equals
(
'existing gradlew'
));
expect
(
sampleAppAndroid
.
childDirectory
(
'gradle'
)
.
childDirectory
(
'wrapper'
)
.
childFile
(
'gradle-wrapper.jar'
)
.
existsSync
(),
isTrue
);
expect
(
sampleAppAndroid
.
childDirectory
(
'gradle'
)
.
childDirectory
(
'wrapper'
)
.
childFile
(
'gradle-wrapper.properties'
)
.
existsSync
(),
isTrue
);
expect
(
sampleAppAndroid
.
childDirectory
(
'gradle'
)
.
childDirectory
(
'wrapper'
)
.
childFile
(
'gradle-wrapper.properties'
)
.
readAsStringSync
(),
'distributionBase=GRADLE_USER_HOME
\n
'
'distributionPath=wrapper/dists
\n
'
'zipStoreBase=GRADLE_USER_HOME
\n
'
'zipStorePath=wrapper/dists
\n
'
'distributionUrl=https
\\
://services.gradle.org/distributions/gradle-4.10.2-all.zip
\n
'
);
},
overrides:
<
Type
,
Generator
>{
Cache:
()
=>
Cache
(
rootOverride:
tempDir
),
FileSystem:
()
=>
memoryFileSystem
,
});
testUsingContext
(
'Gives executable permission to gradle'
,
()
{
final
Directory
sampleAppAndroid
=
fs
.
directory
(
'/sample-app/android'
);
sampleAppAndroid
.
createSync
(
recursive:
true
);
// Make gradlew in the wrapper executable.
os
.
makeExecutable
(
gradleWrapperDirectory
.
childFile
(
'gradlew'
));
injectGradleWrapperIfNeeded
(
sampleAppAndroid
);
final
File
gradlew
=
sampleAppAndroid
.
childFile
(
'gradlew'
);
expect
(
gradlew
.
existsSync
(),
isTrue
);
expect
(
gradlew
.
statSync
().
modeString
().
contains
(
'x'
),
isTrue
);
},
overrides:
<
Type
,
Generator
>{
Cache:
()
=>
Cache
(
rootOverride:
tempDir
),
FileSystem:
()
=>
memoryFileSystem
,
OperatingSystemUtils:
()
=>
OperatingSystemUtils
(),
});
});
group
(
'gradle build'
,
()
{
MockAndroidSdk
mockAndroidSdk
;
MockAndroidStudio
mockAndroidStudio
;
...
...
@@ -855,6 +975,7 @@ flutter:
MockProcessManager
mockProcessManager
;
FakePlatform
android
;
FileSystem
fs
;
Cache
cache
;
setUp
(()
{
fs
=
MemoryFileSystem
();
...
...
@@ -863,6 +984,28 @@ flutter:
mockArtifacts
=
MockLocalEngineArtifacts
();
mockProcessManager
=
MockProcessManager
();
android
=
fakePlatform
(
'android'
);
final
Directory
tempDir
=
fs
.
systemTempDirectory
.
createTempSync
(
'artifacts_test.'
);
cache
=
Cache
(
rootOverride:
tempDir
);
final
Directory
gradleWrapperDirectory
=
tempDir
.
childDirectory
(
'bin'
)
.
childDirectory
(
'cache'
)
.
childDirectory
(
'artifacts'
)
.
childDirectory
(
'gradle_wrapper'
);
gradleWrapperDirectory
.
createSync
(
recursive:
true
);
gradleWrapperDirectory
.
childFile
(
'gradlew'
)
.
writeAsStringSync
(
'irrelevant'
);
gradleWrapperDirectory
.
childDirectory
(
'gradle'
)
.
childDirectory
(
'wrapper'
)
.
createSync
(
recursive:
true
);
gradleWrapperDirectory
.
childDirectory
(
'gradle'
)
.
childDirectory
(
'wrapper'
)
.
childFile
(
'gradle-wrapper.jar'
)
.
writeAsStringSync
(
'irrelevant'
);
});
testUsingContext
(
'build aar uses selected local engine'
,
()
async
{
...
...
@@ -928,6 +1071,7 @@ flutter:
AndroidSdk:
()
=>
mockAndroidSdk
,
AndroidStudio:
()
=>
mockAndroidStudio
,
Artifacts:
()
=>
mockArtifacts
,
Cache:
()
=>
cache
,
ProcessManager:
()
=>
mockProcessManager
,
Platform:
()
=>
android
,
FileSystem:
()
=>
fs
,
...
...
packages/flutter_tools/test/general.shard/application_package_test.dart
View file @
4a1c62c2
...
...
@@ -39,17 +39,20 @@ void main() {
AndroidSdk
sdk
;
ProcessManager
mockProcessManager
;
MemoryFileSystem
fs
;
Cache
mockCache
;
File
gradle
;
final
Map
<
Type
,
Generator
>
overrides
=
<
Type
,
Generator
>{
AndroidSdk:
()
=>
sdk
,
ProcessManager:
()
=>
mockProcessManager
,
FileSystem:
()
=>
fs
,
Cache:
()
=>
mockCache
,
};
setUp
(()
async
{
sdk
=
MockitoAndroidSdk
();
mockProcessManager
=
MockitoProcessManager
();
fs
=
MemoryFileSystem
();
mockCache
=
MockCache
();
Cache
.
flutterRoot
=
'../..'
;
when
(
sdk
.
licensesAvailable
).
thenReturn
(
true
);
when
(
mockProcessManager
.
canRun
(
any
)).
thenReturn
(
true
);
...
...
@@ -100,6 +103,14 @@ void main() {
platform
.
isWindows
?
'gradlew.bat'
:
'gradlew'
,
)..
createSync
(
recursive:
true
);
final
Directory
gradleWrapperDir
=
fs
.
systemTempDirectory
.
createTempSync
(
'gradle_wrapper.'
);
when
(
mockCache
.
getArtifactDirectory
(
'gradle_wrapper'
)).
thenReturn
(
gradleWrapperDir
);
fs
.
directory
(
gradleWrapperDir
.
childDirectory
(
'gradle'
).
childDirectory
(
'wrapper'
))
.
createSync
(
recursive:
true
);
fs
.
file
(
fs
.
path
.
join
(
gradleWrapperDir
.
path
,
'gradlew'
)).
writeAsStringSync
(
'irrelevant'
);
fs
.
file
(
fs
.
path
.
join
(
gradleWrapperDir
.
path
,
'gradlew.bat'
)).
writeAsStringSync
(
'irrelevant'
);
await
ApplicationPackageFactory
.
instance
.
getPackageForPlatform
(
TargetPlatform
.
android_arm
,
applicationBinary:
fs
.
file
(
'app.apk'
),
...
...
@@ -606,4 +617,5 @@ const String plistData = '''
{"CFBundleIdentifier": "fooBundleId"}
'''
;
class
MockCache
extends
Mock
implements
Cache
{}
class
MockOperatingSystemUtils
extends
Mock
implements
OperatingSystemUtils
{
}
packages/flutter_tools/test/general.shard/base/file_system_test.dart
View file @
4a1c62c2
...
...
@@ -58,6 +58,29 @@ void main() {
// There's still 3 things in the original directory as there were initially.
expect
(
sourceMemoryFs
.
directory
(
sourcePath
).
listSync
().
length
,
3
);
});
testUsingContext
(
'Skip files if shouldCopyFile returns false'
,
()
{
final
Directory
origin
=
fs
.
directory
(
'/origin'
);
origin
.
createSync
();
fs
.
file
(
fs
.
path
.
join
(
'origin'
,
'a.txt'
)).
writeAsStringSync
(
'irrelevant'
);
fs
.
directory
(
'/origin/nested'
).
createSync
();
fs
.
file
(
fs
.
path
.
join
(
'origin'
,
'nested'
,
'a.txt'
)).
writeAsStringSync
(
'irrelevant'
);
fs
.
file
(
fs
.
path
.
join
(
'origin'
,
'nested'
,
'b.txt'
)).
writeAsStringSync
(
'irrelevant'
);
final
Directory
destination
=
fs
.
directory
(
'/destination'
);
copyDirectorySync
(
origin
,
destination
,
shouldCopyFile:
(
File
origin
,
File
dest
)
{
return
origin
.
basename
==
'b.txt'
;
});
expect
(
destination
.
existsSync
(),
isTrue
);
expect
(
destination
.
childDirectory
(
'nested'
).
existsSync
(),
isTrue
);
expect
(
destination
.
childDirectory
(
'nested'
).
childFile
(
'b.txt'
).
existsSync
(),
isTrue
);
expect
(
destination
.
childFile
(
'a.txt'
).
existsSync
(),
isFalse
);
expect
(
destination
.
childDirectory
(
'nested'
).
childFile
(
'a.txt'
).
existsSync
(),
isFalse
);
},
overrides:
<
Type
,
Generator
>{
FileSystem:
()
=>
MemoryFileSystem
(),
});
});
group
(
'canonicalizePath'
,
()
{
...
...
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