Skip to content

Commit 1d65d36

Browse files
committedAug 23, 2016
add simple CLI generator for github metadata in this repo
1 parent b9eccc2 commit 1d65d36

File tree

6 files changed

+125
-34
lines changed

6 files changed

+125
-34
lines changed
 

‎.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.*.swp
2+
*.exe
3+
*.native
4+
_build/

‎_tags

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
true: annot, bin_annot, debug
2+
true: package(github.unix), package(cmdliner), package(fmt.tty)

‎jar_cli.mli

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
(*
2+
* Copyright (c) 2014 David Sheets <sheets@alum.mit.edu>
3+
*
4+
* Permission to use, copy, modify, and distribute this software for any
5+
* purpose with or without fee is hereby granted, provided that the above
6+
* copyright notice and this permission notice appear in all copies.
7+
*
8+
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9+
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10+
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11+
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12+
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13+
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14+
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15+
*
16+
*)
17+
18+
val repos : ?doc_append:string -> unit -> string list Cmdliner.Term.t
19+
val cookie : ?doc_append:string -> unit -> Github.Token.t Cmdliner.Term.t

‎list_issues.ml

+76-34
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,16 @@
1-
#!/usr/bin/env ocamlscript
2-
Ocaml.packs := ["github.unix"; "cmdliner"] ;;
3-
Ocaml.sources := ["jar_cli.ml"] ;;
4-
--
5-
61
open Lwt
72
open Cmdliner
83
open Printf
94

105
module T = Github_t
116

12-
let ask_github fn = Github.(Monad.run (fn ()))
7+
let ocl_classes_of_labels labels =
8+
let names = List.map (fun { T.label_name } -> label_name) labels in
9+
List.map Ocamllabs.of_string names
1310

1411
let string_of_labels labels =
1512
let names = List.map (fun { T.label_name } -> label_name) labels in
13+
let _ocl_classes (* TODO *) = List.map Ocamllabs.of_string names in
1614
String.concat ", " names
1715

1816
let print_issue user repo issue =
@@ -25,34 +23,85 @@ let print_issue user repo issue =
2523
issue_created_at;
2624
issue_closed_at;
2725
} = issue in
28-
printf "%s/%s#%d %s\n" user repo issue_number issue_title;
29-
printf " Labels: %s\n" (string_of_labels issue_labels);
30-
printf " Comments: %d\n" issue_comments;
26+
(* box drawing from https://en.wikipedia.org/wiki/Box-drawing_character *)
27+
printf "┏ #%d %s\n%!" issue_number issue_title;
28+
printf "┣ Labels: %s\n%!" (string_of_labels issue_labels);
29+
printf "┣ Comments: %d\n%!" issue_comments;
3130
(match issue_state with
32-
| `Open -> printf " Created at %s\n" issue_created_at
31+
| `Open -> printf " Created at %s\n" issue_created_at
3332
| `Closed -> match issue_closed_at with
34-
| Some timestamp -> printf " Closed at %s\n" timestamp
35-
| None -> printf " Closed timestamp missing!"
33+
| Some timestamp -> printf " Closed at %s\n" timestamp
34+
| None -> printf " Closed timestamp missing!"
3635
)
3736

38-
let list_issues token repos ~all ~closed ~prs ~issues =
39-
let repos = List.map (fun r ->
37+
let get_user_repos =
38+
List.map (fun r ->
4039
match Stringext.split ~max:2 ~on:'/' r with
4140
| [user;repo] -> (user,repo)
4241
| _ -> eprintf "Repositories must be in username/repo format"; exit 1
43-
) repos in
44-
(* Get the issues per repo *)
42+
)
43+
44+
let print_milestone m =
45+
let open Github_t in
46+
Fmt.(pf stdout "╳ %a (%a/%d issues)\n%!"
47+
(styled `Bold string) m.milestone_title
48+
(styled `Green int) m.milestone_closed_issues
49+
m.milestone_open_issues)
50+
51+
let list_issues token repos ~all ~closed ~milestone =
52+
(* Get the issues per repo *)
4553
Lwt_list.iter_s (fun (user,repo) ->
4654
let state = if all then `All else if closed then `Closed else `Open in
4755
Github.(Monad.(run (
48-
let issues_s = Issue.for_repo ~token ~state ~user ~repo () in
56+
let issues_s = Issue.for_repo ~token ~state ~user ~repo ~milestone () in
4957
Stream.to_list issues_s (* TODO: bound?!?! *)
50-
>>= fun list -> return (List.iter (fun i -> match i with
51-
| { T.issue_pull_request=None } when issues -> print_issue user repo i
52-
| { T.issue_pull_request=Some _ } when prs -> print_issue user repo i
53-
| _ -> ()
58+
>>= fun list -> return (List.iter (fun i -> print_issue user repo i
5459
) list))))
55-
) repos
60+
) (get_user_repos repos)
61+
62+
let github_map_s fn l =
63+
let open Github.Monad in
64+
let rec iter acc =
65+
function
66+
| hd::tl ->
67+
fn hd >>= fun r ->
68+
iter (r :: acc) tl
69+
| [] -> return acc
70+
in
71+
iter [] l
72+
73+
let github_iter_s fn l =
74+
let open Github.Monad in
75+
let rec iter = function
76+
| hd::tl -> fn hd >>= fun () -> iter tl
77+
| [] -> return ()
78+
in
79+
iter l
80+
81+
let list_one_milestone token user repo ~all ~closed =
82+
let open Github in
83+
let open Github.Monad in
84+
let milestone_s = Milestone.for_repo ~token ~user ~repo () in
85+
Stream.to_list milestone_s
86+
>>= fun list ->
87+
github_iter_s (fun m ->
88+
print_milestone m;
89+
let state = if all then `All else if closed then `Closed else `Open in
90+
let milestone = `Num m.Github_t.milestone_number in
91+
let issues_s = Issue.for_repo ~token ~state ~milestone ~user ~repo () in
92+
Stream.to_list issues_s
93+
>>= fun list ->
94+
github_iter_s (fun i ->
95+
Github.Monad.return (print_issue user repo i)
96+
) list
97+
) list
98+
99+
let list_milestones token repos ~all ~closed =
100+
Lwt_list.iter_s (fun (user,repo) ->
101+
Github.(Monad.(run (
102+
list_one_milestone token user repo ~all ~closed
103+
)))
104+
) (get_user_repos repos)
56105

57106
let cmd =
58107
let cookie = Jar_cli.cookie () in
@@ -65,25 +114,18 @@ let cmd =
65114
let docv = "ALL" in
66115
let all = Arg.(value & flag & info ["all"] ~docv ~doc) in
67116

68-
let doc = "show PRs" in
69-
let docv = "PRS" in
70-
let no_prs = Arg.(value & flag & info ["prs"] ~docv ~doc) in
71-
let doc = "show regular (non-PR) issues" in
72-
let docv = "ISSUES" in
73-
let no_issues = Arg.(value & flag & info ["issues"] ~docv ~doc) in
74-
75117
let doc = "list issues on GitHub repositories (open only by default)" in
76118
let man = [
77119
`S "BUGS";
78120
`P "Email bug reports to <mirageos-devel@lists.xenproject.org>.";
79121
] in
80-
Term.((pure (fun t r all closed prs_flag issues_flag ->
81-
let prs = prs_flag || (not issues_flag) in
82-
let issues = issues_flag || (not prs_flag) in
83-
Lwt_main.run (list_issues t r ~all ~closed ~prs ~issues)
84-
) $ cookie $ repos $ all $ closed $ no_prs $ no_issues)),
122+
Term.((pure (fun t r all closed ->
123+
Lwt_main.run (list_milestones t r ~all ~closed)
124+
) $ cookie $ repos $ all $ closed)),
85125
Term.info "git-list-issues" ~version:"1.0.0" ~doc ~man
86126

127+
let () = Fmt_tty.setup_std_outputs ()
128+
87129
let () = match Term.eval cmd with `Error _ -> exit 1 | _ -> exit 0
88130

89131
(*

‎ocamllabs.ml

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
(* Conventions for labelling in ocamllabs/Projects repos *)
2+
3+
type t =
4+
| Event of string
5+
| Project of string
6+
| Task of string
7+
| Other of string
8+
9+
let of_string s =
10+
match Stringext.split ~max:2 ~on:':' (String.lowercase_ascii s) with
11+
|["event";x] -> Event (Stringext.trim_left x)
12+
|["project";x] -> Project (Stringext.trim_left x)
13+
|["task";x] -> Task (Stringext.trim_left x)
14+
|_ -> Other s
15+
16+
let to_string = function
17+
| Event s -> "Event: " ^ s
18+
| Project s -> "Project: " ^ s
19+
| Task s -> "Task: " ^ s
20+
| Other s -> s
21+

‎run.sh

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#!/bin/sh
2+
ocamlbuild -use-ocamlfind list_issues.native
3+
./list_issues.native -c private ocamllabs/Projects

0 commit comments

Comments
 (0)
Please sign in to comment.