From e78d00f9b91b85e4f0ee6ed2b49e43778086656f Mon Sep 17 00:00:00 2001 From: arman taherighaletaki Date: Thu, 5 Jun 2025 05:28:34 +0330 Subject: [PATCH 1/7] refactor: redesign with cobra and add autocomplete and version option --- .golangci.yml | 67 ++++++++++++++--------- .goreleaser.yaml | 14 +++-- Makefile | 11 ++-- cmd/403unlockercli/main.go | 7 --- cmd/cli/bestdns.go | 41 ++++++++++++++ cmd/cli/check.go | 32 +++++++++++ cmd/cli/fastdocker.go | 38 +++++++++++++ cmd/cli/root.go | 26 +++++++++ cmd/main.go | 10 ++++ go.mod | 41 +++++++------- go.sum | 101 ++++++++++++---------------------- internal/check/function.go | 8 +-- internal/dns/function.go | 11 ++-- internal/docker/function.go | 8 +-- internal/unlockercli/cli.go | 106 ------------------------------------ 15 files changed, 270 insertions(+), 251 deletions(-) delete mode 100644 cmd/403unlockercli/main.go create mode 100644 cmd/cli/bestdns.go create mode 100644 cmd/cli/check.go create mode 100644 cmd/cli/fastdocker.go create mode 100644 cmd/cli/root.go create mode 100644 cmd/main.go delete mode 100644 internal/unlockercli/cli.go diff --git a/.golangci.yml b/.golangci.yml index 8731aef..0df1b35 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,32 +1,47 @@ +version: "2" linters: enable: - depguard - - goimports - misspell - revive - -issues: - exclude-rules: - - path: _test.go - linters: - - errcheck - -linters-settings: - depguard: - rules: - no_exec_policy: - files: - - "!$test" - deny: - - pkg: "os/exec" - desc: "Using os/exec to run sub processes it not allowed by policy" - errcheck: - exclude-functions: - # Used in HTTP handlers, any error is handled by the server itself. - - (net/http.ResponseWriter).Write - revive: + settings: + depguard: + rules: + no_exec_policy: + files: + - '!$test' + deny: + - pkg: os/exec + desc: Using os/exec to run sub processes it not allowed by policy + errcheck: + exclude-functions: + - (net/http.ResponseWriter).Write + revive: + rules: + - name: unused-parameter + severity: warning + disabled: true + exclusions: + generated: lax + presets: + - comments + - common-false-positives + - legacy + - std-error-handling rules: - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#unused-parameter - - name: unused-parameter - severity: warning - disabled: true + - linters: + - errcheck + path: _test.go + paths: + - third_party$ + - builtin$ + - examples$ +formatters: + enable: + - goimports + exclusions: + generated: lax + paths: + - third_party$ + - builtin$ + - examples$ diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 0a651a3..a6ec3ed 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -6,7 +6,7 @@ before: builds: - id: "403unlockercli-linux" # Unique ID for this build - main: ./cmd/403unlockercli + main: ./cmd binary: "403unlocker" env: - CGO_ENABLED=0 @@ -15,9 +15,11 @@ builds: goarch: - amd64 - arm64 + ldflags: + - -X 403unlocker-cli/cmd/cli.Version={{ .Version }} - id: "403unlockercli-windows" # Unique ID for this build - main: ./cmd/403unlockercli + main: ./cmd binary: "403unlocker" env: - CGO_ENABLED=0 @@ -25,9 +27,11 @@ builds: - windows goarch: - amd64 + ldflags: + - -X 403unlocker-cli/cmd/cli.Version={{ .Version }} - id: "403unlockercli-darwin" # Unique ID for this build - main: ./cmd/403unlockercli + main: ./cmd binary: "403unlocker" env: - CGO_ENABLED=0 @@ -36,6 +40,8 @@ builds: goarch: - amd64 - arm64 + ldflags: + - -X 403unlocker-cli/cmd/cli.Version={{ .Version }} archives: - format: tar.gz @@ -65,4 +71,4 @@ release: --- - Released by [GoReleaser](https://github.com/goreleaser/goreleaser). \ No newline at end of file + Released by [GoReleaser](https://github.com/goreleaser/goreleaser). diff --git a/Makefile b/Makefile index c6e90ab..597d490 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ OUTPUT = 403unlocker -MAIN = cmd/403unlockercli/main.go +MAIN = cmd/main.go BIN_DIR = ~/.local/bin CONFIG_DIR= ~/.config/403unlocker DNS_CONFIG_FILE_URL=https://raw.githubusercontent.com/403unlocker/403Unlocker-cli/refs/heads/main/config/dns.conf @@ -10,6 +10,7 @@ DOCKER_CONFIG_FILE_URL=https://raw.githubusercontent.com/403unlocker/403Unlocker .PHONY: help lint build test clean install uninstall +GITHUB_TAG="${GITHUB_TAG:-local}" help: @echo "Usage: make [target]" @@ -23,18 +24,18 @@ lint: build: - @go build -o $(OUTPUT) $(MAIN) + @go build -ldflags "-X 403unlocker-cli/cmd/cli.Version=$(GITHUB_TAG)" -o $(OUTPUT) $(MAIN) -test: +test: @go test ./... -clean: +clean: @rm -f $(OUTPUT) -install: build +install: build @echo "Installing $(OUTPUT) to $(BIN_DIR)..." @install -m 755 $(OUTPUT) $(BIN_DIR) @echo "Downloading config files dns.conf to $(CONFIG_DIR)..." diff --git a/cmd/403unlockercli/main.go b/cmd/403unlockercli/main.go deleted file mode 100644 index b6ce52a..0000000 --- a/cmd/403unlockercli/main.go +++ /dev/null @@ -1,7 +0,0 @@ -package main - -import "github.com/salehborhani/403Unlocker-cli/internal/unlockercli" - -func main() { - unlockercli.Run() -} diff --git a/cmd/cli/bestdns.go b/cmd/cli/bestdns.go new file mode 100644 index 0000000..d0bbd5d --- /dev/null +++ b/cmd/cli/bestdns.go @@ -0,0 +1,41 @@ +package cli + +import ( + "403unlocker-cli/internal/dns" + "fmt" + + "github.com/spf13/cobra" +) + +var ( + timeoutBestDns int + checkfirst bool +) + +var bestdnsCmd = &cobra.Command{ + Use: "bestdns", + Short: "Finds the fastest DNS SNI-Proxy for downloading a specific URL", + Long: `Finds the fastest DNS SNI-Proxy for downloading a specific URL + +Examples: + 403unlocker bestdns --timeout 15 https://packages.gitlab.com/gitlab/gitlab-ce/packages/el/7/gitlab-ce-16.8.0-ce.0.el7.x86_64.rpm/download.rpm`, + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + if !dns.URLValidator(args[0]) { + fmt.Println("Error: Invalid URL") + return cmd.Help() + } + return dns.CheckWithURL(args[0], checkfirst, timeoutBestDns) + }, + Aliases: []string{"dns"}, + ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return []string{}, cobra.ShellCompDirectiveNoFileComp + }, +} + +func init() { + bestdnsCmd.PersistentFlags().IntVarP(&timeoutBestDns, "timeout", "t", 10, "Sets timeout") + bestdnsCmd.PersistentFlags().BoolVarP(&checkfirst, "check", "c", false, "first check with GET to route '/' of domain ") + + rootCmd.AddCommand(bestdnsCmd) +} diff --git a/cmd/cli/check.go b/cmd/cli/check.go new file mode 100644 index 0000000..0693e2b --- /dev/null +++ b/cmd/cli/check.go @@ -0,0 +1,32 @@ +package cli + +import ( + "403unlocker-cli/internal/check" + + "github.com/spf13/cobra" +) + +var checkCmd = &cobra.Command{ + Use: "check", + Short: "Checks if the DNS SNI-Proxy can bypass 403 error for a specific domain", + Long: `Checks if the DNS SNI-Proxy can bypass 403 error for a specific domain + +Examples: + 403unlocker check https://pkg.go.dev`, + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + if !check.DomainValidator(args[0]) { + cmd.Printf("Error: '%s' is not a valid domain format\n\n", args[0]) + return cmd.Help() + } + return check.CheckWithDNS(args[0]) + }, + Aliases: []string{"c"}, + ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return []string{}, cobra.ShellCompDirectiveNoFileComp + }, +} + +func init() { + rootCmd.AddCommand(checkCmd) +} diff --git a/cmd/cli/fastdocker.go b/cmd/cli/fastdocker.go new file mode 100644 index 0000000..1f75973 --- /dev/null +++ b/cmd/cli/fastdocker.go @@ -0,0 +1,38 @@ +package cli + +import ( + "403unlocker-cli/internal/docker" + + "github.com/spf13/cobra" +) + +var ( + timeoutFastDocker int +) + +var fastdockerCmd = &cobra.Command{ + Use: "fastdocker", + Short: "Finds the fastest docker registries for a specific docker image", + Long: `Examples: + 403unlocker fastdocker --timeout 15 gitlab/gitlab-ce:17.0.0-ce.0`, + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + if docker.DockerImageValidator(args[0]) { + return docker.CheckWithDockerImage(args[0], timeoutFastDocker) + } else { + cmd.Printf("Error: '%s' is not a valid docker image format\n\n", args[0]) + return cmd.Help() + } + }, + Aliases: []string{"docker"}, + ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return []string{}, cobra.ShellCompDirectiveNoFileComp + }, +} + +func init() { + fastdockerCmd.PersistentFlags().IntVarP(&timeoutFastDocker, "timeout", "t", 10, "Sets timeout") + + rootCmd.AddCommand(fastdockerCmd) + +} diff --git a/cmd/cli/root.go b/cmd/cli/root.go new file mode 100644 index 0000000..ce8e27c --- /dev/null +++ b/cmd/cli/root.go @@ -0,0 +1,26 @@ +package cli + +import ( + "os" + + "github.com/spf13/cobra" +) + +var Version = "dev" // <- Injected by ldflags + +var rootCmd = &cobra.Command{ + Use: "403unlocker", + Short: "403Unlocker-CLI is a versatile command-line tool designed to bypass 403 restrictions effectively", + Long: `403Unlocker-CLI is a versatile command-line tool designed to bypass 403 restrictions effectively`, + Version: Version, // Enables --version flag +} + +func Execute() { + err := rootCmd.Execute() + if err != nil { + os.Exit(1) + } +} + +func init() { +} diff --git a/cmd/main.go b/cmd/main.go new file mode 100644 index 0000000..19c2530 --- /dev/null +++ b/cmd/main.go @@ -0,0 +1,10 @@ +package main + +import ( + "403unlocker-cli/cmd/cli" +) + +func main() { + cli.Execute() + +} diff --git a/go.mod b/go.mod index b9450b6..ff34052 100644 --- a/go.mod +++ b/go.mod @@ -1,36 +1,33 @@ -module github.com/salehborhani/403Unlocker-cli +module 403unlocker-cli -go 1.23.1 +go 1.24.1 require ( github.com/cavaliergopher/grab/v3 v3.0.1 - github.com/google/go-containerregistry v0.20.2 - github.com/stretchr/testify v1.8.4 - github.com/urfave/cli/v2 v2.27.5 - gotest.tools/v3 v3.0.3 + github.com/google/go-containerregistry v0.20.5 + github.com/spf13/cobra v1.9.1 + github.com/stretchr/testify v1.10.0 + gotest.tools/v3 v3.5.2 ) require ( - github.com/containerd/stargz-snapshotter/estargz v0.14.3 // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect + github.com/containerd/stargz-snapshotter/estargz v0.16.3 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/docker/cli v27.1.1+incompatible // indirect - github.com/docker/distribution v2.8.2+incompatible // indirect - github.com/docker/docker-credential-helpers v0.7.0 // indirect - github.com/google/go-cmp v0.5.9 // indirect - github.com/klauspost/compress v1.16.5 // indirect - github.com/kr/pretty v0.2.1 // indirect - github.com/kr/text v0.2.0 // indirect + github.com/docker/cli v28.1.1+incompatible // indirect + github.com/docker/distribution v2.8.3+incompatible // indirect + github.com/docker/docker-credential-helpers v0.9.3 // indirect + github.com/google/go-cmp v0.7.0 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/klauspost/compress v1.18.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/opencontainers/image-spec v1.1.0-rc3 // indirect + github.com/opencontainers/image-spec v1.1.1 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/russross/blackfriday/v2 v2.1.0 // indirect - github.com/sirupsen/logrus v1.9.1 // indirect - github.com/vbatts/tar-split v0.11.3 // indirect - github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect - golang.org/x/sync v0.2.0 // indirect - golang.org/x/sys v0.15.0 // indirect + github.com/sirupsen/logrus v1.9.3 // indirect + github.com/spf13/pflag v1.0.6 // indirect + github.com/vbatts/tar-split v0.12.1 // indirect + golang.org/x/sync v0.14.0 // indirect + golang.org/x/sys v0.33.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 00328de..39cd45c 100644 --- a/go.sum +++ b/go.sum @@ -1,86 +1,57 @@ -github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/cavaliergopher/grab/v3 v3.0.1 h1:4z7TkBfmPjmLAAmkkAZNX/6QJ1nNFdv3SdIHXju0Fr4= github.com/cavaliergopher/grab/v3 v3.0.1/go.mod h1:1U/KNnD+Ft6JJiYoYBAimKH2XrYptb8Kl3DFGmsjpq4= -github.com/containerd/stargz-snapshotter/estargz v0.14.3 h1:OqlDCK3ZVUO6C3B/5FSkDwbkEETK84kQgEeFwDC+62k= -github.com/containerd/stargz-snapshotter/estargz v0.14.3/go.mod h1:KY//uOCIkSuNAHhJogcZtrNHdKrA99/FCCRjE3HD36o= -github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc= -github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/containerd/stargz-snapshotter/estargz v0.16.3 h1:7evrXtoh1mSbGj/pfRccTampEyKpjpOnS3CyiV1Ebr8= +github.com/containerd/stargz-snapshotter/estargz v0.16.3/go.mod h1:uyr4BfYfOj3G9WBVE8cOlQmXAbPN9VEQpBBeJIuOipU= +github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/docker/cli v27.1.1+incompatible h1:goaZxOqs4QKxznZjjBWKONQci/MywhtRv2oNn0GkeZE= -github.com/docker/cli v27.1.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= -github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= -github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A= -github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-containerregistry v0.20.2 h1:B1wPJ1SN/S7pB+ZAimcciVD+r+yV/l/DSArMxlbwseo= -github.com/google/go-containerregistry v0.20.2/go.mod h1:z38EKdKh4h7IP2gSfUUqEvalZBqs6AoLeWfUy34nQC8= -github.com/klauspost/compress v1.16.5 h1:IFV2oUNUzZaz+XyusxpLzpzS8Pt5rh0Z16For/djlyI= -github.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= -github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/docker/cli v28.1.1+incompatible h1:eyUemzeI45DY7eDPuwUcmDyDj1pM98oD5MdSpiItp8k= +github.com/docker/cli v28.1.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= +github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/docker-credential-helpers v0.9.3 h1:gAm/VtF9wgqJMoxzT3Gj5p4AqIjCBS4wrsOh9yRqcz8= +github.com/docker/docker-credential-helpers v0.9.3/go.mod h1:x+4Gbw9aGmChi3qTLZj8Dfn0TD20M/fuWy0E5+WDeCo= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/go-containerregistry v0.20.5 h1:4RnlYcDs5hoA++CeFjlbZ/U9Yp1EuWr+UhhTyYQjOP0= +github.com/google/go-containerregistry v0.20.5/go.mod h1:Q14vdOOzug02bwnhMkZKD4e30pDaD9W65qzXpyzF49E= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= +github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/opencontainers/image-spec v1.1.0-rc3 h1:fzg1mXZFj8YdPeNkRXMg+zb88BFV0Ys52cJydRwBkb8= -github.com/opencontainers/image-spec v1.1.0-rc3/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= +github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/sirupsen/logrus v1.9.1 h1:Ou41VVR3nMWWmTiEUnj0OlsgOSCUFgsPAOl6jRIcVtQ= -github.com/sirupsen/logrus v1.9.1/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo= +github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0= +github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= +github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/urfave/cli v1.22.12/go.mod h1:sSBEIC79qR6OvcmsD4U3KABeOTxDqQtdDnaFuUN30b8= -github.com/urfave/cli/v2 v2.27.5 h1:WoHEJLdsXr6dDWoJgMq/CboDmyY/8HMMH1fTECbih+w= -github.com/urfave/cli/v2 v2.27.5/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ= -github.com/vbatts/tar-split v0.11.3 h1:hLFqsOLQ1SsppQNTMpkpPXClLDfC2A3Zgy9OUU+RVck= -github.com/vbatts/tar-split v0.11.3/go.mod h1:9QlHN18E+fEH7RdG+QAJJcuya3rqT7eXSTY7wGrAokY= -github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4= -github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI= -golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/vbatts/tar-split v0.12.1 h1:CqKoORW7BUWBe7UL/iqTVvkTBOF8UvOMKOIZykxnnbo= +github.com/vbatts/tar-split v0.12.1/go.mod h1:eF6B6i6ftWQcDqEn3/iGFRFRo8cBIMSJVOpnNdfTMFA= +golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ= +golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220906165534-d0df966e6959/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= -golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= +golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0= -gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= +gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q= +gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA= diff --git a/internal/check/function.go b/internal/check/function.go index 5148d44..7caccfb 100644 --- a/internal/check/function.go +++ b/internal/check/function.go @@ -1,6 +1,7 @@ package check import ( + "403unlocker-cli/internal/common" "fmt" "net/http" "net/url" @@ -8,13 +9,10 @@ import ( "strconv" "strings" "sync" - - "github.com/salehborhani/403Unlocker-cli/internal/common" - "github.com/urfave/cli/v2" ) -func CheckWithDNS(c *cli.Context) error { - url := c.Args().First() +func CheckWithDNS(commandLintFirstArg string) error { + url := commandLintFirstArg url = ensureHTTPS(url) fmt.Println("URL: ", url) diff --git a/internal/dns/function.go b/internal/dns/function.go index 7a85ca0..d17a1e4 100644 --- a/internal/dns/function.go +++ b/internal/dns/function.go @@ -11,9 +11,9 @@ import ( "sync" "time" + "403unlocker-cli/internal/common" + "github.com/cavaliergopher/grab/v3" - "github.com/salehborhani/403Unlocker-cli/internal/common" - "github.com/urfave/cli/v2" ) func URLValidator(URL string) bool { @@ -122,11 +122,11 @@ func CheckAndCacheDNS(url string) error { return nil } -func CheckWithURL(c *cli.Context) error { - fileToDownload := c.Args().First() +func CheckWithURL(commandLintFirstArg string, check bool, timeout int) error { + fileToDownload := commandLintFirstArg var dnsFile string - if c.Bool("check") { + if check { err := CheckAndCacheDNS(fileToDownload) if err != nil { return err @@ -152,7 +152,6 @@ func CheckWithURL(c *cli.Context) error { dnsSizeMap := make(map[string]int64) - timeout := c.Int("timeout") fmt.Printf("\nTimeout: %d seconds\n", timeout) fmt.Printf("URL: %s\n\n", fileToDownload) diff --git a/internal/docker/function.go b/internal/docker/function.go index 51eaedb..d0b2f4d 100644 --- a/internal/docker/function.go +++ b/internal/docker/function.go @@ -14,12 +14,12 @@ import ( "sync/atomic" "time" + "403unlocker-cli/internal/common" + "github.com/google/go-containerregistry/pkg/authn" "github.com/google/go-containerregistry/pkg/name" "github.com/google/go-containerregistry/pkg/v1/remote" "github.com/google/go-containerregistry/pkg/v1/tarball" - "github.com/salehborhani/403Unlocker-cli/internal/common" - "github.com/urfave/cli/v2" ) // DockerImageValidator validates a Docker image name using a regular expression. @@ -99,10 +99,8 @@ func DownloadDockerImage(ctx context.Context, imageName, registry, outputPath st } // CheckWithDockerImage downloads the image from multiple registries and reports the downloaded data size. -func CheckWithDockerImage(c *cli.Context) error { +func CheckWithDockerImage(imageName string, timeout int) error { registrySizeMap := make(map[string]int64) - timeout := c.Int("timeout") - imageName := c.Args().First() rand := time.Now().UnixMilli() tempDir := common.AddPathToDir(common.GetTempDir(), strconv.Itoa(int(rand))) fmt.Printf("\nTimeout: %d seconds\n", timeout) diff --git a/internal/unlockercli/cli.go b/internal/unlockercli/cli.go deleted file mode 100644 index 0022d3e..0000000 --- a/internal/unlockercli/cli.go +++ /dev/null @@ -1,106 +0,0 @@ -package unlockercli - -import ( - "fmt" - "log" - "os" - - "github.com/salehborhani/403Unlocker-cli/internal/check" - "github.com/salehborhani/403Unlocker-cli/internal/dns" - "github.com/salehborhani/403Unlocker-cli/internal/docker" - "github.com/urfave/cli/v2" -) - -func Run() { - app := &cli.App{ - EnableBashCompletion: true, - Name: "403unlocker", - Usage: "403Unlocker-CLI is a versatile command-line tool designed to bypass 403 restrictions effectively", - Commands: []*cli.Command{ - { - Name: "check", - Aliases: []string{"c"}, - Usage: "Checks if the DNS SNI-Proxy can bypass 403 error for a specific domain", - Description: `Examples: - 403unlocker check https://pkg.go.dev`, - Action: func(cCtx *cli.Context) error { - if check.DomainValidator(cCtx.Args().First()) { - return check.CheckWithDNS(cCtx) - } else { - err := cli.ShowSubcommandHelp(cCtx) - if err != nil { - fmt.Println(err) - } - } - return nil - }, - }, - { - Name: "fastdocker", - Aliases: []string{"docker"}, - Usage: "Finds the fastest docker registries for a specific docker image", - Description: `Examples: - 403unlocker fastdocker --timeout 15 gitlab/gitlab-ce:17.0.0-ce.0`, - Flags: []cli.Flag{ - &cli.IntFlag{ - Name: "timeout", - Usage: "Sets timeout", - Value: 10, - Aliases: []string{"t"}, - }, - }, - Action: func(cCtx *cli.Context) error { - if docker.DockerImageValidator(cCtx.Args().First()) { - return docker.CheckWithDockerImage(cCtx) - } else { - err := cli.ShowSubcommandHelp(cCtx) - if err != nil { - fmt.Println(err) - } - } - return nil - }, - }, - { - Name: "bestdns", - Aliases: []string{"dns"}, - Usage: "Finds the fastest DNS SNI-Proxy for downloading a specific URL", - Description: `Examples: - 403unlocker bestdns --timeout 15 https://packages.gitlab.com/gitlab/gitlab-ce/packages/el/7/gitlab-ce-16.8.0-ce.0.el7.x86_64.rpm/download.rpm`, - Flags: []cli.Flag{ - &cli.IntFlag{ - Name: "timeout", - Usage: "Sets timeout in seconds", - Value: 10, - Aliases: []string{"t"}, - }, - &cli.BoolFlag{ - Name: "check", - Usage: "Update the DNS cache before running the check", - Aliases: []string{"c"}, - }, - }, - Action: func(cCtx *cli.Context) error { - // Validate the URL argument - if cCtx.Args().Len() < 1 { - fmt.Println("Error: URL is required") - return cli.ShowSubcommandHelp(cCtx) - } - - // Validate the provided URL - url := cCtx.Args().First() - if !dns.URLValidator(url) { - fmt.Println("Error: Invalid URL") - return cli.ShowSubcommandHelp(cCtx) - } - - // Call CheckWithURL with the current context - return dns.CheckWithURL(cCtx) - }, - }, - }, - } - if err := app.Run(os.Args); err != nil { - log.Fatal(err) - } -} From e0ed6c335ee090980ca2c2868728d7271a7889c9 Mon Sep 17 00:00:00 2001 From: arman taherighaletaki Date: Thu, 5 Jun 2025 05:59:12 +0330 Subject: [PATCH 2/7] chore: update github action version --- .github/workflows/go.yml | 2 +- .github/workflows/golangci-lint.yml | 8 ++++---- Makefile | 3 +-- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index fec1a89..2c4aec1 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -20,7 +20,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v4 with: - go-version: '>1.23.1' + go-version: '>1.24.0' - name: Test run: go test -v ./... diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml index 5d40b07..5bece36 100644 --- a/.github/workflows/golangci-lint.yml +++ b/.github/workflows/golangci-lint.yml @@ -25,11 +25,11 @@ jobs: - name: Checkout repository uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Install Go - uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 + uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 with: - go-version: 1.23.x + go-version: 1.24.x - name: Lint - uses: golangci/golangci-lint-action@971e284b6050e8a5849b72094c50ab08da042db8 # v6.1.1 + uses: golangci/golangci-lint-action@4afd733a84b1f43292c63897423277bb7f4313a9 # v8.0.0 with: args: --verbose - version: v1.62.0 + version: v2.1.6 diff --git a/Makefile b/Makefile index 597d490..87c71ce 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,6 @@ DOCKER_CONFIG_FILE_URL=https://raw.githubusercontent.com/403unlocker/403Unlocker .PHONY: help lint build test clean install uninstall -GITHUB_TAG="${GITHUB_TAG:-local}" help: @echo "Usage: make [target]" @@ -24,7 +23,7 @@ lint: build: - @go build -ldflags "-X 403unlocker-cli/cmd/cli.Version=$(GITHUB_TAG)" -o $(OUTPUT) $(MAIN) + @go build -ldflags "-X 403unlocker-cli/cmd/cli.Version=dev" -o $(OUTPUT) $(MAIN) test: From 8ecc6acfd8c384ff9090e662034447dcf4533417 Mon Sep 17 00:00:00 2001 From: arman taherighaletaki Date: Thu, 5 Jun 2025 06:47:26 +0330 Subject: [PATCH 3/7] feat: use viper for reading config from file --- config/dns.conf | 21 +++++++++++++- go.mod | 12 ++++++++ go.sum | 36 ++++++++++++++++++++++- internal/dns/function.go | 63 ++++++++++++++++++++++------------------ 4 files changed, 101 insertions(+), 31 deletions(-) diff --git a/config/dns.conf b/config/dns.conf index 0a8915b..81b6db8 100644 --- a/config/dns.conf +++ b/config/dns.conf @@ -1 +1,20 @@ -178.22.122.100 185.51.200.2 192.104.158.78 194.104.158.48 172.29.0.100 172.29.2.100 10.202.10.202 10.202.10.102 185.55.226.26 185.55.225.25 10.202.10.10 10.202.10.11 37.27.41.228 9.9.9.9 8.8.8.8 8.8.4.4 1.1.1.1 1.0.0.1 87.107.52.11 87.107.52.13 5.202.100.100 5.202.100.101 94.103.125.157 94.103.125.158 +dnsServers: + - 178.22.122.100 + - 185.51.200.2 + - 192.104.158.78 + - 194.104.158.48 + - 172.29.0.100 + - 172.29.2.100 + - 10.202.10.202 + - 10.202.10.102 + - 185.55.226.26 + - 185.55.225.25 + - 10.202.10.10 + - 10.202.10.11 + - 37.27.41.228 + - 87.107.52.11 + - 87.107.52.13 + - 5.202.100.100 + - 5.202.100.101 + - 94.103.125.157 + - 94.103.125.158 diff --git a/go.mod b/go.mod index ff34052..0dd6edd 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/cavaliergopher/grab/v3 v3.0.1 github.com/google/go-containerregistry v0.20.5 github.com/spf13/cobra v1.9.1 + github.com/spf13/viper v1.20.1 github.com/stretchr/testify v1.10.0 gotest.tools/v3 v3.5.2 ) @@ -16,18 +17,29 @@ require ( github.com/docker/cli v28.1.1+incompatible // indirect github.com/docker/distribution v2.8.3+incompatible // indirect github.com/docker/docker-credential-helpers v0.9.3 // indirect + github.com/fsnotify/fsnotify v1.8.0 // indirect + github.com/go-viper/mapstructure/v2 v2.2.1 // indirect github.com/google/go-cmp v0.7.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/klauspost/compress v1.18.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.1 // indirect + github.com/pelletier/go-toml/v2 v2.2.3 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/sagikazarmark/locafero v0.7.0 // indirect github.com/sirupsen/logrus v1.9.3 // indirect + github.com/sourcegraph/conc v0.3.0 // indirect + github.com/spf13/afero v1.12.0 // indirect + github.com/spf13/cast v1.7.1 // indirect github.com/spf13/pflag v1.0.6 // indirect + github.com/subosito/gotenv v1.6.0 // indirect github.com/vbatts/tar-split v0.12.1 // indirect + go.uber.org/atomic v1.9.0 // indirect + go.uber.org/multierr v1.9.0 // indirect golang.org/x/sync v0.14.0 // indirect golang.org/x/sys v0.33.0 // indirect + golang.org/x/text v0.21.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 39cd45c..baceb4e 100644 --- a/go.sum +++ b/go.sum @@ -12,6 +12,12 @@ github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBi github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/docker-credential-helpers v0.9.3 h1:gAm/VtF9wgqJMoxzT3Gj5p4AqIjCBS4wrsOh9yRqcz8= github.com/docker/docker-credential-helpers v0.9.3/go.mod h1:x+4Gbw9aGmChi3qTLZj8Dfn0TD20M/fuWy0E5+WDeCo= +github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= +github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M= +github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= +github.com/go-viper/mapstructure/v2 v2.2.1 h1:ZAaOCxANMuZx5RCeg0mBdEZk7DZasvvZIxtHqx8aGss= +github.com/go-viper/mapstructure/v2 v2.2.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/go-containerregistry v0.20.5 h1:4RnlYcDs5hoA++CeFjlbZ/U9Yp1EuWr+UhhTyYQjOP0= @@ -20,36 +26,64 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M= +github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M= +github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/sagikazarmark/locafero v0.7.0 h1:5MqpDsTGNDhY8sGp0Aowyf0qKsPrhewaLSsFaodPcyo= +github.com/sagikazarmark/locafero v0.7.0/go.mod h1:2za3Cg5rMaTMoG/2Ulr9AwtFaIppKXTRYnozin4aB5k= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= +github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= +github.com/spf13/afero v1.12.0 h1:UcOPyRBYczmFn6yvphxkn9ZEOY65cpwGKb5mL36mrqs= +github.com/spf13/afero v1.12.0/go.mod h1:ZTlWwG4/ahT8W7T0WQ5uYmjI9duaLQGy3Q2OAl4sk/4= +github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y= +github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo= github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0= github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.20.1 h1:ZMi+z/lvLyPSCoNtFCpqjy0S4kPbirhpTMwl8BkW9X4= +github.com/spf13/viper v1.20.1/go.mod h1:P9Mdzt1zoHIG8m2eZQinpiBjo6kCmZSKBClNNqjJvu4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= +github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/vbatts/tar-split v0.12.1 h1:CqKoORW7BUWBe7UL/iqTVvkTBOF8UvOMKOIZykxnnbo= github.com/vbatts/tar-split v0.12.1/go.mod h1:eF6B6i6ftWQcDqEn3/iGFRFRo8cBIMSJVOpnNdfTMFA= +go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= +go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= +go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ= golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/internal/dns/function.go b/internal/dns/function.go index d17a1e4..dd68a7f 100644 --- a/internal/dns/function.go +++ b/internal/dns/function.go @@ -2,6 +2,7 @@ package dns import ( "context" + "errors" "fmt" "net/http" "net/url" @@ -14,6 +15,7 @@ import ( "403unlocker-cli/internal/common" "github.com/cavaliergopher/grab/v3" + "github.com/spf13/viper" ) func URLValidator(URL string) bool { @@ -34,23 +36,29 @@ func URLValidator(URL string) bool { } func CheckAndCacheDNS(url string) error { - cacheFile := common.CHECKED_DNS_CONFIG_FILE - - dnsList, err := common.ReadDNSFromFile(common.DNS_CONFIG_FILE) - if err != nil { - err = common.DownloadConfigFile(common.DNS_CONFIG_URL, common.DNS_CONFIG_FILE) - if err != nil { - fmt.Println("Error downloading DNS config file:", err) - return err + // Initialize Viper for DNS configuration + dnsViper := viper.New() + dnsViper.SetConfigFile(common.DNS_CONFIG_FILE) + + // Try to read the DNS config file + if err := dnsViper.ReadInConfig(); err != nil { + // If file doesn't exist, download it + if err := common.DownloadConfigFile(common.DNS_CONFIG_URL, common.DNS_CONFIG_FILE); err != nil { + return fmt.Errorf("error downloading DNS config: %w", err) } - dnsList, err = common.ReadDNSFromFile(common.DNS_CONFIG_FILE) - if err != nil { - fmt.Println("Error reading DNS list from file:", err) - return err + // Try reading again after download + if err := dnsViper.ReadInConfig(); err != nil { + return fmt.Errorf("error reading DNS config: %w", err) } } + // Get DNS list from config + dnsList := dnsViper.GetStringSlice("dnsServers") + if len(dnsList) == 0 { + return errors.New("no DNS servers found in config") + } + fmt.Println("\n+--------------------+------------+") fmt.Printf("| %-18s | %-10s |\n", "DNS Server", "Status") fmt.Println("+--------------------+------------+") @@ -64,10 +72,7 @@ func CheckAndCacheDNS(url string) error { go func(dns string) { defer wg.Done() - // Change DNS for the HTTP client client := common.ChangeDNS(dns) - - // Perform the GET request resp, err := client.Get(url) if err != nil { fmt.Printf("| %-18s | %s%-10s%s |\n", dns, common.Red, "Error", common.Reset) @@ -75,22 +80,19 @@ func CheckAndCacheDNS(url string) error { } defer resp.Body.Close() - // Parse the status code - codeParts := strings.Split(resp.Status, " ") - if len(codeParts) < 2 { + statusParts := strings.Split(resp.Status, " ") + if len(statusParts) < 2 { fmt.Printf("| %-18s | %s%-10s%s |\n", dns, common.Red, "Invalid", common.Reset) return } - statusCode, err := strconv.Atoi(codeParts[0]) + statusCode, err := strconv.Atoi(statusParts[0]) if err != nil { fmt.Printf("| %-18s | %s%-10s%s |\n", dns, common.Red, "Error", common.Reset) return } - // Output the status with appropriate color - statusText := codeParts[1] - + statusText := statusParts[1] if statusCode == http.StatusOK { mu.Lock() validDNSList = append(validDNSList, dns) @@ -103,18 +105,21 @@ func CheckAndCacheDNS(url string) error { } wg.Wait() - fmt.Println("+--------------------+------------+") - fmt.Println("Valid DNS List: ", validDNSList) + // Initialize Viper for cache + cacheViper := viper.New() + cacheViper.SetConfigFile(common.CHECKED_DNS_CONFIG_FILE) + // Save valid DNS list if any found if len(validDNSList) > 0 { - err = common.WriteDNSToFile(cacheFile, validDNSList) - if err != nil { - fmt.Println("Error writing to cached DNS file:", err) - return err + cacheViper.Set("validDNSServers", validDNSList) + if err := cacheViper.WriteConfig(); err != nil { + if err := cacheViper.SafeWriteConfig(); err != nil { + return fmt.Errorf("error writing cached DNS config: %w", err) + } } - fmt.Printf("Cached %d valid DNS servers to %s\n", len(validDNSList), cacheFile) + fmt.Printf("Cached %d valid DNS servers to %s\n", len(validDNSList), common.CHECKED_DNS_CONFIG_FILE) } else { fmt.Println("No valid DNS servers found to cache.") } From e1681f43e64cd9d167dc607497837117a5f63e04 Mon Sep 17 00:00:00 2001 From: arman taherighaletaki Date: Thu, 5 Jun 2025 20:11:52 +0330 Subject: [PATCH 4/7] feat: use yaml format for config file --- config/dockerRegistry.conf | 10 +++++- internal/common/function.go | 36 ++++++++++++++++++--- internal/dns/function.go | 63 +++++++++++++++++-------------------- internal/docker/function.go | 5 ++- 4 files changed, 71 insertions(+), 43 deletions(-) diff --git a/config/dockerRegistry.conf b/config/dockerRegistry.conf index 34e44ae..4fbec7d 100644 --- a/config/dockerRegistry.conf +++ b/config/dockerRegistry.conf @@ -1 +1,9 @@ -docker.arvancloud.ir focker.ir registry.docker.ir docker.host:5000 docker.iranserver.com docker.haiocloud.com registry.registryhub.ir docker-mirror.kubarcloud.com +registryList: + - "docker.arvancloud.ir" + - "focker.ir" + - "registry.docker.ir" + - "docker.host:5000" + - "docker.iranserver.com" + - "docker.haiocloud.com" + - "registry.registryhub.ir" + - "docker-mirror.kubarcloud.com" diff --git a/internal/common/function.go b/internal/common/function.go index 251bfc9..facfb15 100644 --- a/internal/common/function.go +++ b/internal/common/function.go @@ -10,6 +10,8 @@ import ( "path/filepath" "runtime" "strings" + + "github.com/spf13/viper" ) const ( @@ -54,7 +56,6 @@ func FormatDataSize(bytes int64) string { return fmt.Sprintf("%d Bytes", bytes) } } - func DownloadConfigFile(url, path string) error { homeDir := GetHomeDir() if homeDir == "" { @@ -136,14 +137,39 @@ func ReadDNSFromFile(filename string) ([]string, error) { os.Exit(1) } filename = AddPathToDir(homeDir, filename) - data, err := os.ReadFile(filename) - if err != nil { - return nil, err + viper.SetConfigFile(filename) + viper.SetConfigType("yaml") + if err := viper.ReadInConfig(); err != nil { + return nil, fmt.Errorf("error reading config file: %w", err) + } + // Get DNS list + dnsServers := viper.GetStringSlice("dnsServers") + if len(dnsServers) == 0 { + return nil, fmt.Errorf("no DNS servers found in config") } - dnsServers := strings.Fields(string(data)) return dnsServers, nil } +func ReadDockerromFile(filename string) ([]string, error) { + homeDir := GetHomeDir() + if homeDir == "" { + fmt.Println("HOME environment variable not set") + os.Exit(1) + } + filename = AddPathToDir(homeDir, filename) + viper.SetConfigFile(filename) + viper.SetConfigType("yaml") + if err := viper.ReadInConfig(); err != nil { + return nil, fmt.Errorf("error reading config file: %w", err) + } + // Get DNS list + registryList := viper.GetStringSlice("registryList") + if len(registryList) == 0 { + return nil, fmt.Errorf("no DNS servers found in config") + } + return registryList, nil +} + func ChangeDNS(dns string) *http.Client { dialer := &net.Dialer{} customResolver := &net.Resolver{ diff --git a/internal/dns/function.go b/internal/dns/function.go index dd68a7f..d17a1e4 100644 --- a/internal/dns/function.go +++ b/internal/dns/function.go @@ -2,7 +2,6 @@ package dns import ( "context" - "errors" "fmt" "net/http" "net/url" @@ -15,7 +14,6 @@ import ( "403unlocker-cli/internal/common" "github.com/cavaliergopher/grab/v3" - "github.com/spf13/viper" ) func URLValidator(URL string) bool { @@ -36,27 +34,21 @@ func URLValidator(URL string) bool { } func CheckAndCacheDNS(url string) error { - // Initialize Viper for DNS configuration - dnsViper := viper.New() - dnsViper.SetConfigFile(common.DNS_CONFIG_FILE) - - // Try to read the DNS config file - if err := dnsViper.ReadInConfig(); err != nil { - // If file doesn't exist, download it - if err := common.DownloadConfigFile(common.DNS_CONFIG_URL, common.DNS_CONFIG_FILE); err != nil { - return fmt.Errorf("error downloading DNS config: %w", err) - } + cacheFile := common.CHECKED_DNS_CONFIG_FILE - // Try reading again after download - if err := dnsViper.ReadInConfig(); err != nil { - return fmt.Errorf("error reading DNS config: %w", err) + dnsList, err := common.ReadDNSFromFile(common.DNS_CONFIG_FILE) + if err != nil { + err = common.DownloadConfigFile(common.DNS_CONFIG_URL, common.DNS_CONFIG_FILE) + if err != nil { + fmt.Println("Error downloading DNS config file:", err) + return err } - } - // Get DNS list from config - dnsList := dnsViper.GetStringSlice("dnsServers") - if len(dnsList) == 0 { - return errors.New("no DNS servers found in config") + dnsList, err = common.ReadDNSFromFile(common.DNS_CONFIG_FILE) + if err != nil { + fmt.Println("Error reading DNS list from file:", err) + return err + } } fmt.Println("\n+--------------------+------------+") @@ -72,7 +64,10 @@ func CheckAndCacheDNS(url string) error { go func(dns string) { defer wg.Done() + // Change DNS for the HTTP client client := common.ChangeDNS(dns) + + // Perform the GET request resp, err := client.Get(url) if err != nil { fmt.Printf("| %-18s | %s%-10s%s |\n", dns, common.Red, "Error", common.Reset) @@ -80,19 +75,22 @@ func CheckAndCacheDNS(url string) error { } defer resp.Body.Close() - statusParts := strings.Split(resp.Status, " ") - if len(statusParts) < 2 { + // Parse the status code + codeParts := strings.Split(resp.Status, " ") + if len(codeParts) < 2 { fmt.Printf("| %-18s | %s%-10s%s |\n", dns, common.Red, "Invalid", common.Reset) return } - statusCode, err := strconv.Atoi(statusParts[0]) + statusCode, err := strconv.Atoi(codeParts[0]) if err != nil { fmt.Printf("| %-18s | %s%-10s%s |\n", dns, common.Red, "Error", common.Reset) return } - statusText := statusParts[1] + // Output the status with appropriate color + statusText := codeParts[1] + if statusCode == http.StatusOK { mu.Lock() validDNSList = append(validDNSList, dns) @@ -105,21 +103,18 @@ func CheckAndCacheDNS(url string) error { } wg.Wait() + fmt.Println("+--------------------+------------+") - // Initialize Viper for cache - cacheViper := viper.New() - cacheViper.SetConfigFile(common.CHECKED_DNS_CONFIG_FILE) + fmt.Println("Valid DNS List: ", validDNSList) - // Save valid DNS list if any found if len(validDNSList) > 0 { - cacheViper.Set("validDNSServers", validDNSList) - if err := cacheViper.WriteConfig(); err != nil { - if err := cacheViper.SafeWriteConfig(); err != nil { - return fmt.Errorf("error writing cached DNS config: %w", err) - } + err = common.WriteDNSToFile(cacheFile, validDNSList) + if err != nil { + fmt.Println("Error writing to cached DNS file:", err) + return err } - fmt.Printf("Cached %d valid DNS servers to %s\n", len(validDNSList), common.CHECKED_DNS_CONFIG_FILE) + fmt.Printf("Cached %d valid DNS servers to %s\n", len(validDNSList), cacheFile) } else { fmt.Println("No valid DNS servers found to cache.") } diff --git a/internal/docker/function.go b/internal/docker/function.go index d0b2f4d..3a38c81 100644 --- a/internal/docker/function.go +++ b/internal/docker/function.go @@ -110,14 +110,13 @@ func CheckWithDockerImage(imageName string, timeout int) error { return fmt.Errorf("image name cannot be empty") } - registryList, err := common.ReadDNSFromFile(common.DOCKER_CONFIG_FILE) + registryList, err := common.ReadDockerromFile(common.DOCKER_CONFIG_FILE) if err != nil { err = common.DownloadConfigFile(common.DOCKER_CONFIG_URL, common.DOCKER_CONFIG_FILE) if err != nil { return err } - - registryList, err = common.ReadDNSFromFile(common.DOCKER_CONFIG_FILE) + registryList, err = common.ReadDockerromFile(common.DOCKER_CONFIG_FILE) if err != nil { log.Printf("Error reading registry list: %v", err) return err From 7057553822c58e0a49f2e16f6346feae23c06190 Mon Sep 17 00:00:00 2001 From: arman taherighaletaki Date: Thu, 5 Jun 2025 21:55:40 +0330 Subject: [PATCH 5/7] chore: change config format of dns to yaml --- Makefile | 8 +++---- config/{dns.conf => dns.yml} | 0 ...ockerRegistry.conf => dockerRegistry.yaml} | 0 go.mod | 1 + go.sum | 2 ++ internal/common/function.go | 21 ++++++++++--------- internal/dns/function.go | 11 +++++----- 7 files changed, 24 insertions(+), 19 deletions(-) rename config/{dns.conf => dns.yml} (100%) rename config/{dockerRegistry.conf => dockerRegistry.yaml} (100%) diff --git a/Makefile b/Makefile index 87c71ce..6d989c2 100644 --- a/Makefile +++ b/Makefile @@ -3,8 +3,8 @@ OUTPUT = 403unlocker MAIN = cmd/main.go BIN_DIR = ~/.local/bin CONFIG_DIR= ~/.config/403unlocker -DNS_CONFIG_FILE_URL=https://raw.githubusercontent.com/403unlocker/403Unlocker-cli/refs/heads/main/config/dns.conf -DOCKER_CONFIG_FILE_URL=https://raw.githubusercontent.com/403unlocker/403Unlocker-cli/refs/heads/main/config/dockerRegistry.conf +DNS_CONFIG_FILE_URL=https://raw.githubusercontent.com/403unlocker/403Unlocker-cli/refs/heads/main/config/dns.yml +DOCKER_CONFIG_FILE_URL=https://raw.githubusercontent.com/403unlocker/403Unlocker-cli/refs/heads/main/config/dockerRegistry.yaml .DEFAULT_GOAL := help @@ -37,9 +37,9 @@ clean: install: build @echo "Installing $(OUTPUT) to $(BIN_DIR)..." @install -m 755 $(OUTPUT) $(BIN_DIR) - @echo "Downloading config files dns.conf to $(CONFIG_DIR)..." + @echo "Downloading config files dns.yml to $(CONFIG_DIR)..." @wget $(DNS_CONFIG_FILE_URL) -q -P $(CONFIG_DIR) - @echo "Downloading dockerRegistry.conf $(CONFIG_DIR)..." + @echo "Downloading dockerRegistry.yaml $(CONFIG_DIR)..." @wget $(DOCKER_CONFIG_FILE_URL) -q -P $(CONFIG_DIR) diff --git a/config/dns.conf b/config/dns.yml similarity index 100% rename from config/dns.conf rename to config/dns.yml diff --git a/config/dockerRegistry.conf b/config/dockerRegistry.yaml similarity index 100% rename from config/dockerRegistry.conf rename to config/dockerRegistry.yaml diff --git a/go.mod b/go.mod index 0dd6edd..9d19371 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require ( github.com/spf13/cobra v1.9.1 github.com/spf13/viper v1.20.1 github.com/stretchr/testify v1.10.0 + gopkg.in/yaml.v2 v2.4.0 gotest.tools/v3 v3.5.2 ) diff --git a/go.sum b/go.sum index baceb4e..1fa665d 100644 --- a/go.sum +++ b/go.sum @@ -84,6 +84,8 @@ golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/internal/common/function.go b/internal/common/function.go index facfb15..baff3e7 100644 --- a/internal/common/function.go +++ b/internal/common/function.go @@ -9,9 +9,9 @@ import ( "os" "path/filepath" "runtime" - "strings" "github.com/spf13/viper" + yaml "gopkg.in/yaml.v2" ) const ( @@ -27,11 +27,11 @@ const ( White = "\033[97m" // DNS config - DNS_CONFIG_FILE = ".config/403unlocker/dns.conf" - CHECKED_DNS_CONFIG_FILE = ".config/403unlocker/checked_dns.conf" - DOCKER_CONFIG_FILE = ".config/403unlocker/dockerRegistry.conf" - DNS_CONFIG_URL = "https://raw.githubusercontent.com/403unlocker/403Unlocker-cli/refs/heads/main/config/dns.conf" - DOCKER_CONFIG_URL = "https://raw.githubusercontent.com/403unlocker/403Unlocker-cli/refs/heads/main/config/dockerRegistry.conf" + DNS_CONFIG_FILE = ".config/403unlocker/dns.yml" + CHECKED_DNS_CONFIG_FILE = ".config/403unlocker/checked_dns.yml" + DOCKER_CONFIG_FILE = ".config/403unlocker/dockerRegistry.yaml" + DNS_CONFIG_URL = "https://raw.githubusercontent.com/403unlocker/403Unlocker-cli/refs/heads/main/config/dns.yml" + DOCKER_CONFIG_URL = "https://raw.githubusercontent.com/403unlocker/403Unlocker-cli/refs/heads/main/config/dockerRegistry.yaml" // OS names WINDOWS_OS_NAME = "windows" @@ -118,10 +118,11 @@ func WriteDNSToFile(filename string, dnsList []string) error { } file.Close() } - - content := strings.Join(dnsList, " ") - - err = os.WriteFile(filename, []byte(content), 0644) + data := map[string][]string{ + "dnsServers": dnsList, + } + yamlData, err := yaml.Marshal(data) + err = os.WriteFile(filename, yamlData, 0644) if err != nil { fmt.Printf("Error writing to file %s: %v\n", filename, err) return err diff --git a/internal/dns/function.go b/internal/dns/function.go index d17a1e4..b5cb73b 100644 --- a/internal/dns/function.go +++ b/internal/dns/function.go @@ -34,8 +34,6 @@ func URLValidator(URL string) bool { } func CheckAndCacheDNS(url string) error { - cacheFile := common.CHECKED_DNS_CONFIG_FILE - dnsList, err := common.ReadDNSFromFile(common.DNS_CONFIG_FILE) if err != nil { err = common.DownloadConfigFile(common.DNS_CONFIG_URL, common.DNS_CONFIG_FILE) @@ -109,12 +107,13 @@ func CheckAndCacheDNS(url string) error { fmt.Println("Valid DNS List: ", validDNSList) if len(validDNSList) > 0 { - err = common.WriteDNSToFile(cacheFile, validDNSList) + err = common.WriteDNSToFile(common.CHECKED_DNS_CONFIG_FILE, validDNSList) if err != nil { fmt.Println("Error writing to cached DNS file:", err) return err } - fmt.Printf("Cached %d valid DNS servers to %s\n", len(validDNSList), cacheFile) + homeDir, _ := os.UserHomeDir() + fmt.Printf("Cached %d valid DNS servers to %s\n", len(validDNSList), homeDir+"/"+common.CHECKED_DNS_CONFIG_FILE) } else { fmt.Println("No valid DNS servers found to cache.") } @@ -123,6 +122,7 @@ func CheckAndCacheDNS(url string) error { } func CheckWithURL(commandLintFirstArg string, check bool, timeout int) error { + var dnsList []string fileToDownload := commandLintFirstArg var dnsFile string @@ -140,11 +140,12 @@ func CheckWithURL(commandLintFirstArg string, check bool, timeout int) error { dnsList, err := common.ReadDNSFromFile(dnsFile) if err != nil { // Fallback to download and read from the original DNS file + println("kir") err = common.DownloadConfigFile(common.DNS_CONFIG_URL, common.DNS_CONFIG_FILE) if err != nil { return fmt.Errorf("error downloading DNS config file: %w", err) } - dnsList, err = common.ReadDNSFromFile(common.DNS_CONFIG_FILE) + dnsList, err = common.ReadDNSFromFile(dnsFile) if err != nil { return fmt.Errorf("error reading DNS list from file: %w", err) } From 4b794f5709b02002cfabfd9af49da9ecd085cc4c Mon Sep 17 00:00:00 2001 From: arman taherighaletaki Date: Thu, 5 Jun 2025 22:00:06 +0330 Subject: [PATCH 6/7] fix: change yaml to yml --- Makefile | 4 ++-- config/{dockerRegistry.yaml => dockerRegistry.yml} | 0 internal/common/function.go | 4 ++-- internal/dns/function.go | 1 - 4 files changed, 4 insertions(+), 5 deletions(-) rename config/{dockerRegistry.yaml => dockerRegistry.yml} (100%) diff --git a/Makefile b/Makefile index 6d989c2..c65139f 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ MAIN = cmd/main.go BIN_DIR = ~/.local/bin CONFIG_DIR= ~/.config/403unlocker DNS_CONFIG_FILE_URL=https://raw.githubusercontent.com/403unlocker/403Unlocker-cli/refs/heads/main/config/dns.yml -DOCKER_CONFIG_FILE_URL=https://raw.githubusercontent.com/403unlocker/403Unlocker-cli/refs/heads/main/config/dockerRegistry.yaml +DOCKER_CONFIG_FILE_URL=https://raw.githubusercontent.com/403unlocker/403Unlocker-cli/refs/heads/main/config/dockerRegistry.yml .DEFAULT_GOAL := help @@ -39,7 +39,7 @@ install: build @install -m 755 $(OUTPUT) $(BIN_DIR) @echo "Downloading config files dns.yml to $(CONFIG_DIR)..." @wget $(DNS_CONFIG_FILE_URL) -q -P $(CONFIG_DIR) - @echo "Downloading dockerRegistry.yaml $(CONFIG_DIR)..." + @echo "Downloading dockerRegistry.yml $(CONFIG_DIR)..." @wget $(DOCKER_CONFIG_FILE_URL) -q -P $(CONFIG_DIR) diff --git a/config/dockerRegistry.yaml b/config/dockerRegistry.yml similarity index 100% rename from config/dockerRegistry.yaml rename to config/dockerRegistry.yml diff --git a/internal/common/function.go b/internal/common/function.go index baff3e7..84fad74 100644 --- a/internal/common/function.go +++ b/internal/common/function.go @@ -29,9 +29,9 @@ const ( // DNS config DNS_CONFIG_FILE = ".config/403unlocker/dns.yml" CHECKED_DNS_CONFIG_FILE = ".config/403unlocker/checked_dns.yml" - DOCKER_CONFIG_FILE = ".config/403unlocker/dockerRegistry.yaml" + DOCKER_CONFIG_FILE = ".config/403unlocker/dockerRegistry.yml" DNS_CONFIG_URL = "https://raw.githubusercontent.com/403unlocker/403Unlocker-cli/refs/heads/main/config/dns.yml" - DOCKER_CONFIG_URL = "https://raw.githubusercontent.com/403unlocker/403Unlocker-cli/refs/heads/main/config/dockerRegistry.yaml" + DOCKER_CONFIG_URL = "https://raw.githubusercontent.com/403unlocker/403Unlocker-cli/refs/heads/main/config/dockerRegistry.yml" // OS names WINDOWS_OS_NAME = "windows" diff --git a/internal/dns/function.go b/internal/dns/function.go index b5cb73b..34b9dad 100644 --- a/internal/dns/function.go +++ b/internal/dns/function.go @@ -140,7 +140,6 @@ func CheckWithURL(commandLintFirstArg string, check bool, timeout int) error { dnsList, err := common.ReadDNSFromFile(dnsFile) if err != nil { // Fallback to download and read from the original DNS file - println("kir") err = common.DownloadConfigFile(common.DNS_CONFIG_URL, common.DNS_CONFIG_FILE) if err != nil { return fmt.Errorf("error downloading DNS config file: %w", err) From b4729b88def3b691f68ad215f0ec9c2d19fe35b5 Mon Sep 17 00:00:00 2001 From: arman taherighaletaki Date: Sat, 7 Jun 2025 04:19:03 +0330 Subject: [PATCH 7/7] chore: make exeption better --- internal/common/function.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/internal/common/function.go b/internal/common/function.go index 84fad74..b090c7e 100644 --- a/internal/common/function.go +++ b/internal/common/function.go @@ -122,6 +122,10 @@ func WriteDNSToFile(filename string, dnsList []string) error { "dnsServers": dnsList, } yamlData, err := yaml.Marshal(data) + if err != nil { + fmt.Printf("%v", err) + return err + } err = os.WriteFile(filename, yamlData, 0644) if err != nil { fmt.Printf("Error writing to file %s: %v\n", filename, err)