- `init` accepts an optional argument --dir=DIR, which allows to
initialize forests in a specified directory. By default it initializes
the forest in the current directory.
- The git subroutine which initializes the theme is improved:
It no longer fails quietly, and no longer fails with status 141.
(This had to do with the arguments to Eio.Process.run)
- factoring out `try_create_dir` and `try_create_file` means that all
attempts to create files are reported properly by Asai, rather than
dumping a stack trace.
Since the `build` command can't build a forest outside of the current
working directory, we currently can't call it at the end of
initialization.
---
bin/forester/dune | 14 ++++++-bin/forester/main.ml | 89 +++++++++++++++++++---------------------lib/frontend/Eio_util.ml | 21 ++++++++++lib/frontend/dune | 1 +
4 files changed, 77 insertions(+), 48 deletions(-)
diff --git a/bin/forester/dune b/bin/forester/dune
index 24ea6be..7d50324 100644
--- a/bin/forester/dune
@@ -5,4 +5,16 @@
(link_flags (-g))
(preprocess
(pps ppx_deriving.show))
- (libraries forester.prelude forester.core forester.frontend cmdliner dune-build-info asai eio eio.unix bwd eio_main))+ (libraries+ forester.prelude+ forester.core+ forester.frontend+ cmdliner+ dune-build-info+ asai+ eio+ eio.core+ eio.unix+ bwd+ eio_main+ fmt))
diff --git a/bin/forester/main.ml b/bin/forester/main.ml
index e257c4b..e3c88c7 100644
--- a/bin/forester/main.ml
@@ -51,27 +51,16 @@ let query_all ~env config_filename =
Forester.plant_forest_from_dirs ~env ~host: config.host ~dev: true @@ paths_of_dirs ~env config.trees;
Forester.json_manifest ~host: config.host ~home: config.home ~dev: true |> Format.printf "%s"
-let init ~env () =- let default_theme_url = "https://git.sr.ht/~jonsterling/forester-base-theme" in- let theme_version = "4.3.0" in- let fs = Eio.Stdenv.fs env in- let try_create_dir name =- try- EP.mkdir ~perm: 0o755 EP.(fs / name)- with- | _ ->- Reporter.emitf Initialization_warning "Directory `%s` already exists" name- in- let default_config_str =- (* More convenient to just write this string instead of constructing it with the toml library*)- {|[forest]-trees = ["trees" ] # The directories in which your trees are stored-assets = ["assets"] # The directories in which your assets are stored-theme = "theme" # The directory in which your theme is stored+let default_config_str =+ {|+[forest]+trees = ["trees" ] # The directories in which your trees are stored+assets = ["assets"] # The directories in which your assets are stored+theme = "theme" # The directory in which your theme is stored|}
- in- let index_tree_str =- {|++let index_tree_str =+ {|\title{Hello, World!}
\p{
Welcome to your first tree! This tree is the root of your forest.
@@ -83,17 +72,21 @@ theme = "theme" # The directory in which your theme is stor
}
}
|}
++let init ~env dir =+ let default_theme_url = "https://git.sr.ht/~jonsterling/forester-base-theme" in+ let theme_version = "4.3.0" in+ let cwd =+ match dir with+ | None -> Eio.Stdenv.cwd env+ | Some d ->+ let cwd = (Eio.Stdenv.cwd env) in+ Eio_util.try_create_dir ~cwd d;+ cwd in
- begin- if EP.is_file EP.(Eio.Stdenv.fs env / "forest.toml") then- Reporter.emitf Initialization_warning "forest.toml already exists"- else- EP.(save ~create: (`Exclusive 0o644) (fs / "forest.toml") default_config_str)- end;- EP.(save ~create: (`Exclusive 0o644) (fs / ".gitignore") {|output/|}); begin
try
- let shut_up = Eio_util.null_sink () in+ let proc_mgr = Eio.Stdenv.process_mgr env in let@ cmd =
List.iter @~
[
@@ -103,30 +96,28 @@ theme = "theme" # The directory in which your theme is stor
["git"; "-C"; "theme"; "checkout"; theme_version];
]
in
- Eio.Process.run (Eio.Stdenv.process_mgr env) ~stdout: shut_up ~stderr: shut_up cmd+ Eio.Process.run ~cwd proc_mgr cmd with
- | _ ->+ | exn -> Reporter.fatalf
Configuration_error
- {|Failed to set up theme. To perform this step manually, run the commands-- git init- git submodule add %s- git -C theme checkout %s|}+ {|+Failed to set up theme: %a. To perform this step manually, run the commands++git init+git submodule add %s+git -C theme checkout %s+ |}+ Eio.Exn.pp+ exn default_theme_url
theme_version
end;
- ["trees"; "assets"] |> List.iter try_create_dir;- begin- try- EP.(save ~create: (`Exclusive 0o644) (fs / "trees" / "index.tree") index_tree_str)- with- | _ ->- let@ () = Reporter.with_backtrace Emp in- Reporter.emitf Initialization_warning "`index.tree` already exists"- end;- build ~env "forest.toml" true None false false;- Format.printf "%s" "Initialized forest, try editing `trees/index.tree` and running `forester build`. Afterwards, you can open `output/index.xml` in your browser to view your forest.\n"+ ["trees"; "assets"] |> List.iter (Eio_util.try_create_dir ~cwd);+ Eio_util.try_create_file ~cwd ~content: default_config_str "forest.toml";+ Eio_util.try_create_file ~cwd ~content: "output/" ".gitignore";+ Eio_util.try_create_file ~cwd ~content: index_tree_str "trees/index.tree";+ Reporter.emitf Log "%s" "Initialized forest, try editing `trees/index.tree` and running `forester build`. Afterwards, you can open `output/index.xml` in your browser to view your forest."let arg_config =
let doc = "A TOML file like $(i,forest.toml)" in
@@ -226,6 +217,10 @@ let query_cmd ~env =
Cmd.group info [query_all_cmd ~env]
let init_cmd ~env =
+ let arg_dir =+ let doc = "The directory in which to initialize the forest" in+ Arg.value @@ Arg.opt (Arg.some Arg.string) None @@ Arg.info ["dir"] ~docv: "DIR" ~doc+ in let doc = "Initialize a new forest" in
let man =
[
@@ -234,7 +229,7 @@ let init_cmd ~env =
]
in
let info = Cmd.info "init" ~version ~doc ~man in
- Cmd.v info Term.(const (init ~env) $ const ())+ Cmd.v info Term.(const (init ~env) $ arg_dir)let cmd ~env =
let doc = "a tool for tending mathematical forests" in
diff --git a/lib/frontend/Eio_util.ml b/lib/frontend/Eio_util.ml
index 4d40588..ed6bdc5 100644
--- a/lib/frontend/Eio_util.ml+++ b/lib/frontend/Eio_util.ml
@@ -1,5 +1,6 @@
open Forester_prelude
open Eio
+let ( / ) = Eio.Path.( / )module NullSink: Flow.Pi.SINK with type t = unit = struct
type t = unit
@@ -55,6 +56,26 @@ let file_exists path =
with
| Eio.Io (Eio.Fs.E (Eio.Fs.Not_found _), _) -> false
+let try_create_dir ~cwd dname =+ if Eio.Path.is_directory (cwd / dname) then+ Forester_core.Reporter.emitf Initialization_warning "`%s` already exists" dname+ else+ try+ Eio.Path.mkdir ~perm: 0o755 (cwd / dname)+ with+ | exn ->+ Forester_core.Reporter.emitf Initialization_warning "Failed to create directory `%s`: %a" dname Eio.Exn.pp exn++let try_create_file ~cwd ?(content = "") fname =+ if Eio.Path.is_file (cwd / fname) then+ Forester_core.Reporter.emitf Initialization_warning "`%s` already exists" fname+ else+ try+ Eio.Path.save ~create: (`Exclusive 0o644) (cwd / fname) content+ with+ | exn ->+ Forester_core.Reporter.emitf Initialization_warning "Failed to create file `%s`: %a" fname Eio.Exn.pp exn+(* TODO: make this portable *)
let copy_to_dir ~env ~cwd ~source ~dest_dir =
run_process ~quiet: true ~env ~cwd ["cp"; "-R"; source; dest_dir ^ "/"]
diff --git a/lib/frontend/dune b/lib/frontend/dune
index 7f3eeb9..0e3d7b9 100644
--- a/lib/frontend/dune+++ b/lib/frontend/dune
@@ -15,6 +15,7 @@
eio
eio.core
eio.unix
+ fmt yojson
asai
algaeff
--
2.46.0