Skip to content

Analytics #2778

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 20 commits into from
Oct 15, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion lib/pub.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,15 @@ import 'src/command_runner.dart';
import 'src/pub_embeddable_command.dart';
export 'src/executable.dart'
show getExecutableForCommand, CommandResolutionFailedException;
export 'src/pub_embeddable_command.dart' show PubAnalytics;

/// Returns a [Command] for pub functionality that can be used by an embedding
/// CommandRunner.
Command<int> pubCommand() => PubEmbeddableCommand();
///
/// If [analytics] is given, pub will use that analytics instance to send
/// statistics about resolutions.
Command<int> pubCommand({PubAnalytics analytics}) =>
PubEmbeddableCommand(analytics);

/// Support for the `pub` toplevel command.
@Deprecated('Use [pubCommand] instead.')
Expand Down
2 changes: 2 additions & 0 deletions lib/src/command.dart
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@ abstract class PubCommand extends Command<int> {
return _pubEmbeddableCommand ?? (runner as PubCommandRunner);
}

PubAnalytics get analytics => _pubEmbeddableCommand?.analytics;

@override
String get invocation {
var command = this;
Expand Down
17 changes: 10 additions & 7 deletions lib/src/command/add.dart
Original file line number Diff line number Diff line change
Expand Up @@ -150,11 +150,10 @@ class AddCommand extends PubCommand {
// TODO(jonasfj): Stop abusing Entrypoint.global for dry-run output
await Entrypoint.global(newRoot, entrypoint.lockFile, cache,
solveResult: solveResult)
.acquireDependencies(
SolveType.GET,
dryRun: true,
precompile: argResults['precompile'],
);
.acquireDependencies(SolveType.GET,
dryRun: true,
precompile: argResults['precompile'],
analytics: analytics);
} else {
/// Update the `pubspec.yaml` before calling [acquireDependencies] to
/// ensure that the modification timestamp on `pubspec.lock` and
Expand All @@ -165,14 +164,18 @@ class AddCommand extends PubCommand {
/// Create a new [Entrypoint] since we have to reprocess the updated
/// pubspec file.
final updatedEntrypoint = Entrypoint(directory, cache);
await updatedEntrypoint.acquireDependencies(SolveType.GET,
precompile: argResults['precompile']);
await updatedEntrypoint.acquireDependencies(
SolveType.GET,
precompile: argResults['precompile'],
analytics: analytics,
);

if (argResults['example'] && entrypoint.example != null) {
await entrypoint.example.acquireDependencies(
SolveType.GET,
precompile: argResults['precompile'],
onlyReportSuccessOrFailure: true,
analytics: analytics,
);
}
}
Expand Down
13 changes: 9 additions & 4 deletions lib/src/command/downgrade.dart
Original file line number Diff line number Diff line change
Expand Up @@ -53,16 +53,21 @@ class DowngradeCommand extends PubCommand {
'The --packages-dir flag is no longer used and does nothing.'));
}
var dryRun = argResults['dry-run'];

await entrypoint.acquireDependencies(
SolveType.DOWNGRADE,
unlock: argResults.rest,
dryRun: dryRun,
analytics: analytics,
);
if (argResults['example'] && entrypoint.example != null) {
await entrypoint.example.acquireDependencies(SolveType.GET,
unlock: argResults.rest,
dryRun: dryRun,
onlyReportSuccessOrFailure: true);
await entrypoint.example.acquireDependencies(
SolveType.GET,
unlock: argResults.rest,
dryRun: dryRun,
onlyReportSuccessOrFailure: true,
analytics: analytics,
);
}

if (isOffline) {
Expand Down
19 changes: 13 additions & 6 deletions lib/src/command/get.dart
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,21 @@ class GetCommand extends PubCommand {
log.warning(log.yellow(
'The --packages-dir flag is no longer used and does nothing.'));
}
await entrypoint.acquireDependencies(SolveType.GET,
dryRun: argResults['dry-run'], precompile: argResults['precompile']);
await entrypoint.acquireDependencies(
SolveType.GET,
dryRun: argResults['dry-run'],
precompile: argResults['precompile'],
analytics: analytics,
);

if (argResults['example'] && entrypoint.example != null) {
await entrypoint.example.acquireDependencies(SolveType.GET,
dryRun: argResults['dry-run'],
precompile: argResults['precompile'],
onlyReportSuccessOrFailure: true);
await entrypoint.example.acquireDependencies(
SolveType.GET,
dryRun: argResults['dry-run'],
precompile: argResults['precompile'],
onlyReportSuccessOrFailure: true,
analytics: analytics,
);
}
}
}
8 changes: 6 additions & 2 deletions lib/src/command/global_activate.dart
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,12 @@ class GlobalActivateCommand extends PubCommand {

var path = readArg('No package to activate given.');
validateNoExtraArgs();
return globals.activatePath(path, executables,
overwriteBinStubs: overwrite);
return globals.activatePath(
path,
executables,
overwriteBinStubs: overwrite,
analytics: analytics,
);
}

throw StateError('unreachable');
Expand Down
25 changes: 15 additions & 10 deletions lib/src/command/remove.dart
Original file line number Diff line number Diff line change
Expand Up @@ -68,25 +68,30 @@ class RemoveCommand extends PubCommand {
final newRoot = Package.inMemory(newPubspec);

await Entrypoint.global(newRoot, entrypoint.lockFile, cache)
.acquireDependencies(
SolveType.GET,
precompile: argResults['precompile'],
dryRun: true,
);
.acquireDependencies(SolveType.GET,
precompile: argResults['precompile'],
dryRun: true,
analytics: null);
} else {
/// Update the pubspec.
_writeRemovalToPubspec(packages);

/// Create a new [Entrypoint] since we have to reprocess the updated
/// pubspec file.
final updatedEntrypoint = Entrypoint(directory, cache);
await updatedEntrypoint.acquireDependencies(SolveType.GET,
precompile: argResults['precompile']);
await updatedEntrypoint.acquireDependencies(
SolveType.GET,
precompile: argResults['precompile'],
analytics: analytics,
);

if (argResults['example'] && entrypoint.example != null) {
await entrypoint.example.acquireDependencies(SolveType.GET,
precompile: argResults['precompile'],
onlyReportSuccessOrFailure: true);
await entrypoint.example.acquireDependencies(
SolveType.GET,
precompile: argResults['precompile'],
onlyReportSuccessOrFailure: true,
analytics: analytics,
);
}
}
}
Expand Down
17 changes: 12 additions & 5 deletions lib/src/command/upgrade.dart
Original file line number Diff line number Diff line change
Expand Up @@ -122,11 +122,14 @@ class UpgradeCommand extends PubCommand {
}

Future<void> _runUpgrade(Entrypoint e, {bool onlySummary = false}) async {
await e.acquireDependencies(SolveType.UPGRADE,
unlock: argResults.rest,
dryRun: _dryRun,
precompile: _precompile,
onlyReportSuccessOrFailure: onlySummary);
await e.acquireDependencies(
SolveType.UPGRADE,
unlock: argResults.rest,
dryRun: _dryRun,
precompile: _precompile,
onlyReportSuccessOrFailure: onlySummary,
analytics: analytics,
);

_showOfflineWarning();
}
Expand Down Expand Up @@ -233,6 +236,7 @@ be direct 'dependencies' or 'dev_dependencies', following packages are not:
SolveType.UPGRADE,
dryRun: true,
precompile: _precompile,
analytics: null, // No analytics for dry-run
);
} else {
await _updatePubspec(changes);
Expand All @@ -243,6 +247,7 @@ be direct 'dependencies' or 'dev_dependencies', following packages are not:
await Entrypoint(directory, cache).acquireDependencies(
SolveType.UPGRADE,
precompile: _precompile,
analytics: analytics,
);
}

Expand Down Expand Up @@ -326,6 +331,7 @@ be direct 'dependencies' or 'dev_dependencies', following packages are not:
SolveType.UPGRADE,
dryRun: true,
precompile: _precompile,
analytics: null,
);
} else {
await _updatePubspec(changes);
Expand All @@ -336,6 +342,7 @@ be direct 'dependencies' or 'dev_dependencies', following packages are not:
await Entrypoint(directory, cache).acquireDependencies(
SolveType.UPGRADE,
precompile: _precompile,
analytics: analytics,
);
}

Expand Down
6 changes: 6 additions & 0 deletions lib/src/entrypoint.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import 'package_config.dart' show PackageConfig;
import 'package_graph.dart';
import 'package_name.dart';
import 'packages_file.dart' as packages_file;
import 'pub_embeddable_command.dart';
import 'pubspec.dart';
import 'sdk.dart';
import 'solver.dart';
Expand Down Expand Up @@ -247,6 +248,7 @@ class Entrypoint {
Iterable<String> unlock,
bool dryRun = false,
bool precompile = false,
@required PubAnalytics analytics,
bool onlyReportSuccessOrFailure = false,
}) async {
final suffix = root.dir == null || root.dir == '.' ? '' : ' in ${root.dir}';
Expand Down Expand Up @@ -307,6 +309,10 @@ class Entrypoint {
}

if (!dryRun) {
if (analytics != null) {
result.sendAnalytics(analytics);
}

/// Build a package graph from the version solver results so we don't
/// have to reload and reparse all the pubspecs.
_packageGraph = PackageGraph.fromSolveResult(this, result);
Expand Down
12 changes: 10 additions & 2 deletions lib/src/executable.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import 'io.dart';
import 'isolate.dart' as isolate;
import 'log.dart' as log;
import 'log.dart';
import 'pub_embeddable_command.dart';
import 'solver/type.dart';
import 'system_cache.dart';
import 'utils.dart';
Expand Down Expand Up @@ -236,7 +237,9 @@ Future<int> _runDartProgram(
/// [CommandResolutionFailedException].
///
/// * Otherwise if the current package resolution is outdated do an implicit
/// `pub get`, if that fails, throw a [CommandResolutionFailedException].
/// `pub get`, if that fails, throw a [CommandResolutionFailedException].
///
/// This pub get will send analytics events to [analytics] if provided.
///
/// * Otherwise let `<current>` be the name of the package at [root], and
/// interpret [descriptor] as `[<package>][:<command>]`.
Expand Down Expand Up @@ -269,6 +272,7 @@ Future<String> getExecutableForCommand(
bool allowSnapshot = true,
String root,
String pubCacheDir,
PubAnalytics analytics,
}) async {
root ??= p.current;
var asPath = descriptor;
Expand All @@ -294,7 +298,11 @@ Future<String> getExecutableForCommand(
entrypoint.assertUpToDate();
} on DataException {
await warningsOnlyUnlessTerminal(
() => entrypoint.acquireDependencies(SolveType.GET));
() => entrypoint.acquireDependencies(
SolveType.GET,
analytics: analytics,
),
);
}

String command;
Expand Down
5 changes: 3 additions & 2 deletions lib/src/global_packages.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import 'lock_file.dart';
import 'log.dart' as log;
import 'package.dart';
import 'package_name.dart';
import 'pub_embeddable_command.dart';
import 'pubspec.dart';
import 'sdk.dart';
import 'solver.dart';
Expand Down Expand Up @@ -144,11 +145,11 @@ class GlobalPackages {
/// existing binstubs in other packages will be overwritten by this one's.
/// Otherwise, the previous ones will be preserved.
Future<void> activatePath(String path, List<String> executables,
{bool overwriteBinStubs}) async {
{bool overwriteBinStubs, @required PubAnalytics analytics}) async {
var entrypoint = Entrypoint(path, cache);

// Get the package's dependencies.
await entrypoint.acquireDependencies(SolveType.GET);
await entrypoint.acquireDependencies(SolveType.GET, analytics: analytics);
var name = entrypoint.root.name;

try {
Expand Down
18 changes: 17 additions & 1 deletion lib/src/pub_embeddable_command.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
// BSD-style license that can be found in the LICENSE file.

// @dart=2.10
import 'package:meta/meta.dart';
import 'package:usage/usage.dart';

import 'command.dart' show PubCommand, PubTopLevel;
import 'command.dart';
import 'command/add.dart';
import 'command/build.dart';
Expand All @@ -24,6 +27,16 @@ import 'command/uploader.dart';
import 'log.dart' as log;
import 'log.dart';

/// The information needed for the embedded pub command to send analytics.
@sealed
class PubAnalytics {
/// Name of the custom dimension of the dependency kind.
final String dependencyKindCustomDimensionName;
final Analytics analytics;
PubAnalytics(this.analytics,
{@required this.dependencyKindCustomDimensionName});
}

/// Exposes the `pub` commands as a command to be embedded in another command
/// runner such as `dart pub`.
class PubEmbeddableCommand extends PubCommand implements PubTopLevel {
Expand All @@ -34,10 +47,13 @@ class PubEmbeddableCommand extends PubCommand implements PubTopLevel {
@override
String get docUrl => 'https://dart.dev/tools/pub/cmd/pub-global';

@override
final PubAnalytics analytics;

@override
String get directory => argResults['directory'];

PubEmbeddableCommand() : super() {
PubEmbeddableCommand(this.analytics) : super() {
argParser.addFlag('trace',
help: 'Print debugging information when an error occurs.');
argParser.addFlag('verbose',
Expand Down
Loading