.\" Automatically generated by Pod::Man 2.1801 (Pod::Simple 3.05) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is turned on, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .ie \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . nr % 0 . rr F .\} .el \{\ . de IX .. .\} .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "Debbugs::Control 3pm" .TH Debbugs::Control 3pm "2010-08-06" "perl v5.10.0" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Debbugs::Control \-\- Routines for modifying the state of bugs .SH "SYNOPSIS" .IX Header "SYNOPSIS" use Debbugs::Control; .SH "DESCRIPTION" .IX Header "DESCRIPTION" This module is an abstraction of a lot of functions which originally were only present in service.in, but as time has gone on needed to be called from elsewhere. .PP All of the public functions take the following options: .IP "debug \*(-- scalar reference to which debbuging information is appended" 4 .IX Item "debug scalar reference to which debbuging information is appended" .PD 0 .IP "transcript \*(-- scalar reference to which transcript information is appended" 4 .IX Item "transcript scalar reference to which transcript information is appended" .IP "affected_bugs \*(-- hashref which is updated with bugs affected by this function" 4 .IX Item "affected_bugs hashref which is updated with bugs affected by this function" .PD .PP Functions which should (probably) append to the .log file take the following options: .IP "requester \*(-- Email address of the individual who requested the change" 4 .IX Item "requester Email address of the individual who requested the change" .PD 0 .IP "request_addr \*(-- Address to which the request was sent" 4 .IX Item "request_addr Address to which the request was sent" .IP "request_nn \*(-- Name of queue file which caused this request" 4 .IX Item "request_nn Name of queue file which caused this request" .IP "request_msgid \*(-- Message id of message which caused this request" 4 .IX Item "request_msgid Message id of message which caused this request" .IP "location \*(-- Optional location; currently ignored but may be supported in the future for updating archived bugs upon archival" 4 .IX Item "location Optional location; currently ignored but may be supported in the future for updating archived bugs upon archival" .IP "message \*(-- The original message which caused the action to be taken" 4 .IX Item "message The original message which caused the action to be taken" .IP "append_log \*(-- Whether or not to append information to the log." 4 .IX Item "append_log Whether or not to append information to the log." .PD .PP \&\fBappend_log\fR (for most functions) is a special option. When set to false, no appending to the log is done at all. When it is not present, the above information is faked, and appended to the log file. When it is true, the above options must be present, and their values are used. .SH "GENERAL FUNCTIONS" .IX Header "GENERAL FUNCTIONS" .SS "set_blocks" .IX Subsection "set_blocks" .Vb 10 \& eval { \& set_block(bug => $ref, \& transcript => $transcript, \& ($dl > 0 ? (debug => $transcript):()), \& requester => $header{from}, \& request_addr => $controlrequestaddr, \& message => \e@log, \& affected_packages => \e%affected_packages, \& recipients => \e%recipients, \& block => [], \& ); \& }; \& if ($@) { \& $errors++; \& print {$transcript} "Failed to set blockers of $ref: $@"; \& } .Ve .PP Alters the set of bugs that block this bug from being fixed .PP This requires altering both this bug (and those it's merged with) as well as the bugs that block this bug from being fixed (and those that it's merged with) .IP "block \*(-- scalar or arrayref of blocking bugs to set, add or remove" 4 .IX Item "block scalar or arrayref of blocking bugs to set, add or remove" .PD 0 .IP "add \*(-- if true, add blocking bugs" 4 .IX Item "add if true, add blocking bugs" .IP "remove \*(-- if true, remove blocking bugs" 4 .IX Item "remove if true, remove blocking bugs" .PD .SS "set_tag" .IX Subsection "set_tag" .Vb 10 \& eval { \& set_tag(bug => $ref, \& transcript => $transcript, \& ($dl > 0 ? (debug => $transcript):()), \& requester => $header{from}, \& request_addr => $controlrequestaddr, \& message => \e@log, \& affected_packages => \e%affected_packages, \& recipients => \e%recipients, \& tag => [], \& add => 1, \& ); \& }; \& if ($@) { \& $errors++; \& print {$transcript} "Failed to set tag on $ref: $@"; \& } .Ve .PP Sets, adds, or removes the specified tags on a bug .IP "tag \*(-- scalar or arrayref of tags to set, add or remove" 4 .IX Item "tag scalar or arrayref of tags to set, add or remove" .PD 0 .IP "add \*(-- if true, add tags" 4 .IX Item "add if true, add tags" .IP "remove \*(-- if true, remove tags" 4 .IX Item "remove if true, remove tags" .IP "warn_on_bad_tags \*(-- if true (the default) warn if bad tags are passed." 4 .IX Item "warn_on_bad_tags if true (the default) warn if bad tags are passed." .PD .SS "set_severity" .IX Subsection "set_severity" .Vb 10 \& eval { \& set_severity(bug => $ref, \& transcript => $transcript, \& ($dl > 0 ? (debug => $transcript):()), \& requester => $header{from}, \& request_addr => $controlrequestaddr, \& message => \e@log, \& affected_packages => \e%affected_packages, \& recipients => \e%recipients, \& severity => \*(Aqnormal\*(Aq, \& ); \& }; \& if ($@) { \& $errors++; \& print {$transcript} "Failed to set the severity of bug $ref: $@"; \& } .Ve .PP Sets the severity of a bug. If severity is not passed, is undefined, or has zero length, sets the severity to the defafult severity. .SS "reopen" .IX Subsection "reopen" .Vb 10 \& eval { \& set_foo(bug => $ref, \& transcript => $transcript, \& ($dl > 0 ? (debug => $transcript):()), \& requester => $header{from}, \& request_addr => $controlrequestaddr, \& message => \e@log, \& affected_packages => \e%affected_packages, \& recipients => \e%recipients, \& summary => undef, \& ); \& }; \& if ($@) { \& $errors++; \& print {$transcript} "Failed to set foo $ref bar: $@"; \& } .Ve .PP Foo frobinates .SS "set_submitter" .IX Subsection "set_submitter" .Vb 10 \& eval { \& set_submitter(bug => $ref, \& transcript => $transcript, \& ($dl > 0 ? (debug => $transcript):()), \& requester => $header{from}, \& request_addr => $controlrequestaddr, \& message => \e@log, \& affected_packages => \e%affected_packages, \& recipients => \e%recipients, \& submitter => $new_submitter, \& notify_submitter => 1, \& ); \& }; \& if ($@) { \& $errors++; \& print {$transcript} "Failed to set the forwarded\-to\-address of $ref: $@"; \& } .Ve .PP Sets the submitter of a bug. If notify_submitter is true (the default), notifies the old submitter of a bug on changes .SS "set_forwarded" .IX Subsection "set_forwarded" .Vb 10 \& eval { \& set_forwarded(bug => $ref, \& transcript => $transcript, \& ($dl > 0 ? (debug => $transcript):()), \& requester => $header{from}, \& request_addr => $controlrequestaddr, \& message => \e@log, \& affected_packages => \e%affected_packages, \& recipients => \e%recipients, \& forwarded => $forward_to, \& ); \& }; \& if ($@) { \& $errors++; \& print {$transcript} "Failed to set the forwarded\-to\-address of $ref: $@"; \& } .Ve .PP Sets the location to which a bug is forwarded. Given an undef forwarded, unsets forwarded. .SS "set_title" .IX Subsection "set_title" .Vb 10 \& eval { \& set_title(bug => $ref, \& transcript => $transcript, \& ($dl > 0 ? (debug => $transcript):()), \& requester => $header{from}, \& request_addr => $controlrequestaddr, \& message => \e@log, \& affected_packages => \e%affected_packages, \& recipients => \e%recipients, \& title => $new_title, \& ); \& }; \& if ($@) { \& $errors++; \& print {$transcript} "Failed to set the title of $ref: $@"; \& } .Ve .PP Sets the title of a specific bug .SS "set_package" .IX Subsection "set_package" .Vb 10 \& eval { \& set_package(bug => $ref, \& transcript => $transcript, \& ($dl > 0 ? (debug => $transcript):()), \& requester => $header{from}, \& request_addr => $controlrequestaddr, \& message => \e@log, \& affected_packages => \e%affected_packages, \& recipients => \e%recipients, \& package => $new_package, \& is_source => 0, \& ); \& }; \& if ($@) { \& $errors++; \& print {$transcript} "Failed to assign or reassign $ref to a package: $@"; \& } .Ve .PP Indicates that a bug is in a particular package. If is_source is true, indicates that the package is a source package. [Internally, this causes src: to be prepended to the package name.] .PP The default for is_source is 0. As a special case, if the package starts with 'src:', it is assumed to be a source package and is_source is overridden. .PP The package option must match the package_name_re regex. .SS "set_found" .IX Subsection "set_found" .Vb 10 \& eval { \& set_found(bug => $ref, \& transcript => $transcript, \& ($dl > 0 ? (debug => $transcript):()), \& requester => $header{from}, \& request_addr => $controlrequestaddr, \& message => \e@log, \& affected_packages => \e%affected_packages, \& recipients => \e%recipients, \& found => [], \& add => 1, \& ); \& }; \& if ($@) { \& $errors++; \& print {$transcript} "Failed to set found on $ref: $@"; \& } .Ve .PP Sets, adds, or removes the specified found versions of a package .PP If the version list is empty, and the bug is currently not \*(L"done\*(R", causes the done field to be cleared. .PP If any of the versions added to found are greater than any version in which the bug is fixed (or when the bug is found and there are no fixed versions) the done field is cleared. .SS "set_fixed" .IX Subsection "set_fixed" .Vb 10 \& eval { \& set_fixed(bug => $ref, \& transcript => $transcript, \& ($dl > 0 ? (debug => $transcript):()), \& requester => $header{from}, \& request_addr => $controlrequestaddr, \& message => \e@log, \& affected_packages => \e%affected_packages, \& recipients => \e%recipients, \& fixed => [], \& add => 1, \& reopen => 0, \& ); \& }; \& if ($@) { \& $errors++; \& print {$transcript} "Failed to set fixed on $ref: $@"; \& } .Ve .PP Sets, adds, or removes the specified fixed versions of a package .PP If the fixed versions are empty (or end up being empty after this call) or the greatest fixed version is less than the greatest found version and the reopen option is true, the bug is reopened. .PP This function is also called by the reopen function, which causes all of the fixed versions to be cleared. .SS "affects" .IX Subsection "affects" .Vb 10 \& eval { \& affects(bug => $ref, \& transcript => $transcript, \& ($dl > 0 ? (debug => $transcript):()), \& requester => $header{from}, \& request_addr => $controlrequestaddr, \& message => \e@log, \& affected_packages => \e%affected_packages, \& recipients => \e%recipients, \& packages => undef, \& add => 1, \& remove => 0, \& ); \& }; \& if ($@) { \& $errors++; \& print {$transcript} "Failed to mark $ref as affecting $packages: $@"; \& } .Ve .PP This marks a bug as affecting packages which the bug is not actually in. This should only be used in cases where fixing the bug instantly resolves the problem in the other packages. .PP By default, the packages are set to the list of packages passed. However, if you pass add => 1 or remove => 1, the list of packages passed are added or removed from the affects list, respectively. .SH "SUMMARY FUNCTIONS" .IX Header "SUMMARY FUNCTIONS" .SS "summary" .IX Subsection "summary" .Vb 10 \& eval { \& summary(bug => $ref, \& transcript => $transcript, \& ($dl > 0 ? (debug => $transcript):()), \& requester => $header{from}, \& request_addr => $controlrequestaddr, \& message => \e@log, \& affected_packages => \e%affected_packages, \& recipients => \e%recipients, \& summary => undef, \& ); \& }; \& if ($@) { \& $errors++; \& print {$transcript} "Failed to mark $ref with summary foo: $@"; \& } .Ve .PP Handles all setting of summary fields .PP If summary is undef, unsets the summary .PP If summary is 0, sets the summary to the first paragraph contained in the message passed. .PP If summary is numeric, sets the summary to the message specified. .SH "OWNER FUNCTIONS" .IX Header "OWNER FUNCTIONS" .SS "owner" .IX Subsection "owner" .Vb 10 \& eval { \& owner(bug => $ref, \& transcript => $transcript, \& ($dl > 0 ? (debug => $transcript):()), \& requester => $header{from}, \& request_addr => $controlrequestaddr, \& message => \e@log, \& recipients => \e%recipients, \& owner => undef, \& ); \& }; \& if ($@) { \& $errors++; \& print {$transcript} "Failed to mark $ref as having an owner: $@"; \& } .Ve .PP Handles all setting of the owner field; given an owner of undef or of no length, indicates that a bug is not owned by anyone. .SH "ARCHIVE FUNCTIONS" .IX Header "ARCHIVE FUNCTIONS" .SS "bug_archive" .IX Subsection "bug_archive" .Vb 10 \& my $error = \*(Aq\*(Aq; \& eval { \& bug_archive(bug => $bug_num, \& debug => \e$debug, \& transcript => \e$transcript, \& ); \& }; \& if ($@) { \& $errors++; \& transcript("Unable to archive $bug_num\en"); \& warn $@; \& } \& transcript($transcript); .Ve .PP This routine archives a bug .IP "bug \*(-- bug number" 4 .IX Item "bug bug number" .PD 0 .IP "check_archiveable \*(-- check wether a bug is archiveable before archiving; defaults to 1" 4 .IX Item "check_archiveable check wether a bug is archiveable before archiving; defaults to 1" .IP "archive_unarchived \*(-- whether to archive bugs which have not previously been archived; defaults to 1. [Set to 0 when used from control@]" 4 .IX Item "archive_unarchived whether to archive bugs which have not previously been archived; defaults to 1. [Set to 0 when used from control@]" .IP "ignore_time \*(-- whether to ignore time constraints when archiving a bug; defaults to 0." 4 .IX Item "ignore_time whether to ignore time constraints when archiving a bug; defaults to 0." .PD .SS "bug_unarchive" .IX Subsection "bug_unarchive" .Vb 12 \& my $error = \*(Aq\*(Aq; \& eval { \& bug_unarchive(bug => $bug_num, \& debug => \e$debug, \& transcript => \e$transcript, \& ); \& }; \& if ($@) { \& $errors++; \& transcript("Unable to archive bug: $bug_num"); \& } \& transcript($transcript); .Ve .PP This routine unarchives a bug .SS "append_action_to_log" .IX Subsection "append_action_to_log" .Vb 1 \& append_action_to_log .Ve .PP This should probably be moved to Debbugs::Log; have to think that out some more. .SH "PRIVATE FUNCTIONS" .IX Header "PRIVATE FUNCTIONS" .SS "_\|_handle_affected_packages" .IX Subsection "__handle_affected_packages" .Vb 3 \& _\|_handle_affected_packages(affected_packages => {}, \& data => [@data], \& ) .Ve .SS "_\|_handle_debug_transcript" .IX Subsection "__handle_debug_transcript" .Vb 1 \& my ($debug,$transcript) = _\|_handle_debug_transcript(%param); .Ve .PP Returns a debug and transcript filehandle .SS "_\|_bug_info" .IX Subsection "__bug_info" .Vb 1 \& _\|_bug_info($data) .Ve .PP Produces a small bit of bug information to kick out to the transcript .SS "_\|_internal_request" .IX Subsection "__internal_request" .Vb 2 \& _\|_internal_request() \& _\|_internal_request($level) .Ve .PP Returns true if the caller of the function calling _\|_internal_request belongs to _\|_PACKAGE_\|_ .PP This allows us to be magical, and don't bother to print bug info if the second caller is from this package, amongst other things. .PP An optional level is allowed, which increments the number of levels to check by the given value. [This is basically for use by internal functions like _\|_begin_control which are always called by \&\f(CW\*(C`_\|_PACKAGE_\|_\*(C'\fR. .SS "_\|_begin_control" .IX Subsection "__begin_control" .Vb 6 \& my %info = _\|_begin_control(%param, \& archived=>1, \& command=>\*(Aqunarchive\*(Aq); \& my ($debug,$transcript) = @info{qw(debug transcript)}; \& my @data = @{$info{data}}; \& my @bugs = @{$info{bugs}}; .Ve .PP Starts the process of modifying a bug; handles all of the generic things that almost every control request needs .PP Returns a hash containing .IP "new_locks \*(-- number of new locks taken out by this call" 4 .IX Item "new_locks number of new locks taken out by this call" .PD 0 .IP "debug \*(-- the debug file handle" 4 .IX Item "debug the debug file handle" .IP "transcript \*(-- the transcript file handle" 4 .IX Item "transcript the transcript file handle" .IP "data \*(-- an arrayref containing the data of the bugs corresponding to this request" 4 .IX Item "data an arrayref containing the data of the bugs corresponding to this request" .IP "bugs \*(-- an arrayref containing the bug numbers of the bugs corresponding to this request" 4 .IX Item "bugs an arrayref containing the bug numbers of the bugs corresponding to this request" .PD .SS "_\|_end_control" .IX Subsection "__end_control" .Vb 1 \& _\|_end_control(%info); .Ve .PP Handles tearing down from a control request .SS "_\|_check_limit" .IX Subsection "__check_limit" .Vb 1 \& _\|_check_limit(data => \e@data, limit => $param{limit}); .Ve .PP Checks to make sure that bugs match any limits; each entry of \f(CW@data\fR much satisfy the limit. .PP Returns true if there are no entries in data, or there are no keys in limit; returns false (0) if there are any entries which do not match. .PP The limit hashref elements can contain an arrayref of scalars to match; regexes are also acccepted. At least one of the entries in each element needs to match the corresponding field in all data for the limit to succeed. .SS "die" .IX Subsection "die" .Vb 1 \& sig_die "foo" .Ve .PP We override die to specially handle unlocking files in the cases where we are called via eval. [If we're not called via eval, it doesn't matter.]