Montrez vos mains, combien d’entre nous comprennent vraiment comment votre outil d’automatisation de construction génère son arbre de dépendances? Maintenant, baissez la main si vous comprenez parce que vous travaillez sur des outils d’automatisation de construction. C’était prévisible!
Une responsabilité frustrante des ingénieurs logiciels est de comprendre les dépendances de votre projet : quelles dépendances transitives ont été introduites et par qui ; pourquoi v1.3.1 est utilisé alors que v1.2.10 a été déclaré ; quelles ont été les conséquences des changements des dépendances transitives ; comment se produisent-elles plusieurs versions du même artefact?
Chaque ingénieur logiciel a pipé un arbre de dépendances dans un fichier texte, recherché des artefacts spécifiques, puis remonté pour identifier son origine. Pour tout projet autre que trivial, créer une carte mentale des dépendances est extrêmement difficile, voire impossible.
I faced this problem when starting a new job with a mature code base, presenting a challenge to assemble the puzzle pieces. I’ve previously worked with graph databases and thought a graphical view of the dependency artifacts could be created using Neo4J, which resulted in DependencyLoader.
Note: ce n’est pas un tutoriel sur les bases de données graphes, ni ce tutoriel n’exige une formation en bases de données graphes. Si vous êtes intéressé, Neo4J propose tutoriels et livres blancs pour vous aider à démarrer.
Configurer l’environnement
Installer Java
Java 11 ou ultérieur est requis. Si ce n’est pas déjà le cas, installez votre OpenJDK préféré.
Installer Neo4J
Le tutoriel requiert une base de données Neo4J dans laquelle les informations de dépendance sont chargées, de préférence non partagée, car le chargeur purge la base de données avant chaque exécution.Vous avez été prévenu !
Neo4J fournit des sandbox personnelles, idéales pour des projets à court terme comme ce tutoriel.
Sinon, installez Neo4J localement sur votre ordinateur de bureau ou portable. Homebrew simplifie les installations sous MacOS :
brew install neo4j && brew services start neo4j
Avant de continuer, confirmez l’accès à votre base de données Neo4J en utilisant le navigateur, en utilisant soit le lien et les identifiants pour le sandbox Neo4J, soit localement à http://localhost:7474. Les identifiants par défaut pour une installation locale sont neo4j/neo4j; après une connexion réussie, vous êtes obligé de changer le mot de passe.
Cloner les dépôts
Le référentiel neo4j-gradle-dependencies contient les éléments pour charger les dépendances dans Neo4J. Ce tutoriel générera un graphe de dépendance pour spring-boot. Vous devez cloner ces deux référentiels.
Scott.Sosna@mymachine src% git clone [email protected]:scsosna99/neo4j-gradle-dependencies.git
Scott.Sosna@mymachine src% git clone [email protected]:spring-projects/spring-boot.git
Note : Gradle local n’est pas nécessaire car les deux référentiels utilisent le Gradle Wrapper, qui télécharge tous les composants nécessaires la première fois que le wrapper est utilisé.
Générer des dépendances
DependencyLoader
prend en entrée l’arborescence des dépendances générée par Gradle. Bien que plusieurs configurations puissent être chargées ensemble — par exemple, compileClasspath
, runtimeClasspath
, testCompileClasspath
, testRuntimeClasspath
— commencer avec une seule configuration est plus simple à naviguer, surtout pour un tutoriel.
Pour générer des dépendances pour toutes les configurations :
gradle dependencies
./gradlew dependencies
Pour générer des dépendances pour une seule configuration
gradle dependencies --configuration <configuration>
./gradlew dependencies --configuration <configuration>
Générer les dépendances Spring Boot
Ce tutoriel crée un graphe de dépendances dans Neo4J en utilisant les dépendances compileClasspath
de Spring Boot. À partir du répertoire où les dépôts ont été clonés, exécutez les commandes suivantes :
Scott.Sosna@mymachine src% cd spring-boot/spring-boot-project/spring-boot
Scott.Sosna@mymachine spring-boot% ./gradlew dependencies --configuration compileClasspath > dependencies.out
Le fichier dependencies.out
contient les dépendances de la classe à la compilation pour Spring Boot.
Charger les Dépendances
Tout d’abord, confirmez l’URL de connexion et les informations d’identification d’authentification dans DependencyLoader.java et modifiez-les si nécessaire.
Exécutez les commandes suivantes pour charger les dépendances de Spring Boot dans Neo4j :
Scott.Sosna@mymachine spring-boot% cd ../../../neo4j-gradle-dependencies
Scott.Sosna@mymachine neo4j-gradle-dependencies% ./gradlew clean run --args="../spring-boot/spring-boot-project/spring-boot/dependencies.out"
Lorsque cela réussit, les lignes de sortie de gradle sont :
Scott.Sosna@PVHY32M6KG neo4j-gradle-dependencies % ./gradlew clean run --args="../spring-boot/spring-boot-project/spring-boot/dependencies.out"
> Task :compileJava
Note: /Users/Scott.Sosna/data/src/github/neo4j-gradle-dependencies/src/main/java/dev/scottsosna/neo4j/gradle/relationship/DependsOn.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
> Task :run
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Jun 02, 2023 6:19:22 AM org.neo4j.driver.internal.logging.JULogger info
INFO: Direct driver instance 1606286799 created for server address localhost:7687
dependencies.out completed.
Jun 02, 2023 6:19:23 AM org.neo4j.driver.internal.logging.JULogger info
INFO: Closing driver instance 1606286799
Jun 02, 2023 6:19:23 AM org.neo4j.driver.internal.logging.JULogger info
INFO: Closing connection pool towards localhost:7687
Deprecated Gradle features were used in this build, making it incompatible with Gradle 8.0.
You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins.
See https://docs.gradle.org/7.5.1/userguide/command_line_interface.html#sec:command_line_warnings
BUILD SUCCESSFUL in 3s
Afficher les Dépendances
Plusieurs outils sont disponibles pour afficher les graphes Neo4J, mais l’outil de navigateur intégré convient pour ce tutoriel.
Afficher l’Arbre Complet
La requête MATCH(a) RETURN a
est l’équivalent relationnel de SELECT * FROM <table>
Afficher les Détails d’un Artifact
Chaque artefact trouvé crée un nœud dont les propriétés identifient l’artefact (groupId/artifactId) et son type, affiché dans le volet de droite.
Voir les détails d’une dépendance
Chaque dépendance est créée sous la forme d’une relation dont les propriétés identifient les spécificités de la dépendance : configuration, version spécifiée et configuration. La dépendance sélectionnée ci-dessous montre spring-security:spring-web dépend de io.micormeter:micrometer-observation, mais la version spécifiée 1.10.7 de spring-web a été résolue en version 1.11.0.
Parcourir les dépendances
Neo4J vous permet d’explorer le graphique nœud par nœud, vous permettant d’étendre manuellement le nœud du graphique nœud par nœud, offrant un moyen d’explorer des zones spécifiques de l’arbre des dépendances.
Supposons que vous souhaitiez comprendre les dépendances pour l’artéfact io.projectreactor.netty:reactor-netty-http. Tout d’abord, nous interrogerons Neo4J pour ce nœud spécifique.
MATCH(a:Artifact {groupId: 'io.projectreactor.netty', artifactId: 'reactor-netty-http'}) RETURN a
En double-cliquant sur le nœud, vous voyez ses nœuds voisins — les artéfacts dont il dépend et les artéfacts dont il est dépendant.
Cette vue élargie du graphique montre un artéfact qui en dépend — la racine du projet avec un type d’artéfact PROJET et six autres dépendances dont il dépend.
Ensuite, double-cliquez sur io.netty:netty-code https://github.com/netty/netty/tree/4.1/codec-httpc-http pour afficher le niveau de dépendances suivant. Notez que, en plus des relations (dépendances) du nœud sélectionné, des relations supplémentaires pour les nœuds déjà présents sur le graphique peuvent être affichées.
Identifier un désalignement de version
La sortie des dépendances de Gradle indique l’endroit où la version spécifiée n’était pas la version résolue par Gradle. Les propriétés sur la dépendance (relation) peuvent être utilisées dans une requête Neo4J, restreignant les relations affichées et les artefacts attachés (nœuds).
MATCH (a:Artifact)-[d:DEPENDS_ON]->(b:Artifact) WHERE d.specifiedVersion<>d.resolvedVersion RETURN a,b,d
Neo4J peut retourner des résultats sous forme tabulaire pour une revue plus aisée, si nécessaire.
MATCH (a:Artifact)-[d:DEPENDS_ON]->(b:Artifact) WHERE d.specifiedVersion<>d.resolvedVersion RETURNa.name AS source, b.name AS dependency, d.specifiedVersion AS specified, d.resolvedVersion AS resolved
Information supplémentaire
mappings.out
Le fichier mappings.out vous permet de personnaliser le type d’artefact attribué à un nœud en fonction du groupId de l’artefact, le plus souvent pour identifier spécifiquement les artefacts créés par votre organisation.
Répertoire d’entrée
L’argument de ligne de commande pour DependencyLoader
peut être un répertoire contenant plusieurs arbres de dépendances Gradle chargés dans la même base de données Neo4J. Cela aide à comprendre les dépendances de projets liés ayant des fichiers build.gradle séparés.
Contraintes et Omissions
Gradle identifie certaines dépendances comme Contraintes et Omissions. Actuellement, celles-ci ne sont pas chargées mais pourraient être facilement incluses, probablement en créant des propriétés supplémentaires pour les relations.
Source:
https://dzone.com/articles/understanding-dependenciesvisually