Skip to content

Commit 3af7d0c

Browse files
authored
Fix: extinctions scans take hours (#331)
There was a logic issue that was causing a commit diff patch to be scanned multiple times - once for each changed file in the commit. Bug introduced in [2.5.0](https://github.com/launchdarkly/ld-find-code-refs/releases/tag/2.5.0)
1 parent 84c2d94 commit 3af7d0c

File tree

1 file changed

+58
-37
lines changed

1 file changed

+58
-37
lines changed

internal/git/git.go

Lines changed: 58 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -248,52 +248,73 @@ func (c Client) FindExtinctions(project options.Project, flags []string, matcher
248248
if err != nil {
249249
return nil, err
250250
}
251-
for _, filePatch := range patch.FilePatches() {
252-
fromFile, toFile := filePatch.Files()
253-
printDebugStatement(fromFile, toFile)
254-
if project.Dir != "" && (toFile == nil || !strings.HasPrefix(toFile.Path(), project.Dir)) {
255-
if fromFile != nil && !strings.HasPrefix(fromFile.Path(), project.Dir) {
256-
continue
257-
}
258-
}
259251

260-
patchLines := strings.Split(patch.String(), "\n")
261-
nextFlags := make([]string, 0, len(flags))
262-
for _, flag := range flags {
263-
removalCount := 0
264-
for _, patchLine := range patchLines {
265-
delta := 0
266-
// Is a change line and not a metadata line
267-
if strings.HasPrefix(patchLine, "-") && !strings.HasPrefix(patchLine, "---") {
268-
delta = 1
269-
} else if strings.HasPrefix(patchLine, "+") && !strings.HasPrefix(patchLine, "+++") {
270-
delta = -1
271-
}
272-
if delta != 0 && matcher.MatchElement(patchLine, flag) {
273-
removalCount += delta
274-
}
252+
if !shouldScanPatch(project.Dir, patch) {
253+
log.Debug.Printf("Skipping commit: %s", c.commit.Hash)
254+
continue
255+
}
256+
257+
log.Debug.Printf("Scanning commit: %s", c.commit.Hash)
258+
patchLines := strings.Split(patch.String(), "\n")
259+
nextFlags := make([]string, 0, len(flags))
260+
for _, flag := range flags {
261+
removalCount := 0
262+
for _, patchLine := range patchLines {
263+
delta := 0
264+
// Is a change line and not a metadata line
265+
if strings.HasPrefix(patchLine, "-") && !strings.HasPrefix(patchLine, "---") {
266+
delta = 1
267+
} else if strings.HasPrefix(patchLine, "+") && !strings.HasPrefix(patchLine, "+++") {
268+
delta = -1
275269
}
276-
if removalCount > 0 {
277-
ret = append(ret, ld.ExtinctionRep{
278-
Revision: c.commit.Hash.String(),
279-
Message: c.commit.Message,
280-
Time: c.commit.Author.When.Unix() * 1000,
281-
ProjKey: project.Key,
282-
FlagKey: flag,
283-
})
284-
log.Debug.Printf("Found extinct flag: %s in project: %s", flag, project.Key)
285-
} else {
286-
// this flag was not removed in the current commit, so check for it again in the next commit
287-
nextFlags = append(nextFlags, flag)
270+
if delta != 0 && matcher.MatchElement(patchLine, flag) {
271+
removalCount += delta
288272
}
289273
}
290-
flags = nextFlags
274+
if removalCount > 0 {
275+
ret = append(ret, ld.ExtinctionRep{
276+
Revision: c.commit.Hash.String(),
277+
Message: c.commit.Message,
278+
Time: c.commit.Author.When.Unix() * 1000,
279+
ProjKey: project.Key,
280+
FlagKey: flag,
281+
})
282+
log.Debug.Printf("Found extinct flag: %s in project: %s", flag, project.Key)
283+
} else {
284+
// this flag was not removed in the current commit, so check for it again in the next commit
285+
nextFlags = append(nextFlags, flag)
286+
}
291287
}
288+
flags = nextFlags
292289
}
293290

294291
return ret, err
295292
}
296293

294+
// Determine if any changed files should be scanned
295+
func shouldScanPatch(projectDir string, patch *object.Patch) bool {
296+
for _, filePatch := range patch.FilePatches() {
297+
fromFile, toFile := filePatch.Files()
298+
printDebugStatement(fromFile, toFile)
299+
300+
if projectDir == "" {
301+
return true
302+
}
303+
304+
// Ignore files outside of the project directory
305+
306+
if toFile != nil && strings.HasPrefix(toFile.Path(), projectDir) {
307+
return true
308+
}
309+
310+
if fromFile != nil && strings.HasPrefix(fromFile.Path(), projectDir) {
311+
return true
312+
}
313+
}
314+
315+
return false
316+
}
317+
297318
func printDebugStatement(fromFile, toFile diff.File) {
298319
fromPath, toPath := "FROM_PATH", "TO_PATH"
299320
if fromFile != nil {
@@ -302,5 +323,5 @@ func printDebugStatement(fromFile, toFile diff.File) {
302323
if toFile != nil {
303324
toPath = toFile.Path()
304325
}
305-
log.Debug.Printf("Examining from file: %s and to file: %s", fromPath, toPath)
326+
log.Debug.Printf("Deciding to scan from file: %s and to file: %s", fromPath, toPath)
306327
}

0 commit comments

Comments
 (0)