Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/cli.ml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ let ignore_size_warning_arg =
Arg.(value & flag & info [ "i"; "ignore-size-warning" ] ~doc)

let run owner_repo local_path log_file ignore_size_warning =
Tui.start ~owner_repo ~local_path ~log_file ~ignore_size_warning
Tui.start { owner_repo; local_path; log_file; ignore_size_warning }

let gh_tui_term =
Term.(
Expand Down
1 change: 1 addition & 0 deletions lib/tui/dune
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
extra
fs
gh
init
log
model
pretty
Expand Down
7 changes: 7 additions & 0 deletions lib/tui/init/dune
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
(library
(name init)
(libraries
terminal_size
;; Internal dependencies
model
fs))
78 changes: 78 additions & 0 deletions lib/tui/init/init.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
type owner_repo = {
owner : string;
repo : string;
}

let parse_owner_repo owner_repo =
match String.split_on_char '/' owner_repo with
| [ owner; repo ] -> { owner; repo }
| _ ->
Printf.eprintf "❌ Expected <owner>/<repo> but got: '%s'\n" owner_repo;
exit 1

let clone_repo ~owner_repo ~local_path =
match local_path with
| Some path -> path
| None ->
let { owner; repo } = owner_repo in
let temp_dir =
Filename.temp_dir "github-tui-" (Printf.sprintf "%s-%s" owner repo)
in
let cmd =
Printf.sprintf "git clone git@github.com:%s/%s.git %s" owner repo
temp_dir
in
Shell.proc cmd;
temp_dir

let read_root_tree ~root_dir_path =
let tree = Fs.read_tree root_dir_path in
let files =
match tree with
| Fs.File { name; _ } ->
Printf.eprintf "Given path '%s' is not a directory!" name;
exit 1
| Fs.Dir { children = files; _ } -> files
in
files

type terminal = {
height : int;
width : int;
}

let min_height, min_width = (40, 140)

let get_terminal_dimensions ignore_size_warning =
match (Terminal_size.get_rows (), Terminal_size.get_columns ()) with
| Some height, Some width ->
if (not ignore_size_warning) && (height < min_height || width < min_width)
then (
Printf.eprintf
{|⚠️ Terminal size is too small! GitHub TUI works better on bigger terminals.
Expected size: %3d width x %3d height
But got: %3d width x %3d height

Pass the --ignore-size-warning flag to run anyway.
|}
min_width min_height width height;
exit 1);
{ height; width }
| _ ->
Printf.eprintf "⚠️ Not able to get the terminal size.\n";
exit 1

type t = {
owner_repo : string;
local_path : string option;
log_file : string option;
ignore_size_warning : bool;
}

let init { owner_repo; local_path; ignore_size_warning; log_file = _ } :
Model.initial_data =
let ({ owner; repo } as owner_repo) = parse_owner_repo owner_repo in
let root_dir_path = clone_repo ~owner_repo ~local_path in
let files = Lazy.force (read_root_tree ~root_dir_path) in
let { height; width } = get_terminal_dimensions ignore_size_warning in
{ owner; repo; root_dir_path; files; width; height }
8 changes: 8 additions & 0 deletions lib/tui/init/init.mli
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
type t = {
owner_repo : string;
local_path : string option;
log_file : string option;
ignore_size_warning : bool;
}

val init : t -> Model.initial_data
77 changes: 3 additions & 74 deletions lib/tui/tui.ml
Original file line number Diff line number Diff line change
@@ -1,76 +1,5 @@
type owner_repo = {
owner : string;
repo : string;
}

let parse_owner_repo owner_repo =
match String.split_on_char '/' owner_repo with
| [ owner; repo ] -> { owner; repo }
| _ ->
Printf.eprintf "❌ Expected <owner>/<repo> but got: '%s'\n" owner_repo;
exit 1

let clone_repo ~owner_repo ~local_path =
match local_path with
| Some path -> path
| None ->
let { owner; repo } = owner_repo in
let temp_dir =
Filename.temp_dir "github-tui-" (Printf.sprintf "%s-%s" owner repo)
in
let cmd =
Printf.sprintf "git clone git@github.com:%s/%s.git %s" owner repo
temp_dir
in
Shell.proc cmd;
temp_dir

let read_root_tree ~root_dir_path =
let tree = Fs.read_tree root_dir_path in
let files =
match tree with
| Fs.File { name; _ } ->
Printf.eprintf "Given path '%s' is not a directory!" name;
exit 1
| Fs.Dir { children = files; _ } -> files
in
files

type terminal = {
height : int;
width : int;
}

let min_height, min_width = (40, 140)

let get_terminal_dimensions ignore_size_warning =
match (Terminal_size.get_rows (), Terminal_size.get_columns ()) with
| Some height, Some width ->
if (not ignore_size_warning) && (height < min_height || width < min_width)
then (
Printf.eprintf
{|⚠️ Terminal size is too small! GitHub TUI works better on bigger terminals.
Expected size: %3d width x %3d height
But got: %3d width x %3d height

Pass the --ignore-size-warning flag to run anyway.
|}
min_width min_height width height;
exit 1);
{ height; width }
| _ ->
Printf.eprintf "⚠️ Not able to get the terminal size.\n";
exit 1

let init ~owner_repo ~local_path ~ignore_size_warning : Model.initial_data =
let ({ owner; repo } as owner_repo) = parse_owner_repo owner_repo in
let root_dir_path = clone_repo ~owner_repo ~local_path in
let files = Lazy.force (read_root_tree ~root_dir_path) in
let { height; width } = get_terminal_dimensions ignore_size_warning in
{ owner; repo; root_dir_path; files; width; height }

let start ~owner_repo ~local_path ~log_file ~ignore_size_warning =
let initial_data = init ~owner_repo ~local_path ~ignore_size_warning in
let start args =
let initial_data = Init.init args in
let init = Model.initial_model initial_data in
let app = Tea.make ~init ~update:Update.update ~view:View.view in
Tea.run ?path:log_file app
Tea.run ?path:args.log_file app
7 changes: 1 addition & 6 deletions lib/tui/tui.mli
Original file line number Diff line number Diff line change
@@ -1,6 +1 @@
val start :
owner_repo:string ->
local_path:string option ->
log_file:string option ->
ignore_size_warning:bool ->
unit
val start : Init.t -> unit