@@ -20,7 +20,7 @@ mod markdown_renderer;
20
20
use shlex:: Shlex ;
21
21
use std:: fs;
22
22
use std:: io:: { self , ErrorKind , Read } ;
23
- use std:: path:: PathBuf ;
23
+ use std:: path:: { Path , PathBuf } ;
24
24
use std:: process:: { Command , Stdio } ;
25
25
26
26
use crate :: book:: Book ;
@@ -130,14 +130,44 @@ impl CmdRenderer {
130
130
CmdRenderer { name, cmd }
131
131
}
132
132
133
- fn compose_command ( & self ) -> Result < Command > {
133
+ fn compose_command ( & self , root : & Path , destination : & Path ) -> Result < Command > {
134
134
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 ) ,
137
137
None => bail ! ( "Command string was empty" ) ,
138
138
} ;
139
139
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) ;
141
171
142
172
for arg in words {
143
173
cmd. arg ( arg) ;
@@ -192,7 +222,7 @@ impl Renderer for CmdRenderer {
192
222
let _ = fs:: create_dir_all ( & ctx. destination ) ;
193
223
194
224
let mut child = match self
195
- . compose_command ( ) ?
225
+ . compose_command ( & ctx . root , & ctx . destination ) ?
196
226
. stdin ( Stdio :: piped ( ) )
197
227
. stdout ( Stdio :: inherit ( ) )
198
228
. stderr ( Stdio :: inherit ( ) )
0 commit comments