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
466681ca
Unverified
Commit
466681ca
authored
Jan 29, 2020
by
Emmanuel Garcia
Committed by
GitHub
Jan 29, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Improve error message when a plugin sets an invalid android package (#48104)
parent
7f134d86
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
159 additions
and
17 deletions
+159
-17
platform_plugins.dart
packages/flutter_tools/lib/src/platform_plugins.dart
+28
-14
forbidden_imports_test.dart
...tter_tools/test/general.shard/forbidden_imports_test.dart
+6
-3
platform_plugins_test.dart
...utter_tools/test/general.shard/platform_plugins_test.dart
+67
-0
plugins_test.dart
packages/flutter_tools/test/general.shard/plugins_test.dart
+58
-0
No files found.
packages/flutter_tools/lib/src/platform_plugins.dart
View file @
466681ca
...
@@ -85,33 +85,47 @@ class AndroidPlugin extends PluginPlatform {
...
@@ -85,33 +85,47 @@ class AndroidPlugin extends PluginPlatform {
'src'
,
'src'
,
'main'
,
'main'
,
);
);
File
mainPluginClass
=
globals
.
fs
.
file
(
final
List
<
String
>
mainClassCandidates
=
<
String
>[
globals
.
fs
.
path
.
join
(
globals
.
fs
.
path
.
join
(
baseMainPath
,
baseMainPath
,
'java'
,
'java'
,
package
.
replaceAll
(
'.'
,
globals
.
fs
.
path
.
separator
),
package
.
replaceAll
(
'.'
,
globals
.
fs
.
path
.
separator
),
'
$pluginClass
.java'
,
'
$pluginClass
.java'
,
),
globals
.
fs
.
path
.
join
(
baseMainPath
,
'kotlin'
,
package
.
replaceAll
(
'.'
,
globals
.
fs
.
path
.
separator
),
'
$pluginClass
.kt'
,
)
)
);
];
// Check if the plugin is implemented in Kotlin since the plugin's pubspec.yaml
// doesn't include this information.
File
mainPluginClass
;
if
(!
mainPluginClass
.
existsSync
())
{
bool
mainClassFound
=
false
;
mainPluginClass
=
globals
.
fs
.
file
(
for
(
final
String
mainClassCandidate
in
mainClassCandidates
)
{
globals
.
fs
.
path
.
join
(
mainPluginClass
=
globals
.
fs
.
file
(
mainClassCandidate
);
baseMainPath
,
if
(
mainPluginClass
.
existsSync
())
{
'kotlin'
,
mainClassFound
=
true
;
package
.
replaceAll
(
'.'
,
globals
.
fs
.
path
.
separator
),
break
;
'
$pluginClass
.kt'
,
}
)
}
if
(!
mainClassFound
)
{
assert
(
mainClassCandidates
.
length
<=
2
);
throwToolExit
(
'The plugin `
$name
` doesn
\'
t have a main class defined in
${mainClassCandidates.join(' or ')}
. '
'This is likely to due to an incorrect `androidPackage:
$package
` or `mainClass` entry in the plugin
\'
s pubspec.yaml.
\n
'
'If you are the author of this plugin, fix the `androidPackage` entry or move the main class to any of locations used above. '
'Otherwise, please contact the author of this plugin and consider using a different plugin in the meanwhile. '
);
);
}
}
assert
(
mainPluginClass
.
existsSync
());
String
mainClassContent
;
String
mainClassContent
;
try
{
try
{
mainClassContent
=
mainPluginClass
.
readAsStringSync
();
mainClassContent
=
mainPluginClass
.
readAsStringSync
();
}
on
FileSystemException
{
}
on
FileSystemException
{
throwToolExit
(
throwToolExit
(
'Couldn
\'
t read file
$
mainPluginClass
even though it exists. '
'Couldn
\'
t read file
$
{mainPluginClass.path}
even though it exists. '
'Please verify that this file has read permission and try again.'
'Please verify that this file has read permission and try again.'
);
);
}
}
...
...
packages/flutter_tools/test/general.shard/forbidden_imports_test.dart
View file @
466681ca
...
@@ -111,12 +111,15 @@ void main() {
...
@@ -111,12 +111,15 @@ void main() {
});
});
test
(
'no unauthorized imports of package:path'
,
()
{
test
(
'no unauthorized imports of package:path'
,
()
{
final
String
whitelistedPath
=
globals
.
fs
.
path
.
join
(
flutterTools
,
'lib'
,
'src'
,
'build_runner'
,
'web_compilation_delegate.dart'
);
final
List
<
String
>
whitelistedPath
=
<
String
>[
globals
.
fs
.
path
.
join
(
flutterTools
,
'lib'
,
'src'
,
'build_runner'
,
'web_compilation_delegate.dart'
),
globals
.
fs
.
path
.
join
(
flutterTools
,
'test'
,
'general.shard'
,
'platform_plugins_test.dart'
),
];
for
(
final
String
dirName
in
<
String
>[
'lib'
,
'bin'
,
'test'
])
{
for
(
final
String
dirName
in
<
String
>[
'lib'
,
'bin'
,
'test'
])
{
final
Iterable
<
File
>
files
=
globals
.
fs
.
directory
(
globals
.
fs
.
path
.
join
(
flutterTools
,
dirName
))
final
Iterable
<
File
>
files
=
globals
.
fs
.
directory
(
globals
.
fs
.
path
.
join
(
flutterTools
,
dirName
))
.
listSync
(
recursive:
true
)
.
listSync
(
recursive:
true
)
.
where
(
_isDartFile
)
.
where
(
_isDartFile
)
.
where
((
FileSystemEntity
entity
)
=>
entity
.
path
!=
whitelistedPath
)
.
where
((
FileSystemEntity
entity
)
=>
!
whitelistedPath
.
contains
(
entity
.
path
)
)
.
map
(
_asFile
);
.
map
(
_asFile
);
for
(
final
File
file
in
files
)
{
for
(
final
File
file
in
files
)
{
for
(
final
String
line
in
file
.
readAsLinesSync
())
{
for
(
final
String
line
in
file
.
readAsLinesSync
())
{
...
...
packages/flutter_tools/test/general.shard/platform_plugins_test.dart
0 → 100644
View file @
466681ca
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'package:file/file.dart'
;
import
'package:flutter_tools/src/platform_plugins.dart'
;
import
'package:mockito/mockito.dart'
;
import
'package:path/path.dart'
as
p
;
import
'../src/common.dart'
;
import
'../src/context.dart'
;
void
main
(
)
{
group
(
'AndroidPlugin'
,
()
{
MockFileSystem
mockFileSystem
;
MockPathContext
pathContext
;
setUp
(()
{
pathContext
=
MockPathContext
();
when
(
pathContext
.
separator
).
thenReturn
(
'/'
);
mockFileSystem
=
MockFileSystem
();
when
(
mockFileSystem
.
path
).
thenReturn
(
pathContext
);
});
testUsingContext
(
'throws tool exit if the plugin main class can
\'
t be read'
,
()
{
when
(
pathContext
.
join
(
'.pub_cache/plugin_a'
,
'android'
,
'src'
,
'main'
))
.
thenReturn
(
'.pub_cache/plugin_a/android/src/main'
);
when
(
pathContext
.
join
(
'.pub_cache/plugin_a/android/src/main'
,
'java'
,
'com/company'
,
'PluginA.java'
))
.
thenReturn
(
'.pub_cache/plugin_a/android/src/main/java/com/company/PluginA.java'
);
when
(
pathContext
.
join
(
'.pub_cache/plugin_a/android/src/main'
,
'kotlin'
,
'com/company'
,
'PluginA.kt'
))
.
thenReturn
(
'.pub_cache/plugin_a/android/src/main/kotlin/com/company/PluginA.kt'
);
final
MockFile
pluginJavaMainClass
=
MockFile
();
when
(
pluginJavaMainClass
.
existsSync
()).
thenReturn
(
true
);
when
(
pluginJavaMainClass
.
readAsStringSync
()).
thenThrow
(
const
FileSystemException
());
when
(
mockFileSystem
.
file
(
'.pub_cache/plugin_a/android/src/main/java/com/company/PluginA.java'
))
.
thenReturn
(
pluginJavaMainClass
);
final
MockFile
pluginKotlinMainClass
=
MockFile
();
when
(
pluginKotlinMainClass
.
existsSync
()).
thenReturn
(
false
);
when
(
mockFileSystem
.
file
(
'.pub_cache/plugin_a/android/src/main/kotlin/com/company/PluginA.kt'
))
.
thenReturn
(
pluginKotlinMainClass
);
expect
(()
{
AndroidPlugin
(
name:
'pluginA'
,
package:
'com.company'
,
pluginClass:
'PluginA'
,
pluginPath:
'.pub_cache/plugin_a'
,
).
toMap
();
},
throwsToolExit
(
message:
'Couldn
\'
t read file null even though it exists. '
'Please verify that this file has read permission and try again.'
));
},
overrides:
<
Type
,
Generator
>{
FileSystem:
()
=>
mockFileSystem
,
ProcessManager:
()
=>
FakeProcessManager
.
any
(),
});
});
}
class
MockFile
extends
Mock
implements
File
{}
class
MockFileSystem
extends
Mock
implements
FileSystem
{}
class
MockPathContext
extends
Mock
implements
p
.
Context
{}
packages/flutter_tools/test/general.shard/plugins_test.dart
View file @
466681ca
...
@@ -146,6 +146,36 @@ flutter:
...
@@ -146,6 +146,36 @@ flutter:
);
);
}
}
void
createPluginWithInvalidAndroidPackage
()
{
final
Directory
pluginUsingJavaAndNewEmbeddingDir
=
fs
.
systemTempDirectory
.
createTempSync
(
'flutter_plugin_invalid_package.'
);
pluginUsingJavaAndNewEmbeddingDir
.
childFile
(
'pubspec.yaml'
)
.
writeAsStringSync
(
'''
flutter:
plugin:
androidPackage: plugin1.invalid
pluginClass: UseNewEmbedding
'''
);
pluginUsingJavaAndNewEmbeddingDir
.
childDirectory
(
'android'
)
.
childDirectory
(
'src'
)
.
childDirectory
(
'main'
)
.
childDirectory
(
'java'
)
.
childDirectory
(
'plugin1'
)
.
childDirectory
(
'correct'
)
.
childFile
(
'UseNewEmbedding.java'
)
..
createSync
(
recursive:
true
)
..
writeAsStringSync
(
'import io.flutter.embedding.engine.plugins.FlutterPlugin;'
);
flutterProject
.
directory
.
childFile
(
'.packages'
)
.
writeAsStringSync
(
'plugin1:
${pluginUsingJavaAndNewEmbeddingDir.childDirectory('lib').uri.toString()}
\n
'
,
mode:
FileMode
.
append
,
);
}
void
createNewKotlinPlugin2
()
{
void
createNewKotlinPlugin2
()
{
final
Directory
pluginUsingKotlinAndNewEmbeddingDir
=
final
Directory
pluginUsingKotlinAndNewEmbeddingDir
=
fs
.
systemTempDirectory
.
createTempSync
(
'flutter_plugin_using_kotlin_and_new_embedding_dir.'
);
fs
.
systemTempDirectory
.
createTempSync
(
'flutter_plugin_using_kotlin_and_new_embedding_dir.'
);
...
@@ -556,6 +586,33 @@ dependencies:
...
@@ -556,6 +586,33 @@ dependencies:
XcodeProjectInterpreter:
()
=>
xcodeProjectInterpreter
,
XcodeProjectInterpreter:
()
=>
xcodeProjectInterpreter
,
});
});
// Issue: https://github.com/flutter/flutter/issues/47803
testUsingContext
(
'exits the tool if a plugin sets an invalid android package in pubspec.yaml'
,
()
async
{
when
(
flutterProject
.
isModule
).
thenReturn
(
false
);
when
(
androidProject
.
getEmbeddingVersion
()).
thenReturn
(
AndroidEmbeddingVersion
.
v1
);
createPluginWithInvalidAndroidPackage
();
await
expectLater
(
()
async
{
await
injectPlugins
(
flutterProject
);
},
throwsToolExit
(
message:
'The plugin `plugin1` doesn
\'
t have a main class defined in '
'/.tmp_rand2/flutter_plugin_invalid_package.rand2/android/src/main/java/plugin1/invalid/UseNewEmbedding.java or '
'/.tmp_rand2/flutter_plugin_invalid_package.rand2/android/src/main/kotlin/plugin1/invalid/UseNewEmbedding.kt. '
'This is likely to due to an incorrect `androidPackage: plugin1.invalid` or `mainClass` entry in the plugin
\'
s pubspec.yaml.
\n
'
'If you are the author of this plugin, fix the `androidPackage` entry or move the main class to any of locations used above. '
'Otherwise, please contact the author of this plugin and consider using a different plugin in the meanwhile.'
,
),
);
},
overrides:
<
Type
,
Generator
>{
FileSystem:
()
=>
fs
,
ProcessManager:
()
=>
FakeProcessManager
.
any
(),
FeatureFlags:
()
=>
featureFlags
,
XcodeProjectInterpreter:
()
=>
xcodeProjectInterpreter
,
});
testUsingContext
(
'old embedding app uses a plugin that supports v1 and v2 embedding'
,
()
async
{
testUsingContext
(
'old embedding app uses a plugin that supports v1 and v2 embedding'
,
()
async
{
when
(
flutterProject
.
isModule
).
thenReturn
(
false
);
when
(
flutterProject
.
isModule
).
thenReturn
(
false
);
when
(
androidProject
.
getEmbeddingVersion
()).
thenReturn
(
AndroidEmbeddingVersion
.
v1
);
when
(
androidProject
.
getEmbeddingVersion
()).
thenReturn
(
AndroidEmbeddingVersion
.
v1
);
...
@@ -776,6 +833,7 @@ class MockAndroidProject extends Mock implements AndroidProject {}
...
@@ -776,6 +833,7 @@ class MockAndroidProject extends Mock implements AndroidProject {}
class
MockFeatureFlags
extends
Mock
implements
FeatureFlags
{}
class
MockFeatureFlags
extends
Mock
implements
FeatureFlags
{}
class
MockFlutterProject
extends
Mock
implements
FlutterProject
{}
class
MockFlutterProject
extends
Mock
implements
FlutterProject
{}
class
MockFile
extends
Mock
implements
File
{}
class
MockFile
extends
Mock
implements
File
{}
class
MockFileSystem
extends
Mock
implements
FileSystem
{}
class
MockIosProject
extends
Mock
implements
IosProject
{}
class
MockIosProject
extends
Mock
implements
IosProject
{}
class
MockMacOSProject
extends
Mock
implements
MacOSProject
{}
class
MockMacOSProject
extends
Mock
implements
MacOSProject
{}
class
MockXcodeProjectInterpreter
extends
Mock
implements
XcodeProjectInterpreter
{}
class
MockXcodeProjectInterpreter
extends
Mock
implements
XcodeProjectInterpreter
{}
...
...
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