aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/library/lux/tool/compiler/meta/export.lux
blob: 9b21de75b704c56005457109aa71a1092ca47f0a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
(.using
 [library
  [lux {"-" Source}
   [abstract
    ["[0]" monad {"+" do}]]
   [control
    ["[0]" try {"+" Try} ("[1]#[0]" monad)]
    [concurrency
     ["[0]" async {"+" Async} ("[1]#[0]" functor)]]]
   [data
    ["[0]" text
     ["%" format {"+" format}]]
    [collection
     ["[0]" dictionary]
     ["[0]" sequence]]
    [format
     ["[0]" binary]
     ["[0]" tar]]]
   [time
    ["[0]" instant]]
   [tool
    [compiler
     [meta
      [cli {"+" Source Export}]
      ["[0]" io "_"
       ["[1]" context]]]]]
   [world
    ["[0]" file]]]])

(def: .public file
  "library.tar")

(def: .public mode
  ($_ tar.and
      tar.read_by_owner tar.write_by_owner
      tar.read_by_group tar.write_by_group
      tar.read_by_other))

(def: .public 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)))
  (|> sources
      (io.listing fs)
      (async#each (|>> (try#each (|>> dictionary.entries
                                      (monad.each try.monad
                                                  (function (_ [path source_code])
                                                    (do try.monad
                                                      [path (|> path
                                                                (text.replaced (# fs separator) .module_separator)
                                                                tar.path)]
                                                      (try#each (|>> [path
                                                                      (instant.of_millis +0)
                                                                      ..mode
                                                                      ..ownership]
                                                                     {tar.#Normal})
                                                                (tar.content source_code)))))
                                      (try#each sequence.of_list)))
                       try#conjoint))))

(def: .public (export fs [sources target])
  (-> (file.System Async) Export (Async (Try Any)))
  (do [! (try.with async.monad)]
    [tar (|> sources
             (..library fs)
             (# ! each (binary.result tar.writer)))
     .let [/ (# fs separator)]]
    (# fs write tar (format target / ..file))))