@@ -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 ;
@@ -130,14 +130,44 @@ impl CmdRenderer {
130130 CmdRenderer { name, cmd }
131131 }
132132
133- fn compose_command ( & self ) -> Result < Command > {
133+ fn compose_command ( & self , root : & Path , destination : & Path ) -> Result < Command > {
134134 let mut words = Shlex :: new ( & self . cmd ) ;
135- let executable = match words. next ( ) {
136- Some ( e) => e ,
135+ let exe = match words. next ( ) {
136+ Some ( e) => PathBuf :: from ( e ) ,
137137 None => bail ! ( "Command string was empty" ) ,
138138 } ;
139139
140- let mut cmd = Command :: new ( executable) ;
140+ let exe = if exe. components ( ) . count ( ) == 1 {
141+ // Search PATH for the executable.
142+ exe
143+ } else {
144+ // Relative paths are preferred to be relative to the book root.
145+ let abs_exe = root. join ( & exe) ;
146+ if abs_exe. exists ( ) {
147+ abs_exe
148+ } else {
149+ // Historically paths were relative to the destination, but
150+ // this is not the preferred way.
151+ let legacy_path = destination. join ( & exe) ;
152+ if legacy_path. exists ( ) {
153+ warn ! (
154+ "Renderer command `{}` uses a path relative to the \
155+ renderer output directory `{}`. This was previously \
156+ accepted, but has been deprecated. Relative executable \
157+ paths should be relative to the book root.",
158+ exe. display( ) ,
159+ destination. display( )
160+ ) ;
161+ legacy_path
162+ } else {
163+ // Let this bubble through to later be handled by
164+ // handle_render_command_error.
165+ abs_exe. to_path_buf ( )
166+ }
167+ }
168+ } ;
169+
170+ let mut cmd = Command :: new ( exe) ;
141171
142172 for arg in words {
143173 cmd. arg ( arg) ;
@@ -192,7 +222,7 @@ impl Renderer for CmdRenderer {
192222 let _ = fs:: create_dir_all ( & ctx. destination ) ;
193223
194224 let mut child = match self
195- . compose_command ( ) ?
225+ . compose_command ( & ctx . root , & ctx . destination ) ?
196226 . stdin ( Stdio :: piped ( ) )
197227 . stdout ( Stdio :: inherit ( ) )
198228 . stderr ( Stdio :: inherit ( ) )
0 commit comments