@@ -20,7 +20,7 @@ mod markdown_renderer;
2020use shlex:: Shlex ;
2121use std:: fs;
2222use std:: io:: { self , ErrorKind , Read } ;
23- use std:: path:: PathBuf ;
23+ use std:: path:: { Path , PathBuf } ;
2424use std:: process:: { Command , Stdio } ;
2525
2626use crate :: book:: Book ;
@@ -133,14 +133,44 @@ impl CmdRenderer {
133133 CmdRenderer { name, cmd }
134134 }
135135
136- fn compose_command ( & self ) -> Result < Command > {
136+ fn compose_command ( & self , root : & Path , destination : & Path ) -> Result < Command > {
137137 let mut words = Shlex :: new ( & self . cmd ) ;
138- let executable = match words. next ( ) {
139- Some ( e) => e ,
138+ let exe = match words. next ( ) {
139+ Some ( e) => PathBuf :: from ( e ) ,
140140 None => bail ! ( "Command string was empty" ) ,
141141 } ;
142142
143- let mut cmd = Command :: new ( executable) ;
143+ let exe = if exe. components ( ) . count ( ) == 1 {
144+ // Search PATH for the executable.
145+ exe
146+ } else {
147+ // Relative paths are preferred to be relative to the book root.
148+ let abs_exe = root. join ( & exe) ;
149+ if abs_exe. exists ( ) {
150+ abs_exe
151+ } else {
152+ // Historically paths were relative to the destination, but
153+ // this is not the preferred way.
154+ let legacy_path = destination. join ( & exe) ;
155+ if legacy_path. exists ( ) {
156+ warn ! (
157+ "Renderer command `{}` uses a path relative to the \
158+ renderer output directory `{}`. This was previously \
159+ accepted, but has been deprecated. Relative executable \
160+ paths should be relative to the book root.",
161+ exe. display( ) ,
162+ destination. display( )
163+ ) ;
164+ legacy_path
165+ } else {
166+ // Let this bubble through to later be handled by
167+ // handle_render_command_error.
168+ abs_exe. to_path_buf ( )
169+ }
170+ }
171+ } ;
172+
173+ let mut cmd = Command :: new ( exe) ;
144174
145175 for arg in words {
146176 cmd. arg ( arg) ;
@@ -195,7 +225,7 @@ impl Renderer for CmdRenderer {
195225 let _ = fs:: create_dir_all ( & ctx. destination ) ;
196226
197227 let mut child = match self
198- . compose_command ( ) ?
228+ . compose_command ( & ctx . root , & ctx . destination ) ?
199229 . stdin ( Stdio :: piped ( ) )
200230 . stdout ( Stdio :: inherit ( ) )
201231 . stderr ( Stdio :: inherit ( ) )
0 commit comments