(.module: [library [lux {"-" [Source]} [abstract ["[0]" monad {"+" [do]}]] [control ["[0]" try {"+" [Try]}] [concurrency ["[0]" async {"+" [Async]}]]] [data ["[0]" text ["%" format {"+" [format]}]] [collection ["[0]" dictionary] ["[0]" row]] [format ["[0]" binary] ["[0]" tar]]] [time ["[0]" instant]] [tool [compiler [meta ["[0]" io "_" ["[1]" context {"+" [Extension]}]]]]] [world ["[0]" file]]]] [// [cli {"+" [Source Export]}]]) (def: file "library.tar") (def: no_ownership tar.Ownership (let [commons (: tar.Owner [#tar.name tar.anonymous #tar.id tar.no_id])] [#tar.user commons #tar.group commons])) (def: .public (library fs sources) (-> (file.System Async) (List Source) (Async (Try tar.Tar))) (do (try.with async.monad) [files (io.listing fs sources)] (|> (dictionary.entries files) (monad.each try.monad (function (_ [path source_code]) (do try.monad [path (|> path (text.replaced (\ fs separator) .module_separator) tar.path) source_code (tar.content source_code)] (in {#tar.Normal [path (instant.of_millis +0) ($_ tar.and tar.read_by_owner tar.write_by_owner tar.read_by_group tar.write_by_group tar.read_by_other) ..no_ownership source_code]})))) (\ try.monad each row.of_list) (\ async.monad in)))) (def: .public (export fs [sources target]) (-> (file.System Async) Export (Async (Try Any))) (do [! (try.with async.monad)] [tar (\ ! each (binary.result tar.writer) (..library fs sources))] (|> ..file (format target (\ fs separator)) (\ fs write tar))))