Source file ThunkLuaParams.ml

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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
type import = {
  import_library : MlFront_Core.LibraryId.t;
  import_version : ThunkSemver64.t;
  import_distribution_file : MlFront_Core.FilePath.t;
  import_checksums : import_checksum list;
}

and import_checksum = {
  checksum_algorithm : [ `SHA256 | `BLAKE2b_256 | `SHA1 ];
  checksum_digest : string;
}

type mode =
  | Analyze
      (** Track (ie. analyze) the ["build.define_rule"] and
          ["build.import_rule"] calls, and use no-ops for everything else. *)
  | Build of {
      valuescan_origin :
        [ `UserRanLuaWithoutValueScan
        | `UserRanBuild
        | `UserRanLuaWithValueScan ];
      fetch_script_module :
        MlFront_Core.StandardModuleId.t ->
        ThunkSemver64.t ->
        ([ `Found | `NotFound ], string) result;
          (** [fetch_script_module module_id module_semver] synchronously fetch
              a script module.

              Post-condition: When the return value is [Ok `Found] the module
              must have been placed in {!ThunkLuaTypPkgReg}'s registry. *)
    }
  | Unified of {
      fetch_script_module :
        MlFront_Core.StandardModuleId.t ->
        ThunkSemver64.t ->
        ([ `Found | `NotFound ], string) result;
          (** [fetch_script_module module_id module_semver] synchronously fetch
              a script module.

              Post-condition: When the return value is [Ok `Found] the module
              must have been placed in {!ThunkLuaTypPkgReg}'s registry. *)
      add_bundle_with_one_asset :
        bundle_modver:ThunkCommand.module_version ->
        asset_path:string ->
        values_file_json:string ->
        unit ->
        (unit, string) result;
          (** [add_bundle_with_one_asset ~bundle_modver ~asset_path
               ~values_file_json ~values_json_sha256 ()] add the JSON content
              [values_file_json] of a values.json file to the value and trace
              stores which includes the bundle [bundle_modver] with the asset
              path [asset_path]. *)
      stat_absfile :
        MlFront_Core.FilePath.t -> (ThunkLuaTypFile.stats, string) result;
          (** [stat_absfile abs_path] stats the absolute file at [abs_path].

              There {i might} be optimizations to cache the statistics including
              comparing the cached statistics timestamp with the filesystem
              timestamp. *)
      stat_absdir :
        MlFront_Core.FilePath.t -> (ThunkLuaTypFile.stats, string) result;
          (** [stat_absdir abs_path] stats the absolute directory at [abs_path].

              There {i might} be an internal staging directory to perform
              zipping operations when [abs_path] is a directory.

              There {i might} be optimizations to cache the statistics including
              comparing the cached statistics timestamp with the directory
              timestamp and/or directory content timestamps. *)
      asset_io_strategy : [ `EagerCompute | `PersistedOrEager ];
          (** Strategy for how [unified.asset] satisfies its size+checksum
              outputs.

              - [`EagerCompute]: always perform [stat_absfile]/[stat_absdir] and
                return real size+sha256. The [unified._existingoutput] of the
                [unified.asset] command is never consulted. Used by every
                unified script that is {b not} the workspace script so
                [dk0 test]/[dk0 distribute] always produce an accurate diff
                against the script's own existing output.

              - [`PersistedOrEager]: first consult [unified._existingoutput]; if
                a well-formed [['asset'; size; 'sha256:...']] (file) or
                [['asset'; size; { 'sha256:...' }]] (directory) value is
                present, build [values.json] from those values with {b no} file
                I/O. Otherwise fall through to the eager path so [dk0 update]
                computes real values to persist. Used exclusively by the
                workspace script. *)
    }
  | Workspace of {
      import_github_l2 :
        owner_and_repo:string ->
        host:string option ->
        tag:string option ->
        unit ->
        (import list, string) result;
      import_local : path:string -> unit -> (import list, string) result;
      reuse_imports : import list -> (unit, string) result;
      import_dir : MlFront_Core.FilePath.t;
      verify_import : import -> [ `Valid | `Recreate | `Invalid ];
          (** [`Valid] if and only if the import is valid. Set to [`Recreate] to
              force an update. Other [`Invalid]. *)
    }

(** [is_declarative_mode mode] is [true] if and only if the mode could be
    re-implemented {i without Lua}. In other words, Lua is only providing a
    framework to declare typed data:

    {v
      data_constructor("some string", 123, { key = "value" })

      data_constructor2 {
        field1 = "some string",
        field2 = 123,
        field3 = { key = "value" },
      }
    v}

    As much as feasible access to Lua is severely limited. No conventional Lua
    global functions like [print], [assert], or [error] are available. Only some
    libraries and globals will be available, and all library and global
    functions are data constructors.

    The [Unified _] mode allows
    [let modulename = require("modulename").at("version")] to import script
    modules. Those script modules are external libraries whose functions are
    also data constructors because the Lua environment available to those script
    modules only has data constructor libraries and global functions. *)
let is_declarative_mode = function
  | Unified _ | Workspace _ -> true
  | Analyze | Build _ -> false

(** [is_not_declarative_mode mode] is [true] if the mode requires Lua global
    functions to execute the mode. It is the negation of {!is_declarative_mode}.
*)
let is_not_declarative_mode mode = not (is_declarative_mode mode)

module type S = sig
  val mode : mode
end