Analisi delle richieste di unione in GitLab utilizzando PVS-Studio per C#

Analisi delle richieste di unione in GitLab utilizzando PVS-Studio per C#
Ami GitLab e odi i bug? Vuoi migliorare la qualità del tuo codice sorgente? Allora sei nel posto giusto. Oggi ti spiegheremo come configurare l'analizzatore C# di PVS-Studio per verificare le richieste di unione. Buon mood da unicorno e buona lettura a tutti.

Studio PVS è uno strumento per identificare errori e potenziali vulnerabilità nel codice sorgente di programmi scritti in C, C++, C# e Java. Funziona su sistemi a 64 bit su Windows, Linux e macOS. Può analizzare il codice progettato per piattaforme ARM a 32 bit, 64 bit e integrate.

A proposito, abbiamo rilasciato PVS-Studio 7.08, in cui abbiamo fatto molte cose interessante. Ad esempio:

  • Analizzatore C# per Linux e macOS;
  • plugin per Rider;
  • nuova modalità di controllo dell'elenco dei file.

Modalità di controllo dell'elenco dei file

In precedenza, per controllare determinati file, era necessario passare all'analizzatore un file .xml con l'elenco dei file. Ma poiché questo non è molto conveniente, abbiamo aggiunto la possibilità di trasferire .txt, il che rende la vita molto semplice.

Per controllare file specifici, è necessario specificare il flag --file sorgenti (-f) e trasferisci il file .txt con l'elenco dei file. Sembra questo:

pvs-studio-dotnet -t path/to/solution.sln -f fileList.txt -o project.json

Se sei interessato a impostare il controllo del commit o le richieste pull, puoi farlo anche utilizzando questa modalità. La differenza sta nell'ottenere un elenco di file da analizzare e dipenderà dal sistema che stai utilizzando.

Il principio di controllo di una richiesta di fusione

L'essenza principale del controllo è garantire che i problemi rilevati dall'analizzatore durante la fusione non rientrino nel file Mastercard ramo. Inoltre, non vogliamo analizzare ogni volta l’intero progetto. Inoltre, quando uniamo i rami, abbiamo un elenco dei file modificati. Pertanto, suggerisco di aggiungere un controllo della richiesta di unione.

Ecco come appare una richiesta di unione prima di implementare un analizzatore statico:

Analisi delle richieste di unione in GitLab utilizzando PVS-Studio per C#
Cioè, tutti gli errori presenti nel ramo i cambiamenti, si sposterà nel ramo principale. Dato che non lo vorremmo, aggiungiamo l'analisi e ora il diagramma appare così:

Analisi delle richieste di unione in GitLab utilizzando PVS-Studio per C#
Analizzando modifiche2 e, se non ci sono errori, accettiamo la richiesta di fusione, altrimenti la rifiutiamo.

A proposito, se sei interessato ad analizzare commit e pull request per C/C++, puoi leggere informazioni a riguardo qui.

GitLab

GitLab è uno strumento per il ciclo di vita DevOps basato sul web open source che fornisce un sistema di gestione del repository di codice per Git con la propria wiki, sistema di tracciamento dei problemi, pipeline CI/CD e altre funzionalità.

Prima di iniziare ad analizzare le richieste di fusione, devi registrarti e caricare il tuo progetto. Se non sai come farlo, allora ti suggerisco Articolo il mio collega.

Nota. Il metodo di configurazione dell'ambiente descritto di seguito è uno dei possibili. L'obiettivo è mostrare i passaggi per configurare l'ambiente necessario per l'analisi e avviare l'analizzatore. Forse nel tuo caso sarebbe più ottimale separare le fasi di preparazione dell'ambiente (aggiunta di repository, installazione di un analizzatore) e analisi: ad esempio, preparare le immagini Docker con l'ambiente necessario e utilizzarle, o qualche altro metodo.

Per comprendere meglio cosa accadrà ora, suggerisco di guardare il seguente diagramma:

Analisi delle richieste di unione in GitLab utilizzando PVS-Studio per C#
L'analizzatore richiede .NET Core SDK 3 per funzionare, quindi prima di installare l'analizzatore è necessario aggiungere i repository Microsoft da cui verranno installate le dipendenze richieste per l'analizzatore. Aggiunta di repository Microsoft per varie distribuzioni Linux descritto nel documento corrispondente.

Per installare PVS-Studio tramite il gestore pacchetti, dovrai anche aggiungere i repository PVS-Studio. L'aggiunta di repository per diverse distribuzioni è descritta in maggior dettaglio in sezione pertinente della documentazione.

L'analizzatore richiede una chiave di licenza per funzionare. Puoi ottenere una licenza di prova su pagina di download dell'analizzatore.

Nota. Si prega di notare che la modalità operativa descritta (analisi delle richieste di fusione) richiede una licenza Enterprise. Pertanto, se vuoi provare questa modalità di funzionamento, non dimenticare di indicare nel campo “Messaggio” che hai bisogno di una licenza Enterprise.

Se si verifica una richiesta di unione, dobbiamo analizzare solo l'elenco dei file modificati, altrimenti analizziamo tutti i file. Dopo l'analisi, dobbiamo convertire i log nel formato di cui abbiamo bisogno.

Ora, avendo l'algoritmo di lavoro davanti ai tuoi occhi, puoi procedere alla scrittura di una sceneggiatura. Per fare ciò, è necessario modificare il file .gitlab-ci.yml oppure, se non esiste, crealo. Per crearlo, devi cliccare sul nome del tuo progetto -> Configura CI/CD.

Analisi delle richieste di unione in GitLab utilizzando PVS-Studio per C#
Ora siamo pronti per scrivere la sceneggiatura. Scriviamo prima il codice che installerà l'analizzatore e inseriamo la licenza:

before_script:
  - apt-get update && apt-get -y install wget gnupg 

  - apt-get -y install git
  - wget https://packages.microsoft.com/config/debian/10/
packages-microsoft-prod.deb -O packages-microsoft-prod.deb
  - dpkg -i packages-microsoft-prod.deb
  - apt-get update
  - apt-get install apt-transport-https
  - apt-get update
  
  - wget -q -O - https://files.viva64.com/etc/pubkey.txt | apt-key add -
  - wget -O /etc/apt/sources.list.d/viva64.list
https://files.viva64.com/etc/viva64.list
  - apt-get update
  - apt-get -y install pvs-studio-dotnet

  - pvs-studio-analyzer credentials $PVS_NAME $PVS_KEY
  - dotnet restore "$CI_PROJECT_DIR"/Test/Test.sln

Poiché l'installazione e l'attivazione devono avvenire prima di tutti gli altri script, utilizziamo un'etichetta speciale prima_script. Lasciatemi spiegare un po' questo frammento.

Preparazione all'installazione dell'analizzatore:

  - wget https://packages.microsoft.com/config/debian/10/
packages-microsoft-prod.deb -O packages-microsoft-prod.deb
  - dpkg -i packages-microsoft-prod.deb
  - apt-get update
  - apt-get install apt-transport-https
  - apt-get update

Aggiunta di repository e analizzatore PVS-Studio:

  - wget -q -O - https://files.viva64.com/etc/pubkey.txt | apt-key add -
  - wget -O /etc/apt/sources.list.d/viva64.list
https://files.viva64.com/etc/viva64.list
  - apt-get update
  - apt-get -y install pvs-studio-dotnet

Attivazione della licenza:

  - pvs-studio-analyzer credentials $PVS_NAME $PVS_KEY

$PVS_NAME - Nome utente.

$PVS_KEY - chiave del prodotto.

Recupero delle dipendenze del progetto dove $CI_PROJECT_DIR – percorso completo della directory del progetto:

  - dotnet restore "$CI_PROJECT_DIR"/Path/To/Solution.sln

Per una corretta analisi, è necessario che il progetto venga compilato correttamente e che le sue dipendenze siano ripristinate (ad esempio, devono essere scaricati i pacchetti NuGet necessari).

È possibile impostare variabili di ambiente contenenti informazioni sulla licenza facendo clic su Configurazione, e dopo - su CI/CD.

Analisi delle richieste di unione in GitLab utilizzando PVS-Studio per C#
Nella finestra che si apre, trova l'oggetto Variabili, fare clic sul pulsante a destra Espandere e aggiungere variabili. Il risultato dovrebbe assomigliare a questo:

Analisi delle richieste di unione in GitLab utilizzando PVS-Studio per C#
Ora puoi passare all'analisi. Innanzitutto, aggiungiamo uno script per un'analisi completa. Alla bandiera -t passiamo il percorso verso la soluzione alla bandiera -o scrivere il percorso del file in cui verranno scritti i risultati dell'analisi. Siamo interessati anche al codice di ritorno. In questo caso, siamo interessati che l'operazione si interrompa quando il codice restituito contiene informazioni sugli avvisi emessi durante l'analisi. Ecco come appare questo frammento:

job:
  script:
  - exit_code=0
  - pvs-studio-dotnet -t "$CI_PROJECT_DIR"/Test/Test.sln -o 
PVS-Studio.json || exit_code=$?
  - exit_code=$((($exit_code & 8)/8))
  - if [[ $exit_code == 1 ]]; then exit 1; else exit 0; fi

I codici di ritorno funzionano secondo il principio di una maschera di bit. Ad esempio, se a seguito dell'analisi sono stati emessi degli warning, allora il codice restituito sarà pari a 8. Se la licenza scade entro un mese, allora il codice restituito sarà pari a 4. Se durante l'analisi sono stati rilevati errori, e la licenza scade entro un mese, nel codice restituito verranno scritti entrambi i valori: somma i numeri e ottieni il codice restituito finale - 8+4=12. Pertanto, controllando i bit corrispondenti, durante l'analisi è possibile ottenere informazioni sui vari stati. I codici di ritorno sono descritti più dettagliatamente nella sezione "Codici di ritorno pvs-studio-dotnet (Linux/macOS)" del documento"Controllo dei progetti Visual Studio/MSBuild/.NET Core dalla riga di comando utilizzando PVS-Studio".

In questo caso siamo interessati a tutti i codici di ritorno in cui appare 8.

  - exit_code=$((($exit_code & 8)/8))

Riceveremo 1 quando il codice di ritorno contiene il bit del numero che ci interessa, altrimenti riceveremo 0.

È giunto il momento di aggiungere l'analisi delle richieste di unione. Prima di farlo, prepariamo un posto per la sceneggiatura. Abbiamo bisogno che venga eseguito solo quando si verifica una richiesta di unione. Sembra questo:

merge:
  script:
  only:
  - merge_requests

Passiamo allo script stesso. Mi sono trovato di fronte al fatto che la macchina virtuale non sa nulla origine/maestro. Allora aiutiamola un po':

  - git fetch origin

Ora otteniamo la differenza tra i rami e salviamo il risultato txt file:

  - git diff --name-only origin/master $CI_COMMIT_SHA > pvs-fl.txt

Где $CI_COMMIT_SHA – hash dell'ultimo commit.

Successivamente, iniziamo ad analizzare l'elenco dei file utilizzando il flag -f. Trasferiamo ad esso il file .txt ricevuto in precedenza. Bene, per analogia con l'analisi completa, esaminiamo i codici di ritorno:

  - exit_code=0
  - pvs-studio-dotnet -t "$CI_PROJECT_DIR"/Test/Test.sln -f 
pvs-fl.txt -o PVS-Studio.json || exit_code=$?
  - exit_code=$((($exit_code & 8)/8))
  - if [[ $exit_code == 1 ]]; then exit 1; else exit 0; fi

Lo script completo per controllare una richiesta di unione sarà simile al seguente:

merge:
  script:
  - git fetch origin
  - git diff --name-only origin/master $CI_COMMIT_SHA > pvs-fl.txt
  - exit_code=0
  - pvs-studio-dotnet -t "$CI_PROJECT_DIR"/Test/Test.sln -f 
pvs-fl.txt -o PVS-Studio.json || exit_code=$?
  - exit_code=$((($exit_code & 8)/8))
  - if [[ $exit_code == 1 ]]; then exit 1; else exit 0; fi
  only:
  - merge_requests

Tutto ciò che resta è aggiungere la conversione del registro dopo che tutti gli script sono stati elaborati. Usiamo l'etichetta after_script e utilità convertitore di plog:

after_script:
  - plog-converter -t html -o eLog ./PVS-Studio.json

Utilità convertitore di plog è un progetto open source utilizzato per convertire i rapporti sugli errori del parser in varie forme, come HTML. Una descrizione più dettagliata dell'utilità è fornita nella sottosezione "Utilità Plog Converter" sezione pertinente della documentazione.

A proposito, se vuoi lavorare comodamente con i report .json localmente dall'IDE, allora suggerisco il nostro plug-in per IDE Rider. Il suo utilizzo è descritto più dettagliatamente in documento pertinente.

Per comodità, eccolo qui .gitlab-ci.yml in toto:

image: debian

before_script:
  - apt-get update && apt-get -y install wget gnupg 

  - apt-get -y install git
  - wget https://packages.microsoft.com/config/debian/10/
packages-microsoft-prod.deb -O packages-microsoft-prod.deb
  - dpkg -i packages-microsoft-prod.deb
  - apt-get update
  - apt-get install apt-transport-https
  - apt-get update
  
  - wget -q -O - https://files.viva64.com/etc/pubkey.txt | apt-key add -
  - wget -O /etc/apt/sources.list.d/viva64.list
https://files.viva64.com/etc/viva64.list
  - apt-get update
  - apt-get -y install pvs-studio-dotnet

  - pvs-studio-analyzer credentials $PVS_NAME $PVS_KEY
  - dotnet restore "$CI_PROJECT_DIR"/Test/Test.sln

merge:
  script:
  - git fetch origin
  - git diff --name-only origin/master $CI_COMMIT_SHA > pvs-fl.txt
  - exit_code=0
  - pvs-studio-dotnet -t "$CI_PROJECT_DIR"/Test/Test.sln -f 
pvs-fl.txt -o PVS-Studio.json || exit_code=$?
  - exit_code=$((($exit_code & 8)/8))
  - if [[ $exit_code == 1 ]]; then exit 1; else exit 0; fi
  only:
  - merge_requests

job:
  script:
  - exit_code=0
  - pvs-studio-dotnet -t "$CI_PROJECT_DIR"/Test/Test.sln -o 
PVS-Studio.json || exit_code=$?
  - exit_code=$((($exit_code & 8)/8))
  - if [[ $exit_code == 1 ]]; then exit 1; else exit 0; fi
  
after_script:
  - plog-converter -t html -o eLog ./PVS-Studio.json

Una volta aggiunto tutto al file, fare clic su Conferma modifiche. Per vedere che tutto sia corretto, vai a CI / CD -> Condotte -> corsa. Si aprirà la finestra della macchina virtuale, al termine della quale dovrebbe esserci quanto segue:

Analisi delle richieste di unione in GitLab utilizzando PVS-Studio per C#
sega Il lavoro è riuscito - successo, va tutto bene. Ora puoi testare ciò che hai fatto.

Esempi di lavoro

Per un esempio di lavoro, creiamo un semplice progetto (in Mastercard) che conterrà diversi file. Successivamente, in un altro ramo modificheremo solo un file e proveremo a effettuare una richiesta di unione.

Consideriamo due casi: quando il file modificato contiene un errore e quando no. Innanzitutto, un esempio con un errore.

Diciamo che c'è un file nel ramo master Programma.cs, che non contiene errori, ma in un altro ramo lo sviluppatore ha aggiunto codice errato e desidera effettuare una richiesta di unione. Che tipo di errore ha commesso non è così importante, l'importante è che esista. Ad esempio, l'operatore ha dimenticato gettare (Sì, così sbagliato):

void MyAwesomeMethod(String name)
{
  if (name == null)
    new ArgumentNullException(....);
  // do something
  ....
}

Diamo un'occhiata al risultato dell'analisi di un esempio con un errore. Inoltre, per assicurarmi che fosse analizzato un solo file, ho aggiunto il flag -r alla linea di lancio pvs-studio-dotnet:

Analisi delle richieste di unione in GitLab utilizzando PVS-Studio per C#
Vediamo che l'analizzatore ha trovato un errore e non ha consentito l'unione dei rami.

Controlliamo l'esempio senza errori. Correzione del codice:

void MyAwesomeMethod(String name)
{
  if (name == null)
    throw new ArgumentNullException(....);
  // do something
  ....
}

Risultati dell'analisi della richiesta di unione:

Analisi delle richieste di unione in GitLab utilizzando PVS-Studio per C#
Come possiamo vedere, non sono stati trovati errori e l'esecuzione dell'attività è andata a buon fine, che è ciò che volevamo verificare.

conclusione

Eliminare il codice errato prima di unire i rami è molto comodo e piacevole. Pertanto, se utilizzi CI/CD, prova a incorporare un analizzatore statico per verificare. Inoltre, questo viene fatto in modo abbastanza semplice.

Grazie per la vostra attenzione.

Analisi delle richieste di unione in GitLab utilizzando PVS-Studio per C#
Se desideri condividere questo articolo con un pubblico di lingua inglese, utilizza il link di traduzione: Nikolay Mironov. Analisi delle richieste di unione in GitLab utilizzando PVS-Studio per C#.

Fonte: habr.com

Aggiungi un commento