-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support reading per repository configurations from .gopherci.yml
Users should be able to apply per repository configuration for GopherCI via a config file in the repository, this allows non-admin users to modify GopherCI on a per repository basis if they have write access. Which practically means users can also have their pull request modify GopherCI if they require additional packages to be installed (for cgo for example) or if they want to modify the tools being run. We achieve this by including a YAMLConfig which implements a configReader interface, an interface was chosen primarily to keep tests simpler, but the analyser doesn't really care where the config came from, just that it's able to receive one. The YAMLConfig should be preloaded with the global settings and then it should filter the config based on reading the repository's config file, and finally returning the config to analyser to use. Relates #8.
- Loading branch information
1 parent
7609790
commit 32a8f39
Showing
5 changed files
with
166 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
package analyser | ||
|
||
import ( | ||
"context" | ||
|
||
yaml "gopkg.in/yaml.v1" | ||
|
||
"github.com/bradleyfalzon/gopherci/internal/db" | ||
"github.com/pkg/errors" | ||
) | ||
|
||
// RepoConfig contains the analyser configuration for the repository. | ||
type RepoConfig struct { | ||
Tools []db.Tool | ||
} | ||
|
||
// A ConfigReader returns a repository's configuration. | ||
type ConfigReader interface { | ||
Read(context.Context, Executer) (RepoConfig, error) | ||
} | ||
|
||
// YAMLConfig implements a ConfigReader by reading a yaml configuration file | ||
// from the repositories root. | ||
type YAMLConfig struct { | ||
Tools []db.Tool // Preset tools to use, before per repo config has been applied | ||
} | ||
|
||
var _ ConfigReader = &YAMLConfig{} | ||
|
||
// Read implements the ConfigReader interface. | ||
func (c *YAMLConfig) Read(ctx context.Context, exec Executer) (RepoConfig, error) { | ||
cfg := RepoConfig{ | ||
Tools: c.Tools, | ||
} | ||
|
||
const configFilename = ".gopherci.yml" | ||
|
||
args := []string{"cat", configFilename} | ||
yml, err := exec.Execute(ctx, args) | ||
switch err.(type) { | ||
case nil: | ||
case *NonZeroError: | ||
return cfg, nil | ||
default: | ||
return cfg, errors.Wrapf(err, "could not read %s", configFilename) | ||
} | ||
|
||
if err = yaml.Unmarshal(yml, &cfg); err != nil { | ||
return cfg, errors.Wrapf(err, "could not unmarshal %s", configFilename) | ||
} | ||
|
||
return cfg, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
package analyser | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
"reflect" | ||
"testing" | ||
|
||
"github.com/bradleyfalzon/gopherci/internal/db" | ||
) | ||
|
||
func TestYAMLConfig_default(t *testing.T) { | ||
exec := &mockAnalyser{ | ||
ExecuteOut: [][]byte{{}}, | ||
ExecuteErr: []error{&NonZeroError{ExitCode: 1}}, | ||
} | ||
|
||
reader := &YAMLConfig{ | ||
Tools: []db.Tool{{Name: "tool1"}}, | ||
} | ||
have, err := reader.Read(context.Background(), exec) | ||
if err != nil { | ||
t.Errorf("unexpected error: %v", err) | ||
} | ||
|
||
want := RepoConfig{Tools: reader.Tools} | ||
|
||
if !reflect.DeepEqual(have, want) { | ||
t.Errorf("\nhave: %v\nwant: %v", have, want) | ||
} | ||
} | ||
|
||
func TestYAMLConfig_unknownError(t *testing.T) { | ||
exec := &mockAnalyser{ | ||
ExecuteOut: [][]byte{{}}, | ||
ExecuteErr: []error{errors.New("unknown error")}, | ||
} | ||
|
||
reader := &YAMLConfig{} | ||
_, err := reader.Read(context.Background(), exec) | ||
if err == nil { | ||
t.Errorf("expected error, have: %v", err) | ||
} | ||
} | ||
|
||
func TestYAMLConfig_unmarshalError(t *testing.T) { | ||
contents := []byte("\t") | ||
exec := &mockAnalyser{ | ||
ExecuteOut: [][]byte{contents}, | ||
ExecuteErr: []error{nil}, | ||
} | ||
|
||
reader := &YAMLConfig{} | ||
_, err := reader.Read(context.Background(), exec) | ||
if err == nil { | ||
t.Errorf("expected error, have: %v", err) | ||
} | ||
} | ||
|
||
func TestYAMLConfig(t *testing.T) { | ||
contents := []byte(`# .gopherci.yml config`) | ||
exec := &mockAnalyser{ | ||
ExecuteOut: [][]byte{contents}, | ||
ExecuteErr: []error{nil}, | ||
} | ||
|
||
reader := &YAMLConfig{ | ||
Tools: []db.Tool{{Name: "tool1"}}, | ||
} | ||
have, err := reader.Read(context.Background(), exec) | ||
if err != nil { | ||
t.Errorf("unexpected error: %v", err) | ||
} | ||
|
||
want := RepoConfig{Tools: reader.Tools} | ||
|
||
if !reflect.DeepEqual(have, want) { | ||
t.Errorf("\nhave: %v\nwant: %v", have, want) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters