Start laying out the structure of gooni
This commit is contained in:
commit
7327e1ff7f
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
vendor/
|
||||||
|
/ooni
|
42
Gopkg.lock
generated
Normal file
42
Gopkg.lock
generated
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
|
||||||
|
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
name = "github.com/alecthomas/kingpin"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "947dcec5ba9c011838740e680966fd7087a71d0d"
|
||||||
|
version = "v2.2.6"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
branch = "master"
|
||||||
|
name = "github.com/alecthomas/template"
|
||||||
|
packages = [
|
||||||
|
".",
|
||||||
|
"parse"
|
||||||
|
]
|
||||||
|
revision = "a0175ee3bccc567396460bf5acd36800cb10c49c"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
branch = "master"
|
||||||
|
name = "github.com/alecthomas/units"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "2efee857e7cfd4f3d0138cc3cbb1b4966962b93a"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
branch = "master"
|
||||||
|
name = "github.com/aybabtme/rgbterm"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "cc83f3b3ce5911279513a46d6d3316d67bedaa54"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
name = "github.com/pkg/errors"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "645ef00459ed84a119197bfb8d8205042c6df63d"
|
||||||
|
version = "v0.8.0"
|
||||||
|
|
||||||
|
[solve-meta]
|
||||||
|
analyzer-name = "dep"
|
||||||
|
analyzer-version = 1
|
||||||
|
inputs-digest = "4ed0a29997f4d8f197233e4ba7aa66ed7033443a893a795ed2b4a9a5ec4350bd"
|
||||||
|
solver-name = "gps-cdcl"
|
||||||
|
solver-version = 1
|
42
Gopkg.toml
Normal file
42
Gopkg.toml
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
# Gopkg.toml example
|
||||||
|
#
|
||||||
|
# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
|
||||||
|
# for detailed Gopkg.toml documentation.
|
||||||
|
#
|
||||||
|
# required = ["github.com/user/thing/cmd/thing"]
|
||||||
|
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
|
||||||
|
#
|
||||||
|
# [[constraint]]
|
||||||
|
# name = "github.com/user/project"
|
||||||
|
# version = "1.0.0"
|
||||||
|
#
|
||||||
|
# [[constraint]]
|
||||||
|
# name = "github.com/user/project2"
|
||||||
|
# branch = "dev"
|
||||||
|
# source = "github.com/myfork/project2"
|
||||||
|
#
|
||||||
|
# [[override]]
|
||||||
|
# name = "github.com/x/y"
|
||||||
|
# version = "2.4.0"
|
||||||
|
#
|
||||||
|
# [prune]
|
||||||
|
# non-go = false
|
||||||
|
# go-tests = true
|
||||||
|
# unused-packages = true
|
||||||
|
|
||||||
|
|
||||||
|
[[constraint]]
|
||||||
|
name = "github.com/alecthomas/kingpin"
|
||||||
|
version = "2.2.6"
|
||||||
|
|
||||||
|
[[constraint]]
|
||||||
|
branch = "master"
|
||||||
|
name = "github.com/aybabtme/rgbterm"
|
||||||
|
|
||||||
|
[prune]
|
||||||
|
go-tests = true
|
||||||
|
unused-packages = true
|
||||||
|
|
||||||
|
[[constraint]]
|
||||||
|
name = "github.com/pkg/errors"
|
||||||
|
version = "0.8.0"
|
6
Makefile
Normal file
6
Makefile
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
GO ?= go
|
||||||
|
|
||||||
|
build:
|
||||||
|
@echo "Building ./ooni"
|
||||||
|
@$(GO) build -o ooni cmd/ooni/main.go
|
||||||
|
.PHONY: build
|
23
cmd/ooni/main.go
Normal file
23
cmd/ooni/main.go
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
// commands
|
||||||
|
_ "github.com/openobservatory/gooni/internal/cli/info"
|
||||||
|
_ "github.com/openobservatory/gooni/internal/cli/list"
|
||||||
|
_ "github.com/openobservatory/gooni/internal/cli/nettest"
|
||||||
|
_ "github.com/openobservatory/gooni/internal/cli/run"
|
||||||
|
_ "github.com/openobservatory/gooni/internal/cli/show"
|
||||||
|
_ "github.com/openobservatory/gooni/internal/cli/upload"
|
||||||
|
_ "github.com/openobservatory/gooni/internal/cli/version"
|
||||||
|
"github.com/openobservatory/gooni/internal/util"
|
||||||
|
|
||||||
|
"github.com/openobservatory/gooni/internal/cli/app"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
err := app.Run()
|
||||||
|
if err == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
util.Fatal(err)
|
||||||
|
}
|
7
config/advanced.go
Normal file
7
config/advanced.go
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
package config
|
||||||
|
|
||||||
|
// Advanced settings
|
||||||
|
type Advanced struct {
|
||||||
|
IncludeCountry bool `json:"include_country"`
|
||||||
|
UseDomainFronting bool `json:"use_domain_fronting"`
|
||||||
|
}
|
8
config/automated_testing.go
Normal file
8
config/automated_testing.go
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
package config
|
||||||
|
|
||||||
|
// AutomatedTesting settings
|
||||||
|
type AutomatedTesting struct {
|
||||||
|
Enabled bool `json:"enabled"`
|
||||||
|
EnabledTests []string `json:"enabled_tests"`
|
||||||
|
MonthlyAllowance string `json:"monthly_allowance"`
|
||||||
|
}
|
29
config/nettest_groups.go
Normal file
29
config/nettest_groups.go
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
package config
|
||||||
|
|
||||||
|
type websiteSettings struct {
|
||||||
|
EnabledCategories []string `json:"enabled_categories"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type instantMessagingSettings struct {
|
||||||
|
EnabledTests []string `json:"enabled_tests"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type performanceSettings struct {
|
||||||
|
EnabledTests []string `json:"enabled_tests"`
|
||||||
|
NDTServer string `json:"ndt_server"`
|
||||||
|
NDTServerPort string `json:"ndt_server_port"`
|
||||||
|
DashServer string `json:"dash_server"`
|
||||||
|
DashServerPort string `json:"dash_server_port"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type middleboxSettings struct {
|
||||||
|
EnabledTests []string `json:"enabled_tests"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NettestGroups related settings
|
||||||
|
type NettestGroups struct {
|
||||||
|
Websites websiteSettings `json:"websites"`
|
||||||
|
InstantMessaging instantMessagingSettings `json:"instant_messaging"`
|
||||||
|
Performance performanceSettings `json:"performance"`
|
||||||
|
Middlebox middleboxSettings `json:"middlebox"`
|
||||||
|
}
|
8
config/notifications.go
Normal file
8
config/notifications.go
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
package config
|
||||||
|
|
||||||
|
// Notifications settings
|
||||||
|
type Notifications struct {
|
||||||
|
Enabled bool `json:"enabled"`
|
||||||
|
NotifyOnTestCompletion bool `json:"notify_on_test_completion"`
|
||||||
|
NotifyOnNews bool `json:"notify_on_news"`
|
||||||
|
}
|
10
config/sharing.go
Normal file
10
config/sharing.go
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
package config
|
||||||
|
|
||||||
|
// Sharing settings
|
||||||
|
type Sharing struct {
|
||||||
|
IncludeIP bool `json:"include_ip"`
|
||||||
|
IncludeASN bool `json:"include_asn"`
|
||||||
|
IncludeGPS bool `json:"include_gps"`
|
||||||
|
UploadResults bool `json:"upload_results"`
|
||||||
|
SendCrashReports bool `json:"send_crash_reports"`
|
||||||
|
}
|
17
internal/cli/app/app.go
Normal file
17
internal/cli/app/app.go
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
package app
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/openobservatory/gooni/internal/cli/root"
|
||||||
|
"github.com/openobservatory/gooni/internal/cli/version"
|
||||||
|
"github.com/openobservatory/gooni/internal/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Run the app. This is the main app entry point
|
||||||
|
func Run() error {
|
||||||
|
util.Log("Running")
|
||||||
|
root.Cmd.Version(version.Version)
|
||||||
|
_, err := root.Cmd.Parse(os.Args[1:])
|
||||||
|
return err
|
||||||
|
}
|
16
internal/cli/info/info.go
Normal file
16
internal/cli/info/info.go
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
package info
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/alecthomas/kingpin"
|
||||||
|
"github.com/openobservatory/gooni/internal/cli/root"
|
||||||
|
"github.com/openobservatory/gooni/internal/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
cmd := root.Command("info", "Display information about OONI Probe")
|
||||||
|
|
||||||
|
cmd.Action(func(_ *kingpin.ParseContext) error {
|
||||||
|
util.Log("Info")
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
16
internal/cli/list/list.go
Normal file
16
internal/cli/list/list.go
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
package list
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/alecthomas/kingpin"
|
||||||
|
"github.com/openobservatory/gooni/internal/cli/root"
|
||||||
|
"github.com/openobservatory/gooni/internal/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
cmd := root.Command("list", "List measurements")
|
||||||
|
|
||||||
|
cmd.Action(func(_ *kingpin.ParseContext) error {
|
||||||
|
util.Log("Listing")
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
16
internal/cli/nettest/nettest.go
Normal file
16
internal/cli/nettest/nettest.go
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
package nettest
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/alecthomas/kingpin"
|
||||||
|
"github.com/openobservatory/gooni/internal/cli/root"
|
||||||
|
"github.com/openobservatory/gooni/internal/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
cmd := root.Command("nettest", "Run a specific nettest")
|
||||||
|
|
||||||
|
cmd.Action(func(_ *kingpin.ParseContext) error {
|
||||||
|
util.Log("Nettest")
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
19
internal/cli/root/root.go
Normal file
19
internal/cli/root/root.go
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
package root
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/alecthomas/kingpin"
|
||||||
|
"github.com/openobservatory/gooni/internal/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Cmd is the root command
|
||||||
|
var Cmd = kingpin.New("ooni", "")
|
||||||
|
|
||||||
|
// Command is syntax sugar for defining sub-commands
|
||||||
|
var Command = Cmd.Command
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
Cmd.PreAction(func(ctx *kingpin.ParseContext) error {
|
||||||
|
util.Log("Running pre-action")
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
18
internal/cli/run/run.go
Normal file
18
internal/cli/run/run.go
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
package run
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/alecthomas/kingpin"
|
||||||
|
"github.com/openobservatory/gooni/internal/cli/root"
|
||||||
|
"github.com/openobservatory/gooni/internal/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
cmd := root.Command("run", "Run a test group or OONI Run link")
|
||||||
|
|
||||||
|
nettestGroup := cmd.Arg("name", "the nettest group to run").Required().String()
|
||||||
|
|
||||||
|
cmd.Action(func(_ *kingpin.ParseContext) error {
|
||||||
|
util.Log("Starting %s", nettestGroup)
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
16
internal/cli/show/show.go
Normal file
16
internal/cli/show/show.go
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
package nettest
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/alecthomas/kingpin"
|
||||||
|
"github.com/openobservatory/gooni/internal/cli/root"
|
||||||
|
"github.com/openobservatory/gooni/internal/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
cmd := root.Command("show", "Show a specific measurement")
|
||||||
|
|
||||||
|
cmd.Action(func(_ *kingpin.ParseContext) error {
|
||||||
|
util.Log("Show")
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
16
internal/cli/upload/upload.go
Normal file
16
internal/cli/upload/upload.go
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
package upload
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/alecthomas/kingpin"
|
||||||
|
"github.com/openobservatory/gooni/internal/cli/root"
|
||||||
|
"github.com/openobservatory/gooni/internal/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
cmd := root.Command("upload", "Upload a specific measurement")
|
||||||
|
|
||||||
|
cmd.Action(func(_ *kingpin.ParseContext) error {
|
||||||
|
util.Log("Uploading")
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
18
internal/cli/version/version.go
Normal file
18
internal/cli/version/version.go
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
package version
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/alecthomas/kingpin"
|
||||||
|
"github.com/openobservatory/gooni/internal/cli/root"
|
||||||
|
)
|
||||||
|
|
||||||
|
const Version = "0.0.1"
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
cmd := root.Command("version", "Show version.")
|
||||||
|
cmd.Action(func(_ *kingpin.ParseContext) error {
|
||||||
|
fmt.Println(Version)
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
40
internal/colors/colors.go
Normal file
40
internal/colors/colors.go
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
package colors
|
||||||
|
|
||||||
|
import (
|
||||||
|
color "github.com/aybabtme/rgbterm"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Gray string.
|
||||||
|
func Gray(s string) string {
|
||||||
|
return color.FgString(s, 150, 150, 150)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Blue string.
|
||||||
|
func Blue(s string) string {
|
||||||
|
return color.FgString(s, 77, 173, 247)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cyan string.
|
||||||
|
func Cyan(s string) string {
|
||||||
|
return color.FgString(s, 34, 184, 207)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Green string.
|
||||||
|
func Green(s string) string {
|
||||||
|
return color.FgString(s, 0, 200, 255)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Red string.
|
||||||
|
func Red(s string) string {
|
||||||
|
return color.FgString(s, 194, 37, 92)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Yellow string.
|
||||||
|
func Yellow(s string) string {
|
||||||
|
return color.FgString(s, 252, 196, 25)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Purple string.
|
||||||
|
func Purple(s string) string {
|
||||||
|
return color.FgString(s, 96, 97, 190)
|
||||||
|
}
|
19
internal/util/util.go
Normal file
19
internal/util/util.go
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
package util
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/openobservatory/gooni/internal/colors"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Log outputs a log message.
|
||||||
|
func Log(msg string, v ...interface{}) {
|
||||||
|
fmt.Printf(" %s\n", colors.Purple(fmt.Sprintf(msg, v...)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fatal error
|
||||||
|
func Fatal(err error) {
|
||||||
|
fmt.Fprintf(os.Stderr, "\n %s %s\n\n", colors.Red("Error:"), err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
141
ooni.go
Normal file
141
ooni.go
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
package ooni
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/openobservatory/gooni/config"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Config for the OONI Probe installation
|
||||||
|
type Config struct {
|
||||||
|
// Private settings
|
||||||
|
Comment string `json:"_"`
|
||||||
|
ConfigVersion string `json:"_config_version"`
|
||||||
|
InformedConsent bool `json:"_informed_consent"`
|
||||||
|
|
||||||
|
AutoUpdate bool `json:"auto_update"`
|
||||||
|
Sharing config.Sharing `json:"sharing"`
|
||||||
|
Notifications config.Notifications `json:"notifications"`
|
||||||
|
AutomatedTesting config.AutomatedTesting `json:"automated_testing"`
|
||||||
|
NettestGroups config.NettestGroups `json:"test_settings"`
|
||||||
|
Advanced config.Sharing `json:"advanced"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default config settings
|
||||||
|
func (c *Config) Default() error {
|
||||||
|
// This is the default configuration:
|
||||||
|
/*
|
||||||
|
_: 'This is your OONI Probe config file. See https://ooni.io/help/ooniprobe-cli for help',
|
||||||
|
auto_update: true,
|
||||||
|
sharing: {
|
||||||
|
include_ip: false,
|
||||||
|
include_asn: true,
|
||||||
|
include_gps: true,
|
||||||
|
upload_results: true,
|
||||||
|
send_crash_reports: true
|
||||||
|
},
|
||||||
|
notifications: {
|
||||||
|
enabled: true,
|
||||||
|
notify_on_test_completion: true,
|
||||||
|
notify_on_news: false
|
||||||
|
},
|
||||||
|
automated_testing: {
|
||||||
|
enabled: false,
|
||||||
|
enabled_tests: [
|
||||||
|
'web-connectivity',
|
||||||
|
'facebook-messenger',
|
||||||
|
'whatsapp',
|
||||||
|
'telegram',
|
||||||
|
'dash',
|
||||||
|
'ndt',
|
||||||
|
'http-invalid-request-line',
|
||||||
|
'http-header-field-manipulation'
|
||||||
|
],
|
||||||
|
monthly_allowance: '300MB'
|
||||||
|
},
|
||||||
|
test_settings: {
|
||||||
|
websites: {
|
||||||
|
enabled_categories: []
|
||||||
|
},
|
||||||
|
instant_messaging: {
|
||||||
|
enabled_tests: [
|
||||||
|
'facebook-messenger',
|
||||||
|
'whatsapp',
|
||||||
|
'telegram'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
performance: {
|
||||||
|
enabled_tests: [
|
||||||
|
'ndt'
|
||||||
|
],
|
||||||
|
ndt_server: 'auto',
|
||||||
|
ndt_server_port: 'auto',
|
||||||
|
dash_server: 'auto',
|
||||||
|
dash_server_port: 'auto'
|
||||||
|
},
|
||||||
|
middlebox: {
|
||||||
|
enabled_tests: [
|
||||||
|
'http-invalid-request-line',
|
||||||
|
'http-header-field-manipulation'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
advanced: {
|
||||||
|
include_country: true,
|
||||||
|
use_domain_fronting: true
|
||||||
|
},
|
||||||
|
_config_version: CONFIG_VERSION,
|
||||||
|
_informed_consent: false
|
||||||
|
*/
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate the config file
|
||||||
|
func (c *Config) Validate() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseConfig returns config from JSON bytes.
|
||||||
|
func ParseConfig(b []byte) (*Config, error) {
|
||||||
|
c := &Config{}
|
||||||
|
|
||||||
|
if err := json.Unmarshal(b, c); err != nil {
|
||||||
|
return nil, errors.Wrap(err, "parsing json")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := c.Default(); err != nil {
|
||||||
|
return nil, errors.Wrap(err, "defaulting")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := c.Validate(); err != nil {
|
||||||
|
return nil, errors.Wrap(err, "validating")
|
||||||
|
}
|
||||||
|
|
||||||
|
return c, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadConfig reads the configuration from the path
|
||||||
|
func ReadConfig(path string) (*Config, error) {
|
||||||
|
b, err := ioutil.ReadFile(path)
|
||||||
|
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
c := &Config{}
|
||||||
|
|
||||||
|
if err = c.Default(); err != nil {
|
||||||
|
return nil, errors.Wrap(err, "defaulting")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = c.Validate(); err != nil {
|
||||||
|
return nil, errors.Wrap(err, "validating")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "reading file")
|
||||||
|
}
|
||||||
|
|
||||||
|
return ParseConfig(b)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user