@@ -2,103 +2,147 @@ open Stdune
22open Dune_sexp
33
44module Host = struct
5- type kind =
6- | Github
7- | Bitbucket
8- | Gitlab
9- | Sourcehut
10-
11- let to_string = function
12- | Github -> " github"
13- | Bitbucket -> " bitbucket"
14- | Gitlab -> " gitlab"
15- | Sourcehut -> " sourcehut"
16- ;;
17-
18- type t =
5+ type user_repo =
196 { user : string
207 ; repo : string
21- ; kind : kind
228 }
239
24- let dyn_of_kind kind = kind |> to_string |> Dyn. string
10+ type gitlab_repo =
11+ | User_repo of user_repo
12+ | Org_repo of
13+ { org : string
14+ ; proj : string
15+ ; repo : string
16+ }
17+
18+ type t =
19+ | Github of user_repo
20+ | Bitbucket of user_repo
21+ | Gitlab of gitlab_repo
22+ | Sourcehut of user_repo
23+
24+ let kind_string = function
25+ | Github _ -> " github"
26+ | Bitbucket _ -> " bitbucket"
27+ | Gitlab _ -> " gitlab"
28+ | Sourcehut _ -> " sourcehut"
29+ ;;
2530
26- let to_dyn { user; repo; kind } =
31+ let dyn_of_user_repo kind { user; repo } =
2732 let open Dyn in
28- record [ " kind" , dyn_of_kind kind; " user" , string user; " repo" , string repo ]
33+ record [ " kind" , kind; " user" , string user; " repo" , string repo ]
2934 ;;
3035
31- let host_of_kind = function
32- | Github -> " github.com"
33- | Bitbucket -> " bitbucket.org"
34- | Gitlab -> " gitlab.com"
35- | Sourcehut -> " sr.ht"
36+ let dyn_of_gitlab_repo kind repo =
37+ match repo with
38+ | User_repo user_repo -> dyn_of_user_repo kind user_repo
39+ | Org_repo { org; proj; repo } ->
40+ let open Dyn in
41+ record [ " kind" , kind; " org" , string org; " proj" , string proj; " repo" , string repo ]
3642 ;;
3743
38- let base_uri { kind; user; repo } =
39- let host = host_of_kind kind in
40- sprintf
41- " %s/%s/%s"
42- host
43- (match kind with
44- | Sourcehut -> " ~" ^ user
45- | _ -> user)
46- repo
44+ let to_dyn repo =
45+ let kind = Dyn. string (kind_string repo) in
46+ match repo with
47+ | Gitlab gitlab_repo -> dyn_of_gitlab_repo kind gitlab_repo
48+ | Github user_repo | Bitbucket user_repo | Sourcehut user_repo ->
49+ dyn_of_user_repo kind user_repo
50+ ;;
51+
52+ let host_of_repo = function
53+ | Github _ -> " github.com"
54+ | Bitbucket _ -> " bitbucket.org"
55+ | Gitlab _ -> " gitlab.com"
56+ | Sourcehut _ -> " sr.ht"
57+ ;;
58+
59+ let base_uri repo =
60+ let host = host_of_repo repo in
61+ match repo with
62+ | Gitlab (Org_repo { org; proj; repo } ) -> sprintf " %s/%s/%s/%s" host org proj repo
63+ | Sourcehut { user; repo } -> sprintf " %s/~%s/%s" host user repo
64+ | Gitlab (User_repo { user; repo }) | Github { user; repo } | Bitbucket { user; repo }
65+ -> sprintf " %s/%s/%s" host user repo
4766 ;;
4867
4968 let add_https s = " https://" ^ s
5069 let homepage t = add_https (base_uri t)
5170
52- let bug_reports t =
53- match t.kind with
54- | Sourcehut -> add_https (" todo." ^ base_uri t)
55- | _ ->
56- homepage t
57- ^
58- (match t.kind with
59- | Sourcehut -> assert false
60- | Bitbucket | Github -> " /issues"
61- | Gitlab -> " /-/issues" )
71+ let bug_reports = function
72+ | Gitlab _ as repo -> homepage repo ^ " /-/issues"
73+ | Github _ as repo -> homepage repo ^ " /issues"
74+ | Bitbucket _ as repo -> homepage repo ^ " /issues"
75+ | Sourcehut _ as repo -> add_https (" todo." ^ base_uri repo)
6276 ;;
6377
6478 let enum k =
65- [ " GitHub" , Github , None
66- ; " Bitbucket" , Bitbucket , Some (2 , 8 )
67- ; " Gitlab" , Gitlab , Some (2 , 8 )
68- ; " Sourcehut" , Sourcehut , Some (3 , 1 )
79+ let stub_user_repo = { user = " " ; repo = " " } in
80+ let stub_org_repo = Org_repo { org = " " ; proj = " " ; repo = " " } in
81+ let repo_name k = k |> kind_string |> String. capitalize in
82+ [ Github stub_user_repo
83+ ; Bitbucket stub_user_repo
84+ ; Sourcehut stub_user_repo
85+ ; Gitlab (User_repo stub_user_repo)
86+ ; Gitlab stub_org_repo
6987 ]
70- |> List. map ~f: (fun (name , kind , since ) ->
71- let decode =
72- let of_string ~loc s =
73- match String. split ~on: '/' s with
74- | [ user; repo ] -> k { kind; user; repo }
75- | _ ->
76- User_error. raise
77- ~loc
78- [ Pp. textf " %s repository must be of form user/repo" name ]
79- in
88+ |> List. map ~f: (fun kind ->
89+ let of_string ~loc str =
90+ let name = repo_name kind in
91+ match kind, String. split ~on: '/' str with
92+ | Github _ , [ user; repo ] -> Github { user; repo }, None
93+ | Bitbucket _ , [ user; repo ] -> Bitbucket { user; repo }, Some ((2 , 8 ), name)
94+ | Sourcehut _ , [ user; repo ] -> Sourcehut { user; repo }, Some ((3 , 1 ), name)
95+ | Gitlab _ , [ user; repo ] ->
96+ Gitlab (User_repo { user; repo }), Some ((2 , 8 ), name)
97+ | Gitlab _ , [ org; proj; repo ] ->
98+ Gitlab (Org_repo { org; proj; repo }), Some ((3 , 17 ), " Gitlab organization repo" )
99+ | Gitlab _ , _ ->
100+ User_error. raise
101+ ~loc
102+ [ Pp. textf " %s repository must be of form user/repo or org/proj/repo" name ]
103+ | _ , [ _; _; _ ] ->
104+ User_error. raise
105+ ~loc
106+ ~hints:
107+ [ Pp. textf " The provided form '%s' is specific to Gitlab projects" str ]
108+ [ Pp. textf " %s repository must be of form user/repo" name ]
109+ | _ , _ ->
110+ User_error. raise
111+ ~loc
112+ [ Pp. textf " %s repository must be of form user/repo" name ]
113+ in
114+ let decoder =
80115 let open Decoder in
116+ plain_string of_string
117+ >> = fun (t , since ) ->
81118 (match since with
82119 | None -> return ()
83- | Some v -> Syntax. since Stanza. syntax v)
84- >>> plain_string of_string
120+ | Some (v , what ) -> Syntax. since ~what Stanza. syntax v)
121+ >>> return t
122+ >> | k
85123 in
86- let constr = to_string kind in
87- constr, decode)
124+ kind_string kind, decoder)
88125 ;;
89126
90- let encode { user; repo; kind } =
91- let forge = to_string kind in
92- let path = user ^ " /" ^ repo in
127+ let encode repo =
128+ let path =
129+ match repo with
130+ | Gitlab (Org_repo { org; proj; repo } ) -> sprintf " %s/%s/%s" org proj repo
131+ | Gitlab (User_repo { user; repo } ) -> sprintf " %s/%s" user repo
132+ | Sourcehut { user; repo } -> sprintf " %s/%s" user repo
133+ | Github { user; repo } -> sprintf " %s/%s" user repo
134+ | Bitbucket { user; repo } -> sprintf " %s/%s" user repo
135+ in
93136 let open Encoder in
137+ let forge = kind_string repo in
94138 pair string string (forge, path)
95139 ;;
96140
97- let to_string t =
141+ let to_string repo =
98142 let base_uri =
99- let base = base_uri t in
100- match t.kind with
101- | Sourcehut -> " git." ^ base
143+ let base = base_uri repo in
144+ match repo with
145+ | Sourcehut _ -> " git." ^ base
102146 | _ -> base ^ " .git"
103147 in
104148 " git+https://" ^ base_uri
0 commit comments