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
c92cc258
Unverified
Commit
c92cc258
authored
Dec 03, 2020
by
Jonah Williams
Committed by
GitHub
Dec 03, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[flutter_tools] report basic analytics for null-safety (#71487)
parent
b3588541
Changes
10
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
223 additions
and
0 deletions
+223
-0
build.dart
packages/flutter_tools/lib/src/commands/build.dart
+3
-0
build_aar.dart
packages/flutter_tools/lib/src/commands/build_aar.dart
+3
-0
build_ios_framework.dart
...s/flutter_tools/lib/src/commands/build_ios_framework.dart
+3
-0
run.dart
packages/flutter_tools/lib/src/commands/run.dart
+3
-0
events.dart
packages/flutter_tools/lib/src/reporting/events.dart
+62
-0
reporting.dart
packages/flutter_tools/lib/src/reporting/reporting.dart
+3
-0
usage.dart
packages/flutter_tools/lib/src/reporting/usage.dart
+2
-0
flutter_command.dart
packages/flutter_tools/lib/src/runner/flutter_command.dart
+16
-0
events_test.dart
...utter_tools/test/general.shard/reporting/events_test.dart
+46
-0
flutter_command_test.dart
...tools/test/general.shard/runner/flutter_command_test.dart
+82
-0
No files found.
packages/flutter_tools/lib/src/commands/build.dart
View file @
c92cc258
...
@@ -49,4 +49,7 @@ abstract class BuildSubCommand extends FlutterCommand {
...
@@ -49,4 +49,7 @@ abstract class BuildSubCommand extends FlutterCommand {
BuildSubCommand
()
{
BuildSubCommand
()
{
requiresPubspecYaml
();
requiresPubspecYaml
();
}
}
@override
bool
get
reportNullSafety
=>
true
;
}
}
packages/flutter_tools/lib/src/commands/build_aar.dart
View file @
c92cc258
...
@@ -62,6 +62,9 @@ class BuildAarCommand extends BuildSubCommand {
...
@@ -62,6 +62,9 @@ class BuildAarCommand extends BuildSubCommand {
@override
@override
final
String
name
=
'aar'
;
final
String
name
=
'aar'
;
@override
bool
get
reportNullSafety
=>
false
;
@override
@override
Future
<
Set
<
DevelopmentArtifact
>>
get
requiredArtifacts
async
=>
<
DevelopmentArtifact
>{
Future
<
Set
<
DevelopmentArtifact
>>
get
requiredArtifacts
async
=>
<
DevelopmentArtifact
>{
DevelopmentArtifact
.
androidGenSnapshot
,
DevelopmentArtifact
.
androidGenSnapshot
,
...
...
packages/flutter_tools/lib/src/commands/build_ios_framework.dart
View file @
c92cc258
...
@@ -108,6 +108,9 @@ class BuildIOSFrameworkCommand extends BuildSubCommand {
...
@@ -108,6 +108,9 @@ class BuildIOSFrameworkCommand extends BuildSubCommand {
FlutterVersion
_flutterVersion
;
FlutterVersion
_flutterVersion
;
@override
bool
get
reportNullSafety
=>
false
;
@override
@override
final
String
name
=
'ios-framework'
;
final
String
name
=
'ios-framework'
;
...
...
packages/flutter_tools/lib/src/commands/run.dart
View file @
c92cc258
...
@@ -145,6 +145,9 @@ abstract class RunCommandBase extends FlutterCommand with DeviceBasedDevelopment
...
@@ -145,6 +145,9 @@ abstract class RunCommandBase extends FlutterCommand with DeviceBasedDevelopment
bool
get
runningWithPrebuiltApplication
=>
argResults
[
'use-application-binary'
]
!=
null
;
bool
get
runningWithPrebuiltApplication
=>
argResults
[
'use-application-binary'
]
!=
null
;
bool
get
trackWidgetCreation
=>
boolArg
(
'track-widget-creation'
);
bool
get
trackWidgetCreation
=>
boolArg
(
'track-widget-creation'
);
@override
bool
get
reportNullSafety
=>
true
;
/// Whether to start the application paused by default.
/// Whether to start the application paused by default.
bool
get
startPausedDefault
;
bool
get
startPausedDefault
;
...
...
packages/flutter_tools/lib/src/reporting/events.dart
View file @
c92cc258
...
@@ -249,3 +249,65 @@ class CodeSizeEvent extends UsageEvent {
...
@@ -249,3 +249,65 @@ class CodeSizeEvent extends UsageEvent {
class
ErrorHandlingEvent
extends
UsageEvent
{
class
ErrorHandlingEvent
extends
UsageEvent
{
ErrorHandlingEvent
(
String
parameter
)
:
super
(
'error-handling'
,
parameter
,
flutterUsage:
globals
.
flutterUsage
);
ErrorHandlingEvent
(
String
parameter
)
:
super
(
'error-handling'
,
parameter
,
flutterUsage:
globals
.
flutterUsage
);
}
}
/// Emit various null safety analytic events.
///
/// 1. The current null safety runtime mode.
/// 2. The number of packages that are migrated, along with the total number of packages
/// 3. The main packages language version.
class
NullSafetyAnalysisEvent
implements
UsageEvent
{
NullSafetyAnalysisEvent
(
this
.
packageConfig
,
this
.
nullSafetyMode
,
this
.
currentPackage
,
this
.
flutterUsage
,
);
/// The category for analytics events related to null safety.
static
const
String
kNullSafetyCategory
=
'null-safety'
;
final
PackageConfig
packageConfig
;
final
NullSafetyMode
nullSafetyMode
;
final
String
currentPackage
;
@override
final
Usage
flutterUsage
;
@override
void
send
()
{
if
(
packageConfig
.
packages
.
isEmpty
)
{
return
;
}
int
migrated
=
0
;
LanguageVersion
languageVersion
;
for
(
final
Package
package
in
packageConfig
.
packages
)
{
if
(
package
.
name
==
currentPackage
)
{
languageVersion
=
package
.
languageVersion
;
}
if
(
package
.
languageVersion
.
major
>=
nullSafeVersion
.
major
&&
package
.
languageVersion
.
minor
>=
nullSafeVersion
.
minor
)
{
migrated
+=
1
;
}
}
flutterUsage
.
sendEvent
(
kNullSafetyCategory
,
'runtime-mode'
,
label:
nullSafetyMode
.
toString
());
flutterUsage
.
sendEvent
(
kNullSafetyCategory
,
'stats'
,
parameters:
<
String
,
String
>{
cdKey
(
CustomDimensions
.
nullSafeMigratedLibraries
):
migrated
.
toString
(),
cdKey
(
CustomDimensions
.
nullSafeTotalLibraries
):
packageConfig
.
packages
.
length
.
toString
(),
});
if
(
languageVersion
!=
null
)
{
final
String
formattedVersion
=
'
${languageVersion.major}
.
${languageVersion.minor}
'
;
flutterUsage
.
sendEvent
(
kNullSafetyCategory
,
'language-version'
,
label:
formattedVersion
);
}
}
@override
String
get
category
=>
kNullSafetyCategory
;
@override
String
get
label
=>
throw
UnsupportedError
(
''
);
@override
String
get
parameter
=>
throw
UnsupportedError
(
''
);
@override
int
get
value
=>
throw
UnsupportedError
(
''
);
}
packages/flutter_tools/lib/src/reporting/reporting.dart
View file @
c92cc258
...
@@ -10,6 +10,7 @@ import 'package:file/file.dart';
...
@@ -10,6 +10,7 @@ import 'package:file/file.dart';
import
'package:http/http.dart'
as
http
;
import
'package:http/http.dart'
as
http
;
import
'package:intl/intl.dart'
;
import
'package:intl/intl.dart'
;
import
'package:meta/meta.dart'
;
import
'package:meta/meta.dart'
;
import
'package:package_config/package_config.dart'
;
import
'package:usage/usage_io.dart'
;
import
'package:usage/usage_io.dart'
;
import
'../base/async_guard.dart'
;
import
'../base/async_guard.dart'
;
...
@@ -21,8 +22,10 @@ import '../base/os.dart';
...
@@ -21,8 +22,10 @@ import '../base/os.dart';
import
'../base/platform.dart'
;
import
'../base/platform.dart'
;
import
'../base/process.dart'
;
import
'../base/process.dart'
;
import
'../base/time.dart'
;
import
'../base/time.dart'
;
import
'../build_info.dart'
;
import
'../build_system/exceptions.dart'
;
import
'../build_system/exceptions.dart'
;
import
'../convert.dart'
;
import
'../convert.dart'
;
import
'../dart/language_version.dart'
;
import
'../devfs.dart'
;
import
'../devfs.dart'
;
import
'../doctor.dart'
;
import
'../doctor.dart'
;
import
'../features.dart'
;
import
'../features.dart'
;
...
...
packages/flutter_tools/lib/src/reporting/usage.dart
View file @
c92cc258
...
@@ -59,6 +59,8 @@ enum CustomDimensions {
...
@@ -59,6 +59,8 @@ enum CustomDimensions {
commandPackagesAndroidEmbeddingVersion
,
// cd46
commandPackagesAndroidEmbeddingVersion
,
// cd46
nullSafety
,
// cd47
nullSafety
,
// cd47
fastReassemble
,
// cd48
fastReassemble
,
// cd48
nullSafeMigratedLibraries
,
// cd49
nullSafeTotalLibraries
,
// cd 50
}
}
String
cdKey
(
CustomDimensions
cd
)
=>
'cd
${cd.index + 1}
'
;
String
cdKey
(
CustomDimensions
cd
)
=>
'cd
${cd.index + 1}
'
;
...
...
packages/flutter_tools/lib/src/runner/flutter_command.dart
View file @
c92cc258
...
@@ -487,6 +487,9 @@ abstract class FlutterCommand extends Command<void> {
...
@@ -487,6 +487,9 @@ abstract class FlutterCommand extends Command<void> {
/// Whether it is safe for this command to use a cached pub invocation.
/// Whether it is safe for this command to use a cached pub invocation.
bool
get
cachePubGet
=>
true
;
bool
get
cachePubGet
=>
true
;
/// Whether this command should report null safety analytics.
bool
get
reportNullSafety
=>
false
;
Duration
get
deviceDiscoveryTimeout
{
Duration
get
deviceDiscoveryTimeout
{
if
(
_deviceDiscoveryTimeout
==
null
if
(
_deviceDiscoveryTimeout
==
null
&&
argResults
.
options
.
contains
(
FlutterOptions
.
kDeviceTimeout
)
&&
argResults
.
options
.
contains
(
FlutterOptions
.
kDeviceTimeout
)
...
@@ -1112,6 +1115,9 @@ abstract class FlutterCommand extends Command<void> {
...
@@ -1112,6 +1115,9 @@ abstract class FlutterCommand extends Command<void> {
checkUpToDate:
cachePubGet
,
checkUpToDate:
cachePubGet
,
);
);
await
project
.
regeneratePlatformSpecificTooling
();
await
project
.
regeneratePlatformSpecificTooling
();
if
(
reportNullSafety
)
{
await
_sendNullSafetyAnalyticsEvents
(
project
);
}
}
}
setupApplicationPackages
();
setupApplicationPackages
();
...
@@ -1128,6 +1134,16 @@ abstract class FlutterCommand extends Command<void> {
...
@@ -1128,6 +1134,16 @@ abstract class FlutterCommand extends Command<void> {
return
await
runCommand
();
return
await
runCommand
();
}
}
Future
<
void
>
_sendNullSafetyAnalyticsEvents
(
FlutterProject
project
)
async
{
final
BuildInfo
buildInfo
=
await
getBuildInfo
();
NullSafetyAnalysisEvent
(
buildInfo
.
packageConfig
,
buildInfo
.
nullSafetyMode
,
project
.
manifest
.
appName
,
globals
.
flutterUsage
,
).
send
();
}
/// The set of development artifacts required for this command.
/// The set of development artifacts required for this command.
///
///
/// Defaults to an empty set. Including [DevelopmentArtifact.universal] is
/// Defaults to an empty set. Including [DevelopmentArtifact.universal] is
...
...
packages/flutter_tools/test/general.shard/reporting/events_test.dart
View file @
c92cc258
...
@@ -2,9 +2,11 @@
...
@@ -2,9 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// found in the LICENSE file.
import
'package:flutter_tools/src/build_info.dart'
;
import
'package:flutter_tools/src/doctor.dart'
;
import
'package:flutter_tools/src/doctor.dart'
;
import
'package:flutter_tools/src/reporting/reporting.dart'
;
import
'package:flutter_tools/src/reporting/reporting.dart'
;
import
'package:mockito/mockito.dart'
;
import
'package:mockito/mockito.dart'
;
import
'package:package_config/package_config.dart'
;
import
'../../src/common.dart'
;
import
'../../src/common.dart'
;
...
@@ -50,6 +52,50 @@ void main() {
...
@@ -50,6 +52,50 @@ void main() {
verify
(
usage
.
sendEvent
(
'doctor-result'
,
any
,
label:
anyNamed
(
'label'
))).
called
(
1
);
verify
(
usage
.
sendEvent
(
'doctor-result'
,
any
,
label:
anyNamed
(
'label'
))).
called
(
1
);
});
});
testWithoutContext
(
'Reports null safe analytics events'
,
()
{
final
Usage
usage
=
MockUsage
();
final
PackageConfig
packageConfig
=
PackageConfig
(<
Package
>[
Package
(
'foo'
,
Uri
.
parse
(
'file:///foo/'
),
languageVersion:
LanguageVersion
(
2
,
12
)),
Package
(
'bar'
,
Uri
.
parse
(
'file:///fizz/'
),
languageVersion:
LanguageVersion
(
2
,
1
)),
Package
(
'baz'
,
Uri
.
parse
(
'file:///bar/'
),
languageVersion:
LanguageVersion
(
2
,
2
)),
]);
NullSafetyAnalysisEvent
(
packageConfig
,
NullSafetyMode
.
sound
,
'foo'
,
usage
,
).
send
();
verify
(
usage
.
sendEvent
(
NullSafetyAnalysisEvent
.
kNullSafetyCategory
,
'runtime-mode'
,
label:
'NullSafetyMode.sound'
)).
called
(
1
);
verify
(
usage
.
sendEvent
(
NullSafetyAnalysisEvent
.
kNullSafetyCategory
,
'stats'
,
parameters:
<
String
,
String
>{
'cd49'
:
'1'
,
'cd50'
:
'3'
,
})).
called
(
1
);
verify
(
usage
.
sendEvent
(
NullSafetyAnalysisEvent
.
kNullSafetyCategory
,
'language-version'
,
label:
'2.12'
)).
called
(
1
);
});
testWithoutContext
(
'Does not crash if main package is missing'
,
()
{
final
Usage
usage
=
MockUsage
();
final
PackageConfig
packageConfig
=
PackageConfig
(<
Package
>[
Package
(
'foo'
,
Uri
.
parse
(
'file:///foo/lib/'
),
languageVersion:
LanguageVersion
(
2
,
12
)),
Package
(
'bar'
,
Uri
.
parse
(
'file:///fizz/lib/'
),
languageVersion:
LanguageVersion
(
2
,
1
)),
Package
(
'baz'
,
Uri
.
parse
(
'file:///bar/lib/'
),
languageVersion:
LanguageVersion
(
2
,
2
)),
]);
NullSafetyAnalysisEvent
(
packageConfig
,
NullSafetyMode
.
sound
,
'something-unrelated'
,
usage
,
).
send
();
verify
(
usage
.
sendEvent
(
NullSafetyAnalysisEvent
.
kNullSafetyCategory
,
'runtime-mode'
,
label:
'NullSafetyMode.sound'
)).
called
(
1
);
verify
(
usage
.
sendEvent
(
NullSafetyAnalysisEvent
.
kNullSafetyCategory
,
'stats'
,
parameters:
<
String
,
String
>{
'cd49'
:
'1'
,
'cd50'
:
'3'
,
})).
called
(
1
);
verifyNever
(
usage
.
sendEvent
(
NullSafetyAnalysisEvent
.
kNullSafetyCategory
,
'language-version'
,
label:
anyNamed
(
'label'
)));
});
}
}
class
FakeGroupedValidator
extends
GroupedValidator
{
class
FakeGroupedValidator
extends
GroupedValidator
{
...
...
packages/flutter_tools/test/general.shard/runner/flutter_command_test.dart
View file @
c92cc258
...
@@ -14,6 +14,7 @@ import 'package:flutter_tools/src/base/io.dart';
...
@@ -14,6 +14,7 @@ import 'package:flutter_tools/src/base/io.dart';
import
'package:flutter_tools/src/base/signals.dart'
;
import
'package:flutter_tools/src/base/signals.dart'
;
import
'package:flutter_tools/src/base/time.dart'
;
import
'package:flutter_tools/src/base/time.dart'
;
import
'package:flutter_tools/src/cache.dart'
;
import
'package:flutter_tools/src/cache.dart'
;
import
'package:flutter_tools/src/dart/pub.dart'
;
import
'package:flutter_tools/src/reporting/reporting.dart'
;
import
'package:flutter_tools/src/reporting/reporting.dart'
;
import
'package:flutter_tools/src/runner/flutter_command.dart'
;
import
'package:flutter_tools/src/runner/flutter_command.dart'
;
import
'package:flutter_tools/src/version.dart'
;
import
'package:flutter_tools/src/version.dart'
;
...
@@ -485,6 +486,47 @@ void main() {
...
@@ -485,6 +486,47 @@ void main() {
);
);
}
}
});
});
testUsingContext
(
'reports null safety analytics when reportNullSafety is true'
,
()
async
{
globals
.
fs
.
file
(
'lib/main.dart'
)
..
createSync
(
recursive:
true
)
..
writeAsStringSync
(
'// @dart=2.12'
);
globals
.
fs
.
file
(
'pubspec.yaml'
)
.
writeAsStringSync
(
'name: example
\n
'
);
globals
.
fs
.
file
(
'.dart_tool/package_config.json'
)
..
createSync
(
recursive:
true
)
..
writeAsStringSync
(
r''
'
{
"configVersion": 2,
"packages": [
{
"name": "example",
"rootUri": "../",
"packageUri": "lib/",
"languageVersion": "2.12"
}
],
"generated": "2020-12-02T19:30:53.862346Z",
"generator": "pub",
"generatorVersion": "2.12.0-76.0.dev"
}
'''
);
final
FakeReportingNullSafetyCommand
command
=
FakeReportingNullSafetyCommand
();
final
CommandRunner
<
void
>
runner
=
createTestCommandRunner
(
command
);
await
runner
.
run
(<
String
>[
'test'
]);
verify
(
globals
.
flutterUsage
.
sendEvent
(
NullSafetyAnalysisEvent
.
kNullSafetyCategory
,
'runtime-mode'
,
label:
'NullSafetyMode.sound'
)).
called
(
1
);
verify
(
globals
.
flutterUsage
.
sendEvent
(
NullSafetyAnalysisEvent
.
kNullSafetyCategory
,
'stats'
,
parameters:
<
String
,
String
>{
'cd49'
:
'1'
,
'cd50'
:
'1'
,
})).
called
(
1
);
verify
(
globals
.
flutterUsage
.
sendEvent
(
NullSafetyAnalysisEvent
.
kNullSafetyCategory
,
'language-version'
,
label:
'2.12'
)).
called
(
1
);
},
overrides:
<
Type
,
Generator
>{
Pub:
()
=>
FakePub
(),
Usage:
()
=>
MockitoUsage
(),
FileSystem:
()
=>
MemoryFileSystem
.
test
(),
ProcessManager:
()
=>
FakeProcessManager
.
any
(),
});
});
});
}
}
...
@@ -541,6 +583,32 @@ class FakeTargetCommand extends FlutterCommand {
...
@@ -541,6 +583,32 @@ class FakeTargetCommand extends FlutterCommand {
String
get
name
=>
'test'
;
String
get
name
=>
'test'
;
}
}
class
FakeReportingNullSafetyCommand
extends
FlutterCommand
{
FakeReportingNullSafetyCommand
()
{
argParser
.
addFlag
(
'debug'
);
argParser
.
addFlag
(
'release'
);
argParser
.
addFlag
(
'jit-release'
);
argParser
.
addFlag
(
'profile'
);
}
@override
String
get
description
=>
'test'
;
@override
String
get
name
=>
'test'
;
@override
bool
get
shouldRunPub
=>
true
;
@override
bool
get
reportNullSafety
=>
true
;
@override
Future
<
FlutterCommandResult
>
runCommand
()
async
{
return
FlutterCommandResult
.
success
();
}
}
class
MockVersion
extends
Mock
implements
FlutterVersion
{}
class
MockVersion
extends
Mock
implements
FlutterVersion
{}
class
MockProcessInfo
extends
Mock
implements
ProcessInfo
{}
class
MockProcessInfo
extends
Mock
implements
ProcessInfo
{}
class
MockIoProcessSignal
extends
Mock
implements
io
.
ProcessSignal
{}
class
MockIoProcessSignal
extends
Mock
implements
io
.
ProcessSignal
{}
...
@@ -569,3 +637,17 @@ class FakeSignals implements Signals {
...
@@ -569,3 +637,17 @@ class FakeSignals implements Signals {
@override
@override
Stream
<
Object
>
get
errors
=>
delegate
.
errors
;
Stream
<
Object
>
get
errors
=>
delegate
.
errors
;
}
}
class
FakePub
extends
Fake
implements
Pub
{
@override
Future
<
void
>
get
({
PubContext
context
,
String
directory
,
bool
skipIfAbsent
=
false
,
bool
upgrade
=
false
,
bool
offline
=
false
,
bool
generateSyntheticPackage
=
false
,
String
flutterRootOverride
,
bool
checkUpToDate
=
false
,
})
async
{
}
}
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