Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions application/server/configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,22 @@ func updateFolderConfig(c *config.Config, settings types.Settings, logger *zerol
}
}

baseBranchChanged := storedConfig.BaseBranch != folderConfig.BaseBranch
referenceFolderChanged := storedConfig.ReferenceFolderPath != folderConfig.ReferenceFolderPath
if baseBranchChanged || referenceFolderChanged {
logger.Info().
Str("folderPath", string(path)).
Str("oldBaseBranch", storedConfig.BaseBranch).
Str("newBaseBranch", folderConfig.BaseBranch).
Str("oldReferenceFolderPath", string(storedConfig.ReferenceFolderPath)).
Str("newReferenceFolderPath", string(folderConfig.ReferenceFolderPath)).
Msg("base branch or reference folder changed, clearing persisted scan cache for folder")
ws := c.Workspace()
if ws != nil {
ws.GetScanSnapshotClearerExister().ClearFolder(path)
}
}

sendFolderConfigAnalytics(c, path, triggerSource, *storedConfig, folderConfig)

folderConfigs = append(folderConfigs, folderConfig)
Expand Down
14 changes: 12 additions & 2 deletions domain/ide/workspace/folder.go
Original file line number Diff line number Diff line change
Expand Up @@ -529,24 +529,33 @@ func (f *Folder) GetDelta(p product.Product) (snyk.IssuesByFile, error) {
defer f.mutex.Unlock()

logger := f.c.Logger().With().Str("method", "getDelta").Logger()
logger.Debug().Msgf("getting delta for product %s, folderPath %s", p, f.path)

issueByFile := f.IssuesByProduct()[p]

if len(issueByFile) == 0 {
// If no issues found in current branch scan. We can't have deltas.
logger.Debug().Msg("no current issues, returning empty")
return issueByFile, nil
}

logger.Debug().Msgf("current issues count=%d", len(getFlatIssueList(issueByFile)))

baseIssueList, err := f.scanPersister.GetPersistedIssueList(f.path, p)
if err != nil {
logger.Debug().Msgf("GetPersistedIssueList returned error: %v", err)
return nil, err
}

logger.Debug().Msgf("base issues count=%d", len(baseIssueList))

baseFindingIdentifiable := make([]delta.Identifiable, len(baseIssueList))
for i := range baseIssueList {
baseFindingIdentifiable[i] = baseIssueList[i]
}

currentFlatIssueList := getFlatIssueList(issueByFile)

currentFindingIdentifiable := make([]delta.Identifiable, len(currentFlatIssueList))
for i := range currentFlatIssueList {
currentFindingIdentifiable[i] = currentFlatIssueList[i]
Expand All @@ -561,8 +570,7 @@ func (f *Folder) GetDelta(p product.Product) (snyk.IssuesByFile, error) {
}

deltaSnykIssues := []types.Issue{}
for i := range enrichedIssues {
identifiable := enrichedIssues[i]
for _, identifiable := range enrichedIssues {
if identifiable == nil || !identifiable.GetIsNew() {
continue
}
Expand All @@ -574,6 +582,8 @@ func (f *Folder) GetDelta(p product.Product) (snyk.IssuesByFile, error) {
}
issueByFile = getIssuePerFileFromFlatList(deltaSnykIssues)

logger.Debug().Msgf("returning %d delta issues", len(deltaSnykIssues))

return issueByFile, nil
}

Expand Down
6 changes: 6 additions & 0 deletions domain/snyk/persistence/file_operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ import (
"github.com/pkg/errors"
"github.com/snyk/go-application-framework/pkg/configuration"

"github.com/snyk/snyk-ls/internal/util"

"github.com/snyk/snyk-ls/internal/constants"
"github.com/snyk/snyk-ls/internal/product"
"github.com/snyk/snyk-ls/internal/types"
Expand Down Expand Up @@ -88,6 +90,10 @@ func snykCacheDir(conf configuration.Configuration) string {
return cacheDir
}

func getHashForFolderPath(folderPath types.FilePath) hashedFolderPath {
return hashedFolderPath(util.Sha256First16Hash(string(folderPath)))
}

func getLocalFilePath(cacheDir string, folderPathHash hashedFolderPath, commitHash string, p product.Product) string {
productName := p.ToProductCodename()
return filepath.Join(cacheDir, fmt.Sprintf("%s.%s.%s.%s.json", SchemaVersion, folderPathHash, commitHash, productName))
Expand Down
51 changes: 39 additions & 12 deletions domain/snyk/persistence/git_persistence_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ import (
"github.com/snyk/snyk-ls/domain/snyk"
"github.com/snyk/snyk-ls/internal/product"
"github.com/snyk/snyk-ls/internal/types"
"github.com/snyk/snyk-ls/internal/util"
)

const (
Expand Down Expand Up @@ -83,6 +82,9 @@ func (g *GitPersistenceProvider) Init(folderPaths []types.FilePath) error {
g.mutex.Lock()
defer g.mutex.Unlock()

logger := g.logger.With().Str("method", "Init").Logger()
logger.Debug().Msgf("called with %d folders", len(folderPaths))

if len(folderPaths) == 0 {
return nil
}
Expand All @@ -94,32 +96,34 @@ func (g *GitPersistenceProvider) Init(folderPaths []types.FilePath) error {
cacheDir, err := g.ensureCacheDirExists()

if err != nil {
g.logger.Error().Err(err).Msgf("could not determine cache dir for folder path %s", folder)
logger.Error().Err(err).Msgf("could not determine cache dir for folder path %s", folder)
return err
}

filePaths, err := g.getPersistedFiles(cacheDir)
if err != nil {
g.logger.Error().Err(err).Msg("failed to load cached file paths")
logger.Error().Err(err).Msg("failed to load cached file paths")
return err
}

for _, filePath := range filePaths {
schemaVersion, hash, commitHash, p, fileParseErr := g.fileSchema(filePath)
fullPath := filepath.Join(cacheDir, filePath)
if fileParseErr != nil || g.isExpired(schemaVersion, fullPath) {
g.logger.Info().Msgf("file %s is expired. attempting to delete", filePath)
logger.Info().Msgf("file %s is expired. attempting to delete", filePath)
err = g.deleteFile(fullPath)
if err != nil {
g.logger.Error().Err(err).Msgf("failed to delete file %s", filePath)
logger.Error().Err(err).Msgf("failed to delete file %s", filePath)
}
continue
}
logger.Debug().Msgf("loaded cache entry: hash=%s, commitHash=%s, product=%s", hash, commitHash, p)
g.createOrAppendToCache(hash, commitHash, p)
}
}

g.initialized = true
logger.Debug().Msgf("complete, cache has %d entries", len(g.cache))
return nil
}

Expand Down Expand Up @@ -161,29 +165,43 @@ func (g *GitPersistenceProvider) Clear(folders []types.FilePath, deleteOnlyExpir
}
}

func (g *GitPersistenceProvider) ClearFolder(folderPath types.FilePath) {
g.mutex.Lock()
defer g.mutex.Unlock()

hash := getHashForFolderPath(folderPath)
g.logger.Debug().Str("folderPath", string(folderPath)).Str("hash", string(hash)).Msg("clearing in-memory cache for folder")
delete(g.cache, hash)
}

func (g *GitPersistenceProvider) GetPersistedIssueList(folderPath types.FilePath, p product.Product) ([]types.Issue, error) {
g.mutex.Lock()
defer g.mutex.Unlock()

logger := g.logger.With().Str("method", "GetPersistedIssueList").Logger()
logger.Debug().Msgf("getting persisted issue list for folderPath=%s, product=%s", folderPath, p)

cacheDir := snykCacheDir(g.conf)
commitHash, err := g.getCommitHashForProduct(folderPath, p)
logger.Debug().Msgf("commitHash=%s, err=%v", commitHash, err)
if err != nil {
logger.Debug().Msgf("returning error: %v", err)
return nil, err
}

if commitHash == "" {
return nil, errors.New("no commit hash found in cache")
}

hash := hashedFolderPath(util.Sha256First16Hash(string(folderPath)))
hash := getHashForFolderPath(folderPath)

filePath := getLocalFilePath(cacheDir, hash, commitHash, p)
content, err := os.ReadFile(filePath)
if err != nil {
if errors.Is(err, os.ErrNotExist) {
err = g.deleteFromCache(hash, commitHash, p)
if err != nil {
g.logger.Error().Err(err).Msg("failed to remove file from cache: " + filePath)
logger.Error().Err(err).Msg("failed to remove file from cache: " + filePath)
}
}
return nil, err
Expand All @@ -199,6 +217,7 @@ func (g *GitPersistenceProvider) GetPersistedIssueList(folderPath types.FilePath
for i := range snykIssues {
results = append(results, &snykIssues[i])
}
logger.Debug().Msgf("returning %d issues", len(results))
return results, nil
}

Expand All @@ -207,7 +226,7 @@ func (g *GitPersistenceProvider) Add(folderPath types.FilePath, commitHash strin
defer g.mutex.Unlock()

cacheDir := snykCacheDir(g.conf)
hash := hashedFolderPath(util.Sha256First16Hash(string(folderPath)))
hash := getHashForFolderPath(folderPath)

shouldPersist := g.shouldPersistOnDisk(hash, commitHash, p)
if !shouldPersist {
Expand Down Expand Up @@ -235,24 +254,32 @@ func (g *GitPersistenceProvider) Exists(folderPath types.FilePath, commitHash st
g.mutex.Lock()
defer g.mutex.Unlock()

logger := g.logger.With().Str("method", "Exists").Logger()
logger.Debug().Msgf("checking for existing snapshot: folderPath=%s, requestedCommitHash=%s, product=%s", folderPath, commitHash, p)

cacheDir := snykCacheDir(g.conf)
existingCommitHash, err := g.getCommitHashForProduct(folderPath, p)

logger.Debug().Msgf("existingCommitHash=%s, err=%v", existingCommitHash, err)

if err != nil || existingCommitHash != commitHash || existingCommitHash == "" {
logger.Debug().Msgf("returning FALSE (err=%v, existingCommitHash=%s, requestedCommitHash=%s)", err, existingCommitHash, commitHash)
return false
}

hash := hashedFolderPath(util.Sha256First16Hash(string(folderPath)))
hash := getHashForFolderPath(folderPath)
exists := g.snapshotExistsOnDisk(cacheDir, hash, commitHash, p)
logger.Debug().Msgf("snapshotExistsOnDisk=%t", exists)
if exists {
logger.Debug().Msg("returning TRUE")
return true
}

g.logger.Debug().Msg(string("entry exists in cache but not on disk. Maybe file was deleted? " + folderPath))
logger.Debug().Msg(string("entry exists in cache but not on disk. Maybe file was deleted? " + folderPath))

err = g.deleteFromCache(hash, commitHash, p)
if err != nil {
g.logger.Error().Err(err).Msg(string("failed to remove file from cache: " + folderPath))
logger.Error().Err(err).Msg(string("failed to remove file from cache: " + folderPath))
}
return false
}
Expand Down Expand Up @@ -314,7 +341,7 @@ func (g *GitPersistenceProvider) deleteFromCache(hash hashedFolderPath, commitHa
}

func (g *GitPersistenceProvider) getCommitHashForProduct(folderPath types.FilePath, p product.Product) (commitHash string, err error) {
hash := hashedFolderPath(util.Sha256First16Hash(string(folderPath)))
hash := getHashForFolderPath(folderPath)

pchMap, ok := g.cache[hash]
if !ok {
Expand Down
Loading
Loading