(.module: [lux #* [abstract ["." monad (#+ do)]] [control ["." io (#+ IO)] ["." try (#+ Try)] ["." exception] [concurrency ["." promise (#+ Promise)]] [security ["!" capability]]] [data [binary (#+ Binary)] ["." text ["%" format (#+ format)] ["." encoding]] [collection ["." list ("#@." monoid)] ["." dictionary] ["." set]] [format ["." binary] ["." tar] ["." xml]]] [world ["." file (#+ Path File Directory)]]] [program [compositor ["." export]]] ["." // #_ ["/" profile (#+ Profile)] ["#." pom] ["#." dependency (#+ Package Resolution Dependency)] ["#." hash] ["#." artifact (#+ Artifact) ["#/." type] ["#/." extension]]]) (def: (local system) (All [a] (-> (file.System a) Path)) (format "~" (:: system separator) ".m2")) (def: (repository system) (All [a] (-> (file.System a) Path)) (format (..local system) (:: system separator) "repository")) (def: (guarantee-repository! system artifact) (-> (file.System Promise) Artifact (Promise (Try Path))) (do {@ (try.with promise.monad)} [_ (: (Promise (Try (Directory Promise))) (file.get-directory promise.monad system (..local system))) #let [root (..repository system)] _ (: (Promise (Try (Directory Promise))) (file.get-directory promise.monad system root))] (monad.fold @ (function (_ child parent) (do @ [#let [path (format parent (:: system separator) child)] _ (: (Promise (Try (Directory Promise))) (file.get-directory promise.monad system path))] (wrap path))) root (//artifact.local artifact)))) (def: (save! system content file) (-> (file.System Promise) Binary Path (Promise (Try Any))) (do (try.with promise.monad) [file (: (Promise (Try (File Promise))) (file.get-file promise.monad system file))] (!.use (:: file over-write) [content]))) (def: #export (install system profile) (-> (file.System Promise) Profile (Promise (Try Any))) (case (get@ #/.identity profile) (#.Some identity) (do (try.with promise.monad) [repository (..guarantee-repository! system identity) #let [artifact-name (format repository (:: system separator) (//artifact.identity identity))] package (export.library system (set.to-list (get@ #/.sources profile))) _ (..save! system (binary.run tar.writer package) (format artifact-name //artifact/extension.lux-library)) pom (:: promise.monad wrap (//pom.project profile))] (..save! system (|> pom (:: xml.codec encode) encoding.to-utf8) (format artifact-name //artifact/extension.pom))) _ (:: promise.monad wrap (exception.throw /.no-identity [])))) (def: #export (cache system [artifact type] package) (-> (file.System Promise) Dependency Package (Promise (Try Any))) (do (try.with promise.monad) [directory (..guarantee-repository! system artifact) #let [prefix (format directory (:: system separator) (//artifact.identity artifact))] directory (: (Promise (Try (Directory Promise))) (file.get-directory promise.monad system directory)) _ (..save! system (get@ #//dependency.library package) (format prefix (//artifact/extension.extension type))) _ (..save! system (encoding.to-utf8 (get@ #//dependency.sha1 package)) (format prefix //artifact/extension.sha1)) _ (..save! system (encoding.to-utf8 (get@ #//dependency.md5 package)) (format prefix //artifact/extension.md5)) _ (..save! system (|> package (get@ #//dependency.pom) (:: xml.codec encode) encoding.to-utf8) (format prefix //artifact/extension.pom))] (wrap []))) (def: #export (cache-all system resolution) (-> (file.System Promise) Resolution (Promise (Try Any))) (do {@ (try.with promise.monad)} [_ (monad.map @ (function (_ [dependency package]) (..cache system dependency package)) (dictionary.entries resolution))] (wrap []))) (def: (read! system path) (-> (file.System Promise) Path (Promise (Try Binary))) (do (try.with promise.monad) [file (: (Promise (Try (File Promise))) (!.use (:: system file) path))] (!.use (:: file content) []))) (def: #export (cached system [artifact type]) (-> (file.System Promise) Dependency (Promise (Try Package))) (do (try.with promise.monad) [directory (..guarantee-repository! system artifact) #let [prefix (format directory (:: system separator) (//artifact.identity artifact))] pom (..read! system (format prefix //artifact/extension.pom)) [pom dependencies] (:: promise.monad wrap (do try.monad [pom (encoding.from-utf8 pom) pom (:: xml.codec decode pom) dependencies (//dependency.from-pom pom)] (wrap [pom dependencies]))) library (..read! system (format prefix (//artifact/extension.extension type))) sha1 (..read! system (format prefix //artifact/extension.sha1)) md5 (..read! system (format prefix //artifact/extension.md5))] (wrap {#//dependency.library library #//dependency.pom pom #//dependency.dependencies dependencies #//dependency.sha1 (|> sha1 (:coerce (//hash.Hash //hash.SHA-1)) (:: //hash.sha1-codec encode)) #//dependency.md5 (|> md5 (:coerce (//hash.Hash //hash.MD5)) (:: //hash.md5-codec encode))}))) (def: #export (all-cached system dependencies resolution) (-> (file.System Promise) (List Dependency) Resolution (Promise (Try Resolution))) (case dependencies #.Nil (:: (try.with promise.monad) wrap resolution) (#.Cons head tail) (do promise.monad [package (case (dictionary.get head resolution) (#.Some package) (wrap (#try.Success package)) #.None (..cached system head))] (with-expansions [ (as-is (all-cached system tail resolution))] (case package (#try.Success package) (let [resolution (dictionary.put head package resolution)] (do (try.with promise.monad) [resolution (all-cached system (get@ #//dependency.dependencies package) resolution)] )) (#try.Failure error) ))))) (def: #export (path system artifact) (All [a] (-> (file.System a) Artifact Path)) (format (..repository system) (:: system separator) (//artifact.identity artifact)))