2009-03-04 10:59:14 +00:00
package Hydra::Controller::Project ;
use strict ;
use warnings ;
use base 'Hydra::Base::Controller::ListBuilds' ;
use Hydra::Helper::Nix ;
use Hydra::Helper::CatalystUtils ;
sub project : Chained('/') PathPart('project') CaptureArgs(1) {
my ( $ self , $ c , $ projectName ) = @ _ ;
2009-03-12 23:46:17 +00:00
my $ project = $ c - > model ( 'DB::Projects' ) - > find ( $ projectName )
or notFound ( $ c , "Project $projectName doesn't exist." ) ;
2009-03-04 10:59:14 +00:00
2009-03-13 15:41:19 +00:00
$ c - > stash - > { project } = $ project ;
2010-03-18 15:59:24 +00:00
2009-03-04 10:59:14 +00:00
}
sub view : Chained('project') PathPart('') Args(0) {
my ( $ self , $ c ) = @ _ ;
$ c - > stash - > { template } = 'project.tt' ;
2010-02-09 12:35:20 +00:00
#getBuildStats($c, scalar $c->stash->{project}->builds);
2009-04-02 16:15:57 +00:00
2009-10-15 21:35:19 +00:00
$ c - > stash - > { views } = [ $ c - > stash - > { project } - > views - > all ] ;
2010-06-04 14:43:28 +00:00
$ c - > stash - > { jobsets } = [ $ c - > stash - > { project } - > jobsets - > search ( isProjectOwner ( $ c , $ c - > stash - > { project } - > name ) ? { } : { hidden = > 0 } ,
2010-03-18 15:59:24 +00:00
{ order_by = > "name"
, "+select" = > [
"(SELECT COUNT(*) FROM Builds AS a NATURAL JOIN BuildSchedulingInfo WHERE me.project = a.project AND me.name = a.jobset AND a.isCurrent = 1 )"
, "(SELECT COUNT(*) FROM Builds AS a NATURAL JOIN BuildResultInfo WHERE me.project = a.project AND me.name = a.jobset AND buildstatus <> 0 AND a.isCurrent = 1 )"
, "(SELECT COUNT(*) FROM Builds AS a NATURAL JOIN BuildResultInfo WHERE me.project = a.project AND me.name = a.jobset AND buildstatus = 0 AND a.isCurrent = 1 )"
2010-03-19 08:36:31 +00:00
, "(SELECT COUNT(*) FROM Builds AS a WHERE me.project = a.project AND me.name = a.jobset AND a.isCurrent = 1 )"
2010-03-18 15:59:24 +00:00
]
2010-03-19 08:36:31 +00:00
, "+as" = > [ "nrscheduled" , "nrfailed" , "nrsucceeded" , "nrtotal" ]
2010-03-18 15:59:24 +00:00
} ) ] ;
2009-03-04 10:59:14 +00:00
}
sub edit : Chained('project') PathPart Args(0) {
my ( $ self , $ c ) = @ _ ;
2009-03-13 15:41:19 +00:00
requireProjectOwner ( $ c , $ c - > stash - > { project } ) ;
2009-03-04 10:59:14 +00:00
$ c - > stash - > { template } = 'project.tt' ;
$ c - > stash - > { edit } = 1 ;
}
sub submit : Chained('project') PathPart Args(0) {
my ( $ self , $ c ) = @ _ ;
2009-03-13 15:41:19 +00:00
requireProjectOwner ( $ c , $ c - > stash - > { project } ) ;
2009-04-02 16:15:57 +00:00
requirePost ( $ c ) ;
2009-03-04 10:59:14 +00:00
2009-04-22 22:43:04 +00:00
txn_do ( $ c - > model ( 'DB' ) - > schema , sub {
2009-03-13 15:41:19 +00:00
updateProject ( $ c , $ c - > stash - > { project } ) ;
2009-03-04 10:59:14 +00:00
} ) ;
2009-04-02 16:15:57 +00:00
$ c - > res - > redirect ( $ c - > uri_for ( $ self - > action_for ( "view" ) , [ $ c - > stash - > { project } - > name ] ) ) ;
2009-03-04 10:59:14 +00:00
}
2010-06-04 14:43:28 +00:00
sub hide : Chained('project') PathPart Args(0) {
my ( $ self , $ c ) = @ _ ;
requireProjectOwner ( $ c , $ c - > stash - > { project } ) ;
txn_do ( $ c - > model ( 'DB' ) - > schema , sub {
$ c - > stash - > { project } - > update ( { hidden = > 1 , enabled = > 0 } ) ;
} ) ;
$ c - > res - > redirect ( $ c - > uri_for ( "/" ) ) ;
}
sub unhide : Chained('project') PathPart Args(0) {
my ( $ self , $ c ) = @ _ ;
requireProjectOwner ( $ c , $ c - > stash - > { project } ) ;
txn_do ( $ c - > model ( 'DB' ) - > schema , sub {
$ c - > stash - > { project } - > update ( { hidden = > 0 } ) ;
} ) ;
$ c - > res - > redirect ( $ c - > uri_for ( "/" ) ) ;
}
2009-03-04 10:59:14 +00:00
sub delete : Chained('project') PathPart Args(0) {
my ( $ self , $ c ) = @ _ ;
2009-03-13 15:41:19 +00:00
requireProjectOwner ( $ c , $ c - > stash - > { project } ) ;
2009-04-02 16:15:57 +00:00
requirePost ( $ c ) ;
2009-03-04 10:59:14 +00:00
2009-04-22 22:43:04 +00:00
txn_do ( $ c - > model ( 'DB' ) - > schema , sub {
2009-03-13 15:41:19 +00:00
$ c - > stash - > { project } - > delete ;
2009-03-04 10:59:14 +00:00
} ) ;
$ c - > res - > redirect ( $ c - > uri_for ( "/" ) ) ;
}
2009-03-24 14:22:59 +00:00
sub requireMayCreateProjects {
my ( $ c ) = @ _ ;
requireLogin ( $ c ) if ! $ c - > user_exists ;
error ( $ c , "Only administrators or authorised users can perform this operation." )
unless $ c - > check_user_roles ( 'admin' ) || $ c - > check_user_roles ( 'create-projects' ) ;
}
2009-03-04 11:03:43 +00:00
sub create : Path('/create-project') {
2009-03-04 10:59:14 +00:00
my ( $ self , $ c ) = @ _ ;
2009-03-24 14:22:59 +00:00
requireMayCreateProjects ( $ c ) ;
2009-03-04 10:59:14 +00:00
$ c - > stash - > { template } = 'project.tt' ;
$ c - > stash - > { create } = 1 ;
$ c - > stash - > { edit } = 1 ;
}
2009-03-04 11:03:43 +00:00
sub create_submit : Path('/create-project/submit') {
2009-03-04 10:59:14 +00:00
my ( $ self , $ c ) = @ _ ;
2009-03-24 14:22:59 +00:00
requireMayCreateProjects ( $ c ) ;
2009-03-04 10:59:14 +00:00
my $ projectName = trim $ c - > request - > params - > { name } ;
2009-04-22 22:43:04 +00:00
txn_do ( $ c - > model ( 'DB' ) - > schema , sub {
2009-03-04 10:59:14 +00:00
# Note: $projectName is validated in updateProject,
# which will abort the transaction if the name isn't
# valid. Idem for the owner.
2009-03-24 14:22:59 +00:00
my $ owner = $ c - > check_user_roles ( 'admin' )
? trim $ c - > request - > params - > { owner } : $ c - > user - > username ;
2009-03-04 10:59:14 +00:00
my $ project = $ c - > model ( 'DB::Projects' ) - > create (
2009-03-24 14:22:59 +00:00
{ name = > $ projectName , displayname = > "" , owner = > $ owner } ) ;
2009-03-04 10:59:14 +00:00
updateProject ( $ c , $ project ) ;
} ) ;
$ c - > res - > redirect ( $ c - > uri_for ( $ self - > action_for ( "view" ) , [ $ projectName ] ) ) ;
}
2009-04-02 16:15:57 +00:00
sub create_jobset : Chained('project') PathPart('create-jobset') Args(0) {
my ( $ self , $ c ) = @ _ ;
requireProjectOwner ( $ c , $ c - > stash - > { project } ) ;
$ c - > stash - > { template } = 'jobset.tt' ;
$ c - > stash - > { create } = 1 ;
$ c - > stash - > { edit } = 1 ;
}
sub create_jobset_submit : Chained('project') PathPart('create-jobset/submit') Args(0) {
my ( $ self , $ c ) = @ _ ;
requireProjectOwner ( $ c , $ c - > stash - > { project } ) ;
my $ jobsetName = trim $ c - > request - > params - > { name } ;
2009-04-22 22:43:04 +00:00
txn_do ( $ c - > model ( 'DB' ) - > schema , sub {
2009-04-02 16:15:57 +00:00
# Note: $jobsetName is validated in updateProject, which will
# abort the transaction if the name isn't valid.
my $ jobset = $ c - > stash - > { project } - > jobsets - > create (
{ name = > $ jobsetName , nixexprinput = > "" , nixexprpath = > "" } ) ;
Hydra::Controller::Jobset:: updateJobset ( $ c , $ jobset ) ;
} ) ;
$ c - > res - > redirect ( $ c - > uri_for ( $ c - > controller ( 'Jobset' ) - > action_for ( "index" ) ,
[ $ c - > stash - > { project } - > name , $ jobsetName ] ) ) ;
}
2009-03-04 10:59:14 +00:00
sub updateProject {
my ( $ c , $ project ) = @ _ ;
my $ projectName = trim $ c - > request - > params - > { name } ;
2009-03-19 15:12:50 +00:00
error ( $ c , "Invalid project name: " . ( $ projectName || "(empty)" ) ) unless $ projectName =~ /^[[:alpha:]][\w\-]*$/ ;
2009-03-04 10:59:14 +00:00
my $ displayName = trim $ c - > request - > params - > { displayname } ;
error ( $ c , "Invalid display name: $displayName" ) if $ displayName eq "" ;
2009-04-02 16:15:57 +00:00
my $ owner = $ project - > owner ;
2009-03-04 10:59:14 +00:00
if ( $ c - > check_user_roles ( 'admin' ) ) {
2009-04-02 16:15:57 +00:00
$ owner = trim $ c - > request - > params - > { owner } ;
2009-03-04 10:59:14 +00:00
error ( $ c , "Invalid owner: $owner" )
unless defined $ c - > model ( 'DB::Users' ) - > find ( { username = > $ owner } ) ;
}
2009-04-02 16:15:57 +00:00
$ project - > update (
{ name = > $ projectName
, displayname = > $ displayName
, description = > trim ( $ c - > request - > params - > { description } )
, homepage = > trim ( $ c - > request - > params - > { homepage } )
, enabled = > trim ( $ c - > request - > params - > { enabled } ) eq "1" ? 1 : 0
, owner = > $ owner
} ) ;
2009-03-04 10:59:14 +00:00
}
# Hydra::Base::Controller::ListBuilds needs this.
sub get_builds : Chained('project') PathPart('') CaptureArgs(0) {
my ( $ self , $ c ) = @ _ ;
2009-03-13 15:41:19 +00:00
$ c - > stash - > { allBuilds } = $ c - > stash - > { project } - > builds ;
2009-04-03 15:37:21 +00:00
$ c - > stash - > { jobStatus } = $ c - > model ( 'DB' ) - > resultset ( 'JobStatusForProject' )
- > search ( { } , { bind = > [ $ c - > stash - > { project } - > name ] } ) ;
2009-04-08 22:08:00 +00:00
$ c - > stash - > { allJobsets } = $ c - > stash - > { project } - > jobsets ;
$ c - > stash - > { allJobs } = $ c - > stash - > { project } - > jobs ;
2009-04-03 15:37:21 +00:00
$ c - > stash - > { latestSucceeded } = $ c - > model ( 'DB' ) - > resultset ( 'LatestSucceededForProject' )
- > search ( { } , { bind = > [ $ c - > stash - > { project } - > name ] } ) ;
2009-03-13 15:41:19 +00:00
$ c - > stash - > { channelBaseName } = $ c - > stash - > { project } - > name ;
2009-03-04 10:59:14 +00:00
}
2009-10-20 12:26:39 +00:00
sub create_view_submit : Chained('project') PathPart('create-view/submit') Args(0) {
my ( $ self , $ c ) = @ _ ;
requireProjectOwner ( $ c , $ c - > stash - > { project } ) ;
my $ viewName = $ c - > request - > params - > { name } ;
my $ view ;
txn_do ( $ c - > model ( 'DB' ) - > schema , sub {
# Note: $viewName is validated in updateView, which will abort
# the transaction if the name isn't valid.
$ view = $ c - > stash - > { project } - > views - > create ( { name = > $ viewName } ) ;
Hydra::Controller::View:: updateView ( $ c , $ view ) ;
} ) ;
$ c - > res - > redirect ( $ c - > uri_for ( $ c - > controller ( 'View' ) - > action_for ( 'view_view' ) ,
[ $ c - > stash - > { project } - > name , $ view - > name ] ) ) ;
}
sub create_view : Chained('project') PathPart('create-view') Args(0) {
my ( $ self , $ c ) = @ _ ;
requireProjectOwner ( $ c , $ c - > stash - > { project } ) ;
$ c - > stash - > { template } = 'edit-view.tt' ;
$ c - > stash - > { create } = 1 ;
}
2009-10-21 15:44:17 +00:00
sub releases : Chained('project') PathPart('releases') Args(0) {
my ( $ self , $ c ) = @ _ ;
$ c - > stash - > { template } = 'releases.tt' ;
2009-11-04 17:17:44 +00:00
$ c - > stash - > { releases } = [ $ c - > stash - > { project } - > releases - > search ( { } ,
{ order_by = > [ "timestamp DESC" ] } ) ] ;
2009-10-21 15:44:17 +00:00
}
2009-10-23 09:58:23 +00:00
sub create_release : Chained('project') PathPart('create-release') Args(0) {
2009-10-21 15:44:17 +00:00
my ( $ self , $ c ) = @ _ ;
2009-10-23 09:58:23 +00:00
requireProjectOwner ( $ c , $ c - > stash - > { project } ) ;
$ c - > stash - > { template } = 'edit-release.tt' ;
$ c - > stash - > { create } = 1 ;
}
sub create_release_submit : Chained('project') PathPart('create-release/submit') Args(0) {
my ( $ self , $ c ) = @ _ ;
requireProjectOwner ( $ c , $ c - > stash - > { project } ) ;
my $ releaseName = $ c - > request - > params - > { name } ;
my $ release ;
txn_do ( $ c - > model ( 'DB' ) - > schema , sub {
# Note: $releaseName is validated in updateRelease, which will
# abort the transaction if the name isn't valid.
$ release = $ c - > stash - > { project } - > releases - > create (
{ name = > $ releaseName
, timestamp = > time
} ) ;
Hydra::Controller::Release:: updateRelease ( $ c , $ release ) ;
} ) ;
$ c - > res - > redirect ( $ c - > uri_for ( $ c - > controller ( 'Release' ) - > action_for ( 'view' ) ,
[ $ c - > stash - > { project } - > name , $ release - > name ] ) ) ;
2009-10-21 15:44:17 +00:00
}
2009-03-04 10:59:14 +00:00
1 ;