הבנת הסמכויות… באופן חזותי!

הרים ידיים, כמה מאיתנו באמת מבינים איך כלי הבנייה האוטומטית שלכם בונה את עץ התלויות? עכשיו, הורדו את היד אם אתם מבינים זאת מכיוון שאתם עובדים על כלים לבנייה אוטומטית. נדמה!

תפקיד מתסכל של מהנדסי תוכנה הוא להבין את התלויות הפרויקט שלך: אילו תלויות מעבריות נכנסו ועל ידי מי; למה v1.3.1 משמש כשv1.2.10 הוכרז; מה נסבה כשהתלויות המעבריות השתנו; איך קרה שהתקיימו גירסאות מרובות של אותו אובייקט?

כל מהנדס תוכנה העביר עץ תלויות לקובץ טקסט, חיפש אובייקטים ספציפיים, ואז עבר בחזרה כדי לזהות את מקורו. עבור כל דבר מעט מפרויקטים טריוויאליים, יצירת מפת מוחית של התלויות היא קשה מאוד, אם לא בלתי אפשרית.

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.

הערה: זו לא הדרכה על מאגרי גרפים, וגם ההדרכה הזו לא דורשת רקע במאגרי גרפים. אם אתם מעוניינים, Neo4J מציע הדרכות ומסמכי לב לעזור לכם להתחיל.

הגדרת סביבת העבודה

התקנת Java

דרוש/ה Java 11 או מאוחר יותר. אם זה כבר לא זמין, התקן את הטעימה שלך של OpenJDK

התקן Neo4J

הדרכה זו דורשת מסד נתונים של Neo4J שבו מועברת מידע הסמכות, מועדף לא משותף, כפי שהמעבד מנקה את המסד הנתונים לפני כל ריצה. הודעת אזהרה!

Neo4J מספק חורים אישיים, מושלמים לפרויקטים קצרי טווח כמו הדרכה זו.

כפול, התקן Neo4J מקומית על השולחן הכתוב או הנייד שלך. Homebrew מקל על התקנות של MacOS: 

Shell

 

brew install neo4j && brew services start neo4j

לפני שתמשיך, תקבע גישה למסד הנתונים של Neo4J באמצעות הדפדפן, באמצעות או קישור ופרטיות לחור Neo4J או מקומית בhttp://localhost:7474. הפרטיות הברירת מחדל להתקנה מקומית היא neo4j/neo4j; לאחר התחברות מוצלחת, אתה נאלץ לשנות את הסיסמה.

שכפול מאגרים

במאגר neo4j-gradle-dependencies מצויים ההסמכות לטעינת ההסמכות ל-Neo4J. הדרכה זו תפקיד גרף הסמכות עבור spring-boot. עליך לשכתב שני המאגרים האלה.

Shell

 

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

הערה: אין צורך ב-Gradle מקומי מאחר ששני המאגרים משתמשים ב-Gradle Wrapper, אשר מוריד את כל הרכיבים ההכרחיים בפעם הראשונה שמשתמשים באפשרות הכפולה. 

ליצור הסמכות

DependencyLoader יש לקחת את עץ הסמכות שנוצר על ידי Gradle כקלט. למרות שניתן לטעון מספר קונפיגורציות יחד – כלומר, compileClasspath, runtimeClasspath, testCompileClasspath, testRuntimeClasspath – התחלה עם קונפיגורציה בודדת פשוטה יותר לניווט, במיוחד עבור דרכה.

כדי ליצור הסמכות עבור כל הקונפיגורציות: 

  • gradle dependencies
  • ./gradlew dependencies

כדי ליצור הסמכות עבור קונפיגורציה בודדת

  • gradle dependencies --configuration <configuration>
  • ./gradlew dependencies --configuration <configuration>

ליצור הסמכות Spring Boot

בדוגמה זו יוצרים גרף הסתייעות ב-Neo4J באמצעות ההסתייעות compileClasspath של Spring Boot. מהספרייה שבה הועתקו המאגרים, הפעל את הפקודות הבאות:

Shell

 

Scott.Sosna@mymachine src% cd spring-boot/spring-boot-project/spring-boot
Scott.Sosna@mymachine spring-boot% ./gradlew dependencies --configuration compileClasspath > dependencies.out

הקובץ dependencies.out מכיל את ההסתייעות בזמן הקמפילציה של Spring Boot.

טעינת הסתייעות

קודם כל, אשר את כתובת שרת הקשר ואת הפרטי האימות בDependencyLoader.java ועדכן אותם במידת הצורך.

הפעל את הפקודות הבאות כדי לטעון את ההסתייעות של Spring Boot לתוך Neo4j:

Shell

 

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"

כאשר הפעולה מצליחה, הפלט מ-gradle יהיה:

Shell

 

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

צפייה בהסתייעות

קיימים כלים רבים להצגת גרפים Neo4J, אך כלי הדפדפן המובנה מראש מספיק לדוגמה זו.

הצגת העץ המלא

השאילתה MATCH(a) RETURN a היא המקבילה הרלוונטית של SELECT * FROM <table>

צפייה בפרטים של אובייקט

כל אובייקט שנמצא יוצר צומת שמאפייניו מזהים את האובייקט (groupId/artifactId) וסוגו, ומוצג בפאנל הימני.

לצפייה בפרטים של תלות

כל תלות נוצרת כקשר שמאפייניו מזהים את הפרטים המפורטים של התלות: תצורה, גרסה מסוימת/גרסה, ותצורה. התלות שנבחרה להלן מציגה spring-security:spring-web תלוי בio.micormeter:micrometer-observation, אך גרסת הspring-web המסומנת 1.10.7 הופחתה לגרסה 1.11.0.

לניווט בתלויות

Neo4J מאפשר לך לחקור את גרף הצמתים צומת-אחר-צומת, מה שמאפשר לך להרחיב את גרף הצמתים באופן ידני צומת אחר צומת, ומספק דרך לחקור אזורים ספציפיים בעץ התלויות.

נניח שאתה רוצה להבין את התלויות עבור הארגומנט io.projectreactor.netty:reactor-netty-http. קודם כל, נבקש מ-Neo4J את הצומת הספציפי הזה.

Cypher

 

MATCH(a:Artifact {groupId: 'io.projectreactor.netty', artifactId: 'reactor-netty-http'}) RETURN a

לחיצה כפולה על הצומת מציגה את הצמתים השכנים שלו – הארגומנטים שתלויים בו והארגומנטים שהוא תלוי בהם.

הגרף המורחב מראה ארגומנט אחד שתלוי בו – השורש של הפרויקט עם סוג ארגומנט PROJECT וששה תלויות אחרות שהוא תלוי בהם.

בשלב הבא, הקליקו פעמיים על io.netty:netty-codehttps://github.com/netty/netty/tree/4.1/codec-httpc-http כדי להציג את הרמה הבאה של התלויות. שימו לב שכמו שמוצגות הקשרות (התלויות) של הצומת הנבחר, עשויות להופיע קשרות נוספות עבור צמתים שכבר בתרשים.

זהו חוסר התאמת גרסאות

פלט התלויות של Gradle מציין היכן הגרסה המפורשת לא הייתה הגרסה שהתגברה על ידי Gradle. תכונות התלויות (הקשר) יכולות לשמש בשאילתת Neo4J, ולהגביל את הקשרים המוצגים והאובייקטים המחוברים (הצמתים).

Cypher

 

MATCH (a:Artifact)-[d:DEPENDS_ON]->(b:Artifact) WHERE d.specifiedVersion<>d.resolvedVersion RETURN a,b,d

Neo4J יכול להחזיר תוצאות בפורמט טבלאי לשם בדיקה קלה יותר, אם יש צורך.

Cypher

 

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

מידע נוסף

mappings.out

קובץ mappings.out מאפשר לכם להתאים את סוג האובייקט המוקצה לצומת על פי groupId של האובייקטים, לרוב כדי לזהות באופן ספציפי אובייקטים שנוצרו על ידי הארגון שלכם.

ספריית הקלט

טענת השורה הפקודה ל-DependencyLoader עשויה להיות תיקייה המכילה מספר עצים הסמכויות של Gradle הטעונים לאותו מסד נתונים Neo4J. זה עוזר בהבנת הסמיכויות של פרויקטים קשורים עם קבצי build.gradle נפרדים.

מוגבל והושמט

Gradle מזהה תלמים מסוימים כ-מוגבל וכ-הושמט. כרגע, אלו אינם נטענים, אך יהיה קל לכלול אותם, כנראה על ידי יצירת תכונות נוספות לקשרים.

Source:
https://dzone.com/articles/understanding-dependenciesvisually