Skip to content

Commit 969ff0f

Browse files
committed
fix!: pass crucial context to help spawning filter processes by adding context to Pipeline::new(). (#1129)
Otherwise, they might now know which repository to apply to, leading to errors.
1 parent 9d7e28d commit 969ff0f

File tree

6 files changed

+36
-8
lines changed

6 files changed

+36
-8
lines changed

gix-filter/src/driver/apply.rs

+1
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ pub struct Context<'a, 'b> {
6363
pub blob: Option<gix_hash::ObjectId>,
6464
}
6565

66+
/// Apply operations to filter programs.
6667
impl State {
6768
/// Apply `operation` of `driver` to the bytes read from `src` and return a reader to immediately consume the output
6869
/// produced by the filter. `rela_path` is the repo-relative path of the entry to handle.

gix-filter/src/driver/delayed.rs

+1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ pub mod fetch {
4545
}
4646
}
4747

48+
/// Operations related to delayed filtering.
4849
impl State {
4950
/// Return a list of delayed paths for `process` that can then be obtained with [`fetch_delayed()`][Self::fetch_delayed()].
5051
///

gix-filter/src/driver/init.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ pub enum Error {
2424
},
2525
}
2626

27+
/// Lifecycle
2728
impl State {
2829
/// Obtain a process as defined in `driver` suitable for a given `operation. `rela_path` may be used to substitute the current
2930
/// file for use in the invoked `SingleFile` process.
@@ -40,7 +41,7 @@ impl State {
4041
let client = match self.running.remove(process) {
4142
Some(c) => c,
4243
None => {
43-
let (child, cmd) = spawn_driver(process.clone())?;
44+
let (child, cmd) = spawn_driver(process.clone(), &self.context)?;
4445
process::Client::handshake(child, "git-filter", &[2], &["clean", "smudge", "delay"]).map_err(
4546
|err| Error::ProcessHandshake {
4647
source: err,
@@ -79,20 +80,25 @@ impl State {
7980
None => return Ok(None),
8081
};
8182

82-
let (child, command) = spawn_driver(cmd)?;
83+
let (child, command) = spawn_driver(cmd, &self.context)?;
8384
Ok(Some(Process::SingleFile { child, command }))
8485
}
8586
}
8687
}
8788
}
8889

89-
fn spawn_driver(cmd: BString) -> Result<(std::process::Child, std::process::Command), Error> {
90+
fn spawn_driver(
91+
cmd: BString,
92+
context: &gix_command::Context,
93+
) -> Result<(std::process::Child, std::process::Command), Error> {
9094
let mut cmd: std::process::Command = gix_command::prepare(gix_path::from_bstr(cmd).into_owned())
9195
.with_shell()
96+
.with_context(context.clone())
9297
.stdin(Stdio::piped())
9398
.stdout(Stdio::piped())
9499
.stderr(Stdio::inherit())
95100
.into();
101+
gix_trace::debug!(cmd = ?cmd, "launching filter driver");
96102
let child = match cmd.spawn() {
97103
Ok(child) => child,
98104
Err(err) => {

gix-filter/src/driver/mod.rs

+15
Original file line numberDiff line numberDiff line change
@@ -70,12 +70,27 @@ pub struct State {
7070
/// Note that these processes are expected to shut-down once their stdin/stdout are dropped, so nothing else
7171
/// needs to be done to clean them up after drop.
7272
running: HashMap<BString, process::Client>,
73+
74+
/// The context to pass to spawned filter programs.
75+
pub context: gix_command::Context,
76+
}
77+
78+
/// Initialization
79+
impl State {
80+
/// Create a new instance using `context` to inform launched processes about their environment.
81+
pub fn new(context: gix_command::Context) -> Self {
82+
Self {
83+
running: Default::default(),
84+
context,
85+
}
86+
}
7387
}
7488

7589
impl Clone for State {
7690
fn clone(&self) -> Self {
7791
State {
7892
running: Default::default(),
93+
context: self.context.clone(),
7994
}
8095
}
8196
}

gix-filter/src/pipeline/mod.rs

+9-5
Original file line numberDiff line numberDiff line change
@@ -52,18 +52,22 @@ const ATTRS: [&str; 6] = ["crlf", "ident", "filter", "eol", "text", "working-tre
5252

5353
/// Lifecycle
5454
impl Pipeline {
55-
/// Create a new pipeline with configured `drivers` (which should be considered safe to invoke) as well as a way to initialize
56-
/// our attributes with `collection`.
55+
/// Create a new pipeline with configured `drivers` (which should be considered safe to invoke) with `context` as well as
56+
/// a way to initialize our attributes with `collection`.
5757
/// `eol_config` serves as fallback to understand how to convert line endings if no line-ending attributes are present.
5858
/// `crlf_roundtrip_check` corresponds to the git-configuration of `core.safecrlf`.
5959
/// `object_hash` is relevant for the `ident` filter.
60-
pub fn new(collection: &gix_attributes::search::MetadataCollection, options: Options) -> Self {
60+
pub fn new(
61+
collection: &gix_attributes::search::MetadataCollection,
62+
context: gix_command::Context,
63+
options: Options,
64+
) -> Self {
6165
let mut attrs = gix_attributes::search::Outcome::default();
6266
attrs.initialize_with_selection(collection, ATTRS);
6367
Pipeline {
6468
attrs,
6569
context: Context::default(),
66-
processes: driver::State::default(),
70+
processes: driver::State::new(context),
6771
options,
6872
bufs: Default::default(),
6973
}
@@ -80,7 +84,7 @@ impl Pipeline {
8084
impl Default for Pipeline {
8185
fn default() -> Self {
8286
let collection = Default::default();
83-
Pipeline::new(&collection, Default::default())
87+
Pipeline::new(&collection, Default::default(), Default::default())
8488
}
8589
}
8690

gix-filter/tests/pipeline/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ fn pipeline(
5959
let (drivers, encodings_with_roundtrip_check, crlf_roundtrip_check, eol_config) = init();
6060
let pipe = gix_filter::Pipeline::new(
6161
cache.attributes_collection(),
62+
Default::default(),
6263
gix_filter::pipeline::Options {
6364
drivers,
6465
eol_config,

0 commit comments

Comments
 (0)