@@ -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 ;
@@ -133,14 +133,44 @@ impl CmdRenderer {
133
133
CmdRenderer { name, cmd }
134
134
}
135
135
136
- fn compose_command ( & self ) -> Result < Command > {
136
+ fn compose_command ( & self , root : & Path , destination : & Path ) -> Result < Command > {
137
137
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 ) ,
140
140
None => bail ! ( "Command string was empty" ) ,
141
141
} ;
142
142
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) ;
144
174
145
175
for arg in words {
146
176
cmd. arg ( arg) ;
@@ -195,7 +225,7 @@ impl Renderer for CmdRenderer {
195
225
let _ = fs:: create_dir_all ( & ctx. destination ) ;
196
226
197
227
let mut child = match self
198
- . compose_command ( ) ?
228
+ . compose_command ( & ctx . root , & ctx . destination ) ?
199
229
. stdin ( Stdio :: piped ( ) )
200
230
. stdout ( Stdio :: inherit ( ) )
201
231
. stderr ( Stdio :: inherit ( ) )
0 commit comments