@@ -25,7 +25,7 @@ type Generator struct {
2525 UseGitIgnore bool
2626 ShowHidden bool
2727 RedactSecrets bool
28- secretsFound bool
28+ lastSecretCount int
2929}
3030
3131// NewGenerator constructs a generator with default settings
@@ -75,23 +75,23 @@ func (g *Generator) SetRedactionMode(redact bool) {
7575}
7676
7777// Generate creates an output file in the specified format
78- func (g * Generator ) Generate () (string , int , bool , error ) {
78+ func (g * Generator ) Generate () (string , int , int , error ) {
7979 if len (g .SelectedFiles ) == 0 {
80- return "" , 0 , false , fmt .Errorf ("no files selected, skipping generation" )
80+ return "" , 0 , 0 , fmt .Errorf ("no files selected, skipping generation" )
8181 }
8282
8383 if g .format == nil {
84- return "" , 0 , false , fmt .Errorf ("no format set, cannot generate output" )
84+ return "" , 0 , 0 , fmt .Errorf ("no format set, cannot generate output" )
8585 }
8686
8787 data , err := g .PrepareTemplateData ()
8888 if err != nil {
89- return "" , 0 , false , fmt .Errorf ("failed to prepare template data: %w" , err )
89+ return "" , 0 , g . lastSecretCount , fmt .Errorf ("failed to prepare template data: %w" , err )
9090 }
9191
9292 content , tokenCount , err := g .format .Render (data )
9393 if err != nil {
94- return "" , 0 , data . SecretsFound , fmt .Errorf ("failed to render %s: %w" , g .format .Name (), err )
94+ return "" , 0 , g . lastSecretCount , fmt .Errorf ("failed to render %s: %w" , g .format .Name (), err )
9595 }
9696
9797 var outputPath string
@@ -100,12 +100,12 @@ func (g *Generator) Generate() (string, int, bool, error) {
100100 if g .UseTempFile {
101101 tmpFile , err := os .CreateTemp ("" , fmt .Sprintf ("codegrab-*%s" , g .format .Extension ()))
102102 if err != nil {
103- return "" , 0 , data . SecretsFound , fmt .Errorf ("failed to create temporary file: %w" , err )
103+ return "" , 0 , g . lastSecretCount , fmt .Errorf ("failed to create temporary file: %w" , err )
104104 }
105105 defer tmpFile .Close ()
106106
107107 if _ , err := tmpFile .Write ([]byte (content )); err != nil {
108- return tmpFile .Name (), tokenCount , data . SecretsFound , fmt .Errorf ("failed to write to temporary file: %w" , err )
108+ return tmpFile .Name (), tokenCount , g . lastSecretCount , fmt .Errorf ("failed to write to temporary file: %w" , err )
109109 }
110110 outputPath = tmpFile .Name ()
111111 displayPath = outputPath
@@ -122,46 +122,46 @@ func (g *Generator) Generate() (string, int, bool, error) {
122122 displayPath = outputPath
123123 absPath , err := filepath .Abs (outputPath )
124124 if err != nil {
125- return "" , tokenCount , data . SecretsFound , fmt .Errorf ("failed to get absolute path: %w" , err )
125+ return displayPath , tokenCount , g . lastSecretCount , fmt .Errorf ("failed to get absolute path: %w" , err )
126126 }
127127
128- if err := os .WriteFile (outputPath , []byte (content ), 0644 ); err != nil {
129- return "" , tokenCount , data . SecretsFound , fmt .Errorf ("failed to write to output file: %w" , err )
128+ if err := os .WriteFile (absPath , []byte (content ), 0644 ); err != nil {
129+ return displayPath , tokenCount , g . lastSecretCount , fmt .Errorf ("failed to write to output file %s : %w" , absPath , err )
130130 }
131-
132- outputPath = absPath
133131 }
134132
135133 if err := utils .CopyFileObject (outputPath ); err != nil {
136134 fmt .Fprintf (os .Stderr , "Warning: clipboard copy failed: %v\n " , err )
137135 }
138136
139- return displayPath , tokenCount , data . SecretsFound , nil
137+ return displayPath , tokenCount , g . lastSecretCount , nil
140138}
141139
142- // GenerateString returns the rendered content as a string along with its estimated token count
143- func (g * Generator ) GenerateString () (string , int , bool , error ) {
140+ // GenerateString returns the rendered content as a string along with counts
141+ func (g * Generator ) GenerateString () (string , int , int , error ) {
144142 if len (g .SelectedFiles ) == 0 {
145- return "" , 0 , false , fmt .Errorf ("no files selected, skipping generation" )
143+ return "" , 0 , 0 , fmt .Errorf ("no files selected, skipping generation" )
146144 }
147145
148146 if g .format == nil {
149- return "" , 0 , false , fmt .Errorf ("no format set, cannot generate output" )
147+ return "" , 0 , 0 , fmt .Errorf ("no format set, cannot generate output" )
150148 }
151149
152150 data , err := g .PrepareTemplateData ()
153151 if err != nil {
154- return "" , 0 , false , fmt .Errorf ("failed to prepare template data: %w" , err )
152+ return "" , 0 , g . lastSecretCount , fmt .Errorf ("failed to prepare template data: %w" , err )
155153 }
156154
157155 content , tokenCount , err := g .format .Render (data )
158- return content , tokenCount , data . SecretsFound , err
156+ return content , tokenCount , g . lastSecretCount , err
159157}
160158
161- // PrepareTemplateData finalizes the selection and builds TemplateData for the template
159+ // PrepareTemplateData finalizes the selection, scans/redacts secrets, and builds TemplateData
162160func (g * Generator ) PrepareTemplateData () (TemplateData , error ) {
163- g .secretsFound = false
161+ g .lastSecretCount = 0
162+
164163 expandedSelection := make (map [string ]bool )
164+
165165 for path := range g .SelectedFiles {
166166 fullPath := filepath .Join (g .RootPath , path )
167167 info , err := os .Stat (fullPath )
@@ -210,6 +210,7 @@ func (g *Generator) PrepareTemplateData() (TemplateData, error) {
210210 expandedSelection [path ] = true
211211 }
212212 }
213+
213214 g .SelectedFiles = expandedSelection
214215
215216 rootNode := g .buildTree ()
@@ -223,18 +224,23 @@ func (g *Generator) PrepareTemplateData() (TemplateData, error) {
223224 var filesData []FileData
224225 collectFiles (rootNode , & filesData )
225226
226- for i := range filesData {
227- if len (filesData [i ].Findings ) > 0 {
228- g .secretsFound = true
229- if g .RedactSecrets && g .SecretScanner != nil {
230- filesData [i ].Content = g .SecretScanner .Redact (filesData [i ].Content , filesData [i ].Findings )
227+ secretCount := 0
228+
229+ if g .SecretScanner != nil {
230+ for i := range filesData {
231+ if len (filesData [i ].Findings ) > 0 {
232+ secretCount += len (filesData [i ].Findings )
233+ if g .RedactSecrets {
234+ filesData [i ].Content = g .SecretScanner .Redact (filesData [i ].Content , filesData [i ].Findings )
235+ }
231236 }
232237 }
233238 }
234239
240+ g .lastSecretCount = secretCount
241+
235242 return TemplateData {
236- Structure : structureBuilder .String (),
237- Files : filesData ,
238- SecretsFound : g .secretsFound ,
243+ Structure : structureBuilder .String (),
244+ Files : filesData ,
239245 }, nil
240246}
0 commit comments