Pianificazione di un pianificatore di revisione del codice Python conservazione delle informazioni di revisione

Nella seconda parte di questa serie, hai visto come raccogliere le informazioni di commit dai log git e inviare le richieste di revisione agli sviluppatori casuali selezionati dall'elenco dei membri del progetto.

In questa parte, vedrai come salvare le informazioni sulla revisione del codice da seguire ogni volta che viene eseguito il programma di pianificazione del codice. Vedrai anche come leggere le email per verificare se il revisore ha risposto alla richiesta di revisione.

Iniziare

Inizia clonando il codice sorgente dalla seconda parte della serie di tutorial.

git clone https://github.com/royagasthyan/CodeReviewer-Part2 CodeReviewer

Modifica il config.json file per includere alcuni indirizzi e-mail pertinenti, mantenendo il file [email protected] indirizzo email. È perché il git ha commit relativi al particolare indirizzo email che è necessario che il codice esegua come previsto. Modifica il SMTP credenziali nel schedule.py file:

FROM_EMAIL = "[email protected]" FROM_PWD = "tua_password"

Passare alla directory del progetto CodeReviewer e prova ad eseguire il seguente comando nel terminale.

python scheduler.py -n 20 -p "project_x"

Dovrebbe inviare la richiesta di revisione del codice agli sviluppatori casuali per la revisione.

Mantenere le informazioni sulla richiesta di revisione

Per seguire le informazioni sulla richiesta di revisione, è necessario tenerlo da qualche parte per riferimento. È possibile selezionare dove si desidera mantenere le informazioni sulla richiesta di revisione del codice. Può essere qualsiasi database o può essere un file. Per motivi di questo tutorial, terremo le informazioni sulla richiesta di revisione all'interno di a reviewer.json file. Ogni volta che viene eseguito lo scheduler, controllerà il file di informazioni per dare seguito alle richieste di revisione a cui non è stata data risposta.

Crea un metodo chiamato save_review_info che salverà le informazioni sulla richiesta di revisione all'interno di un file. Dentro il save_review_info metodo, creare un Informazioni oggetto con il revisore, soggetto e un unico ID.

def save_review_info (reviewer, subject): info = 'reviewer': reviewer, 'subject': subject, 'id': str (uuid.uuid4 ()), 'sendDate': str (datetime.date.today ()) 

Per un ID univoco, importa il uuid Modulo Python.

importa uuid

Hai anche bisogno del appuntamento Modulo Python per ottenere la data corrente. Importa il appuntamento Modulo Python.

importa datetime

È necessario inizializzare il reviewer.json file quando il programma si avvia se non esiste già.

se non os.path.exists ('reviewer.json'): con open ('reviewer.json', 'w +') come outfile: json.dump ([], outfile)

Se il file non esiste, è necessario creare un file chiamato reviewer.json e riempirlo con un array JSON vuoto come si vede nel codice sopra.

Questo metodo verrà chiamato ogni volta che viene inviata una richiesta di revisione. Quindi, dentro save_review_info metodo, apri il reviewer.json file in modalità lettura e leggere il contenuto. Aggiungi le nuove informazioni sul contenuto nel contenuto esistente e riscrivilo nel reviewer.json file. Ecco come apparirà il codice:

def save_review_info (reviewer, subject): info = 'reviewer': reviewer, 'subject': subject, 'id': str (uuid.uuid4 ()), 'sendDate': str (datetime.date.today ())  con open ('reviewer.json', 'r') come infile: review_data = json.load (infile) review_data.append (informazioni) con open ('reviewer.json', 'w') come outfile: json.dump (review_data, outfile)

Dentro il schedule_review_request metodo, prima di inviare la richiesta di revisione del codice, chiamare il save_review_info metodo per salvare le informazioni di revisione.

def schedule_review_request (commit): date = time.strftime ("% Y-% m-% d") per il commit in commit: reviewer = select_reviewer (commit.Author, project_members) subject = date + "Code Review [commit:" + commit.Id + "]" body = "Hello" "+ reviewer +" ", sei stato selezionato per rivedere il codice per commit \ n" body + = "fatto da" "+ commit.Author +" '. \ n "body + =" \ n "body + = format_review_commit (commit) save_review_info (revisore, soggetto); send_email (recensore, oggetto, corpo)

Salvare le modifiche precedenti ed eseguire il programma di pianificazione. Una volta eseguito lo scheduler, dovresti essere in grado di visualizzare il reviewer.json file all'interno della directory del progetto con le informazioni sulla richiesta di revisione del codice. Ecco come apparirebbe:

["revisore": "[email protected]", "id": "8ca7da84-9da7-4a17-9843-be293ea8202c", "sendDate": "2017-02-24", "oggetto": "2017-02 -24 Revisione codice [commit: 16393106c944981f57b2b48a9180a33e217faacc] ", " revisore ":" [email protected] "," id ":" 68765291-1891-4b50-886e-e30ab41a8810 "," sendDate ":" 2017-02- 24 "," subject ":" 2017-02-24 Code Review [commit: 04d11e21fb625215c5e672a93d955f4a176e16e4] "]

Leggere i dati dell'email

Hai raccolto tutte le informazioni sulla richiesta di revisione del codice e salvato in reviewer.json file. Ora, ogni volta che si esegue lo scheduler, è necessario controllare la posta in arrivo per vedere se il revisore ha risposto alla richiesta di revisione del codice. Quindi per prima cosa devi definire un metodo per leggere la tua posta in arrivo di Gmail.

Crea un metodo chiamato read_email che richiede il numero di giorni per controllare la posta in arrivo come parametro. Farai uso di imaplib Modulo Python per leggere la casella di posta elettronica. Importa il imaplib Modulo Python:

Importa Imaplib

Per leggere l'email usando il imaplib modulo, è necessario prima creare il server.

email_server = imaplib.IMAP4_SSL (SERVER)

Accedi al server utilizzando l'indirizzo email e la password:

email_server.login (FROM_EMAIL, FROM_PWD)

Una volta effettuato l'accesso, seleziona la posta in arrivo per leggere le e-mail:

email_server.select ( 'Posta in arrivo')

Leggere le email per il n numero di giorni trascorsi da quando è stata inviata la richiesta di revisione del codice. Importa il timedelta Modulo Python. 

import timedelta

Crea la data dell'email come mostrato:

email_date = datetime.date.today () - timedelta (days = num_days) formatted_date = email_date.strftime ('% d-% b-% Y')

Usando il FORMATTED_DATE, cercare nel server di posta elettronica le e-mail.

typ, data = email_server.search (None, '(SINCE "' + formatted_date + '")')

Restituirà gli ID univoci per ciascuna e-mail e utilizzando gli ID univoci è possibile ottenere i dettagli dell'email.

ids = dati [0] id_list = ids.split () first_email_id = int (id_list [0]) last_email_id = int (id_list [-1])

Ora farai uso di first_email_id e il last_email_id per scorrere le e-mail e recuperare il soggetto e l'indirizzo "da" delle e-mail.

per i in intervallo (last_email_id, first_email_id, -1): typ, data = email_server.fetch (i, '(RFC822)')

dati conterrà il contenuto dell'email, quindi itererà la parte dei dati e controllerà una tupla. Utilizzerai il modulo email di Python per estrarre i dettagli. Quindi importa il e-mail Modulo Python. 

importa email

Puoi estrarre l'oggetto dell'email e l'indirizzo "da" come mostrato:

per response_part nei dati: if isinstance (response_part, tuple): msg = email.message_from_string (response_part [1]) stampa 'From:' + msg ['from'] print '\ n' print 'Oggetto:' + msg [' subject '] print' \ n 'print' ---------------------------------------- --------'

Ecco il completo read_email metodo:

def read_email (num_days): prova: email_server = imaplib.IMAP4_SSL (SERVER) email_server.login (FROM_EMAIL, FROM_PWD) email_server.select ('inbox') email_date = datetime.date.today () - timedelta (days = num_days) formatted_date = email_date.strftime ('% d-% b-% Y') typ, data = email_server.search (None, '(SINCE "' + formatted_date + '")') ids = dati [0] id_list = ids.split ( ) first_email_id = int (id_list [0]) last_email_id = int (id_list [-1]) per i in intervallo (last_email_id, first_email_id, -1): typ, data = email_server.fetch (i, '(RFC822)') per response_part in data: if isinstance (response_part, tuple): msg = email.message_from_string (response_part [1]) stampa 'From:' + msg ['from'] print '\ n' print 'Oggetto:' + msg ['oggetto '] stampa' \ n 'stampa' ----------------------------------------- ------- 'tranne Eccezione, e: print str (e)

Salvare le modifiche precedenti e provare a eseguire quanto sopra read_email metodo:

read_email (1)

Dovrebbe stampare l'oggetto dell'email e l'indirizzo "from" sul terminale. 

Ora raccogliamo l'indirizzo "da" e l'oggetto in un email_info elencare e restituire i dati. 

email_info = []

Invece di stampare il soggetto e l'indirizzo "da", aggiungere i dati al file email_info elencare e restituire il email_info elenco.

email_info.append ( 'From': msg [ 'da'], 'Oggetto':. msg [ 'subject'] sostituire ( "\ r \ n", ""))

Ecco la modifica read_email metodo:

def read_email (num_days): try: email_info = [] email_server = imaplib.IMAP4_SSL (SERVER) email_server.login (FROM_EMAIL, FROM_PWD) email_server.select ('inbox') email_date = datetime.date.today () - timedelta (giorni = num_days) formatted_date = email_date.strftime ('% d-% b-% Y') typ, data = email_server.search (None, '(SINCE "' + formatted_date + '")') ids = data [0] id_list = ids.split () first_email_id = int (id_list [0]) last_email_id = int (id_list [-1]) per i in intervallo (last_email_id, first_email_id, -1): typ, data = email_server.fetch (i, '(RFC822 ) ') per response_part nei dati: if isinstance (response_part, tuple): msg = email.message_from_string (response_part [1]) email_info.append (' From ': msg [' from '],' Subject ': msg [' oggetto ']. replace ("\ r \ n", "")) eccetto Exception, e: print str (e) return email_info

Aggiunta della registrazione per la gestione degli errori

La gestione degli errori è un aspetto importante dello sviluppo del software. È davvero utile durante la fase di debug per tracciare i bug. Se non si gestisce l'errore, diventa molto difficile monitorare l'errore. Dato che stai crescendo con un paio di nuovi metodi, penso che sia il momento giusto per aggiungere la gestione degli errori al codice dello schedulatore.

Per iniziare con la gestione degli errori, avrai bisogno del registrazione Modulo Python e il RotatingFileHandler classe. Importali come mostrato:

importazione registrazione da logging.handlers import RotatingFileHandler

Una volta che hai le importazioni richieste, inizializza il registratore come mostrato:

logger = logging.getLogger ("Code Review Log") logger.setLevel (logging.INFO)

Nel codice precedente, è stato inizializzato il registratore e impostato il livello di registro su INFO. 

Creare un gestore di file di registro rotante che creerà un nuovo file ogni volta che il file di registro ha raggiunto la dimensione massima.

logHandler = RotatingFileHandler ('app.log', maxBytes = 3000, backupCount = 2)

Allegare il logHandler al logger oggetto.

logger.addHandler (logHandler)

Aggiungiamo il logger degli errori per registrare gli errori quando viene rilevata un'eccezione. Nel read_email parte dell'eccezione del metodo, aggiungere il seguente codice:

logger.error (str (datetime.datetime.now ()) + "- Errore durante la lettura della mail:" + str (e) + "\ n") logger.exception (str (e))

La prima riga registra il messaggio di errore con la data e l'ora correnti nel file di registro. La seconda riga registra la traccia dello stack sull'errore. 

Allo stesso modo, è possibile aggiungere la gestione degli errori alla parte principale del codice. Ecco come apparirà il codice con la gestione degli errori:

try: commits = process_commits () if len (commit) == 0: print 'No commit found' else: schedule_review_request (commit) tranne Exception, e: print 'Si è verificato un errore. Controlla il registro per i dettagli. ' logger.error (str (datetime.datetime.now ()) + "- Errore durante la lettura della mail:" + str (e) + "\ n") logger.exception (str (e))

Avvolgendolo

In questa parte della serie hai accantonato le informazioni sulla richiesta di revisione nel file reviewer.json file. Hai anche creato un metodo per leggere le email. Utilizzerai entrambe queste funzioni per dare seguito alle richieste di revisione del codice nella parte finale di questa serie.

Inoltre, non esitare a vedere ciò che abbiamo a disposizione per la vendita e per studiare nel mercato, e non esitare a fare domande e fornire il tuo prezioso feedback utilizzando il feed qui sotto.

Il codice sorgente di questo tutorial è disponibile su GitHub.

Fateci sapere i vostri pensieri e suggerimenti nei commenti qui sotto.