Skip to content

Commit 8d8dbb2

Browse files
github-actions[bot]CopilotCopilotjamesadevine
authored
feat(ir): add typed helper for DeleteFiles@1 (#1071)
Adds `delete_files_step()` to `src/compile/ir/tasks.rs` — a typed factory for the ADO `DeleteFiles@1` task. Required input (`Contents`) is a positional parameter; optional inputs (`SourceFolder`, `RemoveSourceFolder`, `RemoveDotFiles`) are applied via the existing `.with_input(…)` builder on the returned `TaskStep`. Five unit tests are included covering: - default (required-only) construction - optional `SourceFolder` - `RemoveSourceFolder` flag - `RemoveDotFiles` flag - multiline `Contents` patterns Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> 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 9dc3176 commit 8d8dbb2

1 file changed

Lines changed: 84 additions & 0 deletions

File tree

src/compile/ir/tasks.rs

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,29 @@ pub fn download_pipeline_artifact_step(target_path: impl Into<String>) -> TaskSt
358358
.with_input("targetPath", target_path)
359359
}
360360

361+
/// Returns a [`TaskStep`] for `DeleteFiles@1`.
362+
///
363+
/// Deletes files or folders matching one or more patterns from a source folder.
364+
///
365+
/// - `contents` — newline-separated glob patterns identifying the files or
366+
/// folders to remove (e.g. `"**/*.tmp"` or `"dist\n*.log"`). This is the
367+
/// only required input.
368+
///
369+
/// Optional inputs (applied with `.with_input(…)` on the returned value):
370+
///
371+
/// | Input key | Type | Default | Description |
372+
/// |---|---|---|---|
373+
/// | `SourceFolder` | string | working directory | Root folder to delete from. Use `$(Build.ArtifactStagingDirectory)` to clean staging. |
374+
/// | `RemoveSourceFolder` | bool string | `"false"` | Remove the `SourceFolder` itself after deleting its contents. Set to `"true"` and `contents` to `"*"` to wipe the whole folder. |
375+
/// | `RemoveDotFiles` | bool string | `"false"` | Also delete files whose name starts with a dot. Defaults to `"false"` (dot files are preserved). |
376+
///
377+
/// ADO task reference:
378+
/// <https://learn.microsoft.com/en-us/azure/devops/pipelines/tasks/reference/delete-files-v1>
379+
pub fn delete_files_step(contents: impl Into<String>) -> TaskStep {
380+
TaskStep::new("DeleteFiles@1", "Delete Files")
381+
.with_input("Contents", contents)
382+
}
383+
361384
#[cfg(test)]
362385
mod tests {
363386
use super::*;
@@ -909,6 +932,67 @@ mod tests {
909932
);
910933
}
911934

935+
// ── DeleteFiles@1 ────────────────────────────────────────────────────
936+
937+
#[test]
938+
fn delete_files_step_sets_task_and_required_input() {
939+
let t = delete_files_step("**/*.tmp");
940+
assert_eq!(t.task, "DeleteFiles@1");
941+
assert_eq!(t.display_name, "Delete Files");
942+
assert_eq!(
943+
t.inputs.get("Contents").map(|s| s.as_str()),
944+
Some("**/*.tmp")
945+
);
946+
// only the required input is set by default
947+
assert_eq!(t.inputs.len(), 1);
948+
}
949+
950+
#[test]
951+
fn delete_files_step_accepts_source_folder() {
952+
let t =
953+
delete_files_step("**/*.log").with_input("SourceFolder", "$(Build.ArtifactStagingDirectory)");
954+
assert_eq!(t.task, "DeleteFiles@1");
955+
assert_eq!(
956+
t.inputs.get("SourceFolder").map(|s| s.as_str()),
957+
Some("$(Build.ArtifactStagingDirectory)")
958+
);
959+
assert_eq!(t.inputs.len(), 2);
960+
}
961+
962+
#[test]
963+
fn delete_files_step_accepts_remove_source_folder_flag() {
964+
let t = delete_files_step("*")
965+
.with_input("SourceFolder", "$(Build.ArtifactStagingDirectory)")
966+
.with_input("RemoveSourceFolder", "true");
967+
assert_eq!(t.task, "DeleteFiles@1");
968+
assert_eq!(
969+
t.inputs.get("RemoveSourceFolder").map(|s| s.as_str()),
970+
Some("true")
971+
);
972+
assert_eq!(t.inputs.len(), 3);
973+
}
974+
975+
#[test]
976+
fn delete_files_step_accepts_remove_dot_files_flag() {
977+
let t = delete_files_step("**").with_input("RemoveDotFiles", "true");
978+
assert_eq!(t.task, "DeleteFiles@1");
979+
assert_eq!(
980+
t.inputs.get("RemoveDotFiles").map(|s| s.as_str()),
981+
Some("true")
982+
);
983+
assert_eq!(t.inputs.len(), 2);
984+
}
985+
986+
#[test]
987+
fn delete_files_step_multiline_contents() {
988+
let t = delete_files_step("**/*.tmp\n**/*.log\ndist/");
989+
assert_eq!(t.task, "DeleteFiles@1");
990+
assert_eq!(
991+
t.inputs.get("Contents").map(|s| s.as_str()),
992+
Some("**/*.tmp\n**/*.log\ndist/")
993+
);
994+
}
995+
912996
// ── PublishPipelineArtifact@1 ─────────────────────────────────────────
913997

914998
#[test]

0 commit comments

Comments
 (0)