From b1f0014dd9080c6643ecd73db5233fbdff032419 Mon Sep 17 00:00:00 2001 From: Eduardo Julian Date: Sat, 29 Aug 2020 01:06:42 -0400 Subject: Test programs + auti build/test. --- stdlib/source/program/aedifex/build.lux | 144 ----------------------- stdlib/source/program/aedifex/cli.lux | 16 ++- stdlib/source/program/aedifex/command.lux | 8 ++ stdlib/source/program/aedifex/command/auto.lux | 141 +++++++++++++++++++++++ stdlib/source/program/aedifex/command/build.lux | 146 ++++++++++++++++++++++++ stdlib/source/program/aedifex/command/test.lux | 29 +++++ 6 files changed, 338 insertions(+), 146 deletions(-) delete mode 100644 stdlib/source/program/aedifex/build.lux create mode 100644 stdlib/source/program/aedifex/command.lux create mode 100644 stdlib/source/program/aedifex/command/auto.lux create mode 100644 stdlib/source/program/aedifex/command/build.lux create mode 100644 stdlib/source/program/aedifex/command/test.lux (limited to 'stdlib/source/program/aedifex') diff --git a/stdlib/source/program/aedifex/build.lux b/stdlib/source/program/aedifex/build.lux deleted file mode 100644 index 74f64cb59..000000000 --- a/stdlib/source/program/aedifex/build.lux +++ /dev/null @@ -1,144 +0,0 @@ -(.module: - [lux (#- Name) - ["." host (#+ import:)] - [abstract - [monad (#+ Monad do)]] - [control - ["." try (#+ Try)] - ["." exception (#+ exception:)] - ["." io (#+ IO)] - [concurrency - ["." promise (#+ Promise) ("#@." monad)]]] - [data - ["." product] - ["." maybe] - ["." text ("#@." equivalence) - ["%" format (#+ format)]] - [collection - ["." list ("#@." functor)] - ["." dictionary]]] - [world - ["." file (#+ Path)]]] - ["." // #_ - ["#" project] - ["#." action (#+ Action)] - ["#." local] - ["#." artifact (#+ Group Name Artifact)] - ["#." dependency (#+ Dependency Resolution)] - ["#." shell]]) - -(type: #export (Command a) - (-> //.Project (Action a))) - -(type: Finder - (-> Resolution (Maybe Dependency))) - -(def: (dependency-finder group name) - (-> 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))) - (#.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) - -(type: 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@= //dependency.lux-library))) - (list@map (|>> (get@ #//dependency.artifact) (//local.path file.system))))) - -(import: #long java/lang/String) - -## https://docs.oracle.com/javase/tutorial/essential/environment/sysprop.html -(import: #long java/lang/System - (#static getProperty [java/lang/String] #io #? java/lang/String)) - -(def: 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! project) - (Command Any) - (case (get@ #//.program project) - (#.Some program) - (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) - [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)) - command (format prefix " build" - " " (..plural-parameter "--library" libraries) - " " (..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 [])) - - #.None - (promise@wrap (exception.throw ..no-specified-program [])))) 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/command/build.lux b/stdlib/source/program/aedifex/command/build.lux new file mode 100644 index 000000000..0e5d1e229 --- /dev/null +++ b/stdlib/source/program/aedifex/command/build.lux @@ -0,0 +1,146 @@ +(.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]]] + [world + ["." file (#+ Path)]]] + ["." /// #_ + ["#" project] + ["#." action] + ["#." command (#+ Command)] + ["#." local] + ["#." artifact (#+ Group Name Artifact)] + ["#." dependency (#+ Dependency Resolution)] + ["#." shell]]) + +(type: Finder + (-> Resolution (Maybe Dependency))) + +(def: (dependency-finder group name) + (-> 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))) + (#.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) + +(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@= ///dependency.lux-library))) + (list@map (|>> (get@ #///dependency.artifact) (///local.path file.system))))) + +(import: #long java/lang/String) + +## https://docs.oracle.com/javase/tutorial/essential/environment/sysprop.html +(import: #long 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! 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) + resolution (promise.future + (///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 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)) + " " (..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.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 []))) -- cgit v1.2.3