Introduktion til Leiningen for Clojure

1. Introduktion

Leiningen er et moderne byggesystem til vores Clojure-projekter. Det er også skrevet og konfigureret udelukkende i Clojure.

Det fungerer på samme måde som Maven og giver os en deklarativ konfiguration, der beskriver vores projekt uden at skulle konfigurere nøjagtige trin, der skal udføres.

Lad os hoppe ind og se, hvordan vi kommer i gang med Leiningen til opbygning af vores Clojure-projekter.

2. Installation af Leiningen

Leiningen er tilgængelig som en enkeltstående download, såvel som fra et stort antal pakkeforvaltere til forskellige systemer.

Uafhængige downloads er tilgængelige til Windows såvel som til Linux og Mac. I alle tilfælde skal du downloade filen, om nødvendigt gøre den eksekverbar, og så er den klar til brug.

Første gang scriptet køres, downloader det resten af ​​Leiningen-applikationen, og derefter caches dette fra dette tidspunkt:

$ ./lein Download af Leiningen til /Users/user/.lein/self-installs/leiningen-2.8.3-standalone.jar nu ... ..... Leiningen er et værktøj til at arbejde med Clojure-projekter. Flere opgaver er tilgængelige: ..... Kør `lein help $ TASK` for detaljer. .....

3. Oprettelse af et nyt projekt

Når Leiningen er installeret, kan vi bruge det til at oprette et nyt projekt ved at påkalde lein ny.

Dette opretter et projekt ved hjælp af en bestemt skabelon fra et sæt indstillinger:

  • app - Bruges til at oprette en applikation
  • Standard - Bruges til at oprette en generel projektstruktur, typisk til biblioteker
  • plugin - Bruges til at oprette et Leiningen-plugin
  • skabelon - Bruges til at oprette nye Leiningen-skabeloner til fremtidige projekter

For eksempel, for at oprette en ny applikation kaldet "mit-projekt" ville vi udføre:

$ ./lein new app my-project Generering af et projekt kaldet my-project baseret på 'app'-skabelonen.

Dette giver os et projekt, der indeholder:

  • En build-definition - projekt.clj
  • En kildekatalog - src - inklusive en indledende kildefil - src / my_project / core.clj
  • En testmappe - prøve - inklusive en indledende testfil - test / my_project / core_test.clj
  • Nogle yderligere dokumentationsfiler - README.md, LICENS, CHANGELOG.md og doc / intro.md

Når vi ser ind i vores build-definition, ser vi, at det fortæller os, hvad vi skal bygge, men ikke hvordan vi bygger det:

(defproject my-project "0.1.0-SNAPSHOT": beskrivelse "FIXME: skriv beskrivelse": url "//eksempel.com/FIXME": licens {: navn "EPL-2.0 ELLER GPL-2.0-eller-senere MED Classpath -exception-2.0 ": url" //www.eclipse.org/legal/epl-2.0/ "}: afhængigheder [[org.clojure / clojure" 1.9.0 "]]: main ^: skip-aot my-project .core: target-path "target /% s": profiler {: uberjar {: aot: all}})

Dette fortæller os:

  • Detaljerne i projektet, der består af projektnavnet, version, beskrivelse, hjemmeside og licensoplysninger.
  • Det vigtigste navneområde, der skal bruges, når programmet udføres
  • Listen over afhængigheder
  • Målstien til at bygge output i
  • En profil til opbygning af en uberjar

Bemærk, at hovedkildens navneområde er mit-projekt.core, og findes i filen my_project / core.clj. Det afskrækkes i Clojure at bruge navneområder i enkelt segment - svarende til topklasser i et Java-projekt.

Derudover genereres filnavne med understregninger i stedet for bindestreger, fordi JVM har nogle problemer med bindestreger i filnavne.

Den genererede kode er ret enkel:

(ns my-project.core (: gen-class)) (defn -main "Jeg laver ikke meget ... endnu." [& args] (println "Hello, World!"))

Bemærk også, at Clojure bare er en afhængighed her. Dette gør det trivielt at skrive projekter ved hjælp af den ønskede version af Clojure-bibliotekerne, og især at have flere forskellige versioner, der kører på det samme system.

Hvis vi ændrer denne afhængighed, får vi den alternative version i stedet.

4. Bygning og drift

Vores projekt er ikke meget værd, hvis vi ikke kan bygge det, køre det og pakke det op til distribution, så lad os se på det næste.

4.1. Lancering af en REPL

Når vi har et projekt, kan vi starte en REPL inde i det ved hjælp af lein repl. Dette vil give os en REPL, der har alt i projektet allerede tilgængeligt på klassestien - inklusive alle projektfiler samt alle afhængigheder.

Det starter os også i det definerede hovednavneområde for vores projekt:

$ lein repl nREPL-server startet på port 62856 på vært 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-funktion-navn-her) (find-doc "del-af-navn-her") Kilde: (kilde-funktion-navn-her) Javadoc: (javadoc java-objekt-eller- klasse-her) Afslut: Control + D eller (exit) eller (afslut) Resultater: Gemt i vars * 1, * 2, * 3, en undtagelse i * e my-project.core => (-main) Hej, Verden ! nul

Dette udfører funktionen -hovedet i det aktuelle navneområde, som vi så ovenfor.

4.2. Kørsel af applikationen

Hvis vi arbejder på et applikationsprojekt - oprettet ved hjælp af lein ny app - derefter Vi kan simpelthen køre applikationen fra kommandolinjen. Dette gøres ved hjælp af lein løb:

$ lein run Hej, Verden!

Dette udfører den kaldte funktion -hovedet i navneområdet defineret som : hoved i vores projekt.clj fil.

4.3. Opbygning af et bibliotek

Hvis vi arbejder på et biblioteksprojekt - oprettet ved hjælp af lein ny standard - derefter vi kan opbygge biblioteket i en JAR-fil til inkludering i andre projekter.

Vi har to måder, vi kan opnå dette på - ved hjælp af lein jar eller lein installation. Forskellen er simpelthen i, hvor output JAR-filen er placeret.

Hvis vi bruger lein jar så placerer den det i det lokale mål vejviser:

$ lein jar Oprettet /Users/user/source/me/my-library/target/my-library-0.1.0-SNAPSHOT.jar

Hvis vi bruger lein installation, så bygger den JAR-filen, genererer en pom.xml fil, og placer derefter de to i det lokale Maven-arkiv (typisk under .m2 / lager i brugerens hjemmekatalog)

$ lein install Oprettet /Users/user/source/me/my-library/target/my-library-0.1.0-SNAPSHOT.jar Skrev /Users/user/source/me/my-library/pom.xml Installeret jar og pom i lokal repo.

4.4. Bygning af en Uberjar

Hvis vi arbejder på et ansøgningsprojekt, Leiningen giver os muligheden for at bygge det, der kaldes en uberjar. Dette er en JAR-fil, der indeholder selve projektet og alle afhængigheder og indstillet til at lade det køre som det er.

$ lein uberjar Kompilering af mit projekt.core Oprettet /Users/user/source/me/my-project/target/uberjar/my-project-0.1.0-SNAPSHOT.jar Oprettet / Brugere / bruger / kilde / mig / my- project / target / uberjar / my-project-0.1.0-SNAPSHOT-standalone.jar

Filen my-project-0.1.0-SNAPSHOT.jar er en JAR-fil, der indeholder nøjagtigt det lokale projekt og filen my-project-0.1.0-SNAPSHOT-standalone.jar indeholder alt, hvad der er nødvendigt for at køre applikationen.

$ java -jar target / uberjar / my-project-0.1.0-SNAPSHOT-standalone.jar Hej verden!

5. Afhængigheder

Selvom vi selv kan skrive alt, hvad der er nødvendigt til vores projekt, er det generelt betydeligt bedre at genbruge det arbejde, som andre allerede har udført på vores vegne. Vi kan gøre dette ved at have vores projekt afhængigt af disse andre biblioteker.

5.1. Tilføjelse af afhængigheder til vores projekt

For at tilføje afhængigheder til vores projekt skal vi tilføje dem korrekt til vores projekt.clj fil.

Afhængigheder er repræsenteret som en vektor, der består af navnet og versionen af ​​den pågældende afhængighed. Vi har allerede set, at Clojure i sig selv tilføjes som en afhængighed, skrevet i formen [org.clojure / clojure "1.9.0"].

Hvis vi vil tilføje andre afhængigheder, kan vi gøre det ved at føje dem til vektoren ved siden af : afhængigheder nøgleord. For eksempel hvis vi vil stole på clj-json vi opdaterer filen:

 : afhængigheder [[org.clojure / clojure "1.9.0"] [clj-json "0.5.3"]]

Når vi er færdige, hvis vi starter vores REPL - eller nogen anden måde at bygge eller køre vores projekt på - så vil Leiningen sikre, at afhængighederne downloades og er tilgængelige på klassestien:

$ lein repl Henter clj-json / clj-json / 0.5.3 / clj-json-0.5.3.pom fra clojars Henter clj-json / clj-json / 0.5.3 / clj-json-0.5.3.jar fra clojars nREPL-server startet på port 62146 på vært 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-funktion-navn-her) (find-doc "del-af-navn-her") Kilde: (kilde-funktion-navn-her) Javadoc: (javadoc java-objekt-eller-klasse-her) Exit: Control + D eller (exit) eller (quit) Resultater: Gemt i vars * 1, * 2, * 3, en undtagelse i * e my-project.core => (kræver '(clj-json [core: as json])) nul my-project.core => (json / generer-streng {"foo" "bar"}) "{\" foo \ ": \" bar \ "}" my-project.core =>

Vi kan også bruge dem indefra i vores projekt. For eksempel kunne vi opdatere det genererede src / my_project / core.clj fil som følger:

(ns my-project.core (: gen-class)) (kræver '(clj-json [kerne: som json])) (defn -hoved "Jeg laver ikke meget ... endnu." [& args] (println (json / generere-streng {"foo" "bar"})))

Og så vil det køre nøjagtigt som forventet at køre det:

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

5.2. At finde afhængigheder

Ofte kan det være svært at finde de afhængigheder, som vi vil bruge i vores projekt. Leiningen leveres med en indbygget søgefunktionalitet for at gøre dette lettere. Dette gøres ved hjælp af leinsøgning.

For eksempel kan vi finde vores JSON-biblioteker:

$ lein search json Søger central ... [com.jwebmp / ​​json "0.63.0.60"] [com.ufoscout.coreutils / json "3.7.4"] [com.github.iarellano / json "20190129"] ... .. Søger clojars ... [cheshire "5.8.1"] JSON og JSON SMILE-kodning, hurtigt. [json-html "0.4.4"] Giv JSON, og få en DOM-node med en menneskelig repræsentation af den JSON [ring / ring-json "0.5.0-beta1"] Ringmidware til håndtering af JSON [clj-json "0.5. 3 "] Hurtig JSON-kodning og afkodning til Clojure via Jackson-biblioteket. .....

Dette søger i alle de arkiver, som vores projekt arbejder med - i dette tilfælde Maven Central og Clojars. Derefter returnerer den nøjagtige streng, der skal indsættes i vores projekt.clj fil og, hvis tilgængelig, beskrivelsen af ​​biblioteket.

6. Test af vores projekt

Clojure har indbygget support til enhedstest af vores applikation, og Leiningen kan udnytte dette til vores projekter.

Vores genererede projekt indeholder testkode i prøve bibliotek sammen med kildekoden i src vejviser. Det inkluderer også en enkelt, fejlagtig test som standard - fundet i test / my_project / core-test.clj:

(ns my-project.core-test (: kræver [clojure.test: henvis: alt] [mit-project.core: henvis: alt])) (dygtig a-test (test "FIXME, jeg fejler." (er (= 0 1))))

Dette importerer mit-projekt.core navneområde fra vores projekt og clojure.test navneområde fra det centrale Clojure-sprog. Vi definerer derefter en test med dygtig og test opkald.

Vi kan straks se testens navne og det faktum, at den bevidst er skrevet for at mislykkes - det hævder det 0 == 1.

Lad os køre dette ved hjælp af lein test kommando, og se straks testene køre og mislykkes:

$ lein test lein test my-project.core-test lein test: kun my-project.core-test / a-test FAIL i (a-test) (core_test.clj: 7) FIXME, jeg fejler. forventet: (= 0 1) faktisk: (ikke (= 0 1)) Ran 1-tests indeholdende 1 påstande. 1 fejl, 0 fejl. Test mislykkedes.

Hvis vi i stedet retter testen, skal du ændre den for at hævde det 1 == 1 i stedet får vi i stedet en forbipasserende besked:

$ lein test lein test my-project.core-test Ran 1 tests indeholdende 1 påstande. 0 fejl, 0 fejl.

Dette er et meget mere kortfattet output, der kun viser, hvad vi har brug for at vide. Det betyder at når der er fejl, skiller de sig straks ud.

Hvis vi vil, kan vi også køre en bestemt delmængde af testene. Kommandolinjen tillader, at der gives et navneområde, og kun test i dette navneområde udføres:

$ lein test my-project.core-test lein test my-project.core-test Ran 1-tests indeholdende 1 påstande. 0 fejl, 0 fejl. $ lein test my-project.unknown lein test my-project.unknown Kørte 0 tests indeholdende 0 påstande. 0 fejl, 0 fejl.

7. Resume

Denne artikel har vist, hvordan man kommer i gang med Leiningen-byggeværktøjet, og hvordan man bruger det til at styre vores Clojure-baserede projekter - både eksekverbare applikationer og delte biblioteker.

Hvorfor ikke prøve det på det næste projekt og se, hvor godt det kan fungere.


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