diff options
Diffstat (limited to 'stdlib/source/program/aedifex')
-rw-r--r-- | stdlib/source/program/aedifex/cli.lux | 16 | ||||
-rw-r--r-- | stdlib/source/program/aedifex/command.lux | 8 | ||||
-rw-r--r-- | stdlib/source/program/aedifex/command/auto.lux | 141 | ||||
-rw-r--r-- | stdlib/source/program/aedifex/command/build.lux (renamed from stdlib/source/program/aedifex/build.lux) | 72 | ||||
-rw-r--r-- | stdlib/source/program/aedifex/command/test.lux | 29 |
5 files changed, 229 insertions, 37 deletions
diff --git a/stdlib/source/program/aedifex/cli.lux b/stdlib/source/program/aedifex/cli.lux index 3b5a33fb1..3cbb2aae8 100644 --- a/stdlib/source/program/aedifex/cli.lux +++ b/stdlib/source/program/aedifex/cli.lux @@ -4,11 +4,21 @@ ["<>" parser ["." cli (#+ Parser)]]]]) +(type: #export Compilation + #Build + #Test) + +(def: compilation + (Parser Compilation) + (<>.or (cli.this "build") + (cli.this "test"))) + (type: #export Command #POM #Install #Dependencies - #Buikd) + (#Compilation Compilation) + (#Auto Compilation)) (def: #export command (Parser Command) @@ -16,5 +26,7 @@ (cli.this "pom") (cli.this "install") (cli.this "deps") - (cli.this "buikd") + ..compilation + (<>.after (cli.this "auto") + ..compilation) )) diff --git a/stdlib/source/program/aedifex/command.lux b/stdlib/source/program/aedifex/command.lux new file mode 100644 index 000000000..8b4432a97 --- /dev/null +++ b/stdlib/source/program/aedifex/command.lux @@ -0,0 +1,8 @@ +(.module: + [lux #*] + ["." // #_ + ["#" project] + ["#." action (#+ Action)]]) + +(type: #export (Command a) + (-> //.Project (Action a))) diff --git a/stdlib/source/program/aedifex/command/auto.lux b/stdlib/source/program/aedifex/command/auto.lux new file mode 100644 index 000000000..5bf759a06 --- /dev/null +++ b/stdlib/source/program/aedifex/command/auto.lux @@ -0,0 +1,141 @@ +(.module: + [lux #* + ["." host (#+ import:)] + [abstract + ["." monad (#+ do)]] + [control + ["." try (#+ Try)] + ["." io (#+ IO)] + [concurrency + ["." promise]]] + [data + [collection + ["." array] + ["." list]]] + [world + [file (#+ Path)]]] + ["." // #_ + ["/#" // #_ + ["#" project] + ["#." action (#+ Action)] + ["#." command (#+ Command)]]]) + +(import: #long java/nio/file/WatchKey + (reset [] #io boolean)) + +(import: #long java/util/concurrent/TimeUnit + (#enum SECONDS)) + +(import: #long java/nio/file/WatchService + (poll [long java/util/concurrent/TimeUnit] #io #try #? java/nio/file/WatchKey) + (poll #as fetch [] #io #try #? java/nio/file/WatchKey)) + +(import: #long java/nio/file/FileSystem + (newWatchService [] #io #try java/nio/file/WatchService)) + +(import: #long java/nio/file/FileSystems + (#static getDefault [] java/nio/file/FileSystem)) + +(import: #long java/lang/Object) + +(import: #long java/lang/String) + +(import: #long (java/nio/file/WatchEvent$Kind a)) + +(import: #long java/nio/file/StandardWatchEventKinds + (#static ENTRY_CREATE (java/nio/file/WatchEvent$Kind java/nio/file/Path)) + (#static ENTRY_MODIFY (java/nio/file/WatchEvent$Kind java/nio/file/Path)) + (#static ENTRY_DELETE (java/nio/file/WatchEvent$Kind java/nio/file/Path))) + +(import: #long java/nio/file/Path + (register [java/nio/file/WatchService [(java/nio/file/WatchEvent$Kind ?)]] #io #try java/nio/file/WatchKey)) + +(import: #long java/io/File + (new [java/lang/String]) + (exists [] #io #try boolean) + (isDirectory [] #io #try boolean) + (listFiles [] #io #try [java/io/File]) + (getAbsolutePath [] #io #try java/lang/String) + (toPath [] java/nio/file/Path)) + +(def: (targets path) + (-> Path (Action (List Path))) + (promise.future + (loop [path path] + (let [file (java/io/File::new path)] + (do {@ (try.with io.monad)} + [exists? (java/io/File::exists file) + directory? (java/io/File::isDirectory file)] + (if (and exists? + directory?) + (do @ + [children (java/io/File::listFiles file) + children (|> children + array.to-list + (monad.map @ (|>> java/io/File::getAbsolutePath))) + descendants (monad.map @ recur children)] + (wrap (#.Cons path (list.concat descendants)))) + (wrap (list)))))))) + +(type: Watch-Event + (java/nio/file/WatchEvent$Kind java/lang/Object)) + +(def: watch-events + (List Watch-Event) + (list (:coerce Watch-Event (java/nio/file/StandardWatchEventKinds::ENTRY_CREATE)) + (:coerce Watch-Event (java/nio/file/StandardWatchEventKinds::ENTRY_MODIFY)) + (:coerce Watch-Event (java/nio/file/StandardWatchEventKinds::ENTRY_DELETE)))) + +(def: (watch! watcher path) + (-> java/nio/file/WatchService Path (Action Any)) + (promise.future + (do (try.with io.monad) + [_ (java/nio/file/Path::register watcher + (array.from-list ..watch-events) + (|> path java/io/File::new java/io/File::toPath))] + (wrap [])))) + +(def: (poll! watcher) + (-> java/nio/file/WatchService (Action (Maybe java/nio/file/WatchKey))) + (promise.future + (java/nio/file/WatchService::poll 1 java/util/concurrent/TimeUnit::SECONDS watcher))) + +(def: (drain! watcher) + (-> java/nio/file/WatchService (IO (Try Any))) + (do (try.with io.monad) + [?key (java/nio/file/WatchService::fetch watcher)] + (case ?key + (#.Some key) + (do io.monad + [valid? (java/nio/file/WatchKey::reset key)] + (if valid? + (drain! watcher) + (wrap (:: try.monad wrap [])))) + + #.None + (wrap [])))) + +(def: #export (do! command project) + (All [a] (-> (Command a) (Command Any))) + (do {@ ///action.monad} + [#let [fs (java/nio/file/FileSystems::getDefault)] + watcher (promise.future (java/nio/file/FileSystem::newWatchService fs)) + targets (|> project + (get@ #///.sources) + (monad.map @ ..targets) + (:: @ map list.concat)) + _ (monad.map @ (..watch! watcher) targets) + _ (command project)] + (loop [_ []] + (do @ + [?key (..poll! watcher) + _ (case ?key + (#.Some key) + (do @ + [_ (promise.future (..drain! watcher)) + _ (command project)] + (wrap [])) + + #.None + (wrap []))] + (recur []))))) diff --git a/stdlib/source/program/aedifex/build.lux b/stdlib/source/program/aedifex/command/build.lux index 74f64cb59..0e5d1e229 100644 --- a/stdlib/source/program/aedifex/build.lux +++ b/stdlib/source/program/aedifex/command/build.lux @@ -2,13 +2,13 @@ [lux (#- Name) ["." host (#+ import:)] [abstract - [monad (#+ Monad do)]] + [monad (#+ do)]] [control ["." try (#+ Try)] ["." exception (#+ exception:)] ["." io (#+ IO)] [concurrency - ["." promise (#+ Promise) ("#@." monad)]]] + ["." promise ("#@." monad)]]] [data ["." product] ["." maybe] @@ -19,17 +19,15 @@ ["." dictionary]]] [world ["." file (#+ Path)]]] - ["." // #_ + ["." /// #_ ["#" project] - ["#." action (#+ Action)] + ["#." action] + ["#." command (#+ Command)] ["#." local] ["#." artifact (#+ Group Name Artifact)] ["#." dependency (#+ Dependency Resolution)] ["#." shell]]) -(type: #export (Command a) - (-> //.Project (Action a))) - (type: Finder (-> Resolution (Maybe Dependency))) @@ -37,8 +35,8 @@ (-> Group Name Finder) (|>> dictionary.entries (list.search (function (_ [dependency package]) - (if (and (text@= group (get@ [#//dependency.artifact #//artifact.group] dependency)) - (text@= name (get@ [#//dependency.artifact #//artifact.name] dependency))) + (if (and (text@= group (get@ [#///dependency.artifact #///artifact.group] dependency)) + (text@= name (get@ [#///dependency.artifact #///artifact.name] dependency))) (#.Some dependency) #.None))))) @@ -58,7 +56,7 @@ (exception: #export no-available-compiler) (exception: #export no-specified-program) -(type: Compiler +(type: #export Compiler (#JVM Artifact) (#JS Artifact)) @@ -66,7 +64,7 @@ (-> Dependency (-> Resolution Resolution)) (|>> dictionary.entries (list.filter (|>> product.left (is? dependency) not)) - (dictionary.from-list //dependency.hash))) + (dictionary.from-list ///dependency.hash))) (def: (compiler resolution) (-> Resolution (Try [Resolution Compiler])) @@ -74,11 +72,11 @@ (..js-compiler resolution)] [(#.Some dependency) _] (#try.Success [(..remove-dependency dependency resolution) - (#JVM (get@ #//dependency.artifact dependency))]) + (#JVM (get@ #///dependency.artifact dependency))]) [_ (#.Some dependency)] (#try.Success [(..remove-dependency dependency resolution) - (#JS (get@ #//dependency.artifact dependency))]) + (#JS (get@ #///dependency.artifact dependency))]) _ (exception.throw ..no-available-compiler []))) @@ -86,8 +84,8 @@ (def: libraries (-> Resolution (List Path)) (|>> dictionary.keys - (list.filter (|>> (get@ #//dependency.type) (text@= //dependency.lux-library))) - (list@map (|>> (get@ #//dependency.artifact) (//local.path file.system))))) + (list.filter (|>> (get@ #///dependency.type) (text@= ///dependency.lux-library))) + (list@map (|>> (get@ #///dependency.artifact) (///local.path file.system))))) (import: #long java/lang/String) @@ -95,7 +93,7 @@ (import: #long java/lang/System (#static getProperty [java/lang/String] #io #? java/lang/String)) -(def: working-directory +(def: #export working-directory (IO (Try Text)) (do io.monad [?value (java/lang/System::getProperty "user.dir")] @@ -110,35 +108,39 @@ (|> values (list@map (|>> (format name " "))) (text.join-with " "))) (def: #export (do! project) - (Command Any) - (case (get@ #//.program project) + (Command [Compiler + Path]) + (case (get@ #///.program project) (#.Some program) - (do //action.monad - [cache (//local.all-cached (file.async file.system) - (get@ #//.dependencies project) - //dependency.empty) + (do ///action.monad + [cache (///local.all-cached (file.async file.system) + (get@ #///.dependencies project) + ///dependency.empty) resolution (promise.future - (//dependency.resolve-all (get@ #//.repositories project) - (get@ #//.dependencies project) - cache)) - _ (//local.cache-all (file.async file.system) - resolution) + (///dependency.resolve-all (get@ #///.repositories project) + (get@ #///.dependencies project) + cache)) + _ (///local.cache-all (file.async file.system) + resolution) [resolution compiler] (promise@wrap (..compiler resolution)) working-directory (promise.future ..working-directory) #let [libraries (..libraries resolution) - prefix (case compiler - (#JVM artifact) (format "java -jar " (//local.path file.system artifact)) - (#JS artifact) (format "node --stack_size=8192 " (//local.path file.system artifact))) - cache-directory (format working-directory (:: file.system separator) (get@ #//.target project)) + [prefix output] (case compiler + (#JVM artifact) [(format "java -jar " (///local.path file.system artifact)) + "program.jar"] + (#JS artifact) [(format "node --stack_size=8192 " (///local.path file.system artifact)) + "program.js"]) + cache-directory (format working-directory (:: file.system separator) (get@ #///.target project)) command (format prefix " build" " " (..plural-parameter "--library" libraries) - " " (..plural-parameter "--source" (get@ #//.sources project)) + " " (..plural-parameter "--source" (get@ #///.sources project)) " " (..singular-parameter "--target" cache-directory) " " (..singular-parameter "--module" program))] #let [_ (log! "[BUILD STARTED]")] - outcome (//shell.execute command working-directory) - #let [_ (log! "[BUILD END]")]] - (wrap [])) + outcome (///shell.execute command working-directory) + #let [_ (log! "[BUILD ENDED]")]] + (wrap [compiler + (format cache-directory (:: file.system separator) output)])) #.None (promise@wrap (exception.throw ..no-specified-program [])))) diff --git a/stdlib/source/program/aedifex/command/test.lux b/stdlib/source/program/aedifex/command/test.lux new file mode 100644 index 000000000..a27c07f10 --- /dev/null +++ b/stdlib/source/program/aedifex/command/test.lux @@ -0,0 +1,29 @@ +(.module: + [lux (#- Name) + [abstract + [monad (#+ do)]] + [control + [concurrency + ["." promise]]] + [data + [text + ["%" format (#+ format)]]]] + ["." // #_ + ["#." build] + ["/#" // #_ + ["#." action] + ["#." command (#+ Command)] + ["#." shell]]]) + +(def: #export (do! project) + (Command Any) + (do ///action.monad + [[compiler program] (//build.do! project) + working-directory (promise.future //build.working-directory) + #let [command (case compiler + (#//build.JVM artifact) (format "java -jar " program) + (#//build.JS artifact) (format "node --stack_size=8192 " program))] + #let [_ (log! "[TEST STARTED]")] + outcome (///shell.execute command working-directory) + #let [_ (log! "[TEST ENDED]")]] + (wrap []))) |