1
+ open Devkit
2
+
3
+ let log = Log. from " context"
4
+
5
+ exception Context_error of string
6
+
7
+ type cfg_make_args =
8
+ | LocalMake of string
9
+ | RemoteMake of string * Github .t
10
+
11
+ type cfg_origin =
12
+ | Local
13
+ | Remote
14
+
1
15
type data = {
2
- cfg : string ;
3
- secrets : string ;
4
- state : string ;
16
+ mutable cfg_path : string ;
17
+ mutable cfg_filename : string ;
18
+ cfg_source : cfg_origin ;
19
+ cfg_action_after_refresh : Config .t -> unit ;
20
+ secrets_path : string ;
21
+ state_path : string ;
5
22
disable_write : bool ;
6
23
}
7
24
8
25
type t = {
9
26
mutable state : Notabot_t .state ;
10
27
mutable cfg : Config .t ;
28
+ secrets : Notabot_t .secrets ;
11
29
data : data ;
12
30
}
13
31
14
- let refresh_config ctx = ctx.cfg < - Config. load ctx.data.cfg ctx.data.secrets
32
+ type context_thunk = {
33
+ secrets : Notabot_j .secrets ;
34
+ thunk : ?req:Github .t -> unit -> t Lwt .t ;
35
+ mutable ctx : t option ;
36
+ }
37
+
38
+ let get_secrets secrets_path = Config. load_secrets_file ~secrets_path
39
+
40
+ let load_config_json_local config_path = Lwt. return @@ Config. load_config_file ~config_path
41
+
42
+ let resolve_cfg_getter = function
43
+ | Local -> load_config_json_local
44
+ | Remote -> Github. load_config_json
45
+
46
+ let refresh_config ctx =
47
+ ( match ctx.data.cfg_source with
48
+ | Local -> log#info " attempting to retrieve config locally"
49
+ | Remote ->
50
+ match ctx.secrets.gh_token with
51
+ | None -> log#info " attempting to retrieve config remotely without gh_token"
52
+ | Some _ -> log#info " attempting to retrieve config remotely with gh_token"
53
+ );
54
+ let getter = resolve_cfg_getter ctx.data.cfg_source in
55
+ let % lwt cfg_json = getter ctx.data.cfg_path in
56
+ ctx.cfg < - Config. make cfg_json ctx.secrets;
57
+ ctx.data.cfg_action_after_refresh ctx.cfg;
58
+ Lwt. return_unit
15
59
16
60
let refresh_and_get_config ctx =
17
- refresh_config ctx;
18
- ctx.cfg
61
+ let % lwt () = refresh_config ctx in
62
+ Lwt. return ctx.cfg
63
+
64
+ let change_remote_url filename ctx req =
65
+ match ctx.data.cfg_source with
66
+ | Local -> raise @@ Context_error " can't load remote config from a local context"
67
+ | Remote ->
68
+ ctx.data.cfg_filename < - filename;
69
+ let url = Github. get_remote_config_json_url filename ?token:ctx.secrets.gh_token req in
70
+ ctx.data.cfg_path < - url;
71
+ refresh_config ctx
19
72
20
- let refresh_state ctx = ctx.state < - State. load ctx.data.state
73
+ let refresh_state ctx = ctx.state < - State. load ctx.data.state_path
21
74
22
75
let refresh_and_get_state ctx =
23
76
refresh_state ctx;
@@ -26,15 +79,62 @@ let refresh_and_get_state ctx =
26
79
let update_state ctx event =
27
80
ctx.state < - State. update_state ctx.state event;
28
81
match ctx.data.disable_write with
29
- | false -> State. save ctx.data.state ctx.state
82
+ | false -> State. save ctx.data.state_path ctx.state
30
83
| true -> ()
31
84
32
85
let update_and_get_state ctx event =
33
86
update_state ctx event;
34
87
ctx.state
35
88
36
- let make ~state_path ~cfg_path ~secrets_path ?(disable_write = false ) () =
37
- let cfg = Config. load cfg_path secrets_path in
89
+ let make_with_secrets ~state_path ~cfg_args ~secrets_path ~(secrets : Notabot_t.secrets ) ?(disable_write = false )
90
+ ?(cfg_action_after_refresh = fun _ -> () ) ()
91
+ =
92
+ let data_cfg_path, cfg_source, cfg_json, cfg_filename =
93
+ match cfg_args with
94
+ | LocalMake p -> p, Local , load_config_json_local p, p
95
+ | RemoteMake (filename , r ) ->
96
+ let token = secrets.gh_token in
97
+ let url = Github. get_remote_config_json_url filename ?token r in
98
+ let cfg_json = Github. load_config_json @@ Github. get_remote_config_json_url filename ?token r in
99
+ url, Remote , cfg_json, filename
100
+ in
101
+ let % lwt cfg_json = cfg_json in
102
+ let data =
103
+ {
104
+ cfg_path = data_cfg_path;
105
+ cfg_source;
106
+ cfg_action_after_refresh;
107
+ secrets_path;
108
+ state_path;
109
+ disable_write;
110
+ cfg_filename;
111
+ }
112
+ in
113
+ let cfg = Config. make cfg_json secrets in
38
114
let state = State. load state_path in
39
- let data = { cfg = cfg_path; secrets = secrets_path; state = state_path; disable_write } in
40
- { cfg; state; data }
115
+ Lwt. return { cfg; state; secrets; data }
116
+
117
+ let make ~state_path ~cfg_args ~secrets_path ?disable_write ?cfg_action_after_refresh () =
118
+ let secrets = get_secrets secrets_path in
119
+ make_with_secrets ~state_path ~cfg_args ~secrets_path ~secrets ?disable_write ?cfg_action_after_refresh ()
120
+
121
+ let make_thunk ~state_path ~cfg_path_or_remote_filename ~secrets_path ?disable_write ?cfg_action_after_refresh () =
122
+ let secrets = get_secrets secrets_path in
123
+ let make_args ?req () =
124
+ match req with
125
+ | None -> LocalMake cfg_path_or_remote_filename
126
+ | Some r -> RemoteMake (cfg_path_or_remote_filename, r)
127
+ in
128
+ let thunk ?req () =
129
+ make_with_secrets ~state_path ~cfg_args: (make_args ?req () ) ~secrets_path ~secrets ?disable_write
130
+ ?cfg_action_after_refresh ()
131
+ in
132
+ { secrets; thunk; ctx = None }
133
+
134
+ let resolve_ctx_in_thunk ctx_thunk req =
135
+ match ctx_thunk.ctx with
136
+ | Some ctx -> Lwt. return ctx
137
+ | None ->
138
+ let % lwt ctx = ctx_thunk.thunk ~req () in
139
+ let % lwt () = Lwt. return @@ (ctx_thunk.ctx < - Some ctx) in
140
+ Lwt. return ctx
0 commit comments