From efc457cc2165f3855a0d212d5514ad978df4596e Mon Sep 17 00:00:00 2001 From: Ben Konyi Date: Fri, 20 Oct 2023 10:19:11 -0400 Subject: [PATCH] Migrate pub to use package:unified_analytics --- lib/src/pub_embeddable_command.dart | 10 +--- lib/src/solver/result.dart | 25 +++------ pubspec.yaml | 2 +- test/embedding/embedding_test.dart | 75 +-------------------------- tool/test-bin/pub_command_runner.dart | 69 ------------------------ 5 files changed, 11 insertions(+), 170 deletions(-) diff --git a/lib/src/pub_embeddable_command.dart b/lib/src/pub_embeddable_command.dart index 32ff21e2c..3454f581a 100644 --- a/lib/src/pub_embeddable_command.dart +++ b/lib/src/pub_embeddable_command.dart @@ -2,7 +2,7 @@ // for details. 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:usage/usage.dart'; +import 'package:unified_analytics/unified_analytics.dart'; import 'command.dart' show PubCommand, PubTopLevel; import 'command.dart'; @@ -27,17 +27,11 @@ import 'utils.dart'; /// The information needed for the embedded pub command to send analytics. final class PubAnalytics { - /// Name of the custom dimension of the dependency kind. - final String dependencyKindCustomDimensionName; - final Analytics? Function() _analyticsGetter; Analytics? get analytics => _analyticsGetter(); - PubAnalytics( - this._analyticsGetter, { - required this.dependencyKindCustomDimensionName, - }); + PubAnalytics(this._analyticsGetter); } /// Exposes the `pub` commands as a command to be embedded in another command diff --git a/lib/src/solver/result.dart b/lib/src/solver/result.dart index fb8f2e584..5de0d0058 100644 --- a/lib/src/solver/result.dart +++ b/lib/src/solver/result.dart @@ -4,6 +4,7 @@ import 'package:collection/collection.dart'; import 'package:pub_semver/pub_semver.dart'; +import 'package:unified_analytics/unified_analytics.dart'; import '../http.dart'; import '../io.dart'; @@ -158,29 +159,17 @@ class SolveResult { DependencyType.direct: 'direct', DependencyType.none: 'transitive', }[_root.pubspec.dependencyType(package.name)]!; - analytics.sendEvent( - 'pub-get', - package.name, - label: package.version.canonicalizedVersion, - value: 1, - parameters: { - 'ni': '1', // We consider a pub-get a non-interactive event. - pubAnalytics.dependencyKindCustomDimensionName: dependencyKind, - }, + analytics.send( + Event.pubGet( + packageName: package.name, + version: package.version.canonicalizedVersion, + dependencyType: dependencyKind, + ), ); log.fine( 'Sending analytics hit for "pub-get" of ${package.name} version ${package.version} as dependency-kind $dependencyKind', ); } - - analytics.sendTiming( - 'resolution', - resolutionTime.inMilliseconds, - category: 'pub-get', - ); - log.fine( - 'Sending analytics timing "pub-get" took ${resolutionTime.inMilliseconds} milliseconds', - ); } @override diff --git a/pubspec.yaml b/pubspec.yaml index facd7e344..93eb814a9 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -25,7 +25,7 @@ dependencies: stack_trace: ^1.10.0 tar: ^1.0.1 typed_data: ^1.3.1 - usage: ^4.0.2 + unified_analytics: ^4.0.1 yaml: ^3.1.0 yaml_edit: ^2.0.0 diff --git a/test/embedding/embedding_test.dart b/test/embedding/embedding_test.dart index 11df2d4f4..fc4506ba4 100644 --- a/test/embedding/embedding_test.dart +++ b/test/embedding/embedding_test.dart @@ -2,10 +2,8 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -import 'dart:convert'; import 'dart:io'; -import 'package:path/path.dart' as path; import 'package:path/path.dart' as p; import 'package:pub/src/exit_codes.dart'; import 'package:pub/src/io.dart' show EnvironmentKeys; @@ -87,7 +85,7 @@ extension on GoldenTestContext { Future main() async { setUpAll(() async { final tempDir = Directory.systemTemp.createTempSync(); - snapshot = path.join(tempDir.path, 'command_runner.dart.snapshot'); + snapshot = p.join(tempDir.path, 'command_runner.dart.snapshot'); final r = Process.runSync( Platform.resolvedExecutable, ['--snapshot=$snapshot', _commandRunner], @@ -191,77 +189,6 @@ main() { ); }); - test('analytics', () async { - await servePackages() - ..serve('foo', '1.0.0', deps: {'bar': 'any'}) - ..serve('bar', '1.0.0'); - await d.dir('dep', [ - d.pubspec({ - 'name': 'dep', - 'environment': {'sdk': '^3.0.0'}, - }), - ]).create(); - final app = d.dir(appPath, [ - d.appPubspec( - dependencies: { - 'foo': '1.0.0', - // The path dependency should not go to analytics. - 'dep': {'path': '../dep'}, - }, - ), - ]); - await app.create(); - - final buffer = StringBuffer(); - - await runEmbeddingToBuffer( - ['pub', 'get'], - buffer, - workingDirectory: app.io.path, - environment: {...getPubTestEnvironment(), '_PUB_LOG_ANALYTICS': 'true'}, - ); - final analytics = buffer - .toString() - .split('\n') - .where((line) => line.startsWith('[E] [analytics]: ')) - .map((line) => json.decode(line.substring('[E] [analytics]: '.length))); - expect(analytics, { - { - 'hitType': 'event', - 'message': { - 'category': 'pub-get', - 'action': 'foo', - 'label': '1.0.0', - 'value': 1, - 'cd1': 'direct', - 'ni': '1', - }, - }, - { - 'hitType': 'event', - 'message': { - 'category': 'pub-get', - 'action': 'bar', - 'label': '1.0.0', - 'value': 1, - 'cd1': 'transitive', - 'ni': '1', - }, - }, - { - 'hitType': 'timing', - 'message': { - 'variableName': 'resolution', - 'time': isA(), - 'category': 'pub-get', - 'label': null, - }, - }, - }); - // Don't write the logs to file on a normal run. - expect(File(logFile).existsSync(), isFalse); - }); - test('`embedding --verbose pub` is verbose', () async { await servePackages(); final buffer = StringBuffer(); diff --git a/tool/test-bin/pub_command_runner.dart b/tool/test-bin/pub_command_runner.dart index a11a2a486..e6d84e7d7 100644 --- a/tool/test-bin/pub_command_runner.dart +++ b/tool/test-bin/pub_command_runner.dart @@ -5,7 +5,6 @@ /// A trivial embedding of the pub command. Used from tests. library; -import 'dart:convert'; import 'dart:io'; import 'package:args/args.dart'; @@ -15,9 +14,6 @@ import 'package:pub/src/command.dart'; import 'package:pub/src/exit_codes.dart' as exit_codes; import 'package:pub/src/log.dart' as log; import 'package:pub/src/utils.dart'; -import 'package:usage/usage.dart'; - -final Analytics loggingAnalytics = _LoggingAnalytics(); /// A command for explicitly throwing an exception, to test the handling of /// unexpected exceptions. @@ -83,15 +79,8 @@ class Runner extends CommandRunner { late ArgResults _results; Runner() : super('pub_command_runner', 'Tests the embeddable pub command.') { - final analytics = Platform.environment['_PUB_LOG_ANALYTICS'] == 'true' - ? PubAnalytics( - () => loggingAnalytics, - dependencyKindCustomDimensionName: 'cd1', - ) - : null; addCommand( pubCommand( - analytics: analytics, isVerbose: () => _results.flag('verbose'), ) ..addSubcommand(ThrowingCommand()) @@ -124,61 +113,3 @@ class Runner extends CommandRunner { Future main(List arguments) async { exitCode = await Runner().run(arguments); } - -class _LoggingAnalytics extends AnalyticsMock { - _LoggingAnalytics() { - onSend.listen((event) { - stderr.writeln('[analytics]${json.encode(event)}'); - }); - } - - @override - bool get firstRun => false; - - @override - Future sendScreenView(String viewName, {Map? parameters}) { - parameters ??= {}; - parameters['viewName'] = viewName; - return _log('screenView', parameters); - } - - @override - Future sendEvent( - String category, - String action, { - String? label, - int? value, - Map? parameters, - }) { - parameters ??= {}; - return _log( - 'event', - {'category': category, 'action': action, 'label': label, 'value': value} - ..addAll(parameters), - ); - } - - @override - Future sendSocial(String network, String action, String target) => - _log('social', {'network': network, 'action': action, 'target': target}); - - @override - Future sendTiming( - String variableName, - int time, { - String? category, - String? label, - }) { - return _log('timing', { - 'variableName': variableName, - 'time': time, - 'category': category, - 'label': label, - }); - } - - Future _log(String hitType, Map message) async { - final encoded = json.encode({'hitType': hitType, 'message': message}); - stderr.writeln('[analytics]: $encoded'); - } -}