This commit is contained in:
Eelco Dolstra 2008-11-13 14:54:50 +00:00
parent 46dc10847a
commit f6f5309a02
8 changed files with 185 additions and 19 deletions

View file

@ -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 {
my ( $self, $c, $projectName ) = @_;
my ( $self, $c, $projectName, $subcommand ) = @_;
$c->stash->{template} = 'project.tt';
(my $project) = $c->model('DB::Projects')->search({ name => $projectName });
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->{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 {
my ( $self, $c, $project, $jobName ) = @_;
my ( $self, $c, $projectName, $jobName ) = @_;
$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->{builds} = [$c->model('DB::Builds')->search(
{finished => 1, project => $project, attrName => $jobName},
{finished => 1, project => $projectName, attrName => $jobName},
{order_by => "timestamp DESC"})];
}

View file

@ -1,7 +1,8 @@
[% WRAPPER layout.tt title="Hydra Overview" %]
[% USE HTML %]
<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 %]

View file

@ -38,6 +38,10 @@ td, th {
border: solid black 1px;
}
td {
vertical-align: top;
}
th {
background: #ffffc0;
}
@ -145,6 +149,7 @@ td.buildfarmMainColumn {
.error-msg {
color: red;
white-space: pre;
}
pre.buildlog {
@ -321,3 +326,13 @@ h1 {
#footer {
font-size: 80%;
}
/* Editing */
input.string {
font-family: sans-serif;
font-size: 100%;
background-color: #fffff0;
width: 30em;
}

View file

@ -1,6 +1,6 @@
[% 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">
<thead>

View file

@ -50,6 +50,7 @@
<div class="title"><a href="[% c.uri_for('/project' project.name) %]">[% project.displayname %]</a></div>
[% IF curProject.name == project.name %]
<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 'all') title = "All builds" %]
</ul>
@ -63,7 +64,7 @@
<div class="title">Admin</div>
<ul class="submenu">
[% 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>
</li>
</ul>

View file

@ -1,9 +1,46 @@
[% WRAPPER layout.tt title="Hydra Overview" %]
<h1>Project <tt>[% curProject.name %]</tt></h1>
[% USE HTML %]
<p><strong>Description:</strong> [% curProject.description %]</p>
[% 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>
[% END %]
<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>
@ -17,13 +54,19 @@
<h4>Information</h4>
<table>
[% IF edit %]
<tr>
<th>Identifier:</th>
<td><tt>[% INCLUDE maybeEditString value=jobset.name %]</tt></td>
</tr>
[% END %]
<tr>
<th>Description:</th>
<td>[% jobset.description %]</td>
<td>[% INCLUDE maybeEditString value=jobset.description %]</td>
</tr>
<tr>
<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>
</table>
@ -36,14 +79,33 @@
<tbody>
[% FOREACH input IN jobset.jobsetinputs -%]
<tr>
<td><tt>[% input.name %]</tt></td>
<td><tt>[% input.type %]</tt></td>
<td><tt>[% INCLUDE maybeEditString value=input.name %]</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>
[% FOREACH alt IN input.jobsetinputalts -%]
[% IF input.type == "string" %]
<tt>"[% alt.value %]"</tt>
<tt>
[% IF edit %]
<input type='text' class='string' value='[% alt.value %]' />
<br />
[% ELSE %]
"[% alt.value %]"
[% END %]
</tt>
[% ELSE %]
<tt>[% alt.uri %]</tt>
<tt>[% INCLUDE maybeEditString value=alt.uri %]</tt>
[% END %]
[% END %]
</td>
@ -61,6 +123,9 @@
[% END %]
[% IF !edit %]
<h2>Jobs</h2>
[% IF jobNames.size > 0 %]
@ -108,4 +173,20 @@
</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 %]

View file

@ -174,7 +174,7 @@ create table JobsetInputs (
project text not null,
jobset 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),
foreign key (project, jobset) references Jobsets(project, name) on delete cascade -- ignored by sqlite
);

View file

@ -1,5 +1,5 @@
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 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');