מבוא לליינינגן לקלוז'ר

1. הקדמה

ליינינגן היא מערכת בנייה מודרנית לפרויקטים שלנו ב- Clojure. זה גם כתוב ומוגדר כולו ב- Clojure.

זה עובד באופן דומה ל- Maven, ונותן לנו תצורה הצהרתית המתארת ​​את הפרויקט שלנו, מבלי להזדקק לתצורה של צעדים מדויקים לביצוע.

בואו נקפוץ ונראה איך להתחיל עם ליינינגן לבניית פרויקטי Clojure שלנו.

2. התקנת ליינינגן

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

הורדות עצמאיות זמינות עבור Windows כמו גם עבור Linux ו- Mac. בכל המקרים, הורידו את הקובץ, הפכו אותו להפעלה במידת הצורך ואז הוא מוכן לשימוש.

בפעם הראשונה שהסקריפט מופעל הוא יוריד את שאר היישום Leiningen, ואז זה יישמר במטמון מנקודה זו ואילך:

$ ./lein הורדת Leiningen ל- /Users/user/.lein/self-installs/leiningen-2.8.3-standalone.jar עכשיו ... ..... Leiningen הוא כלי לעבודה עם פרויקטים של Clojure. קיימות מספר משימות: ..... הפעל `lein help $ TASK` לפרטים. .....

3. יצירת פרויקט חדש

לאחר התקנת ליינינגן, נוכל להשתמש בו ליצירת פרויקט חדש על ידי הפעלת lein חדש.

זה יוצר פרויקט באמצעות תבנית מסוימת מתוך קבוצה של אפשרויות:

  • אפליקציה - משמש ליצירת יישום
  • בְּרִירַת מֶחדָל - משמש ליצירת מבנה כללי של הפרויקט, בדרך כלל עבור ספריות
  • חיבור - משמש ליצירת תוסף ליינינגן
  • תבנית - משמש ליצירת תבניות ליינינגן חדשות לפרויקטים עתידיים

לדוגמה, כדי ליצור יישום חדש בשם "הפרויקט שלי" נבצע:

$ ./lein אפליקציה חדשה my-project יצירת פרויקט שנקרא my-project מבוסס על תבנית 'אפליקציה'.

זה נותן לנו פרויקט המכיל:

  • הגדרת build - project.clj
  • ספריית מקור - src - כולל קובץ מקור ראשוני - src / my_project / core.clj
  • מדריך בדיקה - מִבְחָן - כולל תיק בדיקה ראשוני - test / my_project / core_test.clj
  • כמה קבצי תיעוד נוספים - README.md, LICENSE, CHANGELOG.md ו doc / intro.md

כשמסתכלים בתוך הגדרת הבנייה שלנו, נראה שזה אומר לנו מה לבנות, אבל לא איך לבנות אותה:

(defproject my-project "0.1.0-SNAPSHOT": תיאור "FIXME: כתוב תיאור": url "//example.com/FIXME": רישיון {: שם "EPL-2.0 או GPL-2.0-ואילך עם Classpath -exception-2.0 ": url" //www.eclipse.org/legal/epl-2.0/ "}: תלות [[org.clojure / clojure" 1.9.0 "]]: ראשי ^: דלג על פרוייקט שלי .core: target-path "target /% s": פרופילים {: uberjar {: aot: all}})

זה אומר לנו:

  • פרטי הפרויקט המורכבים משם הפרויקט, הגרסה, התיאור, דף הבית ופרטי הרישיון.
  • מרחב השמות הראשי לשימוש בעת ביצוע היישום
  • רשימת התלות
  • נתיב היעד לבנות את הפלט לתוכו
  • פרופיל לבניית אוברג'ר

שים לב שמרחב השמות הראשי של המקור הוא my-project.core, ונמצא בקובץ my_project / core.clj. זה מיואש ב- Clojure להשתמש במרחבי שמות של קטעים בודדים - המקבילה לשיעורים ברמה העליונה בפרויקט Java.

בנוסף, שמות הקבצים נוצרים עם קו תחתון במקום מקפים כי ל- JVM יש כמה בעיות עם מקפים בשמות קבצים.

הקוד שנוצר הוא די פשוט:

(ns my-project.core (: gen-class)) (defn -main "אני לא עושה הרבה ... עדיין." [& args] (println "שלום, עולם!"))

כמו כן, שימו לב כי Clojure הוא רק תלות כאן. זה הופך את זה לטריוויאלי לכתוב פרויקטים המשתמשים בכל הגרסה של ספריות Clojure, ובעיקר שיהיו מספר גרסאות שונות הפועלות באותה מערכת.

אם נשנה תלות זו, נקבל במקום זאת את הגרסה החלופית.

4. בנייה והפעלה

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

4.1. השקת REPL

ברגע שיש לנו פרויקט, נוכל להפעיל REPL בתוכו באמצעות תחליף ליין. זה ייתן לנו REPL שיש את כל מה שבפרויקט כבר זמין בנתיב הכיתה - כולל כל קבצי הפרויקט, כמו גם כל התלות.

זה גם מתחיל אותנו במרחב השמות הראשי שהוגדר עבור הפרויקט שלנו:

שרת nREPL replay $ lein התחיל ביציאה 62856 במארח 127.0.0.1 - nrepl: //127.0.0.1: 62856 [] REPL-y 0.4.3, nREPL 0.5.3 Clojure 1.9.0 Java HotSpot (TM) 64-Bit Server VM 1.8.0_77-b03 Docs: (doc function-name-here) (find-doc "part-of-name-here") מקור: (פונקצית מקור שם-כאן) Javadoc: (javadoc java-object-or- class-here) יציאה: Control + D או (exit) או (quit) תוצאות: מאוחסנות vars * 1, * 2, * 3, יוצא מן הכלל ב- * e my-project.core => (-עיקר) שלום, עולם ! אֶפֶס

פעולה זו מבצעת את הפונקציה -רָאשִׁי במרחב השמות הנוכחי, שראינו לעיל.

4.2. הפעלת האפליקציה

אם אנו עובדים על פרויקט יישום - נוצר באמצעות Lein App חדש - לאחר מכן אנו יכולים פשוט להריץ את היישום משורת הפקודה. זה נעשה באמצעות ריצת lein:

$ lein run שלום, עולם!

פעולה זו תבצע את הפונקציה שנקראה -רָאשִׁי במרחב השמות המוגדר כ- :רָאשִׁי בשלנו project.clj קוֹבֶץ.

4.3. בניית ספרייה

אם אנו עובדים על פרויקט ספרייה - נוצר באמצעות lein ברירת מחדל חדשה - לאחר מכן אנו יכולים לבנות את הספרייה לקובץ JAR להכללה בפרויקטים אחרים.

יש לנו שתי דרכים בהן נוכל להשיג זאת - באמצעות צנצנת מישען אוֹ lein להתקין. ההבדל הוא פשוט במקום בו ממוקם קובץ ה- JAR המוצא.

אם נשתמש צנצנת מישוש ואז הוא ימקם אותו במקומי יַעַד מַדרִיך:

$ lein jar נוצר /Users/user/source/me/my-library/target/my-library-0.1.0-SNAPSHOT.jar

אם נשתמש lein להתקין, אז הוא יבנה את קובץ ה- JAR, ייצור a pom.xml ולאחר מכן הצב את השניים במאגר Maven המקומי (בדרך כלל תחת .m2 / מאגר בספריית הבית של המשתמשים)

$ lein install נוצר /Users/user/source/me/my-library/target/my-library-0.1.0-SNAPSHOT.jar כתב /Users/user/source/me/my-library/pom.xml צנצנת מותקנת פום לתוך רפו מקומי.

4.4. בניית אוברג'אר

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

$ lein uberjar קומפילציה my-project.core נוצר / משתמשים / משתמש / מקור / לי / פרוייקט / מטרה / אובראר / פרוייקט -0.1.0-SNAPSHOT.jar נוצר / משתמשים / משתמש / מקור / אני / שלי- project / target / uberjar / my-project-0.1.0-SNAPSHOT-standalone.jar

הקובץ my-project-0.1.0-SNAPSHOT.jar הוא קובץ JAR המכיל בדיוק את הפרויקט המקומי ואת הקובץ my-project-0.1.0-SNAPSHOT-standalone.jar מכיל את כל הדרוש להפעלת היישום.

$ java -jar target / uberjar / my-project-0.1.0-SNAPSHOT-standalone.jar שלום, עולם!

5. תלות

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

5.1. הוספת תלות לפרויקט שלנו

כדי להוסיף תלות בפרויקט שלנו, עלינו להוסיף אותם בצורה נכונה לפרויקט שלנו project.clj קוֹבֶץ.

תלות מיוצגת כווקטור המורכב משם וגרסת התלות המדוברת. כבר ראינו כי Clojure עצמה מתווספת כתלות, הכתובה בצורה [org.clojure / clojure "1.9.0"].

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

 : תלות [[org.clojure / clojure "1.9.0"] [clj-json "0.5.3"]]

לאחר שתסיים, אם נתחיל את ה- REPL שלנו - או כל דרך אחרת לבנות או להריץ את הפרויקט שלנו - אז ליינינגן תבטיח שההתלות תוריד ותהיה זמינה בדרך הכיתה.:

$ lein repl אחזור clj-json / clj-json / 0.5.3 / clj-json-0.5.3.pom מ clojars אחזור clj-json / clj-json / 0.5.3 / clj-json-0.5.3.jar מ שרת nREPL clojars התחיל ביציאה 62146 במארח 127.0.0.1 - nrepl: //127.0.0.1: 62146 REPL-y 0.4.3, nREPL 0.5.3 Clojure 1.9.0 Java HotSpot (TM) 64-Bit Server VM 1.8.0_77 -b03 Docs: (doc function-name-here) (find-doc "part-of-name-here") מקור: (פונקציית המקור-שם-כאן) Javadoc: (javadoc java-object-or-class-here) יציאה: Control + D או (יציאה) או (quit) תוצאות: מאוחסנים ב vars * 1, * 2, * 3, יוצא מן הכלל ב- * e my-project.core => (דורש '(clj-json [core: as json])) אפס my-project.core => (json / generate-string {"foo" "bar"}) "{\" foo \ ": \" bar \ "}" my-project.core =>

אנו יכולים להשתמש בהם גם מתוך הפרויקט שלנו. לדוגמה, נוכל לעדכן את המופק src / my_project / core.clj הקובץ כדלקמן:

(ns my-project.core (: gen-class)) (דורש '(clj-json [core: as json])) (defn -main "אני לא עושה הרבה ... עדיין." [& args] (println (json / generator-string {"foo" "bar"})))

ואז ההפעלה תעשה בדיוק כצפוי:

$ lein run {"foo": "bar"}

5.2. מציאת תלות

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

לדוגמה, אנו יכולים למצוא את ספריות ה- JSON שלנו:

$ lein search json חיפוש במרכז ... [com.jwebmp / ​​json "0.63.0.60"] [com.ufoscout.coreutils / json "3.7.4"] [com.github.iarellano / json "20190129"] ... .. מחפש באדמות ... [cheshire "5.8.1"] קידוד JSON ו- JSON SMILE, מהיר. [json-html "0.4.4"] ספק JSON וקבל צומת DOM עם ייצוג אנושי של אותו JSON [טבעת / טבעת-ג'סון "0.5.0-beta1"] טבעת אמצעי טבעת לטיפול ב- JSON [clj-json "0.5. 3 "] קידוד ופענוח מהיר של JSON עבור Clojure דרך ספריית ג'קסון. .....

פעולה זו מחפשת בכל המאגרים שהפרויקט שלנו עובד איתם - במקרה זה, Maven Central ו- Clojars. לאחר מכן הוא מחזיר את המחרוזת המדויקת להכניס למערכת שלנו project.clj קובץ, ואם זמין, תיאור הספרייה.

6. בדיקת הפרויקט שלנו

ל- Clojure תמיכה מובנית לבדיקת יחידות היישום שלנו, וליינינגן יכולה לנצל זאת לפרויקטים שלנו.

הפרויקט שנוצר שלנו מכיל קוד בדיקה ב- מִבְחָן ספריה, לצד קוד המקור ב- src מַדרִיך. זה כולל גם מבחן יחיד ונכשל כברירת מחדל - נמצא ב- test / my_project / core-test.clj:

(ns my-project.core-test (: דורש [clojure.test: refer: all] [my-project.core: refer: all])) (מיומנות בדיקת a (בדיקת "FIXME, אני נכשל." (הוא (= 0 1))))

זה מייבא את my-project.core מרחב השמות מהפרויקט שלנו, וה- clojure.test מרחב שמות משפת הליבה של Clojure. לאחר מכן אנו מגדירים מבחן עם ה- מיומן ו בדיקה שיחות.

אנו יכולים לראות מיד את שמות המבחן ואת העובדה שהוא נכתב בכוונה להיכשל - זה טוען 0 == 1.

בואו נפעיל את זה באמצעות מבחן lein פקודה, ומיד לראות את הבדיקות פועלות ונכשלות:

$ lein test lein test my-project.core-test lein test: רק my-project.core-test / a-test FAIL ב- (a-test) (core_test.clj: 7) FIXME, אני נכשל. צפוי: (= 0 1) בפועל: (לא (= 0 1)) בדיקות רן 1 המכילות קביעות אחת. 1 כשלים, 0 שגיאות. המבחנים נכשלו.

אם במקום זאת נתקן את הבדיקה, נשנה אותה כדי לקבוע זאת 1 == 1 במקום זאת, נקבל במקום זאת הודעה עוברת:

$ lein test lein test my-project.core-test Ran 1 מבחנים המכילים 1 קביעות. 0 כשלים, 0 שגיאות.

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

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

$ lein test my-project.core-test lein test my-project.core-test בדיקות רן 1 המכילות קביעות אחת. 0 כשלים, 0 שגיאות. $ lein test my-project.unknown lein test my-project.unknown רן 0 מבחנים המכילים 0 קביעות. 0 כשלים, 0 שגיאות.

7. סיכום

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

מדוע לא לנסות זאת על הפרויקט הבא ולראות עד כמה הוא יכול לעבוד.


$config[zx-auto] not found$config[zx-overlay] not found