ClassifyFile determines which categories a source file belongs to.
(sourceName, sourceBasePath, relPath string)
| 70 | |
| 71 | // ClassifyFile determines which categories a source file belongs to. |
| 72 | func (c *Classifier) ClassifyFile(sourceName, sourceBasePath, relPath string) (FileClassification, error) { |
| 73 | absPath := filepath.Join(sourceBasePath, relPath) |
| 74 | |
| 75 | lineCount, err := CountLines(absPath) |
| 76 | if err != nil { |
| 77 | return FileClassification{}, err |
| 78 | } |
| 79 | |
| 80 | cats := make(map[string]struct{}) |
| 81 | |
| 82 | // Signal 1: Explicit path rules |
| 83 | c.applyPathRules(relPath, cats) |
| 84 | |
| 85 | // Signal 2: Directory structure keywords |
| 86 | c.applyPathKeywords(relPath, cats) |
| 87 | |
| 88 | // Signal 3: Filename keywords |
| 89 | c.applyFilenameKeywords(relPath, cats) |
| 90 | |
| 91 | // Signal 4: Content sampling (only if no categories found yet) |
| 92 | if len(cats) == 0 && c.cfg.ContentSampleLines > 0 { |
| 93 | lines, err := SampleLines(absPath, c.cfg.ContentSampleLines) |
| 94 | if err == nil { |
| 95 | c.applyContentPatterns(lines, cats) |
| 96 | } |
| 97 | } |
| 98 | |
| 99 | // Signal 5: Source-level tags (last resort) |
| 100 | if len(cats) == 0 { |
| 101 | c.applySourceTags(sourceName, cats) |
| 102 | } |
| 103 | |
| 104 | // Determine short eligibility |
| 105 | isShort := c.isShortEligible(relPath, lineCount) |
| 106 | |
| 107 | // Collect and sort categories |
| 108 | catList := make([]string, 0, len(cats)) |
| 109 | for cat := range cats { |
| 110 | catList = append(catList, cat) |
| 111 | } |
| 112 | sort.Strings(catList) |
| 113 | |
| 114 | return FileClassification{ |
| 115 | SourceName: sourceName, |
| 116 | SourcePath: relPath, |
| 117 | AbsPath: absPath, |
| 118 | Categories: catList, |
| 119 | LineCount: lineCount, |
| 120 | IsShortEligible: isShort, |
| 121 | }, nil |
| 122 | } |
| 123 | |
| 124 | // applyPathRules checks explicit path-to-category mappings from config. |
| 125 | func (c *Classifier) applyPathRules(relPath string, cats map[string]struct{}) { |
no test coverage detected