blob: e96f2438b2b33ac2121f9e7d310bfb7fef7458f7 [file] [log] [blame]
// Copyright 2019 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:flutter/foundation.dart';
import '../model/commit.pb.dart';
import '../model/task.pb.dart';
/// [Task.stageName] that maps to StageName enums.
// TODO(chillers): Remove these and use StageName enum when available. https://github.com/flutter/cocoon/issues/441
class StageName {
static const String cirrus = 'cirrus';
static const String cocoon = 'cocoon';
static const String legacyLuci = 'chromebot';
static const String luci = 'luci';
static const String googleTest = 'google_internal';
}
/// Base URLs for various endpoints that can relate to a [Task].
const String _cirrusUrl = 'https://cirrus-ci.com/github/flutter/flutter';
const String _cirrusLogUrl = 'https://cirrus-ci.com/build/flutter/flutter';
const String _luciUrl = 'https://ci.chromium.org/p/flutter';
const String _googleTestUrl = 'https://flutter-rob.corp.google.com';
@immutable
class QualifiedTask {
const QualifiedTask({this.stage, this.task, this.pool});
QualifiedTask.fromTask(Task task)
: stage = task.stageName,
task = task.builderName,
pool = task.isFlaky ? 'luci.flutter.staging' : 'luci.flutter.prod';
final String? pool;
final String? stage;
final String? task;
/// Get the URL for the configuration of this task.
///
/// Luci tasks are stored on Luci.
/// Cirrus tasks are stored on Cirrus.
String get sourceConfigurationUrl {
assert(isLuci || isCirrus || isGoogleTest);
if (isCirrus) {
return '$_cirrusUrl/master';
} else if (isLuci) {
return '$_luciUrl/builders/$pool/$task';
} else if (isGoogleTest) {
return _googleTestUrl;
}
throw Exception('Failed to get source configuration url for $stage.');
}
/// Whether this task was run on google test.
bool get isGoogleTest => stage == StageName.googleTest;
/// Whether this task was run on Cirrus CI.
bool get isCirrus => stage == StageName.cirrus;
/// Whether the task was run on the LUCI infrastructre.
bool get isLuci => stage == StageName.cocoon || stage == StageName.legacyLuci || stage == StageName.luci;
@override
bool operator ==(Object other) {
if (other.runtimeType != runtimeType) {
return false;
}
if (isLuci) {
return other is QualifiedTask && other.task == task;
}
return other is QualifiedTask && other.stage == stage && other.task == task;
}
@override
int get hashCode {
// Ensure tasks from Cocoon or LUCI share the same columns.
if (isLuci) {
return StageName.cocoon.hashCode ^ task.hashCode;
}
return stage.hashCode ^ task.hashCode;
}
}
/// Get the URL for [Task] to view its log.
///
/// Cirrus logs are located via their [Commit.sha].
/// Otherwise, we can redirect to the LUCI build page for [Task].
String logUrl(Task task, {Commit? commit}) {
if (task.stageName == StageName.cirrus) {
if (commit != null) {
return '$_cirrusLogUrl/${commit.sha}?branch=${commit.branch}';
} else {
return '$_cirrusUrl/master';
}
}
return QualifiedTask.fromTask(task).sourceConfigurationUrl;
}