aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/program
diff options
context:
space:
mode:
authorEduardo Julian2021-07-24 02:14:12 -0400
committerEduardo Julian2021-07-24 02:14:12 -0400
commit0f545b7e57d2564e351d907befd2ce26900c5521 (patch)
tree84faaf7b6cd43c2c2f56c5e37bcd61d2b0b1d829 /stdlib/source/program
parent4248cc22881a7eaa8f74bc426f2b0ba284b23153 (diff)
Now packaging JVM programs as "fat" jars in new JVM compiler.
Diffstat (limited to '')
-rw-r--r--stdlib/source/program/aedifex/command/build.lux127
-rw-r--r--stdlib/source/program/aedifex/command/test.lux14
-rw-r--r--stdlib/source/program/compositor.lux29
-rw-r--r--stdlib/source/program/compositor/cli.lux40
4 files changed, 171 insertions, 39 deletions
diff --git a/stdlib/source/program/aedifex/command/build.lux b/stdlib/source/program/aedifex/command/build.lux
index c0f9566a8..17301333a 100644
--- a/stdlib/source/program/aedifex/command/build.lux
+++ b/stdlib/source/program/aedifex/command/build.lux
@@ -1,7 +1,9 @@
(.module:
[library
[lux (#- Name)
+ ["." ffi (#+ import:)]
[abstract
+ [order (#+ Order)]
[monad (#+ do)]]
[control
["." try (#+ Try)]
@@ -12,14 +14,15 @@
[data
["." product]
["." maybe]
- ["." text ("#\." equivalence)
+ ["." text ("#\." order)
["%" format (#+ format)]]
[collection
- ["." list ("#\." functor)]
- ["." dictionary]
+ ["." list ("#\." functor fold)]
+ ["." dictionary (#+ Dictionary)]
["." set]]]
[math
[number
+ ["n" nat]
["i" int]]]
[world
["." program (#+ Program)]
@@ -37,7 +40,7 @@
["#." runtime]
["#." dependency (#+ Dependency)
["#/." resolution (#+ Resolution)]]
- ["#." artifact (#+ Group Name Artifact)
+ ["#." artifact (#+ Group Name Version Artifact)
["#/." type]]])
(type: Finder
@@ -119,9 +122,62 @@
(def: (libraries fs home)
(All [!] (-> (file.System !) Path Resolution (List Path)))
(|>> dictionary.keys
- (list.filter (|>> (get@ #///dependency.type) (text\= ///artifact/type.lux_library)))
+ (list.filter (|>> (get@ #///dependency.type)
+ (text\= ///artifact/type.lux_library)))
(list\map (..path fs home))))
+(def: version_separator
+ ".")
+
+(implementation: version_order
+ (Order Version)
+
+ (def: &equivalence
+ text.equivalence)
+
+ (def: (< left right)
+ (loop [left (text.split_all_with ..version_separator left)
+ right (text.split_all_with ..version_separator right)]
+ (case [left right]
+ [(#.Cons leftH leftT) (#.Cons rightH rightT)]
+ (if (text\= leftH rightH)
+ (recur leftT rightT)
+ (or (n.< (text.size leftH) (text.size rightH))
+ (text\< leftH rightH)))
+
+ [(#.Cons leftH leftT) #.Nil]
+ false
+
+ [#.Nil (#.Cons rightH rightT)]
+ true
+
+ [#.Nil #.Nil]
+ false))))
+
+(def: #export (host_dependencies fs home)
+ (All [!] (-> (file.System !) Path Resolution (List Path)))
+ (|>> dictionary.keys
+ (list.filter (|>> (get@ #///dependency.type)
+ (text\= ///artifact/type.lux_library)
+ not))
+ (list\fold (function (_ dependency uniques)
+ (let [artifact (get@ #///dependency.artifact dependency)
+ identity [(get@ #///artifact.group artifact)
+ (get@ #///artifact.name artifact)]
+ version (get@ #///artifact.version artifact)]
+ (case (dictionary.get identity uniques)
+ (#.Some [current_version current_path])
+ (if (\ version_order < version current_version)
+ (dictionary.put identity [version dependency] uniques)
+ uniques)
+
+ #.None
+ (dictionary.put identity [version dependency] uniques))))
+ (: (Dictionary [Group Name] [Version Dependency])
+ (dictionary.new (product.hash text.hash text.hash))))
+ dictionary.values
+ (list\map (|>> product.right (..path fs home)))))
+
(def: (singular name)
(-> Text Text (List Text))
(|>> (list name)))
@@ -169,6 +225,41 @@
[log_error! error]
)
+(import: java/lang/System
+ ["#::."
+ (#static getProperty [java/lang/String] #io #try java/lang/String)])
+
+(def: windows?
+ Bit
+ (|> (java/lang/System::getProperty "os.name")
+ io.run
+ (try.default "")
+ text.lower_case
+ (text.starts_with? "windows")))
+
+(def: jvm_class_path_separator
+ (if windows?
+ ";"
+ ":"))
+
+(def: (jvm_class_path host_dependencies)
+ (-> (List Path) Text)
+ (|> host_dependencies
+ (#.Cons ".")
+ (text.join_with ..jvm_class_path_separator)
+ %.text))
+
+(def: #export (with_jvm_class_path host_dependencies runtime)
+ (-> (List Path) ///runtime.Runtime ///runtime.Runtime)
+ (case host_dependencies
+ #.Nil
+ runtime
+
+ _
+ (update@ #///runtime.parameters
+ (|>> (list& "-classpath" (..jvm_class_path host_dependencies)))
+ runtime)))
+
(def: #export (do! console program fs shell resolution)
(-> (Console Promise) (Program Promise) (file.System Promise) (Shell Promise) Resolution (Command [Exit Compiler Path]))
(function (_ profile)
@@ -184,29 +275,37 @@
working_directory (\ program directory)]]
(do ///action.monad
[[resolution compiler] (promise\wrap (..compiler resolution (get@ #///.compiler profile)))
- #let [[[command compiler_params] output] (case compiler
+ #let [host_dependencies (..host_dependencies fs home resolution)
+ [[command compiler_params] output] (case compiler
+ (#JVM dependency)
+ [(|> (..path fs home dependency)
+ (///runtime.for (get@ #///.java profile))
+ (with_jvm_class_path host_dependencies))
+ "program.jar"]
+
(^template [<tag> <runtime> <program>]
[(<tag> dependency)
[(///runtime.for (get@ <runtime> profile)
(..path fs home dependency))
<program>]])
- ([#JVM #///.java "program.jar"]
- [#JS #///.js "program.js"]
+ ([#JS #///.js "program.js"]
[#Python #///.java "program.py"]
[#Lua #///.java "program.lua"]
[#Ruby #///.java "program.rb"]))
/ (\ fs separator)
cache_directory (format working_directory / target)]
_ (console.write_line ..start console)
+ #let [full_parameters (list.concat (list compiler_params
+ (list "build")
+ (..plural "--library" (..libraries fs home resolution))
+ (..plural "--host_dependency" host_dependencies)
+ (..plural "--source" (set.to_list (get@ #///.sources profile)))
+ (..singular "--target" cache_directory)
+ (..singular "--module" program_module)))]
process (\ shell execute [environment
working_directory
command
- (list.concat (list compiler_params
- (list "build")
- (..plural "--library" (..libraries fs home resolution))
- (..plural "--source" (set.to_list (get@ #///.sources profile)))
- (..singular "--target" cache_directory)
- (..singular "--module" program_module)))])
+ full_parameters])
_ (..log_output! console process)
_ (..log_error! console process)
exit (\ process await [])
diff --git a/stdlib/source/program/aedifex/command/test.lux b/stdlib/source/program/aedifex/command/test.lux
index 65f2bdc4e..1f32b2fc2 100644
--- a/stdlib/source/program/aedifex/command/test.lux
+++ b/stdlib/source/program/aedifex/command/test.lux
@@ -34,15 +34,23 @@
[environment (program.environment promise.monad program)
#let [working_directory (\ program directory)]]
(do {! ///action.monad}
- [[build_exit compiler program] (//build.do! console program fs shell resolution
+ [#let [home (\ program home)]
+ [build_exit compiler program] (//build.do! console program fs shell resolution
(set@ #///.program (get@ #///.test profile) profile))]
(if (i.= shell.normal build_exit)
(do !
[_ (console.write_line ..start console)
- #let [[test_command test_parameters] (case compiler
+ #let [host_dependencies (//build.host_dependencies fs home resolution)
+ [test_command test_parameters] (case compiler
+ (#//build.JVM dependency)
+ (|> program
+ (///runtime.for (get@ #///.java profile))
+ (//build.with_jvm_class_path host_dependencies))
+
(^template [<tag> <runtime>]
[(<tag> artifact)
- (///runtime.for (get@ <runtime> profile) program)])
+ (///runtime.for (get@ <runtime> profile)
+ program)])
([#//build.JVM #///.java]
[#//build.JS #///.js]
[#//build.Python #///.python]
diff --git a/stdlib/source/program/compositor.lux b/stdlib/source/program/compositor.lux
index bc96e7ae0..aa3239de2 100644
--- a/stdlib/source/program/compositor.lux
+++ b/stdlib/source/program/compositor.lux
@@ -17,7 +17,7 @@
["." text
["%" format (#+ format)]]
[collection
- ["." dictionary]
+ ["." dictionary (#+ Dictionary)]
["." row (#+ Row)]]]
[time
["." instant]]
@@ -84,15 +84,32 @@
(format "Duration: ")))]]
(wrap output)))
-(def: (package! fs [packager package] static archive context)
- (-> (file.System Promise) [Packager file.Path] Static Archive Context (Promise (Try Any)))
- (case (packager archive context)
+(def: (package! fs host_dependencies [packager package] static archive context)
+ (-> (file.System Promise) (Dictionary file.Path Binary) [Packager file.Path] Static Archive Context (Promise (Try Any)))
+ (case (packager host_dependencies archive context)
(#try.Success content)
(\ fs write content package)
(#try.Failure error)
(\ promise.monad wrap (#try.Failure error))))
+(def: (load_host_dependencies fs host_dependencies)
+ (-> (file.System Promise) (List file.Path) (Promise (Try (Dictionary file.Path Binary))))
+ (do {! (try.with promise.monad)}
+ []
+ (loop [pending host_dependencies
+ output (: (Dictionary file.Path Binary)
+ (dictionary.new text.hash))]
+ (case pending
+ #.Nil
+ (wrap output)
+
+ (#.Cons head tail)
+ (do !
+ [content (\ fs read head)]
+ (recur tail
+ (dictionary.put head content output)))))))
+
(with_expansions [<parameters> (as_is anchor expression artifact)]
(def: #export (compiler static
expander host_analysis platform generation_bundle host_directive_bundle program anchorT,expressionT,directiveT extender
@@ -118,7 +135,7 @@
(<| (or_crash! "Compilation failed:")
..timed
(do (try.with promise.monad)
- [#let [[compilation_sources compilation_libraries compilation_target compilation_module] compilation]
+ [#let [[compilation_sources compilation_host_dependencies compilation_libraries compilation_target compilation_module] compilation]
import (/import.import (get@ #platform.&file_system platform) compilation_libraries)
[state archive] (:share [<parameters>]
(Platform <parameters>)
@@ -136,9 +153,11 @@
(:assume (platform.compile import static expander platform compilation [archive state])))
_ (ioW.freeze (get@ #platform.&file_system platform) static archive)
program_context (promise\wrap ($/program.context archive))
+ host_dependencies (..load_host_dependencies (get@ #platform.&file_system platform) compilation_host_dependencies)
_ (..package! (for {@.old (file.async file.default)
@.jvm (file.async file.default)
@.js file.default})
+ host_dependencies
packager,package
static
archive
diff --git a/stdlib/source/program/compositor/cli.lux b/stdlib/source/program/compositor/cli.lux
index d3b61640b..f0fdb80be 100644
--- a/stdlib/source/program/compositor/cli.lux
+++ b/stdlib/source/program/compositor/cli.lux
@@ -16,6 +16,9 @@
(type: #export Source
Path)
+(type: #export Host_Dependency
+ Path)
+
(type: #export Library
Path)
@@ -23,7 +26,7 @@
Path)
(type: #export Compilation
- [(List Source) (List Library) Target Module])
+ [(List Source) (List Host_Dependency) (List Library) Target Module])
(type: #export Export
[(List Source) Target])
@@ -38,10 +41,11 @@
(Parser <type>)
(cli.named <long> cli.any))]
- [^source "--source" Source]
- [^library "--library" Library]
- [^target "--target" Target]
- [^module "--module" Module]
+ [source_parser "--source" Source]
+ [host_dependency_parser "--host_dependency" Host_Dependency]
+ [library_parser "--library" Library]
+ [target_parser "--target" Target]
+ [module_parser "--module" Module]
)
(def: #export service
@@ -49,25 +53,27 @@
($_ <>.or
(<>.after (cli.this "build")
($_ <>.and
- (<>.some ..^source)
- (<>.some ..^library)
- ..^target
- ..^module))
+ (<>.some ..source_parser)
+ (<>.some ..host_dependency_parser)
+ (<>.some ..library_parser)
+ ..target_parser
+ ..module_parser))
(<>.after (cli.this "repl")
($_ <>.and
- (<>.some ..^source)
- (<>.some ..^library)
- ..^target
- ..^module))
+ (<>.some ..source_parser)
+ (<>.some ..host_dependency_parser)
+ (<>.some ..library_parser)
+ ..target_parser
+ ..module_parser))
(<>.after (cli.this "export")
($_ <>.and
- (<>.some ..^source)
- ..^target))
+ (<>.some ..source_parser)
+ ..target_parser))
))
(def: #export target
(-> Service Target)
- (|>> (case> (^or (#Compilation [sources libraries target module])
- (#Interpretation [sources libraries target module])
+ (|>> (case> (^or (#Compilation [sources host_dependencies libraries target module])
+ (#Interpretation [sources host_dependencies libraries target module])
(#Export [sources target]))
target)))