Merge pull request #104 from aykhans/chore/refactor-ci

🔧 Refactor .golangci and Taskfile
This commit is contained in:
Aykhan Shahsuvarov 2025-04-03 05:05:50 +04:00 committed by GitHub
commit bea2a81afa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
17 changed files with 70 additions and 65 deletions

View File

@ -19,7 +19,7 @@ jobs:
with: with:
go-version: stable go-version: stable
- name: golangci-lint - name: golangci-lint
uses: golangci/golangci-lint-action@v6 uses: golangci/golangci-lint-action@v7
with: with:
version: v1.64 version: v2.0.2
args: --timeout=10m --config=.golangci.yml args: --timeout=10m --config=.golangci.yml

View File

@ -1,16 +1,16 @@
version: "2"
run: run:
go: "1.24" go: "1.24"
concurrency: 8 concurrency: 8
timeout: 10m timeout: 10m
linters: linters:
disable-all: true default: none
enable: enable:
- asasalint - asasalint
- asciicheck - asciicheck
- errcheck - errcheck
- gofmt
- goimports
- gomodguard - gomodguard
- goprintffuncname - goprintffuncname
- govet - govet
@ -21,7 +21,13 @@ linters:
- prealloc - prealloc
- reassign - reassign
- staticcheck - staticcheck
- typecheck
- unconvert - unconvert
- unused - unused
- whitespace - whitespace
settings:
staticcheck:
checks:
- "all"
- "-S1002"
- "-ST1000"

View File

@ -20,25 +20,26 @@ vars:
tasks: tasks:
run: go run main.go run: go run main.go
fmt: gofmt -w -d .
lint: golangci-lint run lint: golangci-lint run
build: go build -ldflags "-s -w" -o "dodo" build: go build -ldflags "-s -w" -o "dodo"
fmt: gofmt -w -d .
build-all: build-all:
silent: true silent: true
cmds: cmds:
- rm -rf binaries - rm -rf binaries
- for: { var: PLATFORMS, as: PLATFORM } - |
cmd: | {{ $ext := "" }}
{{ $ext := "" }} {{- range $platform := .PLATFORMS }}
{{- if eq $platform.os "windows" }}
{{ $ext = ".exe" }}
{{- end }}
{{ if eq $.PLATFORM.os "windows" }} {{- range $arch := $platform.archs }}
{{ $ext = ".exe" }} echo "Building for {{$platform.os}}/{{$arch}}"
{{ end }} GOOS={{$platform.os}} GOARCH={{$arch}} go build -ldflags "-s -w" -o "./binaries/dodo-{{$platform.os}}-{{$arch}}{{$ext}}"
{{- end }}
{{range $arch := $.PLATFORM.archs}} {{- end }}
echo "Building for {{$.PLATFORM.os}}/{{$arch}}" - echo -e "\033[32m*** Build completed ***\033[0m"
GOOS={{$.PLATFORM.os}} GOARCH={{$arch}} go build -ldflags "-s -w" -o "./binaries/dodo-{{$.PLATFORM.os}}-{{$arch}}{{$ext}}"
{{end}}

View File

@ -145,20 +145,20 @@ func NewConfig() *Config {
return &Config{} return &Config{}
} }
func (c *Config) Validate() []error { func (config *Config) Validate() []error {
var errs []error var errs []error
if utils.IsNilOrZero(c.URL) { if utils.IsNilOrZero(config.URL) {
errs = append(errs, errors.New("request URL is required")) errs = append(errs, errors.New("request URL is required"))
} else { } else {
if c.URL.Scheme == "" { if config.URL.Scheme == "" {
c.URL.Scheme = "http" config.URL.Scheme = "http"
} }
if c.URL.Scheme != "http" && c.URL.Scheme != "https" { if config.URL.Scheme != "http" && config.URL.Scheme != "https" {
errs = append(errs, errors.New("request URL scheme must be http or https")) errs = append(errs, errors.New("request URL scheme must be http or https"))
} }
urlParams := types.Params{} urlParams := types.Params{}
for key, values := range c.URL.Query() { for key, values := range config.URL.Query() {
for _, value := range values { for _, value := range values {
urlParams = append(urlParams, types.KeyValue[string, []string]{ urlParams = append(urlParams, types.KeyValue[string, []string]{
Key: key, Key: key,
@ -166,24 +166,24 @@ func (c *Config) Validate() []error {
}) })
} }
} }
c.Params = append(urlParams, c.Params...) config.Params = append(urlParams, config.Params...)
c.URL.RawQuery = "" config.URL.RawQuery = ""
} }
if utils.IsNilOrZero(c.Method) { if utils.IsNilOrZero(config.Method) {
errs = append(errs, errors.New("request method is required")) errs = append(errs, errors.New("request method is required"))
} }
if utils.IsNilOrZero(c.Timeout) { if utils.IsNilOrZero(config.Timeout) {
errs = append(errs, errors.New("request timeout must be greater than 0")) errs = append(errs, errors.New("request timeout must be greater than 0"))
} }
if utils.IsNilOrZero(c.DodosCount) { if utils.IsNilOrZero(config.DodosCount) {
errs = append(errs, errors.New("dodos count must be greater than 0")) errs = append(errs, errors.New("dodos count must be greater than 0"))
} }
if utils.IsNilOrZero(c.Duration) && utils.IsNilOrZero(c.RequestCount) { if utils.IsNilOrZero(config.Duration) && utils.IsNilOrZero(config.RequestCount) {
errs = append(errs, errors.New("you should provide at least one of duration or request count")) errs = append(errs, errors.New("you should provide at least one of duration or request count"))
} }
for i, proxy := range c.Proxies { for i, proxy := range config.Proxies {
if proxy.String() == "" { if proxy.String() == "" {
errs = append(errs, fmt.Errorf("proxies[%d]: proxy cannot be empty", i)) errs = append(errs, fmt.Errorf("proxies[%d]: proxy cannot be empty", i))
} else if schema := proxy.Scheme; !slices.Contains(SupportedProxySchemes, schema) { } else if schema := proxy.Scheme; !slices.Contains(SupportedProxySchemes, schema) {

View File

@ -34,7 +34,7 @@ func (config *Config) ReadFile(filePath types.ConfigFile) error {
if err != nil { if err != nil {
return fmt.Errorf("failed to fetch config file from %s", filePath) return fmt.Errorf("failed to fetch config file from %s", filePath)
} }
defer resp.Body.Close() defer func() { _ = resp.Body.Close() }()
data, err = io.ReadAll(io.Reader(resp.Body)) data, err = io.ReadAll(io.Reader(resp.Body))
if err != nil { if err != nil {
@ -47,9 +47,10 @@ func (config *Config) ReadFile(filePath types.ConfigFile) error {
} }
} }
if fileExt == "json" { switch fileExt {
case "json":
return parseJSONConfig(data, config) return parseJSONConfig(data, config)
} else if fileExt == "yml" || fileExt == "yaml" { case "yml", "yaml":
return parseYAMLConfig(data, config) return parseYAMLConfig(data, config)
} }
} }

View File

@ -72,11 +72,12 @@ func getClients(
func getDialFunc(proxy *url.URL, timeout time.Duration) (fasthttp.DialFunc, error) { func getDialFunc(proxy *url.URL, timeout time.Duration) (fasthttp.DialFunc, error) {
var dialer fasthttp.DialFunc var dialer fasthttp.DialFunc
if proxy.Scheme == "socks5" || proxy.Scheme == "socks5h" { switch proxy.Scheme {
case "socks5", "socks5h":
dialer = fasthttpproxy.FasthttpSocksDialerDualStack(proxy.String()) dialer = fasthttpproxy.FasthttpSocksDialerDualStack(proxy.String())
} else if proxy.Scheme == "http" { case "http":
dialer = fasthttpproxy.FasthttpHTTPDialerDualStackTimeout(proxy.String(), timeout) dialer = fasthttpproxy.FasthttpHTTPDialerDualStackTimeout(proxy.String(), timeout)
} else { default:
return nil, errors.New("unsupported proxy scheme") return nil, errors.New("unsupported proxy scheme")
} }
return dialer, nil return dialer, nil

View File

@ -65,9 +65,9 @@ func releaseDodos(
wg sync.WaitGroup wg sync.WaitGroup
streamWG sync.WaitGroup streamWG sync.WaitGroup
requestCountPerDodo uint requestCountPerDodo uint
dodosCount uint = requestConfig.GetValidDodosCountForRequests() dodosCount = requestConfig.GetValidDodosCountForRequests()
responses = make([][]*Response, dodosCount) responses = make([][]*Response, dodosCount)
increase = make(chan int64, requestConfig.RequestCount) increase = make(chan int64, requestConfig.RequestCount)
) )
wg.Add(int(dodosCount)) wg.Add(int(dodosCount))

View File

@ -13,12 +13,12 @@ type Body []string
func (body Body) String() string { func (body Body) String() string {
var buffer bytes.Buffer var buffer bytes.Buffer
if len(body) == 0 { if len(body) == 0 {
return string(buffer.Bytes()) return buffer.String()
} }
if len(body) == 1 { if len(body) == 1 {
buffer.WriteString(body[0]) buffer.WriteString(body[0])
return string(buffer.Bytes()) return buffer.String()
} }
buffer.WriteString(text.FgBlue.Sprint("Random") + "[\n") buffer.WriteString(text.FgBlue.Sprint("Random") + "[\n")
@ -41,7 +41,7 @@ func (body Body) String() string {
} }
buffer.WriteString("\n]") buffer.WriteString("\n]")
return string(buffer.Bytes()) return buffer.String()
} }
func (body *Body) UnmarshalJSON(b []byte) error { func (body *Body) UnmarshalJSON(b []byte) error {

View File

@ -14,7 +14,7 @@ type Cookies []KeyValue[string, []string]
func (cookies Cookies) String() string { func (cookies Cookies) String() string {
var buffer bytes.Buffer var buffer bytes.Buffer
if len(cookies) == 0 { if len(cookies) == 0 {
return string(buffer.Bytes()) return buffer.String()
} }
indent := " " indent := " "
@ -53,7 +53,7 @@ func (cookies Cookies) String() string {
buffer.WriteString(",\n" + text.FgGreen.Sprintf("+%d cookies", remainingPairs)) buffer.WriteString(",\n" + text.FgGreen.Sprintf("+%d cookies", remainingPairs))
} }
return string(buffer.Bytes()) return buffer.String()
} }
func (cookies *Cookies) AppendByKey(key, value string) { func (cookies *Cookies) AppendByKey(key, value string) {

View File

@ -32,7 +32,7 @@ func (duration *Duration) UnmarshalJSON(b []byte) error {
} }
func (duration Duration) MarshalJSON() ([]byte, error) { func (duration Duration) MarshalJSON() ([]byte, error) {
return json.Marshal(duration.Duration.String()) return json.Marshal(duration.String())
} }
func (duration *Duration) UnmarshalYAML(unmarshal func(interface{}) error) error { func (duration *Duration) UnmarshalYAML(unmarshal func(interface{}) error) error {

View File

@ -14,7 +14,7 @@ type Headers []KeyValue[string, []string]
func (headers Headers) String() string { func (headers Headers) String() string {
var buffer bytes.Buffer var buffer bytes.Buffer
if len(headers) == 0 { if len(headers) == 0 {
return string(buffer.Bytes()) return buffer.String()
} }
indent := " " indent := " "
@ -53,7 +53,7 @@ func (headers Headers) String() string {
buffer.WriteString(",\n" + text.FgGreen.Sprintf("+%d headers", remainingPairs)) buffer.WriteString(",\n" + text.FgGreen.Sprintf("+%d headers", remainingPairs))
} }
return string(buffer.Bytes()) return buffer.String()
} }
func (headers *Headers) AppendByKey(key, value string) { func (headers *Headers) AppendByKey(key, value string) {

View File

@ -14,7 +14,7 @@ type Params []KeyValue[string, []string]
func (params Params) String() string { func (params Params) String() string {
var buffer bytes.Buffer var buffer bytes.Buffer
if len(params) == 0 { if len(params) == 0 {
return string(buffer.Bytes()) return buffer.String()
} }
indent := " " indent := " "
@ -53,7 +53,7 @@ func (params Params) String() string {
buffer.WriteString(",\n" + text.FgGreen.Sprintf("+%d params", remainingPairs)) buffer.WriteString(",\n" + text.FgGreen.Sprintf("+%d params", remainingPairs))
} }
return string(buffer.Bytes()) return buffer.String()
} }
func (params *Params) AppendByKey(key, value string) { func (params *Params) AppendByKey(key, value string) {

View File

@ -14,12 +14,12 @@ type Proxies []url.URL
func (proxies Proxies) String() string { func (proxies Proxies) String() string {
var buffer bytes.Buffer var buffer bytes.Buffer
if len(proxies) == 0 { if len(proxies) == 0 {
return string(buffer.Bytes()) return buffer.String()
} }
if len(proxies) == 1 { if len(proxies) == 1 {
buffer.WriteString(proxies[0].String()) buffer.WriteString(proxies[0].String())
return string(buffer.Bytes()) return buffer.String()
} }
buffer.WriteString(text.FgBlue.Sprint("Random") + "[\n") buffer.WriteString(text.FgBlue.Sprint("Random") + "[\n")
@ -42,7 +42,7 @@ func (proxies Proxies) String() string {
} }
buffer.WriteString("\n]") buffer.WriteString("\n]")
return string(buffer.Bytes()) return buffer.String()
} }
func (proxies *Proxies) UnmarshalJSON(b []byte) error { func (proxies *Proxies) UnmarshalJSON(b []byte) error {

View File

@ -18,7 +18,7 @@ func (requestURL *RequestURL) UnmarshalJSON(data []byte) error {
parsedURL, err := url.Parse(urlStr) parsedURL, err := url.Parse(urlStr)
if err != nil { if err != nil {
return errors.New("Request URL is invalid") return errors.New("request URL is invalid")
} }
requestURL.URL = *parsedURL requestURL.URL = *parsedURL
@ -33,7 +33,7 @@ func (requestURL *RequestURL) UnmarshalYAML(unmarshal func(interface{}) error) e
parsedURL, err := url.Parse(urlStr) parsedURL, err := url.Parse(urlStr)
if err != nil { if err != nil {
return errors.New("Request URL is invalid") return errors.New("request URL is invalid")
} }
requestURL.URL = *parsedURL requestURL.URL = *parsedURL

View File

@ -32,7 +32,7 @@ func (timeout *Timeout) UnmarshalJSON(b []byte) error {
} }
func (timeout Timeout) MarshalJSON() ([]byte, error) { func (timeout Timeout) MarshalJSON() ([]byte, error) {
return json.Marshal(timeout.Duration.String()) return json.Marshal(timeout.String())
} }
func (timeout *Timeout) UnmarshalYAML(unmarshal func(interface{}) error) error { func (timeout *Timeout) UnmarshalYAML(unmarshal func(interface{}) error) error {

View File

@ -6,9 +6,5 @@ func IsNilOrZero[T comparable](value *T) bool {
} }
var zero T var zero T
if *value == zero { return *value == zero
return true
}
return false
} }

View File

@ -20,9 +20,9 @@ func Flatten[T any](nested [][]*T) []*T {
// The returned function isn't thread-safe and should be used in a single-threaded context. // The returned function isn't thread-safe and should be used in a single-threaded context.
func RandomValueCycle[Value any](values []Value, localRand *rand.Rand) func() Value { func RandomValueCycle[Value any](values []Value, localRand *rand.Rand) func() Value {
var ( var (
clientsCount int = len(values) clientsCount = len(values)
currentIndex int = localRand.Intn(clientsCount) currentIndex = localRand.Intn(clientsCount)
stopIndex int = currentIndex stopIndex = currentIndex
) )
return func() Value { return func() Value {