blob: e438aae85a1bda6c28957a6ea6c59346dafabbb1 [file] [log] [blame]
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
// 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.
/// A trivial embedding of the pub command. Used from tests.
import 'dart:convert';
import 'dart:io';
import 'package:args/args.dart';
import 'package:args/command_runner.dart';
import 'package:pub/pub.dart';
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:usage/usage.dart';
final _LoggingAnalytics loggingAnalytics = _LoggingAnalytics();
// A command for explicitly throwing an exception, to test the handling of
// unexpected eceptions.
class ThrowingCommand extends PubCommand {
String get name => 'fail';
String get description => 'Throws an exception';
bool get hide => true;
Future<int> runProtected() async {
throw StateError('Pub has crashed');
class Runner extends CommandRunner<int> {
late ArgResults _options;
Runner() : super('pub_command_runner', 'Tests the embeddable pub command.') {
final analytics = Platform.environment['_PUB_LOG_ANALYTICS'] == 'true'
? PubAnalytics(() => loggingAnalytics,
dependencyKindCustomDimensionName: 'cd1')
: null;
pubCommand(analytics: analytics, isVerbose: () => _options['verbose'])
Future<int> run(Iterable<String> args) async {
try {
_options = super.parse(args);
return await runCommand(_options);
} on UsageException catch (error) {
return exit_codes.USAGE;
Future<int> runCommand(ArgResults topLevelResults) async {
return await super.runCommand(topLevelResults) ?? 0;
Future<void> main(List<String> arguments) async {
exitCode = await Runner().run(arguments);
class _LoggingAnalytics extends AnalyticsMock {
_LoggingAnalytics() {
onSend.listen((event) {
bool get firstRun => false;
Future sendScreenView(String viewName, {Map<String, String>? parameters}) {
parameters ??= <String, String>{};
parameters['viewName'] = viewName;
return _log('screenView', parameters);
Future sendEvent(String category, String action,
{String? label, int? value, Map<String, String>? parameters}) {
parameters ??= <String, String>{};
return _log(
{'category': category, 'action': action, 'label': label, 'value': value}
Future sendSocial(String network, String action, String target) =>
_log('social', {'network': network, 'action': action, 'target': target});
Future sendTiming(String variableName, int time,
{String? category, String? label}) {
return _log('timing', {
'variableName': variableName,
'time': time,
'category': category,
'label': label
Future<void> _log(String hitType, Map message) async {
final encoded = json.encode({'hitType': hitType, 'message': message});
stderr.writeln('[analytics]: $encoded');