(.module: [lux #* [abstract [codec (#+ Codec)] ["." monad (#+ do)]] [control ["." try (#+ Try)] [concurrency ["." promise (#+ Promise)]] [security ["!" capability]]] [data [binary (#+ Binary)] ["." product] [text ["%" format (#+ format)] ["." encoding]] [collection ["." dictionary] ["." set (#+ Set)] ["." list]] [format ["." xml]]] [world [program (#+ Program)] ["." file (#+ Path File Directory)]]] ["." // #_ ["#" local] ["#." hash] ["#." package (#+ Package)] ["#." artifact (#+ Artifact) ["#/." extension]] [dependency (#+ Dependency) [resolution (#+ Resolution)]]]) (def: (write! 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 (write-one program system [artifact type] package) (-> (Program Promise) (file.System Promise) Dependency Package (Promise (Try Artifact))) (do promise.monad [home (\ program home [])] (do (try.with promise.monad) [directory (: (Promise (Try Path)) (file.make-directories promise.monad system (//.path system home artifact))) #let [prefix (format directory (\ system separator) (//artifact.identity artifact))] directory (: (Promise (Try (Directory Promise))) (file.get-directory promise.monad system directory)) _ (..write! system (get@ #//package.library package) (format prefix (//artifact/extension.extension type))) _ (..write! system (|> package (get@ #//package.sha-1) (\ //hash.sha-1-codec encode) (\ encoding.utf8 encode)) (format prefix //artifact/extension.sha-1)) _ (..write! system (|> package (get@ #//package.md5) (\ //hash.md5-codec encode) (\ encoding.utf8 encode)) (format prefix //artifact/extension.md5)) _ (..write! system (|> package (get@ #//package.pom) (\ xml.codec encode) (\ encoding.utf8 encode)) (format prefix //artifact/extension.pom))] (wrap artifact)))) (def: #export (write-all program system resolution) (-> (Program Promise) (file.System Promise) Resolution (Promise (Try (Set Artifact)))) (do {! (try.with promise.monad)} [] (|> (dictionary.entries resolution) (list.filter (|>> product.right //package.local? not)) (monad.map ! (function (_ [dependency package]) (..write-one program system dependency package))) (\ ! map (set.from-list //artifact.hash))))) (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: (decode codec data) (All [a] (-> (Codec Text a) Binary (Try a))) (let [(^open "_\.") try.monad] (|> data (\ encoding.utf8 decode) (_\map (\ codec decode)) _\join))) (def: #export (read-one program system [artifact type]) (-> (Program Promise) (file.System Promise) Dependency (Promise (Try Package))) (do promise.monad [home (\ program home []) #let [prefix (format (//.path system home artifact) (\ system separator) (//artifact.identity artifact))]] (do (try.with promise.monad) [pom (..read! system (format prefix //artifact/extension.pom)) library (..read! system (format prefix (//artifact/extension.extension type))) sha-1 (..read! system (format prefix //artifact/extension.sha-1)) md5 (..read! system (format prefix //artifact/extension.md5))] (\ promise.monad wrap (do try.monad [pom (..decode xml.codec pom) sha-1 (..decode //hash.sha-1-codec sha-1) md5 (..decode //hash.md5-codec md5)] (wrap {#//package.origin #//package.Local #//package.library library #//package.pom pom #//package.sha-1 sha-1 #//package.md5 md5})))))) (def: #export (read-all program system dependencies resolution) (-> (Program Promise) (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 (..read-one program system head))] (with-expansions [ (as-is (read-all program system tail resolution))] (case package (#try.Success package) (do (try.with promise.monad) [sub-dependencies (|> package //package.dependencies (\ promise.monad wrap)) resolution (|> resolution (dictionary.put head package) (read-all program system (set.to-list sub-dependencies)))] ) (#try.Failure error) )))))