Skip to content

Commit

Permalink
Don't fail on invalid configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
pcarranza committed Aug 22, 2018
1 parent 1892f34 commit 91be7fa
Show file tree
Hide file tree
Showing 5 changed files with 304 additions and 157 deletions.
76 changes: 75 additions & 1 deletion config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@ package config

import (
"fmt"
"github.com/sirupsen/logrus"
"io/ioutil"
neturl "net/url"
"os"
"strings"

"github.com/sirupsen/logrus"

"gitlab.com/yakshaving.art/git-pull-mirror/url"
yaml "gopkg.in/yaml.v2"
Expand All @@ -24,6 +28,27 @@ type RepositoryConfig struct {
TargetURL url.GitURL
}

// Arguments parsed through user provided flags
type Arguments struct {
Address string
ConfigFile string
CallbackURL string
Debug bool

GithubUser string
GithubToken string
GithubURL string

WebhooksTarget string
RepositoriesPath string
SkipRegistration bool
SSHKey string
TimeoutSeconds uint64

DryRun bool
ShowVersion bool
}

// LoadConfiguration loads the file and parses the origin url, returns a
// configuration if everything checks up, an error in case of any failure.
func LoadConfiguration(filename string) (Config, error) {
Expand Down Expand Up @@ -54,3 +79,52 @@ func LoadConfiguration(filename string) (Config, error) {

return c, nil
}

// Check runs the arguments structure through a validation. It returns an error if the arguments are invalid.
func (a Arguments) Check() error {
if strings.TrimSpace(a.ConfigFile) == "" {
return fmt.Errorf("Config file is mandatory, please set it through the -config.file argument")
}
if strings.TrimSpace(a.CallbackURL) == "" {
return fmt.Errorf("Callback URL is mandatory, please set it through the environment CALLBACK_URL variable or with -callback.url")
}

u, err := neturl.ParseRequestURI(a.CallbackURL)
if err != nil {
return fmt.Errorf("Invalid callback URL '%s': %s", a.CallbackURL, err)
}
if strings.TrimSpace(u.Scheme) == "" || strings.TrimSpace(u.Path) == "" || strings.TrimSpace(u.Host) == "" {
return fmt.Errorf("Invalid callback URL '%s', it should include a path", a.CallbackURL)
}

if len(strings.TrimSpace(a.GithubUser)) == 0 {
return fmt.Errorf("GitHub user is mandatory, please set it through the environment GITHUB_USER variable or with -github.user")
}
if len(strings.TrimSpace(a.GithubToken)) == 0 {
return fmt.Errorf("GitHubToken user is mandatory, please set it through the environment GITHUB_TOKEN variable or with -github.token")
}

u, err = neturl.ParseRequestURI(a.GithubURL)
if err != nil {
return fmt.Errorf("Invalid GitHub URL '%s': %s", a.GithubURL, err)
}

f, err := os.Stat(a.RepositoriesPath)
if err != nil {
return fmt.Errorf("Repositories path is not accessible: %s", err)
}
if !f.IsDir() {
return fmt.Errorf("Repositories path folder %s it not a folder", a.RepositoriesPath)
}

if strings.TrimSpace(a.SSHKey) != "" {
if _, err := os.Stat(a.SSHKey); err != nil {
return fmt.Errorf("SSH Key %s is not accessible", err)
}
}
if a.TimeoutSeconds <= 0 {
return fmt.Errorf("Invalid timeout seconds %d, it should be 1 or higher", a.TimeoutSeconds)
}

return nil
}
149 changes: 148 additions & 1 deletion config/config_test.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package config_test

import (
"gitlab.com/yakshaving.art/git-pull-mirror/config"
"fmt"
"testing"

"gitlab.com/yakshaving.art/git-pull-mirror/config"
)

func TestLoadingValidConfiguration(t *testing.T) {
Expand Down Expand Up @@ -63,6 +65,151 @@ func TestLoadingInvalidConfiguration(t *testing.T) {
}
}

func TestArguments(t *testing.T) {
tt := []struct {
name string
args config.Arguments
err string
}{
{
"empty arguments",
config.Arguments{},
"Config file is mandatory, please set it through the -config.file argument",
},
{
"without callback url ",
config.Arguments{
ConfigFile: "/tmp",
},
"Callback URL is mandatory, please set it through the environment CALLBACK_URL variable or with -callback.url",
},
{
"with an invalid callback url",
config.Arguments{
ConfigFile: "/tmp",
CallbackURL: "invalidurl",
},
"Invalid callback URL 'invalidurl': parse invalidurl: invalid URI for request",
},
{
"with a valid callback url without a path",
config.Arguments{
ConfigFile: "/tmp",
CallbackURL: "http://valid.com",
},
"Invalid callback URL 'http://valid.com', it should include a path",
},
{
"without a github user",
config.Arguments{
ConfigFile: "/tmp",
CallbackURL: "http://valid.com/somepath",
},
"GitHub user is mandatory, please set it through the environment GITHUB_USER variable or with -github.user",
},
{
"without a github token",
config.Arguments{
ConfigFile: "/tmp",
CallbackURL: "http://valid.com/somepath",
GithubUser: "pullbot",
},
"GitHubToken user is mandatory, please set it through the environment GITHUB_TOKEN variable or with -github.token",
},
{
"without a github url",
config.Arguments{
ConfigFile: "/tmp",
CallbackURL: "http://valid.com/somepath",
GithubUser: "pullbot",
GithubToken: "sometoken",
},
"Invalid GitHub URL '': parse : empty url",
},
{
"with an invalid github url",
config.Arguments{
ConfigFile: "/tmp",
CallbackURL: "http://valid.com/somepath",
GithubUser: "pullbot",
GithubToken: "sometoken",
GithubURL: "invalid",
},
"Invalid GitHub URL 'invalid': parse invalid: invalid URI for request",
},
{
"without a repositories path",
config.Arguments{
ConfigFile: "/tmp",
CallbackURL: "http://valid.com/somepath",
GithubUser: "pullbot",
GithubToken: "sometoken",
GithubURL: "https://api.github.com/hub",
},
"Repositories path is not accessible: stat : no such file or directory",
},
{
"with a repositories file, not a folder",
config.Arguments{
ConfigFile: "/tmp",
CallbackURL: "http://valid.com/somepath",
GithubUser: "pullbot",
GithubToken: "sometoken",
GithubURL: "https://api.github.com/hub",
RepositoriesPath: "/etc/hosts",
},
"Repositories path folder /etc/hosts it not a folder",
},
{
"with an invalid timeout",
config.Arguments{
ConfigFile: "/tmp",
CallbackURL: "http://valid.com/somepath",
GithubUser: "pullbot",
GithubToken: "sometoken",
GithubURL: "https://api.github.com/hub",
RepositoriesPath: "/tmp",
},
"Invalid timeout seconds 0, it should be 1 or higher",
},
{
"with an invalid ssh key",
config.Arguments{
ConfigFile: "/tmp",
CallbackURL: "http://valid.com/somepath",
GithubUser: "pullbot",
GithubToken: "sometoken",
GithubURL: "https://api.github.com/hub",
RepositoriesPath: "/tmp",
TimeoutSeconds: 1,
SSHKey: "/tmp/non-existing-file-hopefully",
},
"SSH Key stat /tmp/non-existing-file-hopefully: no such file or directory is not accessible",
},
{
"without an invalid timeout",
config.Arguments{
ConfigFile: "/tmp",
CallbackURL: "http://valid.com/somepath",
GithubUser: "pullbot",
GithubToken: "sometoken",
GithubURL: "https://api.github.com/hub",
RepositoriesPath: "/tmp",
TimeoutSeconds: 1,
},
"%!s(<nil>)",
},
}

for _, tc := range tt {
t.Run(tc.name, func(t *testing.T) {
err := tc.args.Check()
assertEquals(t, tc.err, fmt.Sprintf("%s", err))
})
}

}

func assertEquals(t *testing.T, expected, got string) {
if expected != got {
t.Fatalf("Expected %s, got %s", expected, got)
Expand Down
Loading

0 comments on commit 91be7fa

Please sign in to comment.