Skip to content

Commit 4c4204c

Browse files
committed
mustache_cli: add -I and --no-working-dir options to configure the search path
1 parent 640587c commit 4c4204c

File tree

2 files changed

+72
-6
lines changed

2 files changed

+72
-6
lines changed

bin/mustache_cli.ml

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ let load_file f =
1111
close_in ic;
1212
(Bytes.to_string s)
1313

14+
let locate_template search_path relative_filename =
15+
search_path
16+
|> List.map (fun path -> Filename.concat path relative_filename)
17+
|> List.find_opt Sys.file_exists
18+
1419
let load_template template_filename =
1520
let template_data = load_file template_filename in
1621
let lexbuf = Lexing.from_string template_data in
@@ -27,13 +32,14 @@ let load_template template_filename =
2732
let load_json json_filename =
2833
Ezjsonm.from_string (load_file json_filename)
2934

30-
let run json_filename template_filename =
35+
let run search_path json_filename template_filename =
3136
let env = load_json json_filename in
3237
let tmpl = load_template template_filename in
3338
let partials name =
34-
let path = Printf.sprintf "%s.mustache" name in
35-
if not (Sys.file_exists path) then None
36-
else Some (load_template path) in
39+
let file = Printf.sprintf "%s.mustache" name in
40+
let path = locate_template search_path file in
41+
Option.map load_template path
42+
in
3743
try
3844
let output = Mustache.render ~partials tmpl env in
3945
print_string output;
@@ -99,10 +105,25 @@ Mustache is:
99105
let doc = "mustache template" in
100106
Arg.(required & pos 1 (some file) None & info [] ~docv:"TEMPLATE.mustache" ~doc)
101107
in
102-
Term.(const run $ json_file $ template_file),
108+
let search_path =
109+
let includes =
110+
let doc = "Adds the directory $(docv) to the search path for partials." in
111+
Arg.(value & opt_all dir [] & info ["I"] ~docv:"DIR" ~doc)
112+
in
113+
let no_working_dir =
114+
let doc = "Disable the implicit inclusion of the working directory
115+
in the search path for partials." in
116+
Arg.(value & flag & info ["no-working-dir"] ~doc)
117+
in
118+
let search_path includes no_working_dir =
119+
if no_working_dir then includes
120+
else Filename.current_dir_name :: includes
121+
in
122+
Term.(const search_path $ includes $ no_working_dir)
123+
in
124+
Term.(const run $ search_path $ json_file $ template_file),
103125
Term.info "mustache" ~doc ~man
104126

105-
106127
let () =
107128
let open Cmdliner in
108129
Term.exit @@ Term.eval run_command

bin/test/partials.t/run.t

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,48 @@ Include in child or parent directory:
1515
$ echo '{ "src": "child" }' > subdir/child/from_child.json
1616
$ (cd subdir/child; mustache from_child.json from_child.mustache)
1717
Test from child
18+
19+
When working with templates from outside the current directory,
20+
we need to set the search path to locate their included partials.
21+
22+
This fails:
23+
$ (cd subdir; mustache ../data.json ../foo.mustache)
24+
Template render error:
25+
File "../foo.mustache", line 2, characters 23-31:
26+
the partial 'bar' is missing.
27+
[2]
28+
29+
This works with the "-I .." option:
30+
$ (cd subdir; mustache -I .. ../data.json ../foo.mustache)
31+
Inside the include is "Foo Bar !"
32+
33+
Note that the include directory is *not* used to locate the template
34+
(or data) argument. This fails:
35+
$ (cd subdir; mustache -I .. ../data.json foo.mustache)
36+
mustache: TEMPLATE.mustache argument: no `foo.mustache' file or directory
37+
Usage: mustache [OPTION]... DATA.json TEMPLATE.mustache
38+
Try `mustache --help' for more information.
39+
[124]
40+
41+
Search path precedence order.
42+
$ mkdir precedence
43+
$ mkdir precedence/first
44+
$ mkdir precedence/last
45+
$ echo "First" > precedence/first/include.mustache
46+
$ echo "Last" > precedence/last/include.mustache
47+
$ echo "{{>include}}" > precedence/template.mustache
48+
$ echo "{}" > precedence/data.json
49+
50+
The include directory added first (left -I option) has precedence
51+
over the include directories added after:
52+
$ (cd precedence; mustache -I first -I last data.json template.mustache)
53+
First
54+
55+
The working directory has precedence over the include directories:
56+
$ echo "Working" > precedence/include.mustache
57+
$ (cd precedence; mustache -I first -I last data.json template.mustache)
58+
Working
59+
60+
... unless --no-working-dir is used:
61+
$ (cd precedence; mustache --no-working-dir -I first -I last data.json template.mustache)
62+
First

0 commit comments

Comments
 (0)