Skip to content

Commit

Permalink
[Issue #171] | Update talismanrc instead of append in interactive mode
Browse files Browse the repository at this point in the history
  • Loading branch information
svishwanath-tw committed Nov 10, 2019
1 parent 575eb58 commit 424882a
Show file tree
Hide file tree
Showing 9 changed files with 132 additions and 54 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ talisman_darwin_*
talisman_windows_*
vendor/
gitrepo/data/*
detector/.talismanrc
.vscode/**
coverage.out
coverage.txt
6 changes: 3 additions & 3 deletions .talismanrc
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
fileignoreconfig:
- filename: detector/pattern_detector_test.go
checksum: e5d892e5b313a6cf6b0edbcf2eb02ede69b11b6c715f133da937b805a018a55a
ignore_detectors:
- filename: detector/detection_results_test.go
checksum: 69fed055782cddfe0f0d23ea440cef9f9dd0b9e8a3c8a73856741bb26257b223
ignore_detectors:
- filecontent
scopeconfig:
- scope: go
26 changes: 1 addition & 25 deletions detector/detection_results.go
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ func (r *DetectionResults) suggestTalismanRC(fs afero.Fs, ignoreFile string, fil

if promptContext.Interactive {
confirmedEntries := getUserConfirmation(entriesToAdd, promptContext)
addToTalismanIgnoreFile(confirmedEntries, fs, ignoreFile)
talismanrc.Get().AddFileIgnores(confirmedEntries)
} else {
printTalismanIgnoreSuggestion(entriesToAdd)
return
Expand Down Expand Up @@ -342,30 +342,6 @@ func printTalismanIgnoreSuggestion(entriesToAdd []talismanrc.FileIgnoreConfig) {
fmt.Println(string(ignoreEntries))
}

func addToTalismanIgnoreFile(entriesToAdd []talismanrc.FileIgnoreConfig, fs afero.Fs, ignoreFile string) {

if len(entriesToAdd) > 0 {
talismanRcIgnoreConfig := talismanrc.TalismanRCIgnore{FileIgnoreConfig: entriesToAdd}
ignoreEntries, _ := yaml.Marshal(&talismanRcIgnoreConfig)
file, err := fs.OpenFile(ignoreFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
log.Printf("error opening %s: %s", ignoreFile, err)
}
defer func() {
err := file.Close()
if err != nil {
log.Printf("error closing %s: %s", ignoreFile, err)
}

}()

_, err = file.WriteString(string(ignoreEntries))
if err != nil {
log.Printf("error writing to %s: %s", ignoreFile, err)
}
}
}

func confirm(config talismanrc.FileIgnoreConfig, promptContext prompt.PromptContext) bool {
bytes, err := yaml.Marshal(&config)
if err != nil {
Expand Down
48 changes: 34 additions & 14 deletions detector/detection_results_test.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package detector

import (
"github.com/golang/mock/gomock"
"github.com/spf13/afero"
"strings"
mock "talisman/internal/mock/prompt"
"talisman/prompt"
"talisman/talismanrc"
"testing"

"github.com/golang/mock/gomock"
"github.com/spf13/afero"

"github.com/stretchr/testify/assert"
)

Expand Down Expand Up @@ -78,6 +80,9 @@ func TestTalismanRCSuggestionWhenThereAreFailures(t *testing.T) {
assert.NoError(t, err)
ignoreFile := file.Name()

talismanrc.SetFs(fs)
talismanrc.SetRcFilename(ignoreFile)

existingContent := `fileignoreconfig:
- filename: existing.pem
checksum: 123444ddssa75333b25b6275f97680604add51b84eb8f4a3b9dcbbc652e6f27ac
Expand All @@ -100,6 +105,7 @@ scopeconfig: []
assert.Equal(t, existingContent, string(bytesFromFile))
})

_ = afero.WriteFile(fs, ignoreFile, []byte(existingContent), 0666)
t.Run("when user declines, entry should not be added to talismanrc", func(t *testing.T) {
promptContext := prompt.NewPromptContext(true, prompter)
prompter.EXPECT().Confirm("Do you want to add this entry in talismanrc ?").Return(false)
Expand All @@ -112,6 +118,7 @@ scopeconfig: []
assert.Equal(t, existingContent, string(bytesFromFile))
})

_ = afero.WriteFile(fs, ignoreFile, []byte(existingContent), 0666)
t.Run("when interactive flag is set to false, it should not ask user", func(t *testing.T) {
promptContext := prompt.NewPromptContext(false, prompter)
prompter.EXPECT().Confirm(gomock.Any()).Return(false).Times(0)
Expand All @@ -124,18 +131,14 @@ scopeconfig: []
assert.Equal(t, existingContent, string(bytesFromFile))
})

_ = afero.WriteFile(fs, ignoreFile, []byte(existingContent), 0666)
t.Run("when user confirms, entry should be appended to given ignore file", func(t *testing.T) {
promptContext := prompt.NewPromptContext(true, prompter)
prompter.EXPECT().Confirm("Do you want to add this entry in talismanrc ?").Return(true)

results.Fail("some_file.pem", "filecontent", "Bomb", []string{})

expectedFileContent := `fileignoreconfig:
- filename: existing.pem
checksum: 123444ddssa75333b25b6275f97680604add51b84eb8f4a3b9dcbbc652e6f27ac
ignore_detectors: []
scopeconfig: []
fileignoreconfig:
- filename: some_file.pem
checksum: 87139cc4d975333b25b6275f97680604add51b84eb8f4a3b9dcbbc652e6f27ac
ignore_detectors: []
Expand All @@ -148,24 +151,42 @@ scopeconfig: []
assert.Equal(t, expectedFileContent, string(bytesFromFile))
})

t.Run("when user confirms for multiple entries, they should be appended to given ignore file", func(t *testing.T) {
// Clearing file contents from previous tests
err := afero.WriteFile(fs, ignoreFile, []byte{}, 0666)
_ = afero.WriteFile(fs, ignoreFile, []byte(existingContent), 0666)
t.Run("when user confirms, entry for existing file should updated", func(t *testing.T) {
promptContext := prompt.NewPromptContext(true, prompter)
prompter.EXPECT().Confirm("Do you want to add this entry in talismanrc ?").Return(true)
results := NewDetectionResults()
results.Fail("existing.pem", "filecontent", "This will bomb!", []string{})

expectedFileContent := `fileignoreconfig:
- filename: existing.pem
checksum: 5bc0b0692a316bb2919263addaef0ffba3a21b9e1cca62a1028390e97e861e4e
ignore_detectors: []
scopeconfig: []
`
results.Report(fs, ignoreFile, promptContext)
bytesFromFile, err := afero.ReadFile(fs, ignoreFile)

assert.NoError(t, err)
assert.Equal(t, expectedFileContent, string(bytesFromFile))
})

_ = afero.WriteFile(fs, ignoreFile, []byte(existingContent), 0666)
t.Run("when user confirms for multiple entries, they should be appended to given ignore file", func(t *testing.T) {
promptContext := prompt.NewPromptContext(true, prompter)
prompter.EXPECT().Confirm("Do you want to add this entry in talismanrc ?").Return(true).Times(2)

results.Fail("some_file.pem", "filecontent", "Bomb", []string{})
results.Fail("another.pem", "filecontent", "password", []string{})

expectedFileContent := `fileignoreconfig:
- filename: some_file.pem
checksum: 87139cc4d975333b25b6275f97680604add51b84eb8f4a3b9dcbbc652e6f27ac
ignore_detectors: []
- filename: another.pem
checksum: 117e23557c02cbd472854ebce4933d6daec1fd207971286f6ffc9f1774c1a83b
ignore_detectors: []
- filename: some_file.pem
checksum: 87139cc4d975333b25b6275f97680604add51b84eb8f4a3b9dcbbc652e6f27ac
ignore_detectors: []
scopeconfig: []
`
results.Report(fs, ignoreFile, promptContext)
Expand All @@ -175,7 +196,6 @@ scopeconfig: []
assert.Equal(t, expectedFileContent, string(bytesFromFile))
})


err = fs.Remove(ignoreFile)
assert.NoError(t, err)
}
10 changes: 7 additions & 3 deletions git_testing/git_testing.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ import (
)

var Logger *logrus.Entry

const gitConfigFile = "/tmp/talismanTestingGitConfig"
var gitConfigFile string

type GitTesting struct {
gitRoot string
Expand All @@ -24,6 +23,8 @@ func Init(gitRoot string) *GitTesting {
os.MkdirAll(gitRoot, 0777)
testingRepo := &GitTesting{gitRoot}
testingRepo.ExecCommand("git", "init", ".")
gitConfigFileObject, _ := ioutil.TempFile("/tmp", "gitConfigForTalismanTests")
gitConfigFile = gitConfigFileObject.Name()
testingRepo.CreateFileWithContents(gitConfigFile, `[user]
email = talisman-test-user@example.com
name = Talisman Test User`)
Expand Down Expand Up @@ -143,11 +144,14 @@ func (git *GitTesting) GetBlobDetails(fileName string) string {
return object_hash_and_filename
}


//ExecCommand executes a command with given arguments in the git repo directory
func (git *GitTesting) ExecCommand(commandName string, args ...string) string {
var output []byte
git.doInGitRoot(func() {
result := exec.Command(commandName, args...)
result.Env = []string{"GIT_CONFIG=" + gitConfigFile}
//Passes locally, but fails on CI
//result.Env = []string{"GIT_CONFIG=" + gitConfigFile}
var err error
output, err = result.Output()
git.die(fmt.Sprintf("when executing command %s %v in %s", commandName, args, git.gitRoot), err)
Expand Down
1 change: 1 addition & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/golang/mock v1.3.1 h1:qGJ6qTW+x6xX/my+8YUVl4WNpX9B7+/l2tRsHGZ7f2s=
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
github.com/hashicorp/go-version v1.0.0 h1:21MVWPKDphxa7ineQQTrCU5brh7OuVVAzGOCnnCPtE8=
github.com/hashicorp/go-version v1.0.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174 h1:WlZsjVhE8Af9IcZDGgJGQpNflI3+MJSBhsgT5PCtzBQ=
github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174/go.mod h1:DqJ97dSdRW1W22yXSB90986pcOyQ7r45iio1KN2ez1A=
Expand Down
9 changes: 1 addition & 8 deletions runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package main
import (
"fmt"
"log"
"os"
"talisman/checksumcalculator"
"talisman/detector"
"talisman/gitrepo"
Expand Down Expand Up @@ -76,7 +75,7 @@ func (r *Runner) RunChecksumCalculator(fileNamePatterns []string) int {
}

func (r *Runner) doRun() {
rcConfigIgnores := talismanrc.ReadConfigFromRCFile(readRepoFile())
rcConfigIgnores := talismanrc.Get()
scopeMap := getScopeConfig()
additionsToScan := rcConfigIgnores.IgnoreAdditionsByScope(r.additions, scopeMap)
detector.DefaultChain().Test(additionsToScan, rcConfigIgnores, r.results)
Expand Down Expand Up @@ -106,9 +105,3 @@ func (r *Runner) exitStatus() int {
}
return CompletedSuccessfully
}

func readRepoFile() func(string) ([]byte, error) {
wd, _ := os.Getwd()
repo := gitrepo.RepoLocatedAt(wd)
return repo.ReadRepoFileOrNothing
}
78 changes: 77 additions & 1 deletion talismanrc/talismanrc.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@ package talismanrc

import (
"log"
"os"
"reflect"
"regexp"
"sort"
"strings"

logr "github.com/Sirupsen/logrus"
"github.com/spf13/afero"
"gopkg.in/yaml.v2"

"talisman/gitrepo"
Expand All @@ -26,6 +30,9 @@ var (
commentPattern = regexp.MustCompile(LinePattern)
ignorePattern = regexp.MustCompile(IgnoreDetectorCommentPattern)
emptyStringPattern = regexp.MustCompile(`^\s*$`)
fs = afero.NewOsFs()
currentRCFileName = DefaultRCFileName
cachedConfig TalismanRCIgnore
)

//Ignores represents a set of patterns that have been configured to be ignored by the Detectors.
Expand Down Expand Up @@ -56,18 +63,36 @@ type TalismanRCIgnore struct {
ScopeConfig []ScopeConfig `yaml:"scopeconfig"`
}

func SetFs(_fs afero.Fs) {
fs = _fs
}

func SetRcFilename(rcFileName string) {
currentRCFileName = rcFileName
}

func Get() *TalismanRCIgnore {
return ReadConfigFromRCFile(readRepoFile())
}

func (ignore *TalismanRCIgnore) IsEmpty() bool {
return reflect.DeepEqual(TalismanRCIgnore{}, ignore)
}

func ReadConfigFromRCFile(repoFileRead func(string) ([]byte, error)) *TalismanRCIgnore {
fileContents, error := repoFileRead(DefaultRCFileName)
fileContents, error := repoFileRead(currentRCFileName)
if error != nil {
panic(error)
}
return NewTalismanRCIgnore(fileContents)
}

func readRepoFile() func(string) ([]byte, error) {
wd, _ := os.Getwd()
repo := gitrepo.RepoLocatedAt(wd)
return repo.ReadRepoFileOrNothing
}

func NewTalismanRCIgnore(fileContents []byte) *TalismanRCIgnore {
talismanRCIgnore := TalismanRCIgnore{}
err := yaml.Unmarshal([]byte(fileContents), &talismanRCIgnore)
Expand Down Expand Up @@ -146,6 +171,57 @@ func (rcConfigIgnores *TalismanRCIgnore) IgnoreAdditionsByScope(additions []gitr
return result
}

func (rcConfigIgnores *TalismanRCIgnore) AddFileIgnores(entriesToAdd []FileIgnoreConfig) {
if len(entriesToAdd) > 0 {
logr.Debugf("Adding entries: %v", entriesToAdd)
talismanRcIgnoreConfig := Get()
talismanRcIgnoreConfig.FileIgnoreConfig = combineFileIgnores(talismanRcIgnoreConfig.FileIgnoreConfig, entriesToAdd)
ignoreEntries, _ := yaml.Marshal(&talismanRcIgnoreConfig)
file, err := fs.OpenFile(currentRCFileName, os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
log.Printf("error opening %s: %s", currentRCFileName, err)
}
defer func() {
err := file.Close()
if err != nil {
log.Printf("error closing %s: %s", currentRCFileName, err)
}

}()
logr.Debugf("Writing talismanrc: %v", string(ignoreEntries))
_, err = file.WriteString(string(ignoreEntries))
if err != nil {
log.Printf("error writing to %s: %s", currentRCFileName, err)
}
}
}

func combineFileIgnores(exsiting, incoming []FileIgnoreConfig) []FileIgnoreConfig {
existingMap := make(map[string]FileIgnoreConfig)
for _, fIC := range exsiting {
existingMap[fIC.FileName] = fIC
}
for _, fIC := range incoming {
existingMap[fIC.FileName] = fIC
}
result := make([]FileIgnoreConfig, len(existingMap))
resultKeys := make([]string, len(existingMap))
index := 0
//sort keys in alpabetical order
for k, _ := range existingMap {
resultKeys[index] = k
index++
}
sort.Strings(resultKeys)
//add result entries based on sortedkeys
index = 0
for _, k := range resultKeys {
result[index] = existingMap[k]
index++
}
return result
}

//Deny answers true if the Addition.Path is configured to be ignored and not checked by the detectors
func (i *TalismanRCIgnore) Deny(addition gitrepo.Addition, detectorName string) bool {
result := false
Expand Down
7 changes: 7 additions & 0 deletions talismanrc/talismanrc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,13 @@ func TestIgnoringDetectors(t *testing.T) {
assertAcceptsDetector("foo", "someDetector", "foo", "someOtherDetector", t)
}

func TestAddIgnoreFiles(t *testing.T) {
talismanRCIgnoreConfig := CreateTalismanRCIgnoreWithScopeIgnore([]string{})
talismanRCIgnoreConfig.AddFileIgnores([]FileIgnoreConfig{FileIgnoreConfig{"Foo", "SomeCheckSum", []string{}}})
talismanRCIgnoreConfig = Get()
assert.Equal(t, 1, len(talismanRCIgnoreConfig.FileIgnoreConfig))
}

func assertDenies(line, ignoreDetector string, path string, t *testing.T) {
assertDeniesDetector(line, ignoreDetector, path, "filename", t)
}
Expand Down

0 comments on commit 424882a

Please sign in to comment.