From 0f545b7e57d2564e351d907befd2ce26900c5521 Mon Sep 17 00:00:00 2001 From: Eduardo Julian Date: Sat, 24 Jul 2021 02:14:12 -0400 Subject: Now packaging JVM programs as "fat" jars in new JVM compiler. --- stdlib/source/program/aedifex/command/build.lux | 127 +++++++++++++++++++++--- stdlib/source/program/aedifex/command/test.lux | 14 ++- stdlib/source/program/compositor.lux | 29 +++++- stdlib/source/program/compositor/cli.lux | 40 ++++---- 4 files changed, 171 insertions(+), 39 deletions(-) (limited to 'stdlib/source/program') 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 [ ] [( dependency) [(///runtime.for (get@ profile) (..path fs home dependency)) ]]) - ([#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 [ ] [( artifact) - (///runtime.for (get@ profile) program)]) + (///runtime.for (get@ 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 [ (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 [] (Platform ) @@ -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 ) (cli.named 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))) -- cgit v1.2.3