
¿Te gusta GitLab y no te gustan los errores? ¿Quieres mejorar la calidad de tu código fuente? Entonces has venido al lugar correcto. Hoy te contaremos cómo configurar el analizador C# PVS-Studio para revisar solicitudes de fusión. Que tengas un ambiente lleno de unicornios y una buena lectura.
es una herramienta para detectar errores y vulnerabilidades potenciales en el código fuente de programas escritos en los lenguajes C, C++, C# y Java. Funciona en sistemas de 64 bits en Windows, Linux y macOS. Puede analizar código destinado a plataformas ARM de 32 bits, 64 bits e integradas.
Por cierto, hemos lanzado PVS-Studio 7.08, en el que hemos hecho muchas mejoras. Por ejemplo:
- analizador C# para Linux y macOS;
- plugin para Rider;
- nuevo modo de verificación de lista de archivos.
Modo de verificación de la lista de archivos
Antes, para verificar archivos específicos, era necesario pasar al analizador un .xml con la lista de archivos. Pero dado que esto no era muy conveniente, hemos añadido la posibilidad de pasar un .txt, lo que simplifica mucho las cosas.
Para verificar archivos específicos, es necesario indicar la bandera --sourceFiles (-f) y pasar un .txt con la lista de archivos. Se ve de la siguiente manera:
pvs-studio-dotnet -t path/to/solution.sln -f fileList.txt -o project.jsonSi te interesa configurar la verificación de commits o pull requests, también puedes hacerlo utilizando este modo. La diferencia radicará en cómo obtener la lista de archivos para análisis y dependerá de los sistemas que estés utilizando.
Principio de verificación de merge request.
La esencia de la verificación es que los problemas detectados por el analizador no deben entrar en la master rama durante la fusión. Tampoco queremos analizar todo el proyecto cada vez. Especialmente porque al fusionar ramas tenemos una lista de archivos modificados. Por eso propongo añadir la verificación de merge request.
Así es como se ve una solicitud de fusión antes de implementar el analizador estático:

Es decir, todos los errores que estaban en la rama changes, se transferirán a la rama principal. Dado que no queremos que esto suceda, añadimos el análisis, y ahora el esquema se ve de la siguiente manera:

Analizamos changes2 y, si no hay errores, aceptamos la solicitud de fusión, de lo contrario, la rechazamos.
Por cierto, si te interesa el análisis de commits y pull requests para C/C++, puedes leer sobre ello .
GitLab
es una herramienta web de ciclo de vida DevOps de código abierto, que representa un sistema de gestión de repositorios de código para Git con su propio wiki, sistema de seguimiento de errores, pipeline de CI/CD y otras funciones.
Antes de comenzar a implementar el análisis de los merge requests, es necesario registrarse y cargar su proyecto. Si no sabe cómo hacerlo, le propongo de mi colega.
Nota. El método que se describe a continuación para configurar el entorno es solo uno de los posibles. El objetivo es mostrar los pasos necesarios para configurar el entorno para el análisis y ejecutar el analizador. Puede que, en su caso, sea más óptimo separar las etapas de preparación del entorno (agregar repositorios, instalar el analizador) y del análisis: por ejemplo, preparar imágenes de Docker con el entorno necesario y usarlas o algún otro método.
Para entender mejor qué va a suceder, le propongo echar un vistazo al siguiente esquema:

Para que el analizador funcione, se requiere el SDK de .NET Core 3, por lo que antes de instalar el analizador, debe agregar los repositorios de Microsoft desde los cuales se instalarán las dependencias necesarias para el analizador. La adición de los repositorios de Microsoft para diferentes distribuciones de Linux .
Para instalar PVS-Studio a través del gestor de paquetes, también se requiere agregar los repositorios de PVS-Studio. La adición de los repositorios para diversas distribuciones se describe más detalladamente en .
Para que el analizador funcione, se necesita una clave de licencia. Se puede obtener una licencia de prueba en .
NotaTenga en cuenta que para el modo de operación descrito (análisis de merge requests) se necesita una licencia Enterprise. Por lo tanto, si desea probar este modo de trabajo, en el campo "Mensaje" no olvide indicar que necesita precisamente una licencia Enterprise.
Si se produce un merge request, solo necesitaremos analizar la lista de archivos modificados; de lo contrario, analizamos todos los archivos. Tras el análisis, debe convertir los registros al formato que necesitamos.
Ahora, teniendo ante nosotros el algoritmo de trabajo, podemos proceder a escribir el script. Para hacer esto, es necesario modificar el archivo .gitlab-ci.yml o, si no existe, crearlo. Para crearlo, debe hacer clic en el nombre de su proyecto -> Configurar CI/CD.

Ahora estamos listos para escribir el script. Comencemos escribiendo el código que instalará el analizador e introducirá la licencia:
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.slnDado que la instalación y activación deben realizarse antes de todos los demás scripts, utilizamos una etiqueta especial before_script. Permíteme aclarar este fragmento.
Preparativos para la instalación del analizador:
- 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 updateAdición de los repositorios de PVS-Studio y del analizador:
- 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-dotnetActivación de la licencia:
- pvs-studio-analyzer credentials $PVS_NAME $PVS_KEY$PVS_NAME — nombre de usuario.
$PVS_KEY — clave del producto.
Restauración de las dependencias del proyecto, donde $CI_PROJECT_DIR – ruta completa al directorio del proyecto:
- dotnet restore "$CI_PROJECT_DIR"/Path/To/Solution.slnPara un análisis correcto, el proyecto debe compilarse con éxito y sus dependencias deben restaurarse (por ejemplo, deben descargarse los paquetes NuGet necesarios).
Se pueden establecer variables de entorno que contengan información de la licencia haciendo clic en Configuración, y luego en Plataformas en la nube.

En la ventana que se abre, encontramos el elemento Variables, y a la derecha hacemos clic en el botón Expandir y añadimos las variables. El resultado debería ser el siguiente:

Ahora podemos pasar al análisis. Primero agreguemos el script para un análisis completo. En el flag -t pasamos la ruta a la solución, en el flag -o escribimos la ruta al archivo donde se guardarán los resultados del análisis. También nos interesa el código de retorno. En este caso, nos interesa que el proceso se detenga cuando el código de retorno contenga información de que se han emitido advertencias durante el análisis. Este es el aspecto de este fragmento:
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; fiLos códigos de retorno funcionan sobre la base de una máscara de bits. Por ejemplo, si se emitieron advertencias como resultado del análisis, el código de retorno será 8. Si la licencia expira en un mes, el código de retorno será 4. Si durante el análisis se encontraron errores y la licencia también expira en un mes, se registrarán ambos valores en el código de retorno: sumamos los números juntos y obtenemos el código de retorno final: 8+4=12. Así, al verificar los bits correspondientes, se puede obtener información sobre varios estados durante el análisis. Los códigos de retorno se describen más detalladamente en la sección "Códigos de retorno pvs-studio-dotnet (Linux / macOS)" del documento.".
En este caso, nos interesan todos los códigos de retorno que incluyen el 8.
- exit_code=$((($exit_code & 8)/8))Obtendremos 1 cuando el código de retorno contenga el bit que nos interesa, de lo contrario obtendremos 0.
Ha llegado el momento de agregar el análisis de la solicitud de fusión. Antes de hacerlo, preparemos el espacio para el script. Necesitamos que se ejecute solo cuando se produzca la solicitud de fusión. Se ve así:
merge:
script:
only:
- merge_requestsPasemos al propio script. Me encontré con que la máquina virtual no sabe nada sobre origin/master. Por lo tanto, le ayudamos un poco:
- git fetch originAhora obtendremos la diferencia de las ramas y guardaremos el resultado en txt archivo:
- git diff --name-only origin/master $CI_COMMIT_SHA > pvs-fl.txtDonde $CI_COMMIT_SHA – el hash del último commit.
A continuación, iniciamos el análisis de la lista de archivos usando la bandera -f. Le pasamos el archivo .txt obtenido anteriormente. Y de manera similar al análisis completo, observamos los códigos de retorno:
- 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; fiEl script completo para verificar la solicitud de fusión se verá así:
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_requestsSolo queda agregar la conversión del registro después de que todos los scripts se hayan ejecutado. Usamos la etiqueta after_script y la utilidad plog-converter:
after_script:
- plog-converter -t html -o eLog ./PVS-Studio.jsonUtilidad — es un proyecto de código abierto que se utiliza para transformar informes de errores del analizador en diversas formas, como HTML. Una descripción más detallada de la utilidad se presenta en la subsección "Utilidad Plog Converter". .
Por cierto, si deseas trabajar cómodamente con el informe .json localmente desde IDE, te sugiero nuestro para el IDE Rider. Su uso se describe más a fondo en .
Para mayor comodidad aquí está .gitlab-ci.yml completo:
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.jsonUna vez que hayamos añadido todo al archivo, hacemos clic en Commit changes.Para verificar que todo está correcto, ingresamos a CI/CD -> Pipelines. -> En ejecuciónSe abrirá una ventana de la máquina virtual, al final de la cual debería aparecer lo siguiente:

Vimos Job succeeded. – éxito, todo está perfecto. Ahora se puede probar lo que se ha hecho.
Ejemplos de trabajo.
Para ilustrar, crearemos un proyecto simple (en master) en el que habrá varios archivos. Luego, en otra rama, modificaremos solo un archivo y trataremos de hacer un merge request.
Consideremos dos casos: cuando el archivo modificado contiene un error y cuando no. Primero el ejemplo con el error.
Supongamos que en la rama master hay un archivo Program.cs,que no contiene errores, y en otra rama un desarrollador ha añadido un código erróneo y desea hacer un merge request. La naturaleza del error no es tan importante; lo crucial es que existe. Por ejemplo, olvidó el operador throw (sí, ):
void MyAwesomeMethod(String name)
{
if (name == null)
new ArgumentNullException(....);
// hacer algo
....
}Veamos el resultado del análisis del ejemplo con error. Además, para asegurarnos de que solo se analizó un archivo, añadí la bandera -r en la línea de comando de pvs-studio-dotnet:

Vemos que el analizador encontró un error y no permitió la fusión de ramas.
Revisemos el ejemplo sin error. Corregimos el código:
void MyAwesomeMethod(String name)
{
if (name == null)
throw new ArgumentNullException(....);
// hacer algo
....
}Resultados del análisis del merge request:

Como vemos, no se encontraron errores y la ejecución de la tarea fue exitosa, que es lo que queríamos verificar.
Conclusión
Filtrar el código defectuoso antes de fusionar ramas es muy conveniente y agradable. Por lo tanto, si usas CI/CD, intenta integrar un analizador estático para la verificación. Además, hacerlo es bastante simple.
Gracias por su atención.
Si deseas compartir este artículo con una audiencia de habla inglesa, por favor usa el enlace a la traducción: Nikolay Mironov. .
Fuente: habr.com
