(.module: [lux (#- Name) ["." host (#+ import:)] [abstract [monad (#+ do)]] [control ["." try (#+ Try)] ["." exception (#+ exception:)] ["." io (#+ IO)] [concurrency ["." promise ("#@." monad)]]] [data ["." product] ["." maybe] ["." text ("#@." equivalence) ["%" format (#+ format)]] [collection ["." list ("#@." functor)] ["." dictionary] ["." set]]] [world ["." file (#+ Path)]]] ["." /// #_ ["#" profile] ["#." action] ["#." command (#+ Command)] ["#." local] ["#." cache] ["#." dependency (#+ Dependency) ["#/." resolution (#+ Resolution)]] ["#." shell] ["#." artifact (#+ Group Name Artifact) ["#/." type]]]) (type: Finder (-> Resolution (Maybe Dependency))) (def: (dependency-finder group name) (-> Group Name Finder) (|>> dictionary.entries (list.one (function (_ [dependency package]) (if (and (text@= group (get@ [#///dependency.artifact #///artifact.group] dependency)) (text@= name (get@ [#///dependency.artifact #///artifact.name] dependency))) (#.Some dependency) #.None))))) (def: lux-group Group "com.github.luxlang") (template [ ] [(def: Finder (..dependency-finder ..lux-group ))] ["lux-jvm" jvm-compiler] ["lux-js" js-compiler] ) (exception: #export no-available-compiler) (exception: #export no-specified-program) (exception: #export no-specified-target) (type: #export Compiler (#JVM Artifact) (#JS Artifact)) (def: (remove-dependency dependency) (-> Dependency (-> Resolution Resolution)) (|>> dictionary.entries (list.filter (|>> product.left (is? dependency) not)) (dictionary.from-list ///dependency.hash))) (def: (compiler resolution) (-> Resolution (Try [Resolution Compiler])) (case [(..jvm-compiler resolution) (..js-compiler resolution)] [(#.Some dependency) _] (#try.Success [(..remove-dependency dependency resolution) (#JVM (get@ #///dependency.artifact dependency))]) [_ (#.Some dependency)] (#try.Success [(..remove-dependency dependency resolution) (#JS (get@ #///dependency.artifact dependency))]) _ (exception.throw ..no-available-compiler []))) (def: libraries (-> Resolution (List Path)) (|>> dictionary.keys (list.filter (|>> (get@ #///dependency.type) (text@= ///artifact/type.lux-library))) (list@map (|>> (get@ #///dependency.artifact) (///local.path file.default))))) (import: java/lang/String) ## https://docs.oracle.com/javase/tutorial/essential/environment/sysprop.html (import: java/lang/System (#static getProperty [java/lang/String] #io #? java/lang/String)) (def: #export working-directory (IO (Try Text)) (do io.monad [?value (java/lang/System::getProperty "user.dir")] (wrap (#try.Success (maybe.default "~" ?value))))) (def: (singular-parameter name value) (-> Text Text Text) (format name " " value)) (def: (plural-parameter name values) (-> Text (List Text) Text) (|> values (list@map (|>> (format name " "))) (text.join-with " "))) (def: #export (do! profile) (Command [Compiler Path]) (case [(get@ #///.program profile) (get@ #///.target profile)] [#.None _] (promise@wrap (exception.throw ..no-specified-program [])) [_ #.None] (promise@wrap (exception.throw ..no-specified-target [])) [(#.Some program) (#.Some target)] (do ///action.monad [cache (///cache.read-all (file.async file.default) (set.to-list (get@ #///.dependencies profile)) ///dependency/resolution.empty) resolution (promise.future (///dependency/resolution.resolve-all (set.to-list (get@ #///.repositories profile)) (set.to-list (get@ #///.dependencies profile)) cache)) _ (///cache.write-all (file.async file.default) resolution) [resolution compiler] (promise@wrap (..compiler resolution)) working-directory (promise.future ..working-directory) #let [libraries (..libraries resolution) [prefix output] (case compiler (#JVM artifact) [(format "java -jar " (///local.path file.default artifact)) "program.jar"] (#JS artifact) [(format "node --stack_size=8192 " (///local.path file.default artifact)) "program.js"]) cache-directory (format working-directory (:: file.default separator) target) command (format prefix " build" " " (..plural-parameter "--library" libraries) " " (..plural-parameter "--source" (set.to-list (get@ #///.sources profile))) " " (..singular-parameter "--target" cache-directory) " " (..singular-parameter "--module" program))] #let [_ (log! "[BUILD STARTED]")] outcome (///shell.execute command working-directory) #let [_ (log! "[BUILD ENDED]")]] (wrap [compiler (format cache-directory (:: file.default separator) output)])) ))