~jonsterling/forester-devel

This thread contains a patchset. You're looking at the original emails, but you may wish to use the patch review UI. Review patch
2 2

[PATCH v2] Improve init subcommand

Details
Message ID
<20241010195428.1732083-1-kentookura@gmail.com>
DKIM signature
pass
Download raw message
Patch: +77 -48
- `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
Details
Message ID
<F4866555-1B47-45FA-877C-87BA09D9F918@jonmsterling.com>
In-Reply-To
<20241010195428.1732083-1-kentookura@gmail.com> (view parent)
DKIM signature
pass
Download raw message
Hi Kento,

Thanks for this patch!

On 10 Oct 2024, at 20:54, Kento Okura wrote:

> - `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.

This looks like a great feature, but when I tried it, it did not work. 
It created the directory and then proceeded to initialise the outer 
directory as a forest.

>
> - 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
> +++ b/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
> +++ b/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

It might be that the above line is the culprit. Should it return 
something other than 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
Details
Message ID
<D4SYYK1MUCWO.3GTLCDJ30FCK0@gmail.com>
In-Reply-To
<F4866555-1B47-45FA-877C-87BA09D9F918@jonmsterling.com> (view parent)
DKIM signature
pass
Download raw message
On Fri Oct 11, 2024 at 10:29 AM CEST, Jon Sterling wrote:
> Hi Kento,
>
> Thanks for this patch!
>
> On 10 Oct 2024, at 20:54, Kento Okura wrote:
>
> > - `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.
>
> This looks like a great feature, but when I tried it, it did not work. 
> It created the directory and then proceeded to initialise the outer 
> directory as a forest.

Hmm, ok. I'll do some more testing.

> >
> > - 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
> > +++ b/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
> > +++ b/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
>
> It might be that the above line is the culprit. Should it return 
> something other than 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
Reply to thread Export thread (mbox)