@@ -72,15 +72,23 @@ const BINARY_EXTENSIONS: &[&str] = &[
7272] ;
7373
7474impl Fixer {
75- /// Create a new fixer for a repository
75+ /// Create a fixer rooted at `repo_path`.
76+ ///
77+ /// When `dry_run` is true, policy and boundary checks still run, but eligible
78+ /// fixes are only reported and no files or commits are changed.
7679 pub fn new ( repo_path : PathBuf , dry_run : bool ) -> Self {
7780 // Keep one root representation for ignore rules and index paths.
7881 // Invalid roots are retained so apply's boundary check reports the error.
7982 let repo_path = repo_path. canonicalize ( ) . unwrap_or ( repo_path) ;
8083 Fixer { repo_path, dry_run }
8184 }
8285
83- /// Apply a fix for a detected issue
86+ /// Apply a fix after checking the exclusion registry and repository boundary.
87+ ///
88+ /// Policy rejections and action-level non-applicability are represented in
89+ /// [`FixResult`]; failures that prevent the operation itself may be returned
90+ /// as errors. In dry-run mode, eligible fixes report their intended changes
91+ /// without writing them.
8492 pub fn apply ( & self , issue : & DetectedIssue , fix : & Fix ) -> Result < FixResult > {
8593 // EXCLUSION REGISTRY GUARD: refuse the write if the target repo,
8694 // origin, or target path is on the estate-wide denylist. In dry-run
@@ -379,10 +387,10 @@ impl Fixer {
379387 } )
380388 }
381389
382- /// Modify a file with safety checks and rollback support
390+ /// Modify a text file without exposing partially written content.
383391 ///
384- /// Reads the modification specification from the fix, applies it to the file,
385- /// and rolls back if the modification produces invalid content .
392+ /// Binary files are rejected. For supported structured formats, the complete
393+ /// result is parsed before the original file is atomically replaced .
386394 fn apply_modify (
387395 & self ,
388396 target_path : & Path ,
@@ -502,13 +510,12 @@ impl Fixer {
502510 } )
503511 }
504512
505- /// Create a file with template expansion
513+ /// Create a file from explicit fallback content or a built-in template.
506514 ///
507- /// Supports template variables:
508- /// - `gitbot-fleet` - Repository name
509- /// - `hyperpolymath` - Repository owner
510- /// - `{{LICENSE}}` - License identifier
511- /// - `{{YEAR}}` - Current year
515+ /// Existing or ignored targets are not written, and publication uses
516+ /// no-clobber semantics. Template expansion replaces the literal
517+ /// `gitbot-fleet` name and the `{{LICENSE}}`, `{{YEAR}}`, `{{AUTHOR}}` and
518+ /// `{{EMAIL}}` placeholders.
512519 fn apply_create (
513520 & self ,
514521 target_path : & Path ,
@@ -604,7 +611,9 @@ impl Fixer {
604611 } )
605612 }
606613
607- /// Disable a workflow (rename to .disabled)
614+ /// Disable a file by renaming it with a `yml.disabled` extension.
615+ ///
616+ /// The rename does not replace an existing destination.
608617 fn apply_disable (
609618 & self ,
610619 target_path : & Path ,
@@ -671,7 +680,9 @@ impl Fixer {
671680 false
672681 }
673682
674- /// Get template content for a file creation
683+ /// Return explicit fallback content or the built-in template for `target`.
684+ ///
685+ /// Targets without either source return an empty string.
675686 fn get_template_content ( & self , target : & str , fix : & Fix ) -> String {
676687 // If the fix has explicit content in the fallback field, use it
677688 if let Some ( ref fallback) = fix. fallback {
@@ -687,7 +698,7 @@ impl Fixer {
687698 }
688699 }
689700
690- /// Expand template variables in content
701+ /// Expand the repository-specific and fixed metadata placeholders in a template.
691702 fn expand_template ( & self , content : & str ) -> String {
692703 let repo_name = self
693704 . repo_path
@@ -705,7 +716,11 @@ impl Fixer {
705716 . replace ( "{{EMAIL}}" , "j.d.a.jewell@open.ac.uk" )
706717 }
707718
708- /// Commit changes to the repository
719+ /// Stage the listed paths and commit the resulting repository index.
720+ ///
721+ /// Deleted paths are removed from the index, while paths outside the canonical
722+ /// repository root are ignored. Dry-run mode performs the exclusion check but
723+ /// neither stages nor commits changes.
709724 pub fn commit ( & self , message : & str , files : & [ PathBuf ] ) -> Result < ( ) > {
710725 // EXCLUSION REGISTRY GUARD: a commit is a write action even though
711726 // apply() has already checked each file individually, because some
@@ -761,7 +776,11 @@ impl Fixer {
761776 Ok ( ( ) )
762777 }
763778
764- /// Apply multiple fixes and commit
779+ /// Apply each issue/fix pair and commit files reported as modified.
780+ ///
781+ /// No commit is created when nothing changes or dry-run mode is enabled. The
782+ /// separate `issues` slice is retained for caller compatibility and is not
783+ /// consulted; each tuple in `fixes` supplies its associated issue.
765784 pub fn apply_and_commit (
766785 & self ,
767786 _issues : & [ DetectedIssue ] ,
@@ -889,12 +908,14 @@ fn resolve_from_existing_ancestor(path: &Path) -> Result<PathBuf> {
889908 }
890909}
891910
911+ /// Return whether the character at `index` follows an odd run of backslashes.
892912fn is_escaped ( value : & str , index : usize ) -> bool {
893913 value[ ..index] . bytes ( ) . rev ( )
894914 . take_while ( |byte| * byte == b'\\' )
895915 . count ( ) % 2 == 1
896916}
897917
918+ /// Replace each escaped colon with a literal colon, preserving other backslashes.
898919fn unescape_colons ( value : & str ) -> String {
899920 let mut output = String :: with_capacity ( value. len ( ) ) ;
900921 let mut characters = value. chars ( ) . peekable ( ) ;
0 commit comments