Skip to content

Commit 8efb5fb

Browse files
fix(compile): pin LF eol on managed gitattributes entries (#340)
Agent-Logs-Url: https://github.com/githubnext/ado-aw/sessions/5acd63b7-baaf-491a-932a-acee2d27b97f Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: jamesadevine <4742697+jamesadevine@users.noreply.github.com>
1 parent f2595f8 commit 8efb5fb

1 file changed

Lines changed: 33 additions & 12 deletions

File tree

src/compile/gitattributes.rs

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use std::path::Path;
1515

1616
const BEGIN_MARKER: &str = "# BEGIN ado-aw managed (do not edit)";
1717
const END_MARKER: &str = "# END ado-aw managed";
18-
const ATTRIBUTES: &str = "linguist-generated=true merge=ours";
18+
const ATTRIBUTES: &str = "linguist-generated=true merge=ours text eol=lf";
1919

2020
/// Update the managed block of `<repo_root>/.gitattributes` so that exactly
2121
/// the supplied compiled-pipeline paths are marked as generated.
@@ -154,12 +154,12 @@ mod tests {
154154
let written = std::fs::read_to_string(dir.path().join(".gitattributes")).unwrap();
155155
assert!(written.contains(BEGIN_MARKER));
156156
assert!(written.contains(END_MARKER));
157-
assert!(
158-
written.contains(".azdo/pipelines/review.lock.yml linguist-generated=true merge=ours")
159-
);
160-
assert!(
161-
written.contains("agents/my-agent.lock.yml linguist-generated=true merge=ours")
162-
);
157+
assert!(written.contains(
158+
".azdo/pipelines/review.lock.yml linguist-generated=true merge=ours text eol=lf"
159+
));
160+
assert!(written.contains(
161+
"agents/my-agent.lock.yml linguist-generated=true merge=ours text eol=lf"
162+
));
163163
}
164164

165165
#[tokio::test]
@@ -177,14 +177,14 @@ mod tests {
177177

178178
let written = std::fs::read_to_string(dir.path().join(".gitattributes")).unwrap();
179179
assert!(written.starts_with("*.png binary\n# my own comment\n"));
180-
assert!(written.contains("agents/x.lock.yml linguist-generated=true merge=ours"));
180+
assert!(written.contains("agents/x.lock.yml linguist-generated=true merge=ours text eol=lf"));
181181
}
182182

183183
#[tokio::test]
184184
async fn replaces_existing_managed_block() {
185185
let dir = tempfile::tempdir().unwrap();
186186
let initial = format!(
187-
"*.png binary\n{}\nstale/path.lock.yml linguist-generated=true merge=ours\n{}\n",
187+
"*.png binary\n{}\nstale/path.lock.yml linguist-generated=true merge=ours text eol=lf\n{}\n",
188188
BEGIN_MARKER, END_MARKER
189189
);
190190
std::fs::write(dir.path().join(".gitattributes"), initial).unwrap();
@@ -199,7 +199,7 @@ mod tests {
199199
let written = std::fs::read_to_string(dir.path().join(".gitattributes")).unwrap();
200200
assert!(written.starts_with("*.png binary\n"));
201201
assert!(!written.contains("stale/path.lock.yml"));
202-
assert!(written.contains("new/path.lock.yml linguist-generated=true merge=ours"));
202+
assert!(written.contains("new/path.lock.yml linguist-generated=true merge=ours text eol=lf"));
203203
// Block markers should appear exactly once
204204
assert_eq!(written.matches(BEGIN_MARKER).count(), 1);
205205
assert_eq!(written.matches(END_MARKER).count(), 1);
@@ -209,7 +209,7 @@ mod tests {
209209
async fn removes_block_when_no_pipelines() {
210210
let dir = tempfile::tempdir().unwrap();
211211
let initial = format!(
212-
"*.png binary\n{}\nold/path.lock.yml linguist-generated=true merge=ours\n{}\n",
212+
"*.png binary\n{}\nold/path.lock.yml linguist-generated=true merge=ours text eol=lf\n{}\n",
213213
BEGIN_MARKER, END_MARKER
214214
);
215215
std::fs::write(dir.path().join(".gitattributes"), initial).unwrap();
@@ -265,9 +265,30 @@ mod tests {
265265

266266
let written = std::fs::read_to_string(dir.path().join(".gitattributes")).unwrap();
267267
assert!(
268-
written.contains("\"my agents/pipeline.lock.yml\" linguist-generated=true merge=ours"),
268+
written.contains("\"my agents/pipeline.lock.yml\" linguist-generated=true merge=ours text eol=lf"),
269269
"expected quoted path entry, got:\n{}",
270270
written
271271
);
272272
}
273+
274+
#[tokio::test]
275+
async fn entries_pin_lf_eol() {
276+
// Regression: managed entries must include `text eol=lf` so that Git
277+
// doesn't autoconvert LF→CRLF on Windows checkouts and emit warnings
278+
// each time the pipeline is recompiled.
279+
let dir = tempfile::tempdir().unwrap();
280+
update_gitattributes(
281+
dir.path(),
282+
vec![PathBuf::from("agents/x.lock.yml")],
283+
)
284+
.await
285+
.unwrap();
286+
287+
let written = std::fs::read_to_string(dir.path().join(".gitattributes")).unwrap();
288+
assert!(
289+
written.contains("text eol=lf"),
290+
"managed entries must pin LF line endings, got:\n{}",
291+
written
292+
);
293+
}
273294
}

0 commit comments

Comments
 (0)