Skip to content

Commit 6741fb6

Browse files
committed
move config into its own hashtable
1 parent ababd1f commit 6741fb6

File tree

5 files changed

+38
-53
lines changed

5 files changed

+38
-53
lines changed

lib/action.ml

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ module Action (Github_api : Api.Github) (Slack_api : Api.Slack) = struct
8888

8989
let partition_status (ctx : Context.t) (n : status_notification) =
9090
let repo = n.repository in
91-
let cfg = State.find_repo_config_exn ctx.state repo.url in
91+
let cfg = Context.find_repo_config_exn ctx repo.url in
9292
let pipeline = n.context in
9393
let current_status = n.state in
9494
let rules = cfg.status_rules.rules in
@@ -111,8 +111,8 @@ module Action (Github_api : Api.Github) (Slack_api : Api.Slack) = struct
111111
| Ok commit -> Lwt.return @@ partition_commit cfg commit.files
112112
)
113113
in
114-
if State.is_pipeline_allowed ctx.state repo.url ~pipeline then begin
115-
let repo_state = State.find_repo_exn ctx.state repo.url in
114+
if Context.is_pipeline_allowed ctx repo.url ~pipeline then begin
115+
let repo_state = State.find_or_add_repo ctx.state repo.url in
116116
match Rule.Status.match_rules ~rules n with
117117
| Some Ignore | None -> Lwt.return []
118118
| Some Allow -> action_on_match n.branches
@@ -131,7 +131,7 @@ module Action (Github_api : Api.Github) (Slack_api : Api.Slack) = struct
131131
else Lwt.return []
132132

133133
let partition_commit_comment (ctx : Context.t) n =
134-
let cfg = State.find_repo_config_exn ctx.state n.repository.url in
134+
let cfg = Context.find_repo_config_exn ctx n.repository.url in
135135
match n.comment.commit_id with
136136
| None -> action_error "unable to find commit id for this commit comment event"
137137
| Some sha ->
@@ -151,7 +151,7 @@ module Action (Github_api : Api.Github) (Slack_api : Api.Slack) = struct
151151

152152
let generate_notifications (ctx : Context.t) req =
153153
let repo = Github.repo_of_notification req in
154-
let cfg = State.find_repo_config_exn ctx.state repo.url in
154+
let cfg = Context.find_repo_config_exn ctx repo.url in
155155
match req with
156156
| Github.Push n ->
157157
partition_push cfg n |> List.map ~f:(fun (channel, n) -> generate_push_notification n channel) |> Lwt.return
@@ -181,20 +181,19 @@ module Action (Github_api : Api.Github) (Slack_api : Api.Slack) = struct
181181
Lwt_list.iter_s notify notifications
182182

183183
(** `refresh_repo_config ctx n` fetches the latest repo config if it's
184-
uninitialized in state, or if the incoming request `n` is a push
184+
uninitialized, or if the incoming request `n` is a push
185185
notification containing commits that touched the config file. *)
186186
let refresh_repo_config (ctx : Context.t) notification =
187187
let repo = Github.repo_of_notification notification in
188188
let fetch_config () =
189189
match%lwt Github_api.get_config ~ctx ~repo with
190190
| Ok config ->
191-
State.set_repo_config ctx.state ~repo_url:repo.url ~config;
191+
Context.set_repo_config ctx repo.url config;
192192
Context.print_config ctx repo.url;
193193
Lwt.return @@ Ok ()
194194
| Error e -> action_error e
195195
in
196-
let repo_state = State.find_or_add_repo ctx.state repo.url in
197-
match repo_state.config with
196+
match Context.find_repo_config ctx repo.url with
198197
| None -> fetch_config ()
199198
| Some _ ->
200199
match notification with
@@ -251,9 +250,6 @@ module Action (Github_api : Api.Github) (Slack_api : Api.Slack) = struct
251250
| Context.Context_error msg ->
252251
log#error "%s" msg;
253252
Lwt.return_unit
254-
| State.State_error msg ->
255-
log#error "%s" msg;
256-
Lwt.return_unit
257253

258254
let process_link_shared_event (ctx : Context.t) (event : Slack_t.link_shared_event) =
259255
let process link =

lib/context.ml

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,14 @@ open Devkit
44

55
exception Context_error of string
66

7-
let context_error msg = raise (Context_error msg)
7+
let context_error fmt = Printf.ksprintf (fun msg -> raise (Context_error msg)) fmt
88

99
type t = {
1010
config_filename : string;
1111
secrets_filepath : string;
1212
state_filepath : string option;
1313
mutable secrets : Config_t.secrets option;
14+
config : Config_t.config Table.t;
1415
state : State_t.state;
1516
}
1617

@@ -20,6 +21,7 @@ let default () : t =
2021
secrets_filepath = "secrets.json";
2122
state_filepath = None;
2223
secrets = None;
24+
config = Table.empty ();
2325
state = State.empty ();
2426
}
2527

@@ -34,6 +36,15 @@ let get_secrets_exn ctx =
3436
| None -> context_error "secrets is uninitialized"
3537
| Some secrets -> secrets
3638

39+
let find_repo_config ctx repo_url = Hashtbl.find ctx.config repo_url
40+
41+
let find_repo_config_exn ctx repo_url =
42+
match find_repo_config ctx repo_url with
43+
| None -> context_error "config uninitialized for repo %s" repo_url
44+
| Some config -> config
45+
46+
let set_repo_config ctx repo_url config = Hashtbl.set ctx.config ~key:repo_url ~data:config
47+
3748
let gh_token_of_secrets (secrets : Config_t.secrets) repo_url =
3849
match Map.find secrets.repos repo_url with
3950
| None -> secrets.gh_token
@@ -50,6 +61,18 @@ let hook_of_channel ctx channel_name =
5061
| Some hook -> Some hook.url
5162
| None -> None
5263

64+
(** `is_pipeline_allowed s r p` returns `true` if
65+
`status_rules` doesn't define a whitelist of allowed
66+
pipelines in the config of repo `r`, or if the list
67+
contains pipeline `p`; returns `false` otherwise. *)
68+
let is_pipeline_allowed ctx repo_url ~pipeline =
69+
match find_repo_config ctx repo_url with
70+
| None -> false
71+
| Some config ->
72+
match config.status_rules.allowed_pipelines with
73+
| Some allowed_pipelines when not @@ List.exists allowed_pipelines ~f:(String.equal pipeline) -> false
74+
| _ -> true
75+
5376
let log = Log.from "context"
5477

5578
let refresh_secrets ctx =
@@ -81,7 +104,7 @@ let refresh_state ctx =
81104
else Ok ctx
82105

83106
let print_config ctx repo_url =
84-
let cfg = State.find_repo_config_exn ctx.state repo_url in
107+
let cfg = find_repo_config_exn ctx repo_url in
85108
let secrets = get_secrets_exn ctx in
86109
let token = gh_hook_token_of_secrets secrets repo_url in
87110
log#info "using prefix routing:";

lib/state.atd

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ type pipeline_statuses = branch_statuses map_as_object
1313

1414
(* The runtime state of a given GitHub repository *)
1515
type repo_state = {
16-
?config <ocaml mutable>: config option;
1716
pipeline_statuses <ocaml mutable>: pipeline_statuses
1817
}
1918

lib/state.ml

Lines changed: 3 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2,54 +2,21 @@ open Base
22
open Common
33
open Devkit
44

5-
exception State_error of string
6-
7-
let state_error fmt = Printf.ksprintf (fun msg -> raise (State_error msg)) fmt
8-
9-
let empty_repo_state () : State_t.repo_state = { pipeline_statuses = StringMap.empty; config = None }
5+
let empty_repo_state () : State_t.repo_state = { pipeline_statuses = StringMap.empty }
106

117
let empty () : State_t.state = { repos = Table.empty () }
128

139
let find_or_add_repo (state : State_t.state) repo_url =
1410
Hashtbl.find_or_add state.repos repo_url ~default:empty_repo_state
1511

16-
let find_repo_exn (state : State_t.state) repo_url =
17-
match Hashtbl.find state.repos repo_url with
18-
| None -> state_error "state uninitialized for repo %s" repo_url
19-
| Some repo_state -> repo_state
20-
21-
let find_repo_config_exn state repo_url =
22-
match (find_repo_exn state repo_url).config with
23-
| None -> state_error "config uninitialized for repo %s" repo_url
24-
| Some config -> config
25-
26-
let set_repo_config (state : State_t.state) ~repo_url ~config =
27-
match Hashtbl.find state.repos repo_url with
28-
| None -> state_error "state uninitialized for repo %s" repo_url
29-
| Some repo_state -> repo_state.config <- Some config
30-
3112
let set_repo_pipeline_status (state : State_t.state) repo_url ~pipeline ~(branches : Github_t.branch list) ~status =
3213
let set_branch_status branch_statuses =
3314
let new_statuses = List.map branches ~f:(fun b -> b.name, status) in
3415
let init = Option.value branch_statuses ~default:(Map.empty (module String)) in
3516
List.fold_left new_statuses ~init ~f:(fun m (key, data) -> Map.set m ~key ~data)
3617
in
37-
match Hashtbl.find state.repos repo_url with
38-
| None -> state_error "state uninitialized for repo %s" repo_url
39-
| Some repo_state ->
40-
repo_state.pipeline_statuses <- Map.update repo_state.pipeline_statuses pipeline ~f:set_branch_status
41-
42-
(** `is_pipeline_allowed s r p` returns `true` if
43-
`status_rules` doesn't define a whitelist of allowed
44-
pipelines in the config of repo `r`, or if the list
45-
contains pipeline `p`; returns `false` otherwise. *)
46-
let is_pipeline_allowed (state : State_t.state) repo_url ~pipeline =
47-
match (find_repo_exn state repo_url).config with
48-
| None -> false
49-
| Some config ->
50-
match config.status_rules.allowed_pipelines with
51-
| Some allowed_pipelines when not @@ List.exists allowed_pipelines ~f:(String.equal pipeline) -> false
52-
| _ -> true
18+
let repo_state = find_or_add_repo state repo_url in
19+
repo_state.pipeline_statuses <- Map.update repo_state.pipeline_statuses pipeline ~f:set_branch_status
5320

5421
let log = Log.from "state"
5522

test/test.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ let process ~(secrets : Config_t.secrets) ~config (kind, path, state_path) =
2828
ignore (State.find_or_add_repo ctx.state repo.url);
2929
match state_path with
3030
| None ->
31-
State.set_repo_config ctx.state ~config ~repo_url:repo.url;
31+
Context.set_repo_config ctx repo.url config;
3232
Lwt.return ctx
3333
| Some state_path ->
3434
match Common.get_local_file state_path with
@@ -38,7 +38,7 @@ let process ~(secrets : Config_t.secrets) ~config (kind, path, state_path) =
3838
| Ok file ->
3939
let repo_state = State_j.repo_state_of_string file in
4040
Hashtbl.set ctx.state.repos ~key:repo.url ~data:repo_state;
41-
State.set_repo_config ctx.state ~repo_url:repo.url ~config;
41+
Context.set_repo_config ctx repo.url config;
4242
Lwt.return ctx
4343
in
4444
Stdio.printf "===== file %s =====\n" path;

0 commit comments

Comments
 (0)