1package Magus::Port; 2# 3# Copyright (c) 2007,2008 Chris Reinhardt. All rights reserved. 4# 5# Redistribution and use in source and binary forms, with or without 6# modification, are permitted provided that the following conditions are 7# met: 8# 9# 1. Redistributions of source code must retain the above copyright notice 10# this list of conditions and the following disclaimer. 11# 12# 2. Redistributions in binary form must reproduce the above copyright 13# notice, this list of conditions and the following disclaimer in the 14# documentation and/or other materials provided with the distribution. 15# 16# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 17# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 18# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26# 27 28# 29# MAINTAINER= ctriv@MidnightBSD.org 30# 31 32use strict; 33use warnings; 34 35use base 'Magus::DBI'; 36 37__PACKAGE__->table('ports'); 38 39__PACKAGE__->columns(Essential => qw(id run name version status pkgname flavor)); 40__PACKAGE__->columns(All => qw(description license restricted www updated default_flavor cpe)); 41__PACKAGE__->columns(Stringify => qw(pkgname)); 42 43__PACKAGE__->has_a(run => 'Magus::Run'); 44 45__PACKAGE__->has_many(depends => [ 'Magus::Depend' => 'dependency' ] => 'port'); 46__PACKAGE__->has_many(categories => [ 'Magus::PortCategory' => 'category' ]); 47__PACKAGE__->has_many(perms => [ 'Magus::PortLicensePerms' => 'perm' ]); 48__PACKAGE__->has_many(events => 'Magus::Event'); 49__PACKAGE__->has_many(master_sites => 'Magus::MasterSite'); 50__PACKAGE__->has_many(distfiles => 'Magus::Distfile'); 51__PACKAGE__->has_many(restricted_distfiles => 'Magus::RestrictedDistfile'); 52__PACKAGE__->has_many(critical => ['Magus::CriticalPorts' => 'pkgname' ] => 'pkgname' ); 53 54 55__PACKAGE__->set_sql(ready_ports => 'SELECT __ESSENTIAL__ FROM ready_ports WHERE run=?'); 56__PACKAGE__->set_sql(single_ready_port => 'SELECT __ESSENTIAL__ FROM ready_ports WHERE run=? LIMIT 1'); 57__PACKAGE__->set_sql(last_twenty => qq{ 58 SELECT __ESSENTIAL__ 59 FROM __TABLE__ 60 WHERE status!='untested' 61 ORDER BY updated DESC LIMIT 20 62 }); 63 64=head2 Magus::Port->get_ready_port($run); 65 66Return a port that is ready to be tested for the given run. 67Ready is defined as: 68 69=over 4 70 71=item 1 72 73The port is unlocked 74 75=item 2 76 77The port has not been tested. 78 79=item 3 80 81All the port's depends are tested and unlocked. 82 83=back 84 85=cut 86 87sub get_ready_port { 88 my ($class, $run) = @_; 89 return shift->search_single_ready_port($run)->next; 90} 91 92 93=head2 $port->origin 94 95Return the absolute directory where this port lives, such as: 96 97 /usr/mports/foo/bar 98 99=cut 100 101sub origin { 102 return join('/', $Mport::Globals::ROOT, $_[0]->name); 103} 104 105 106# POD removed as method is deprecated. 107sub current_result { 108 require Carp; 109 Carp::confess("Use of deprecated method: Magus::Port->current_result. There is no replacement."); 110} 111 112=head2 $port->all_depends 113 114Returns a list of every port in this port's dependency tree. 115 116=cut 117 118sub all_depends { 119 my ($self) = @_; 120 121 my %depends; 122 _walk($self, \%depends); 123 delete $depends{$self}; 124 return sort values %depends; 125} 126 127sub _walk { 128 my ($port, $depends) = @_; 129 130 foreach my $dep ($port->depends) { 131 if (!$depends->{$dep}) { 132 $depends->{$dep} = $dep; 133 _walk($dep, $depends); 134 } 135 } 136 137} 138 139=head2 $port->bundle_name 140 141Returns the bundle filename for this port. 142 143=cut 144 145sub bundle_name { 146 my ($self) = @_; 147 return sprintf("%s-%s.%s", $self->pkgname, $self->version, $Magus::Config{'PkgExtension'}); 148} 149 150 151 152=head2 $port->set_result_pass($message); 153 154A convience method for setting a port as passed. 155 156=cut 157 158sub set_result_pass { 159 my ($self, $msg) = @_; 160 161 $self->_set_result('pass', $msg, 'info'); 162} 163 164 165=head2 $port->set_result_skip($message); 166 167A convience method for setting a port as skipped. 168 169=cut 170 171sub set_result_skip { 172 my ($self, $msg) = @_; 173 174 $self->_set_result('skip', $msg, 'skip'); 175} 176 177 178=head2 $port->set_result_internal($message); 179 180A convience method for setting a port as internalled. 181 182=cut 183 184sub set_result_internal { 185 my ($self, $msg) = @_; 186 187 $self->_set_result('internal', $msg, 'internal'); 188} 189 190 191=head2 $port->set_result_fail($message); 192 193A convience method for setting a port as failed. 194 195=cut 196 197sub set_result_fail { 198 my ($self, $msg) = @_; 199 200 $self->_set_result('fail', $msg, 'fail'); 201} 202 203 204 205sub _set_result { 206 my ($self, $status, $msg, $type) = @_; 207 208 $self->status($status); 209 $self->update; 210 211 $self->note_event($type, $msg); 212} 213 214=head2 $port->reset(); 215 216Returns the port to a pristine untested state. 217 218=cut 219 220sub reset { 221 my ($self) = @_; 222 223 $self->events->delete_all; 224 225 if (my $log = Magus::Log->retrieve(port => $self)) { 226 $log->delete; 227 } 228 229 $self->status('untested'); 230 $self->update; 231} 232 233=head2 $port->can_reset 234 235Returns true is reseting this port makes sense (the port is tested 236and its run is active). Returns false otherwise. 237 238=cut 239 240sub can_reset { 241 return if $_[0]->status eq 'untested' 242 || $_[0]->run->status ne 'active'; 243 return 1; 244} 245 246=head2 $port->log 247 248Returns the log data for this port, if any. Returns undef if there is no log. 249 250=cut 251 252sub log { 253 require Magus::Log; 254 255 my ($self) = @_; 256 return $self->{__log} if exists $self->{__log}; 257 my $log = Magus::Log->retrieve(port => $self) or return; 258 return $self->{__log} = $log->data; 259} 260 261=head2 $port->note_event(type => $msg); 262 263Add an event to the port of the given type with the given message 264 265=cut 266 267sub note_event { 268 my ($self, $type, $msg) = @_; 269 270 $self->add_to_events({ 271 machine => $Magus::Machine, 272 type => $type, 273 msg => $msg, 274 }); 275} 276 2771; 278__END__ 279