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.
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.
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] "]
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
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))
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.