#!/usr/bin/perl -w #********************** Partie a modifier **********************# #Pour accéder aux fonctions définies dans Bugzilla #On utilise les fonctions ConnectToDatabase(), SendSQL(), #FetchOneColumn(), FetchSQLData(), SqlQuote() et MoreSQLData() #du fichier globals.pl de Bugzilla use lib '/www/bugzillacvs'; #This variable indicates the path to use Bugzilla functions. #variable globale à modifier si nécessaire pour indiquer le chemin #jusqu'aux fichiers de configuration de Bugzilla. $bugzilla_path = "/www/bugzillacvs"; #***************************************************************# require "globals.pl"; ############### Global Variables #The variable below contains the name of the user used for identification #in Bugzilla. $name = scalar(getpwuid($>)); #This number is set in order to make fail the comparison with a Bugzilla #valide number. $UNEXISTING_NUMBER = -123546; #Number of fields in the transaction table $nbFields = 5; #List of the states existing in the state table #The state table contains a description of each state. $STATE0 = 0; $STATE1 = 1; $STATE2 = 2; $STATE3 = 3; $STATE4 = 4; ############### Request #SELECT ############### #Selection of optional unfinished transaction $SelectPrecedingTransaction = "SELECT * FROM arxtransaction WHERE ". "assigned_to = '$name' AND state <> $STATE4 ORDER BY num"; $SelectCurrentTransaction = "SELECT num, date FROM arxtransaction WHERE ". "assigned_to = '$name' AND state = $STATE0 ORDER BY num DESC"; sub SelectBugStatus { my ($bug_id) = @_; &SendSQL("SELECT bug_status FROM bugs WHERE bug_id = '$bug_id'"); $oldstat = &FetchOneColumn(); return $oldstat; } sub SelectNumDateBug { my ($num) = @_; &SendSQL("SELECT bug_id, date FROM arxtransaction WHERE num = '$num'"); @numbugDate = &FetchSQLData(); return @numbugDate; } #INSERT ############### #Inserts values for state $STATE0 in the transaction table $insertState0 = "INSERT INTO arxtransaction (date, assigned_to, state) ". "VALUES (NOW(), '$name', $STATE0)"; #UPDATE ############### sub UpdateState { my ($num, $state) = @_; &SendSQL("UPDATE arxtransaction set date = NOW(), state = '$state' ". "WHERE num = '$num'"); } #DELETE ############### #Deletes all the lines in the arxtransaction table corresponding to the current #transaction sub DeleteFailedTransaction { my ($num) = @_; &SendSQL("DELETE FROM arxtransaction WHERE assigned_to = '$name' ". "AND num = '$num'"); } sub DeleteCurrentTransaction { my ($state) = @_; &SendSQL("SELECT num FROM arxtransaction WHERE assigned_to ". "='$name' AND state = '$state' ORDER BY num DESC LIMIT 1"); $numTransaction = &FetchOneColumn(); if ($numTransaction){ &SendSQL("DELETE FROM arxtransaction WHERE num = ". "'$numTransaction'"); } } #LOCK UNLOCK ############### #Request for blocking writing in the transaction table $lockTransaction = "LOCK TABLES arxtransaction WRITE"; #Deblocking the tables locked by the current thread $unlock = "UNLOCK TABLES"; ############### Warning messages #Message for the state 0 and 1.(add the version number?) sub WarningState { my ($date) = @_; print "The attempt at recording some files has failed\n". "the $date.\nNothing has been recorded in ArX ". "nor in Bugzilla.\nBeginning of the next transaction...\n"; } #ArX has been modified and not Bugzilla. In order to stay consistent, Bugzilla #must be updated. sub UpdateBugzillaMessage { my ($bug_number) = @_; print "During the preceding transaction, ArX has been ". "updated and not Bugzilla for the bug number $bug_number.\n". "Updating Bugzilla...\n"; } $EndUpdating = "End of the update.\n"; $success = "The transaction has finished successfully!\n"; ############### Interruption messages (with the die command) #The user is not assigned to the bug in Bugzilla sub DieMessageNotAllowed { my ($bug_number) = @_; print "You are not allowed to modify the status of this ". "bug number $bug_number\n". "The commit command is canceled\n"; exit(1); } #The bug entered does not exist sub DieMessageNotExistingBug { my ($bug_number) = @_; print "This bug number $bug_number does not exist for Bugzilla\n". "The commit command is canceled\n"; exit(1); } #A simultaneous transaction has been detected sub DieMsgSimulTransaction { die "A simultaneous transaction has been detected, please try again \n". "to record your files"; } sub DieUnknownPb { die "An unknown problem occured during or before the commit command.\n". "Please, check the status of your files in ArX and Bugzilla ". "before continuing.\n"; } ############### Functions used in the script sub RechercheNumBug { #On utilise la valeur de retour de arx make-log pour avoir le nom #du fichier. On suppose donc que la commande arx make-log a déjà été #appelée par l'utilisateur au moins une fois pour rentrer son message #de description. ($file) = @_; unless (open(MESSAGE, "$file")) { print "Sorry, it is impossible to execute the commit command ". "as the file\n$file is not readable\n"; exit(1); } #On met le message de description dans une seule ligne while ($ligne = ){ chop($ligne); $comment .= "$ligne "; } close(MESSAGE); #system "echo $comment >> /home/quenouil/src3/bprojet/temp001"; #On récupère le numéro de bug s'il y en a un if ($comment =~ /\bbug\s*\#?\s*\d+/i){ $num_bug = $&; $num_bug =~ s/\D*//; return $num_bug; } else { return 0; } } sub LeNumeroExiste { ($num_bug) = @_; #Cette fonction vérifie que le numéro de bug saisi est bien un #numéro de bug existant dans Bugzilla &ConnectToDatabase(); &SendSQL($unlock); &SendSQL("SELECT bug_id FROM bugs WHERE bug_id='$num_bug'"); my $num = &FetchOneColumn(); if (!$num){ $num = $UNEXISTING_NUMBER; } if ($num == $num_bug){ return 1; } else { return 0; } } sub LeStatusEstModifiable { ($num_bug) = @_; #On vérifie que le status associé à ce bug est dans l'un des trois #états suivant : NEW, ASSIGNED, REOPENED. Ainsi il pourra devenir #RESOLVED $status = &SelectBugStatus($num_bug); if (($status eq "NEW") || ($status eq "ASSIGNED") || ($status eq "REOPENED")){ return 1; } elsif ($status eq "RESOLVED") { #On vide la table transaction en ce qui concerne l'utilisateur #car l'interruption du programme est volontaire &SendSQL($lockTransaction); &DeleteCurrentTransaction($STATE1); &SendSQL($unlock); print "The bug#$num_bug is already at the RESOLVED status\n". "The commit command is canceled\n"; exit (1); } else { #On vide la table transaction en ce qui concerne l'utilisateur #car l'interruption du programme est volontaire &SendSQL($lockTransaction); &DeleteCurrentTransaction($STATE1); &SendSQL($unlock); print "The bug#$num_bug can't be set to the RESOLVED status as ". "it is now at the $status status\n". "The commit command is canceled\n"; exit (1); } } sub PeutModifierLeStatus { ($num_bug) = @_; #On vérifie que la personne faisant le commit est bien autorisée #à  modifier le status du bug, pour cela elle doit être la #personne responsable du bug et donc être assigned to. #On vérifie que le nom obtenu est bien associé au bug à corriger &SendSQL("SELECT assigned_to FROM bugs WHERE bug_id='$num_bug'"); ($assigned_to_id) = &FetchOneColumn(); &SendSQL("SELECT login_name FROM profiles WHERE userid = '$assigned_to_id'"); $assigned_to_name = &FetchOneColumn(); #On compare le nom de la personne faisant le commit et celle responsable #du bug if ($assigned_to_name eq $name){ return 1; } else { return 0; } } sub ReprendModifieStatus { my($bug_id) = @_; #Le status final est automatiquement RESOLVED. #On place alors la résolution à la valeur FIXED. #Modification de la table bugs_activity #champs modifiés : #bug_when : datetime, fieldid=numéro du champs qui a été changé : #Numéro 8 pour le status, Numéro 11 pour la résolution. #On change d'abord le status &SendSQL($unlock); #On récupère le numéro associé à la personne faisant les modifications. &SendSQL("SELECT userid FROM profiles WHERE login_name = ". &SqlQuote($name).""); $user_id = &FetchOneColumn(); #On récupère l'ancien status &SendSQL("SELECT bug_status FROM bugs WHERE bug_id = '$bug_id'"); $statusold = &FetchOneColumn(); #On bloque les tables utilisées en écriture afin de faire #la mise à jour sans incident &SendSQL("LOCK TABLES bugs WRITE , bugs_activity WRITE"); &SendSQL("INSERT INTO bugs_activity (bug_id, who, bug_when, ". "fieldid, removed, added) VALUES ('$bug_id', '$user_id'". " , NOW(), 8 , ".&SqlQuote($statusold)." , 'RESOLVED')"); #On change ensuite la résolution #On récupère l'ancienne résolution, même si elle contient une chaine vide &SendSQL("SELECT resolution FROM bugs WHERE bug_id = '$bug_id'"); $oldresolution = &FetchOneColumn(); &SendSQL("INSERT INTO bugs_activity (bug_id, who, bug_when, ". "fieldid, removed, added) VALUES ('$bug_id', $user_id ". ", NOW(), 11, ".&SqlQuote($oldresolution).", 'FIXED')"); #Modification de la table bugs &SendSQL("UPDATE bugs SET bug_status='RESOLVED', delta_ts = NOW()". " , resolution = 'FIXED' WHERE bug_id = '$bug_id'"); #On débloque les tables une fois la mise à jour terminée &SendSQL($unlock); &SendSQL($lockTransaction); #Envoie des mails aux personnes concernées #la commande exec entraine le remplacement du processus courant par un #processus shell et donc sort du programme. Nous sommes donc obligés #d'utiliser ici la commande system. system("cd $bugzilla_path; ./processmail $bug_id > /tmp/mailcomment; ". "/bin/rm /tmp/mailcomment"); } sub ModifieStatus { my($bug_id) = @_; #Le status final est automatiquement RESOLVED. #On place alors la résolution à la valeur FIXED. #Modification de la table bugs_activity #champs modifiés : #bug_when : datetime, fieldid=numéro du champs qui a été changé : #Numéro 8 pour le status, Numéro 11 pour la résolution. #On change d'abord le status &SendSQL($unlock); #On récupère le numéro associé à la personne faisant les modifications. &SendSQL("SELECT userid FROM profiles WHERE login_name = ". &SqlQuote($name).""); $user_id = &FetchOneColumn(); #On récupère l'ancien status &SendSQL("SELECT bug_status FROM bugs WHERE bug_id = '$bug_id'"); $statusold = &FetchOneColumn(); #On bloque les tables utilisées en écriture afin de faire #la mise à jour sans incident &SendSQL("LOCK TABLES bugs WRITE , bugs_activity WRITE"); &SendSQL("INSERT INTO bugs_activity (bug_id, who, bug_when, ". "fieldid, removed, added) VALUES ('$bug_id', '$user_id'". " , NOW(), 8 , ".&SqlQuote($statusold)." , 'RESOLVED')"); #On change ensuite la résolution #On récupère l'ancienne résolution, même si elle contient une chaine vide &SendSQL("SELECT resolution FROM bugs WHERE bug_id = '$bug_id'"); $oldresolution = &FetchOneColumn(); &SendSQL("INSERT INTO bugs_activity (bug_id, who, bug_when, ". "fieldid, removed, added) VALUES ('$bug_id', $user_id ". ", NOW(), 11, ".&SqlQuote($oldresolution).", 'FIXED')"); #Modification de la table bugs &SendSQL("UPDATE bugs SET bug_status='RESOLVED', delta_ts = NOW()". " , resolution = 'FIXED' WHERE bug_id = '$bug_id'"); #On débloque les tables une fois la mise à jour terminée &SendSQL($unlock); &SendSQL($lockTransaction); #Envoie des mails aux personnes concernées #la commande exec entraine le remplacement du processus courant par un #processus shell et donc sort du programme. Nous sommes donc obligés #d'utiliser ici la commande system. system("cd $bugzilla_path; ./processmail $bug_id > /tmp/mailcomment; ". "/bin/rm /tmp/mailcomment"); }