Skip to content

Commit c7019c8

Browse files
Remove deprecated /api/v1/viewBuildError.php endpoint (#3619)
1 parent ca951cd commit c7019c8

17 files changed

+41
-1101
lines changed

app/Http/Controllers/BuildController.php

Lines changed: 0 additions & 279 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
use App\Models\BuildUpdateFile;
88
use App\Models\Comment;
99
use App\Models\Project;
10-
use App\Models\RichBuildAlert;
1110
use App\Models\UploadFile;
1211
use App\Models\User;
1312
use App\Utils\DatabaseCleanupUtils;
@@ -16,10 +15,8 @@
1615
use App\Utils\TestingDay;
1716
use CDash\Database;
1817
use CDash\Model\Build;
19-
use CDash\Model\BuildFailure;
2018
use CDash\Model\BuildGroupRule;
2119
use CDash\Model\BuildRelationship;
22-
use CDash\ServiceContainer;
2320
use Illuminate\Http\JsonResponse;
2421
use Illuminate\Http\RedirectResponse;
2522
use Illuminate\Http\Request;
@@ -867,264 +864,6 @@ public function build_file(int $build_id, int $file_id): StreamedResponse
867864
}, $filename, $headers, 'inline');
868865
}
869866

870-
public function apiViewBuildError(): JsonResponse
871-
{
872-
$pageTimer = new PageTimer();
873-
874-
if (!isset($_GET['buildid']) || !is_numeric($_GET['buildid'])) {
875-
abort(400, 'Invalid buildid!');
876-
}
877-
$this->setBuildById((int) $_GET['buildid']);
878-
879-
$eloquentBuild = EloquentBuild::findOrFail((int) $this->build->Id);
880-
881-
$service = ServiceContainer::getInstance();
882-
883-
$response = begin_JSON_response();
884-
$response['title'] = $this->project->Name;
885-
886-
$type = (int) ($_GET['type'] ?? 0);
887-
888-
$date = TestingDay::get($this->project, $this->build->StartTime);
889-
get_dashboard_JSON($this->project->Name, $date, $response);
890-
891-
$menu = [];
892-
if ($this->build->GetParentId() > 0) {
893-
$menu['back'] = 'index.php?project=' . urlencode($this->project->Name) . "&parentid={$this->build->GetParentId()}";
894-
} else {
895-
$menu['back'] = 'index.php?project=' . urlencode($this->project->Name) . '&date=' . $date;
896-
}
897-
898-
$previous_buildid = $this->build->GetPreviousBuildId();
899-
$current_buildid = $this->build->GetCurrentBuildId();
900-
$next_buildid = $this->build->GetNextBuildId();
901-
902-
$menu['previous'] = $previous_buildid > 0 ? "viewBuildError.php?type=$type&buildid=$previous_buildid" : false;
903-
$menu['current'] = "viewBuildError.php?type=$type&buildid=$current_buildid";
904-
$menu['next'] = $next_buildid > 0 ? "viewBuildError.php?type=$type&buildid=$next_buildid" : false;
905-
906-
$response['menu'] = $menu;
907-
908-
// Site
909-
$extra_build_fields = [
910-
'site' => $this->build->GetSite()->name,
911-
];
912-
913-
// Update
914-
if ($eloquentBuild->updateStep !== null) {
915-
$revision = $eloquentBuild->updateStep->revision;
916-
$extra_build_fields['revision'] = $revision;
917-
} else {
918-
$revision = null;
919-
}
920-
921-
// Build
922-
$response['build'] = Build::MarshalResponseArray($this->build, $extra_build_fields);
923-
924-
$buildfailure = $service->get(BuildFailure::class);
925-
926-
// Set the error
927-
if ($type === 0) {
928-
$response['errortypename'] = 'Error';
929-
$response['nonerrortypename'] = 'Warning';
930-
$response['nonerrortype'] = 1;
931-
} else {
932-
$response['errortypename'] = 'Warning';
933-
$response['nonerrortypename'] = 'Error';
934-
$response['nonerrortype'] = 0;
935-
}
936-
937-
$response['parentBuild'] = $this->build->IsParentBuild();
938-
$response['errors'] = [];
939-
$response['numErrors'] = 0;
940-
941-
if (isset($_GET['onlydeltan'])) {
942-
// Build error table
943-
$resolvedBuildErrors = $this->build->GetResolvedBuildErrors($type);
944-
if ($resolvedBuildErrors !== false) {
945-
while ($resolvedBuildError = $resolvedBuildErrors->fetch()) {
946-
$this->addErrorResponse(self::marshalBuildError($resolvedBuildError, $this->project, $revision), $response);
947-
}
948-
}
949-
950-
// Build failure table
951-
$resolvedBuildFailures = $this->build->GetResolvedBuildFailures($type);
952-
foreach ($resolvedBuildFailures as $resolvedBuildFailure) {
953-
$marshaledResolvedBuildFailure = self::marshalBuildFailure($resolvedBuildFailure, $this->project, $revision, false, $buildfailure);
954-
955-
if ($this->project->DisplayLabels) {
956-
get_labels_JSON_from_query_results('
957-
SELECT text
958-
FROM label, label2buildfailure
959-
WHERE
960-
label.id=label2buildfailure.labelid
961-
AND label2buildfailure.buildfailureid=?
962-
ORDER BY text ASC
963-
', [(int) $resolvedBuildFailure['id']], $marshaledResolvedBuildFailure);
964-
}
965-
966-
$marshaledResolvedBuildFailure = array_merge($marshaledResolvedBuildFailure, [
967-
'stderr' => $resolvedBuildFailure['stderror'],
968-
'stderrorrows' => min(10, substr_count($resolvedBuildFailure['stderror'], "\n") + 1),
969-
'stdoutput' => $resolvedBuildFailure['stdoutput'],
970-
'stdoutputrows' => min(10, substr_count($resolvedBuildFailure['stdoutput'], "\n") + 1),
971-
]);
972-
973-
$this->addErrorResponse($marshaledResolvedBuildFailure, $response);
974-
}
975-
} else {
976-
$filter_error_properties = ['type' => $type];
977-
978-
if (isset($_GET['onlydeltap'])) {
979-
$filter_error_properties['newstatus'] = Build::STATUS_NEW;
980-
}
981-
982-
// Build error table
983-
$buildErrors = $this->build->GetErrors($filter_error_properties);
984-
985-
foreach ($buildErrors as $error) {
986-
$this->addErrorResponse(self::marshalBuildError($error, $this->project, $revision), $response);
987-
}
988-
989-
// Build failure table
990-
$buildFailures = $this->build->GetFailures(['type' => $type]);
991-
992-
foreach ($buildFailures as $fail) {
993-
$failure = self::marshalBuildFailure($fail, $this->project, $revision, true, $buildfailure);
994-
995-
if ($this->project->DisplayLabels) {
996-
$labels = RichBuildAlert::findOrFail((int) $fail['id'])->labels()->pluck('text');
997-
if ($labels->count() > 0) {
998-
$failure['labels'] = $labels->toArray();
999-
}
1000-
}
1001-
$this->addErrorResponse($failure, $response);
1002-
}
1003-
}
1004-
1005-
if ($this->build->IsParentBuild()) {
1006-
$response['numSubprojects'] = count(array_unique(array_map(fn ($buildError) => $buildError['subprojectid'], $response['errors'])));
1007-
}
1008-
1009-
$pageTimer->end($response);
1010-
return response()->json(cast_data_for_JSON($response));
1011-
}
1012-
1013-
/**
1014-
* @return array{
1015-
* 'file': string,
1016-
* 'directory': string,
1017-
* }
1018-
*/
1019-
private static function GetSourceFileFromBuildError(array $data): array
1020-
{
1021-
$sourceFile = [];
1022-
1023-
// Detect if the source directory has already been replaced by CTest
1024-
// with /.../. If so, sourcefile is already a relative path from the
1025-
// root of the source tree.
1026-
if (str_contains($data['stdoutput'], '/.../')) {
1027-
$parts = explode('/', $data['sourcefile']);
1028-
$sourceFile['file'] = array_pop($parts);
1029-
$sourceFile['directory'] = implode('/', $parts);
1030-
} else {
1031-
$sourceFile['file'] = basename($data['sourcefile']);
1032-
$sourceFile['directory'] = dirname($data['sourcefile']);
1033-
}
1034-
1035-
return $sourceFile;
1036-
}
1037-
1038-
// Ideally $data would be loaded into $this
1039-
// need an id field?
1040-
/**
1041-
* Marshals the data of a particular build error into a serializable
1042-
* friendly format.
1043-
*
1044-
* Requires the $data of a build error, the $project, and the buildupdate.revision.
1045-
*
1046-
* @return array<string,mixed>
1047-
**/
1048-
public static function marshalBuildError(array $data, \CDash\Model\Project $project, $revision): array
1049-
{
1050-
deepEncodeHTMLEntities($data);
1051-
1052-
$sourceFile = self::GetSourceFileFromBuildError($data);
1053-
1054-
// When building without launchers, CTest truncates the source dir to
1055-
// /.../<project-name>/. Use this pattern to linkify compiler output.
1056-
$source_dir = "/\.\.\./[^/]+";
1057-
1058-
$marshaled = [
1059-
'new' => (int) ($data['newstatus'] ?? -1),
1060-
'logline' => (int) $data['logline'],
1061-
'cvsurl' => RepositoryUtils::get_diff_url($project->Id, $project->CvsUrl ?? '', $sourceFile['directory'], $sourceFile['file'], $revision),
1062-
'precontext' => '',
1063-
'text' => RepositoryUtils::linkify_compiler_output($project->CvsUrl ?? '', $source_dir, $revision, $data['stdoutput']),
1064-
'postcontext' => '',
1065-
'sourcefile' => $data['sourcefile'],
1066-
'sourceline' => $data['sourceline'],
1067-
];
1068-
1069-
if (isset($data['subprojectid'])) {
1070-
$marshaled['subprojectid'] = $data['subprojectid'];
1071-
$marshaled['subprojectname'] = $data['subprojectname'];
1072-
}
1073-
1074-
return $marshaled;
1075-
}
1076-
1077-
/**
1078-
* Marshal a build failure, this includes the build failure arguments.
1079-
**/
1080-
public static function marshalBuildFailure($data, \CDash\Model\Project $project, $revision, $linkifyOutput, $buildfailure): array
1081-
{
1082-
deepEncodeHTMLEntities($data);
1083-
1084-
$marshaled = array_merge([
1085-
'language' => $data['language'],
1086-
'sourcefile' => $data['sourcefile'],
1087-
'targetname' => $data['targetname'],
1088-
'outputfile' => $data['outputfile'],
1089-
'outputtype' => $data['outputtype'],
1090-
'workingdirectory' => $data['workingdirectory'],
1091-
'exitcondition' => $data['exitcondition'],
1092-
], $buildfailure->GetBuildFailureArguments((int) $data['id']));
1093-
1094-
$marshaled['stderror'] = $data['stderror'];
1095-
$marshaled['stdoutput'] = $data['stdoutput'];
1096-
1097-
if (isset($data['sourcefile'])) {
1098-
$file = basename($data['sourcefile']);
1099-
$directory = dirname($data['sourcefile']);
1100-
1101-
$source_dir = RepositoryUtils::get_source_dir($project->Id, $project->CvsUrl ?? '', $directory);
1102-
if (str_starts_with($directory, $source_dir)) {
1103-
$directory = substr($directory, strlen($source_dir));
1104-
}
1105-
1106-
$marshaled['cvsurl'] = RepositoryUtils::get_diff_url($project->Id,
1107-
$project->CvsUrl ?? '',
1108-
$directory,
1109-
$file,
1110-
$revision);
1111-
1112-
if ($source_dir !== null && $linkifyOutput) {
1113-
$marshaled['stderror'] = RepositoryUtils::linkify_compiler_output($project->CvsUrl ?? '', $source_dir,
1114-
$revision, $data['stderror']);
1115-
$marshaled['stdoutput'] = RepositoryUtils::linkify_compiler_output($project->CvsUrl ?? '', $source_dir,
1116-
$revision, $data['stdoutput']);
1117-
}
1118-
}
1119-
1120-
if (isset($data['subprojectid'])) {
1121-
$marshaled['subprojectid'] = $data['subprojectid'];
1122-
$marshaled['subprojectname'] = $data['subprojectname'];
1123-
}
1124-
1125-
return $marshaled;
1126-
}
1127-
1128867
public function manageBuildGroup(): View
1129868
{
1130869
$this->setProjectById(request()->integer('projectid'));
@@ -1137,24 +876,6 @@ public function viewBuildGroup(): View
1137876
return $this->angular_view('index');
1138877
}
1139878

1140-
/**
1141-
* Add a new (marshaled) error to the response.
1142-
* Keeps track of the id necessary for frontend JS, and updates
1143-
* the numErrors response key.
1144-
*
1145-
* @todo id should probably just be a unique id for the builderror?
1146-
* builderror table currently has no integer that serves as a unique identifier.
1147-
*
1148-
* @param array<string,mixed> $response
1149-
**/
1150-
private function addErrorResponse(mixed $data, array &$response): void
1151-
{
1152-
$data['id'] = $response['numErrors'];
1153-
$response['numErrors']++;
1154-
1155-
$response['errors'][] = $data;
1156-
}
1157-
1158879
public function apiBuildUpdateGraph(): JsonResponse
1159880
{
1160881
$this->setBuildById((int) ($_GET['buildid'] ?? -1));

app/Utils/RepositoryUtils.php

Lines changed: 0 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -14,44 +14,6 @@
1414

1515
class RepositoryUtils
1616
{
17-
/** Return the source directory for a source file */
18-
public static function get_source_dir($projectid, $projecturl, $file_path)
19-
{
20-
if (!is_numeric($projectid)) {
21-
return;
22-
}
23-
24-
$service = ServiceContainer::getInstance();
25-
$project = $service->get(Project::class);
26-
$project->Id = $projectid;
27-
$project->Fill();
28-
if (null === $project->CvsViewerType) {
29-
return;
30-
}
31-
$cvsviewertype = strtolower($project->CvsViewerType);
32-
33-
$target_fn = $cvsviewertype . '_get_source_dir';
34-
35-
if (method_exists(self::class, $target_fn)) {
36-
return self::$target_fn($projecturl, $file_path);
37-
}
38-
}
39-
40-
/** Extract the source directory from a Github URL and a full path to
41-
* a source file. This only works properly if the source dir's name matches
42-
* the repo's name, ie it was not renamed as it was cloned.
43-
**/
44-
public static function github_get_source_dir($projecturl, $file_path): string
45-
{
46-
$repo_name = basename($projecturl);
47-
$offset = stripos($file_path, $repo_name);
48-
if ($offset === false) {
49-
return '/.../';
50-
}
51-
$offset += strlen($repo_name);
52-
return substr($file_path, 0, $offset);
53-
}
54-
5517
/** Return the GitHub diff URL */
5618
public static function get_github_diff_url($projecturl, $directory, $file, $revision)
5719
{
@@ -155,36 +117,6 @@ public static function get_revision_url($projectid, $revision, $priorrevision)
155117
return self::get_github_revision_url($projecturl, $revision, $priorrevision);
156118
}
157119

158-
public static function linkify_compiler_output($projecturl, $source_dir, $revision, $compiler_output): string
159-
{
160-
// Escape HTML characters in compiler output first. This allows us to properly
161-
// display characters such as angle brackets in compiler output.
162-
$compiler_output = htmlspecialchars($compiler_output, ENT_QUOTES, 'UTF-8', false);
163-
164-
// set a reasonable default revision if none was specified
165-
if (empty($revision)) {
166-
$revision = 'master';
167-
}
168-
169-
// Make sure we specify a protocol so this isn't interpreted as a relative path.
170-
if (!str_contains($projecturl, '//')) {
171-
$projecturl = '//' . $projecturl;
172-
}
173-
$repo_link = "<a class='cdash-link' href='$projecturl/blob/$revision";
174-
$pattern = "&$source_dir\/*([a-zA-Z0-9_\.\-\\/]+):(\d+)&";
175-
$replacement = "$repo_link/$1#L$2'>$1:$2</a>";
176-
177-
// create links for source files
178-
$compiler_output = preg_replace($pattern, $replacement, $compiler_output);
179-
180-
// remove base dir from other (binary) paths
181-
$base_dir = dirname($source_dir) . '/';
182-
if ($base_dir !== '//') {
183-
return str_replace($base_dir, '', $compiler_output);
184-
}
185-
return $compiler_output;
186-
}
187-
188120
/** Post a comment on a pull request */
189121
public static function post_pull_request_comment($projectid, $pull_request, $comment, $cdash_url): void
190122
{

0 commit comments

Comments
 (0)