1pub mod git;
19pub mod ignore;
20
21use anyhow::bail;
22
23fn validate_patterns_for_library(
25 patterns: &[String],
26 validation_level: PatternValidationLevel,
27) -> anyhow::Result<()> {
28 if validation_level == PatternValidationLevel::None {
29 return Ok(());
30 }
31
32 let issues = ignore::validate_ignore_patterns(patterns);
33 let has_errors = issues.iter().any(|i| i.severity == PatternSeverity::Error);
34 let has_warnings = issues
35 .iter()
36 .any(|i| i.severity == PatternSeverity::Warning);
37
38 if has_errors || (validation_level == PatternValidationLevel::Strict && has_warnings) {
39 let error_messages: Vec<String> = issues
41 .iter()
42 .filter(|issue| {
43 issue.severity == PatternSeverity::Error
44 || (validation_level == PatternValidationLevel::Strict
45 && issue.severity == PatternSeverity::Warning)
46 })
47 .map(|issue| format!("{}: {}", issue.pattern, issue.message))
48 .collect();
49
50 bail!("Pattern validation failed: {}", error_messages.join("; "));
51 }
52
53 Ok(())
54}
55
56#[derive(Debug, Clone, PartialEq, Eq)]
58pub enum PatternSeverity {
59 Info,
61 Warning,
63 Error,
65}
66
67#[derive(Debug, Clone)]
69pub struct PatternIssue {
70 pub pattern: String,
71 pub severity: PatternSeverity,
72 pub message: String,
73}
74
75#[derive(Debug, Clone, PartialEq, Eq)]
77pub enum PatternValidationLevel {
78 None,
80 Warn,
82 Strict,
84}
85
86pub fn add_patterns_to_gitignore(
88 patterns: &[String],
89 validation_level: PatternValidationLevel,
90) -> anyhow::Result<Vec<String>> {
91 validate_patterns_for_library(patterns, validation_level)?;
92 let gitignore_path = git::get_gitignore_path()?;
93 ignore::add_patterns_to_ignore_file(
94 &gitignore_path,
95 patterns,
96 true,
97 PatternValidationLevel::None,
98 )
99}
100
101pub fn add_patterns_to_exclude(
103 patterns: &[String],
104 validation_level: PatternValidationLevel,
105) -> anyhow::Result<Vec<String>> {
106 validate_patterns_for_library(patterns, validation_level)?;
107 let exclude_path = git::get_exclude_file_path()?;
108 ignore::ensure_info_exclude_exists(&exclude_path)?;
109 ignore::add_patterns_to_ignore_file(&exclude_path, patterns, true, PatternValidationLevel::None)
110}
111
112pub fn add_patterns_to_global(
114 patterns: &[String],
115 validation_level: PatternValidationLevel,
116) -> anyhow::Result<Vec<String>> {
117 validate_patterns_for_library(patterns, validation_level)?;
118 let global_path = git::get_global_gitignore_path()
119 .ok_or_else(|| anyhow::anyhow!("No global gitignore file configured"))?;
120 ignore::add_patterns_to_ignore_file(&global_path, patterns, true, PatternValidationLevel::None)
121}