Skip to content

Commit 41c8954

Browse files
Expose all project fields via GraphQL (#3432)
This PR adds all of the missing Project fields and solidifies the database types to better enforce our constraints. I plan to follow this work with a new `updateProject` mutation.
1 parent 3e68317 commit 41c8954

File tree

14 files changed

+457
-99
lines changed

14 files changed

+457
-99
lines changed

app/GraphQL/Scalars/Time.php

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<?php
2+
3+
namespace App\GraphQL\Scalars;
4+
5+
use Carbon\Exceptions\InvalidFormatException;
6+
use GraphQL\Error\InvariantViolation;
7+
use GraphQL\Language\AST\Node;
8+
use GraphQL\Language\AST\ValueNode;
9+
use GraphQL\Type\Definition\ScalarType;
10+
use Illuminate\Support\Carbon;
11+
12+
final class Time extends ScalarType
13+
{
14+
public function serialize(mixed $value): string
15+
{
16+
return $value;
17+
}
18+
19+
/**
20+
* @throws InvariantViolation
21+
*/
22+
public function parseValue(mixed $value): string
23+
{
24+
if (!$this->validateTime($value)) {
25+
throw new InvariantViolation("The value $value is not a valid Time format (H:i:s).");
26+
}
27+
28+
return $value;
29+
}
30+
31+
/**
32+
* @param ValueNode&Node $valueNode
33+
* @param array<string, mixed>|null $variables
34+
*
35+
* @throws InvariantViolation
36+
*/
37+
public function parseLiteral(Node $valueNode, ?array $variables = null): string
38+
{
39+
if (!property_exists($valueNode, 'value')) {
40+
throw new InvariantViolation('Time must be a string.');
41+
}
42+
43+
if (!$this->validateTime($valueNode->value)) {
44+
throw new InvariantViolation("The value {$valueNode->value} is not a valid Time.");
45+
}
46+
47+
return $valueNode->value;
48+
}
49+
50+
private function validateTime(string $time): bool
51+
{
52+
// Simple regex for HH:MM:SS* format to make sure it's actually a time, not a datetime.
53+
if (preg_match('/^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]/', $time) !== 1) {
54+
return false;
55+
}
56+
57+
try {
58+
Carbon::parse($time);
59+
return true;
60+
} catch (InvalidFormatException) {
61+
return false;
62+
}
63+
}
64+
}

app/Models/Project.php

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,23 +14,23 @@
1414
/**
1515
* @property int $id
1616
* @property string $name
17-
* @property string $description
18-
* @property string $homeurl
19-
* @property string $cvsurl
20-
* @property string $bugtrackerurl
21-
* @property string $bugtrackernewissueurl
22-
* @property string $bugtrackertype
23-
* @property string $documentationurl
17+
* @property ?string $description
18+
* @property ?string $homeurl
19+
* @property ?string $cvsurl
20+
* @property ?string $bugtrackerurl
21+
* @property ?string $bugtrackernewissueurl
22+
* @property ?string $bugtrackertype
23+
* @property ?string $documentationurl
2424
* @property int $imageid
2525
* @property int $public
2626
* @property int $coveragethreshold
27-
* @property string $testingdataurl
27+
* @property ?string $testingdataurl
2828
* @property string $nightlytime
2929
* @property bool $emaillowcoverage
3030
* @property bool $emailtesttimingchanged
3131
* @property bool $emailbrokensubmission
3232
* @property bool $emailredundantfailures
33-
* @property string $cvsviewertype
33+
* @property ?string $cvsviewertype
3434
* @property int $testtimestd
3535
* @property int $testtimestdthreshold
3636
* @property bool $showtesttime

app/cdash/app/Lib/Repository/GitHub.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -664,7 +664,7 @@ public function getRepository(): string
664664

665665
protected function getRepositoryInformation(): void
666666
{
667-
$url = str_replace('//', '', $this->project->CvsUrl);
667+
$url = str_replace('//', '', $this->project->CvsUrl ?? '');
668668
$parts = explode('/', $url);
669669
if (isset($parts[1])) {
670670
$this->owner = $parts[1];

app/cdash/app/Model/BuildError.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ public static function marshal(array $data, Project $project, $revision): array
110110
'logline' => (int) $data['logline'],
111111
'cvsurl' => RepositoryUtils::get_diff_url($project->Id, $project->CvsUrl, $sourceFile['directory'], $sourceFile['file'], $revision),
112112
'precontext' => '',
113-
'text' => RepositoryUtils::linkify_compiler_output($project->CvsUrl, $source_dir, $revision, $data['stdoutput']),
113+
'text' => RepositoryUtils::linkify_compiler_output($project->CvsUrl ?? '', $source_dir, $revision, $data['stdoutput']),
114114
'postcontext' => '',
115115
'sourcefile' => $data['sourcefile'],
116116
'sourceline' => $data['sourceline'],

app/cdash/app/Model/BuildFailure.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ public static function marshal($data, Project $project, $revision, $linkifyOutpu
255255
$file = basename($data['sourcefile']);
256256
$directory = dirname($data['sourcefile']);
257257

258-
$source_dir = RepositoryUtils::get_source_dir($project->Id, $project->CvsUrl, $directory);
258+
$source_dir = RepositoryUtils::get_source_dir($project->Id, $project->CvsUrl ?? '', $directory);
259259
if (str_starts_with($directory, $source_dir)) {
260260
$directory = substr($directory, strlen($source_dir));
261261
}
@@ -267,9 +267,9 @@ public static function marshal($data, Project $project, $revision, $linkifyOutpu
267267
$revision);
268268

269269
if ($source_dir !== null && $linkifyOutput) {
270-
$marshaled['stderror'] = RepositoryUtils::linkify_compiler_output($project->CvsUrl, $source_dir,
270+
$marshaled['stderror'] = RepositoryUtils::linkify_compiler_output($project->CvsUrl ?? '', $source_dir,
271271
$revision, $data['stderror']);
272-
$marshaled['stdoutput'] = RepositoryUtils::linkify_compiler_output($project->CvsUrl, $source_dir,
272+
$marshaled['stdoutput'] = RepositoryUtils::linkify_compiler_output($project->CvsUrl ?? '', $source_dir,
273273
$revision, $data['stdoutput']);
274274
}
275275
}

app/cdash/app/Model/Project.php

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -43,25 +43,25 @@ class Project
4343
{
4444
public $Name;
4545
public $Id;
46-
public $Description;
47-
public $HomeUrl;
48-
public $CvsUrl;
49-
public $DocumentationUrl;
50-
public $BugTrackerUrl;
51-
public $BugTrackerNewIssueUrl;
52-
public $BugTrackerType;
46+
public ?string $Description = null;
47+
public ?string $HomeUrl = null;
48+
public ?string $CvsUrl = null;
49+
public ?string $DocumentationUrl = null;
50+
public ?string $BugTrackerUrl = null;
51+
public ?string $BugTrackerNewIssueUrl = null;
52+
public ?string $BugTrackerType = null;
5353
public ?int $ImageId = null;
5454
public $Public;
5555
public $CoverageThreshold;
56-
public $TestingDataUrl;
56+
public ?string $TestingDataUrl = null;
5757
public $NightlyTime;
5858
public $NightlyDateTime;
5959
public $NightlyTimezone;
6060
public $EmailLowCoverage = 0;
6161
public $EmailTestTimingChanged = 0;
6262
public $EmailBrokenSubmission = 0;
6363
public $EmailRedundantFailures = 0;
64-
public $CvsViewerType;
64+
public ?string $CvsViewerType = null;
6565
public $TestTimeStd;
6666
public $TestTimeStdThreshold;
6767
public $ShowTestTime = 0;
@@ -115,15 +115,15 @@ public function Save(): bool
115115
$project->fill([
116116
'name' => $this->Name ?? '',
117117
'description' => $this->Description,
118-
'homeurl' => $this->HomeUrl ?? '',
119-
'cvsurl' => $this->CvsUrl ?? '',
120-
'documentationurl' => $this->DocumentationUrl ?? '',
121-
'bugtrackerurl' => $this->BugTrackerUrl ?? '',
122-
'bugtrackernewissueurl' => $this->BugTrackerNewIssueUrl ?? '',
123-
'bugtrackertype' => $this->BugTrackerType ?? '',
118+
'homeurl' => $this->HomeUrl,
119+
'cvsurl' => $this->CvsUrl,
120+
'documentationurl' => $this->DocumentationUrl,
121+
'bugtrackerurl' => $this->BugTrackerUrl,
122+
'bugtrackernewissueurl' => $this->BugTrackerNewIssueUrl,
123+
'bugtrackertype' => $this->BugTrackerType,
124124
'public' => (int) $this->Public,
125125
'coveragethreshold' => (int) $this->CoverageThreshold,
126-
'testingdataurl' => $this->TestingDataUrl ?? '',
126+
'testingdataurl' => $this->TestingDataUrl,
127127
'nightlytime' => $this->NightlyTime ?? '',
128128
'emaillowcoverage' => (bool) $this->EmailLowCoverage,
129129
'emailtesttimingchanged' => (bool) $this->EmailTestTimingChanged,
@@ -137,7 +137,7 @@ public function Save(): bool
137137
'autoremovetimeframe' => (int) $this->AutoremoveTimeframe,
138138
'autoremovemaxbuilds' => (int) $this->AutoremoveMaxBuilds,
139139
'uploadquota' => (int) $this->UploadQuota,
140-
'cvsviewertype' => $this->CvsViewerType ?? '',
140+
'cvsviewertype' => $this->CvsViewerType,
141141
'testtimestd' => (int) $this->TestTimeStd,
142142
'testtimestdthreshold' => (int) $this->TestTimeStdThreshold,
143143
'showtesttime' => (bool) $this->ShowTestTime,

app/cdash/app/Model/Repository.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ protected static function getRepositoryService(Project $project): ?RepositorySer
107107

108108
public static function getRepositoryInterface(Project $project): RepositoryInterface
109109
{
110-
switch (strtolower($project->CvsViewerType)) {
110+
switch (strtolower($project->CvsViewerType ?? '')) {
111111
case strtolower(self::VIEWER_GITHUB):
112112
$service = new GitHub($project);
113113
break;

app/cdash/include/common.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -572,10 +572,10 @@ function get_dashboard_JSON($projectname, $date, &$response): void
572572
$project->FindByName($projectname);
573573

574574
$project_array = [];
575-
$project_array['cvsurl'] = $project->Id ? $project->CvsUrl : 'unknown';
576-
$project_array['bugtrackerurl'] = $project->Id ? $project->BugTrackerUrl : 'unknown';
577-
$project_array['documentationurl'] = $project->Id ? $project->DocumentationUrl : 'unknown';
578-
$project_array['homeurl'] = $project->Id ? $project->HomeUrl : 'unknown';
575+
$project_array['cvsurl'] = $project->CvsUrl ?? '';
576+
$project_array['bugtrackerurl'] = $project->BugTrackerUrl ?? '';
577+
$project_array['documentationurl'] = $project->DocumentationUrl ?? '';
578+
$project_array['homeurl'] = $project->HomeUrl ?? '';
579579
$project_array['name'] = $projectname;
580580
$project_array['nightlytime'] = $project->Id ? $project->NightlyTime : '00:00:00';
581581

app/cdash/tests/test_builddetails.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public function __construct()
2424

2525
$this->createProject([
2626
'Name' => 'BuildDetails',
27-
'CvsViewerType' => 'viewcvs',
27+
'CvsViewerType' => null,
2828
]);
2929

3030
foreach ($this->testDataFiles as $testDataFile) {
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
<?php
2+
3+
use Illuminate\Database\Migrations\Migration;
4+
use Illuminate\Support\Facades\DB;
5+
6+
return new class extends Migration {
7+
public function up(): void
8+
{
9+
DB::statement('ALTER TABLE project ALTER COLUMN homeurl DROP NOT NULL');
10+
DB::statement('ALTER TABLE project ALTER COLUMN homeurl DROP DEFAULT');
11+
DB::statement('ALTER TABLE project ALTER COLUMN homeurl TYPE text');
12+
DB::update("UPDATE project SET homeurl = NULL WHERE homeurl = ''");
13+
14+
DB::statement('ALTER TABLE project ALTER COLUMN cvsurl DROP NOT NULL');
15+
DB::statement('ALTER TABLE project ALTER COLUMN cvsurl DROP DEFAULT');
16+
DB::statement('ALTER TABLE project ALTER COLUMN cvsurl TYPE text');
17+
DB::update("UPDATE project SET cvsurl = NULL WHERE cvsurl = ''");
18+
19+
DB::statement('ALTER TABLE project ALTER COLUMN bugtrackerurl DROP NOT NULL');
20+
DB::statement('ALTER TABLE project ALTER COLUMN bugtrackerurl DROP DEFAULT');
21+
DB::statement('ALTER TABLE project ALTER COLUMN bugtrackerurl TYPE text');
22+
DB::update("UPDATE project SET bugtrackerurl = NULL WHERE bugtrackerurl = ''");
23+
24+
DB::statement('ALTER TABLE project ALTER COLUMN bugtrackernewissueurl DROP NOT NULL');
25+
DB::statement('ALTER TABLE project ALTER COLUMN bugtrackernewissueurl DROP DEFAULT');
26+
DB::statement('ALTER TABLE project ALTER COLUMN bugtrackernewissueurl TYPE text');
27+
DB::update("UPDATE project SET bugtrackernewissueurl = NULL WHERE bugtrackernewissueurl = ''");
28+
29+
DB::statement('ALTER TABLE project ALTER COLUMN documentationurl DROP NOT NULL');
30+
DB::statement('ALTER TABLE project ALTER COLUMN documentationurl DROP DEFAULT');
31+
DB::statement('ALTER TABLE project ALTER COLUMN documentationurl TYPE text');
32+
DB::update("UPDATE project SET documentationurl = NULL WHERE documentationurl = ''");
33+
34+
DB::statement('ALTER TABLE project ALTER COLUMN testingdataurl DROP NOT NULL');
35+
DB::statement('ALTER TABLE project ALTER COLUMN testingdataurl DROP DEFAULT');
36+
DB::statement('ALTER TABLE project ALTER COLUMN testingdataurl TYPE text');
37+
DB::update("UPDATE project SET testingdataurl = NULL WHERE testingdataurl = ''");
38+
39+
DB::update('UPDATE project SET testtimestd = 4 WHERE testtimestd IS NULL');
40+
DB::statement('ALTER TABLE project ALTER COLUMN testtimestd SET NOT NULL');
41+
42+
DB::update('UPDATE project SET testtimestdthreshold = 1 WHERE testtimestdthreshold IS NULL');
43+
DB::statement('ALTER TABLE project ALTER COLUMN testtimestdthreshold SET NOT NULL');
44+
45+
DB::update('UPDATE project SET testtimemaxstatus = 3 WHERE testtimemaxstatus IS NULL');
46+
DB::statement('ALTER TABLE project ALTER COLUMN testtimemaxstatus SET NOT NULL');
47+
48+
DB::update('UPDATE project SET emailmaxitems = 5 WHERE emailmaxitems IS NULL');
49+
DB::statement('ALTER TABLE project ALTER COLUMN emailmaxitems SET NOT NULL');
50+
51+
DB::update('UPDATE project SET emailmaxchars = 255 WHERE emailmaxchars IS NULL');
52+
DB::statement('ALTER TABLE project ALTER COLUMN emailmaxchars SET NOT NULL');
53+
54+
DB::update('UPDATE project SET autoremovetimeframe = 0 WHERE autoremovetimeframe IS NULL');
55+
DB::statement('ALTER TABLE project ALTER COLUMN autoremovetimeframe SET NOT NULL');
56+
57+
DB::update('UPDATE project SET autoremovemaxbuilds = 300 WHERE autoremovemaxbuilds IS NULL');
58+
DB::statement('ALTER TABLE project ALTER COLUMN autoremovemaxbuilds SET NOT NULL');
59+
60+
DB::update('UPDATE project SET uploadquota = 0 WHERE uploadquota IS NULL');
61+
DB::statement('ALTER TABLE project ALTER COLUMN uploadquota SET NOT NULL');
62+
63+
DB::statement('ALTER TABLE project ALTER COLUMN ldapfilter TYPE text');
64+
65+
DB::statement('ALTER TABLE project ALTER COLUMN banner TYPE text');
66+
67+
// We drop the type first in case the database has been truncated previously.
68+
DB::statement('DROP TYPE IF EXISTS cvsviewertype');
69+
DB::statement("CREATE TYPE cvsviewertype AS ENUM ('github', 'gitlab')");
70+
DB::statement("
71+
ALTER TABLE project
72+
ALTER COLUMN cvsviewertype
73+
TYPE cvsviewertype USING
74+
CASE
75+
WHEN cvsviewertype = 'github' THEN 'github'::cvsviewertype
76+
WHEN cvsviewertype = 'gitlab' THEN 'gitlab'::cvsviewertype
77+
ELSE NULL
78+
END
79+
");
80+
81+
// We drop the type first in case the database has been truncated previously.
82+
DB::statement('DROP TYPE IF EXISTS bugtrackertype');
83+
DB::statement("CREATE TYPE bugtrackertype AS ENUM ('GitHub', 'Buganizer', 'JIRA')");
84+
DB::statement("
85+
ALTER TABLE project
86+
ALTER COLUMN bugtrackertype
87+
TYPE bugtrackertype USING
88+
CASE
89+
WHEN bugtrackertype = 'GitHub' THEN 'GitHub'::bugtrackertype
90+
WHEN bugtrackertype = 'Buganizer' THEN 'Buganizer'::bugtrackertype
91+
WHEN bugtrackertype = 'JIRA' THEN 'JIRA'::bugtrackertype
92+
ELSE NULL
93+
END
94+
");
95+
}
96+
97+
public function down(): void
98+
{
99+
}
100+
};

0 commit comments

Comments
 (0)