forked from lix-project/hydra
This commit is contained in:
parent
46dc10847a
commit
f6f5309a02
|
@ -49,13 +49,51 @@ sub index :Path :Args(0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sub updateProject {
|
||||||
|
my ($c, $project) = @_;
|
||||||
|
|
||||||
|
my $projectName = $c->request->params->{name};
|
||||||
|
die "Invalid project name: $projectName" unless $projectName =~ /^[[:alpha:]]\w*$/;
|
||||||
|
|
||||||
|
my $displayName = $c->request->params->{displayname};
|
||||||
|
die "Invalid display name: $displayName" unless $displayName =~ /^\w.*\w$/;
|
||||||
|
|
||||||
|
$project->name($projectName);
|
||||||
|
$project->displayname($displayName);
|
||||||
|
$project->description($c->request->params->{description});
|
||||||
|
|
||||||
|
$project->update;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
sub project :Local {
|
sub project :Local {
|
||||||
my ( $self, $c, $projectName ) = @_;
|
my ( $self, $c, $projectName, $subcommand ) = @_;
|
||||||
$c->stash->{template} = 'project.tt';
|
$c->stash->{template} = 'project.tt';
|
||||||
|
|
||||||
(my $project) = $c->model('DB::Projects')->search({ name => $projectName });
|
(my $project) = $c->model('DB::Projects')->search({ name => $projectName });
|
||||||
return error($c, "Project <tt>$projectName</tt> doesn't exist.") if !defined $project;
|
return error($c, "Project <tt>$projectName</tt> doesn't exist.") if !defined $project;
|
||||||
|
|
||||||
|
my $isPosted = $c->request->method eq "POST";
|
||||||
|
|
||||||
|
$subcommand = "" unless defined $subcommand;
|
||||||
|
|
||||||
|
if ($subcommand eq "edit") {
|
||||||
|
$c->stash->{edit} = 1;
|
||||||
|
} elsif ($subcommand eq "submit" && $isPosted) {
|
||||||
|
$c->model('DB')->schema->txn_do(sub {
|
||||||
|
updateProject($c, $project);
|
||||||
|
});
|
||||||
|
return $c->res->redirect($c->uri_for("/project", $projectName));
|
||||||
|
} elsif ($subcommand eq "delete" && $isPosted) {
|
||||||
|
$c->model('DB')->schema->txn_do(sub {
|
||||||
|
$project->delete;
|
||||||
|
});
|
||||||
|
return $c->res->redirect($c->uri_for("/"));
|
||||||
|
} elsif ($subcommand eq "") {
|
||||||
|
} else {
|
||||||
|
return error($c, "Unknown subcommand $subcommand.");
|
||||||
|
}
|
||||||
|
|
||||||
$c->stash->{curProject} = $project;
|
$c->stash->{curProject} = $project;
|
||||||
|
|
||||||
$c->stash->{finishedBuilds} = $c->model('DB::Builds')->search(
|
$c->stash->{finishedBuilds} = $c->model('DB::Builds')->search(
|
||||||
|
@ -83,13 +121,43 @@ sub project :Local {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sub createproject :Local {
|
||||||
|
my ( $self, $c, $subcommand ) = @_;
|
||||||
|
|
||||||
|
if (defined $subcommand && $subcommand eq "submit") {
|
||||||
|
eval {
|
||||||
|
my $projectName = $c->request->params->{name};
|
||||||
|
$c->model('DB')->schema->txn_do(sub {
|
||||||
|
# Note: $projectName is validated in updateProject,
|
||||||
|
# which will abort the transaction if the name isn't
|
||||||
|
# valid.
|
||||||
|
my $project = $c->model('DB::Projects')->create({name => $projectName, displayname => ""});
|
||||||
|
updateProject($c, $project);
|
||||||
|
});
|
||||||
|
return $c->res->redirect($c->uri_for("/project", $projectName));
|
||||||
|
};
|
||||||
|
if ($@) {
|
||||||
|
return error($c, $@);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$c->stash->{template} = 'project.tt';
|
||||||
|
$c->stash->{create} = 1;
|
||||||
|
$c->stash->{edit} = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
sub job :Local {
|
sub job :Local {
|
||||||
my ( $self, $c, $project, $jobName ) = @_;
|
my ( $self, $c, $projectName, $jobName ) = @_;
|
||||||
$c->stash->{template} = 'job.tt';
|
$c->stash->{template} = 'job.tt';
|
||||||
$c->stash->{projectName} = $project;
|
|
||||||
|
(my $project) = $c->model('DB::Projects')->search({ name => $projectName });
|
||||||
|
return error($c, "Project <tt>$projectName</tt> doesn't exist.") if !defined $project;
|
||||||
|
$c->stash->{curProject} = $project;
|
||||||
|
|
||||||
$c->stash->{jobName} = $jobName;
|
$c->stash->{jobName} = $jobName;
|
||||||
$c->stash->{builds} = [$c->model('DB::Builds')->search(
|
$c->stash->{builds} = [$c->model('DB::Builds')->search(
|
||||||
{finished => 1, project => $project, attrName => $jobName},
|
{finished => 1, project => $projectName, attrName => $jobName},
|
||||||
{order_by => "timestamp DESC"})];
|
{order_by => "timestamp DESC"})];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
[% WRAPPER layout.tt title="Hydra Overview" %]
|
[% WRAPPER layout.tt title="Hydra Overview" %]
|
||||||
|
[% USE HTML %]
|
||||||
|
|
||||||
<h1>Error</h1>
|
<h1>Error</h1>
|
||||||
|
|
||||||
<p>I'm very sorry, but an error occurred: <span class="error-msg">[% error %]</span></p>
|
<p>I'm very sorry, but an error occurred: <span class="error-msg">[% HTML.escape(error) %]</span></p>
|
||||||
|
|
||||||
[% END %]
|
[% END %]
|
||||||
|
|
|
@ -38,6 +38,10 @@ td, th {
|
||||||
border: solid black 1px;
|
border: solid black 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
td {
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
th {
|
th {
|
||||||
background: #ffffc0;
|
background: #ffffc0;
|
||||||
}
|
}
|
||||||
|
@ -145,6 +149,7 @@ td.buildfarmMainColumn {
|
||||||
|
|
||||||
.error-msg {
|
.error-msg {
|
||||||
color: red;
|
color: red;
|
||||||
|
white-space: pre;
|
||||||
}
|
}
|
||||||
|
|
||||||
pre.buildlog {
|
pre.buildlog {
|
||||||
|
@ -321,3 +326,13 @@ h1 {
|
||||||
#footer {
|
#footer {
|
||||||
font-size: 80%;
|
font-size: 80%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Editing */
|
||||||
|
|
||||||
|
input.string {
|
||||||
|
font-family: sans-serif;
|
||||||
|
font-size: 100%;
|
||||||
|
background-color: #fffff0;
|
||||||
|
width: 30em;
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[% WRAPPER layout.tt title="Hydra Overview" %]
|
[% WRAPPER layout.tt title="Hydra Overview" %]
|
||||||
|
|
||||||
<h1>All builds for job <tt>[% projectName %]:[% jobName %]</tt></h1>
|
<h1>All builds for job <tt>[% curProject.name %]:[% jobName %]</tt></h1>
|
||||||
|
|
||||||
<table class="tablesorter">
|
<table class="tablesorter">
|
||||||
<thead>
|
<thead>
|
||||||
|
|
|
@ -50,6 +50,7 @@
|
||||||
<div class="title"><a href="[% c.uri_for('/project' project.name) %]">[% project.displayname %]</a></div>
|
<div class="title"><a href="[% c.uri_for('/project' project.name) %]">[% project.displayname %]</a></div>
|
||||||
[% IF curProject.name == project.name %]
|
[% IF curProject.name == project.name %]
|
||||||
<ul class="subsubmenu">
|
<ul class="subsubmenu">
|
||||||
|
[% INCLUDE makeLink uri = c.uri_for('/project' project.name 'edit') title = "Edit" %]
|
||||||
[% INCLUDE makeLink uri = c.uri_for('/project' project.name 'status') title = "Status" %]
|
[% INCLUDE makeLink uri = c.uri_for('/project' project.name 'status') title = "Status" %]
|
||||||
[% INCLUDE makeLink uri = c.uri_for('/project' project.name 'all') title = "All builds" %]
|
[% INCLUDE makeLink uri = c.uri_for('/project' project.name 'all') title = "All builds" %]
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -63,7 +64,7 @@
|
||||||
<div class="title">Admin</div>
|
<div class="title">Admin</div>
|
||||||
<ul class="submenu">
|
<ul class="submenu">
|
||||||
[% INCLUDE makeLink uri = c.uri_for('/users') title = "Users" %]
|
[% INCLUDE makeLink uri = c.uri_for('/users') title = "Users" %]
|
||||||
[% INCLUDE makeLink uri = c.uri_for('/create-project') title = "Create a project" %]
|
[% INCLUDE makeLink uri = c.uri_for('/createproject') title = "Create a project" %]
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -1,9 +1,46 @@
|
||||||
[% WRAPPER layout.tt title="Hydra Overview" %]
|
[% WRAPPER layout.tt title="Hydra Overview" %]
|
||||||
|
[% USE HTML %]
|
||||||
|
|
||||||
|
|
||||||
|
[% BLOCK maybeEditString %]
|
||||||
|
[% IF edit %]
|
||||||
|
<input type='text' class='string' [% HTML.attributes(name => param, value => value) %] />
|
||||||
|
[% ELSE %]
|
||||||
|
[% HTML.escape(value) %]
|
||||||
|
[% END %]
|
||||||
|
[% END %]
|
||||||
|
|
||||||
|
|
||||||
|
[% IF edit %]
|
||||||
|
<form action="[% IF create %][% c.uri_for('/createproject/submit') %][% ELSE %][% c.uri_for('/project' curProject.name 'submit') %][% END %]" method="post">
|
||||||
|
[% END %]
|
||||||
|
|
||||||
|
|
||||||
|
[% IF create %]
|
||||||
|
<h1>New Project</h1>
|
||||||
|
[% ELSE %]
|
||||||
<h1>Project <tt>[% curProject.name %]</tt></h1>
|
<h1>Project <tt>[% curProject.name %]</tt></h1>
|
||||||
|
[% END %]
|
||||||
|
|
||||||
|
|
||||||
<p><strong>Description:</strong> [% curProject.description %]</p>
|
<h2>General information</h2>
|
||||||
|
|
||||||
|
<table>
|
||||||
|
[% IF edit %]
|
||||||
|
<tr>
|
||||||
|
<th>Identifier:</th>
|
||||||
|
<td><tt>[% INCLUDE maybeEditString param="name" value=curProject.name %]</tt></td>
|
||||||
|
</tr>
|
||||||
|
[% END %]
|
||||||
|
<tr>
|
||||||
|
<th>Display name:</th>
|
||||||
|
<td>[% INCLUDE maybeEditString param="displayname" value=curProject.displayname %]</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Description:</th>
|
||||||
|
<td>[% INCLUDE maybeEditString param="description" value=curProject.description %]</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
|
||||||
<h2>Definition</h2>
|
<h2>Definition</h2>
|
||||||
|
@ -17,13 +54,19 @@
|
||||||
<h4>Information</h4>
|
<h4>Information</h4>
|
||||||
|
|
||||||
<table>
|
<table>
|
||||||
|
[% IF edit %]
|
||||||
|
<tr>
|
||||||
|
<th>Identifier:</th>
|
||||||
|
<td><tt>[% INCLUDE maybeEditString value=jobset.name %]</tt></td>
|
||||||
|
</tr>
|
||||||
|
[% END %]
|
||||||
<tr>
|
<tr>
|
||||||
<th>Description:</th>
|
<th>Description:</th>
|
||||||
<td>[% jobset.description %]</td>
|
<td>[% INCLUDE maybeEditString value=jobset.description %]</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Nix expression:</th>
|
<th>Nix expression:</th>
|
||||||
<td><tt>[% jobset.nixexprpath %]</tt> in input <tt>[% jobset.nixexprinput %]</tt></td>
|
<td><tt>[% INCLUDE maybeEditString value=jobset.nixexprpath %]</tt> in input <tt>[% INCLUDE maybeEditString value=jobset.nixexprinput %]</tt></td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
@ -36,14 +79,33 @@
|
||||||
<tbody>
|
<tbody>
|
||||||
[% FOREACH input IN jobset.jobsetinputs -%]
|
[% FOREACH input IN jobset.jobsetinputs -%]
|
||||||
<tr>
|
<tr>
|
||||||
<td><tt>[% input.name %]</tt></td>
|
<td><tt>[% INCLUDE maybeEditString value=input.name %]</tt></td>
|
||||||
<td><tt>[% input.type %]</tt></td>
|
<td><tt>
|
||||||
|
[% IF edit %]
|
||||||
|
<select>
|
||||||
|
<option>svn</option>
|
||||||
|
<option>cvs</option>
|
||||||
|
<option>uri</option>
|
||||||
|
<option>string</option>
|
||||||
|
<option>path</option>
|
||||||
|
</select>
|
||||||
|
[% ELSE %]
|
||||||
|
[% input.type %]
|
||||||
|
[% END %]
|
||||||
|
</tt></td>
|
||||||
<td>
|
<td>
|
||||||
[% FOREACH alt IN input.jobsetinputalts -%]
|
[% FOREACH alt IN input.jobsetinputalts -%]
|
||||||
[% IF input.type == "string" %]
|
[% IF input.type == "string" %]
|
||||||
<tt>"[% alt.value %]"</tt>
|
<tt>
|
||||||
|
[% IF edit %]
|
||||||
|
<input type='text' class='string' value='[% alt.value %]' />
|
||||||
|
<br />
|
||||||
[% ELSE %]
|
[% ELSE %]
|
||||||
<tt>[% alt.uri %]</tt>
|
"[% alt.value %]"
|
||||||
|
[% END %]
|
||||||
|
</tt>
|
||||||
|
[% ELSE %]
|
||||||
|
<tt>[% INCLUDE maybeEditString value=alt.uri %]</tt>
|
||||||
[% END %]
|
[% END %]
|
||||||
[% END %]
|
[% END %]
|
||||||
</td>
|
</td>
|
||||||
|
@ -61,6 +123,9 @@
|
||||||
[% END %]
|
[% END %]
|
||||||
|
|
||||||
|
|
||||||
|
[% IF !edit %]
|
||||||
|
|
||||||
|
|
||||||
<h2>Jobs</h2>
|
<h2>Jobs</h2>
|
||||||
|
|
||||||
[% IF jobNames.size > 0 %]
|
[% IF jobNames.size > 0 %]
|
||||||
|
@ -108,4 +173,20 @@
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|
||||||
|
[% END %]
|
||||||
|
|
||||||
|
|
||||||
|
[% IF edit %]
|
||||||
|
|
||||||
|
<p><input type="submit" value="Apply" /></p>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<form action="[% c.uri_for('/project' curProject.name 'delete') %]" method="post">
|
||||||
|
<p><input type="submit" value="Delete this project" /></p>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
[% END %]
|
||||||
|
|
||||||
|
|
||||||
[% END %]
|
[% END %]
|
||||||
|
|
|
@ -174,7 +174,7 @@ create table JobsetInputs (
|
||||||
project text not null,
|
project text not null,
|
||||||
jobset text not null,
|
jobset text not null,
|
||||||
name text not null,
|
name text not null,
|
||||||
type text not null, -- "svn", "cvs", "path", "file", "string"
|
type text not null, -- "svn", "cvs", "path", "uri", "string"
|
||||||
primary key (project, jobset, name),
|
primary key (project, jobset, name),
|
||||||
foreign key (project, jobset) references Jobsets(project, name) on delete cascade -- ignored by sqlite
|
foreign key (project, jobset) references Jobsets(project, name) on delete cascade -- ignored by sqlite
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
insert into projects(name, displayName, description) values('patchelf', 'PatchELF', 'A tool for modifying ELF binaries');
|
insert into projects(name, displayName, description) values('patchelf', 'PatchELF', 'A tool for modifying ELF binaries');
|
||||||
insert into jobSets(project, name, description, nixExprInput, nixExprPath) values('patchelf', 'trunk', 'PatchELF', 'patchelfSrc', 'release.nix');
|
insert into jobSets(project, name, description, nixExprInput, nixExprPath) values('patchelf', 'trunk', 'PatchELF trunk', 'patchelfSrc', 'release.nix');
|
||||||
insert into jobSetInputs(project, jobset, name, type) values('patchelf', 'trunk', 'patchelfSrc', 'path');
|
insert into jobSetInputs(project, jobset, name, type) values('patchelf', 'trunk', 'patchelfSrc', 'path');
|
||||||
insert into jobSetInputAlts(project, jobset, input, altnr, uri) values('patchelf', 'trunk', 'patchelfSrc', 0, '/home/eelco/Dev/patchelf-wc');
|
insert into jobSetInputAlts(project, jobset, input, altnr, uri) values('patchelf', 'trunk', 'patchelfSrc', 0, '/home/eelco/Dev/patchelf-wc');
|
||||||
insert into jobSetInputs(project, jobset, name, type) values('patchelf', 'trunk', 'nixpkgs', 'path');
|
insert into jobSetInputs(project, jobset, name, type) values('patchelf', 'trunk', 'nixpkgs', 'path');
|
||||||
|
|
Loading…
Reference in a new issue