diff --git a/.github/release-rule-set.sh b/.github/release-rule-set.sh new file mode 100755 index 0000000..efb577d --- /dev/null +++ b/.github/release-rule-set.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +set -e -o pipefail + +cd rule-set +git init +git config --local user.email "github-action@users.noreply.github.com" +git config --local user.name "GitHub Action" +git remote add origin https://github-action:$GITHUB_TOKEN@github.com/SagerNet/sing-geosite.git +git branch -M rule-set +git add . +git commit -m "Update rule-set" +git push -f origin rule-set diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index bda5b4e..f4f35a2 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -24,43 +24,26 @@ jobs: id: build run: | go run -v . + - name: Release rule sets + if: steps.build.outputs.skip != 'true' + run: .github/release-rule-set.sh + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Generate sha256 hash if: steps.build.outputs.skip != 'true' run: | sha256sum geosite.db > geosite.db.sha256sum - uses: dev-drprasad/delete-older-releases@v0.3.2 - with: - keep_latest: 3 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Create a release if: steps.build.outputs.skip != 'true' - id: create_release - uses: actions/create-release@v1 + with: + keep_latest: 10 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Release geosite + if: steps.build.outputs.skip != 'true' + uses: softprops/action-gh-release@v1 with: tag_name: ${{ steps.build.outputs.tag }} - release_name: ${{ steps.build.outputs.tag }} - draft: false - prerelease: false - - name: Release geosite.db - if: steps.build.outputs.skip != 'true' - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: ./geosite.db - asset_name: geosite.db - asset_content_type: application/octet-stream - - name: Release geosite.db sha256sum - if: steps.build.outputs.skip != 'true' - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: ./geosite.db.sha256sum - asset_name: geosite.db.sha256sum - asset_content_type: text/plain \ No newline at end of file + files: | + geosite.db + sha256sum \ No newline at end of file diff --git a/.gitignore b/.gitignore index e417e3f..c70ab18 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /.idea/ /vendor/ -/geosite.db \ No newline at end of file +/geosite.db +/rule-set/ \ No newline at end of file diff --git a/.golangci.yml b/.golangci.yml index 948fcc4..4133a1d 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,54 +1,17 @@ -run: - timeout: 5m - linters: - enable-all: true - disable: - - errcheck - - wrapcheck - - varnamelen - - stylecheck - - nonamedreturns - - nlreturn - - ireturn - - gomnd - - exhaustivestruct - - ifshort - - goerr113 - - gochecknoglobals - - forcetypeassert - - exhaustruct - - exhaustive - - cyclop - - containedctx - - wsl - - nestif - - lll - - funlen - - goconst - - godot - - gocognit - - golint - - goimports - - gochecknoinits - - maligned - - tagliatelle - - gocyclo - - maintidx - - gocritic - - nakedret + disable-all: true + enable: + - gofumpt + - govet + - gci + - staticcheck linters-settings: - revive: - rules: - - name: var-naming - disabled: true - govet: - enable-all: true - disable: - - composites - - fieldalignment - - shadow - gosec: - excludes: - - G404 \ No newline at end of file + gci: + custom-order: true + sections: + - standard + - prefix(github.com/sagernet/) + - default + staticcheck: + go: '1.20' diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..f45eb17 --- /dev/null +++ b/Makefile @@ -0,0 +1,17 @@ +fmt: + @gofumpt -l -w . + @gofmt -s -w . + @gci write --custom-order -s standard -s "prefix(github.com/sagernet/)" -s "default" . + +fmt_install: + go install -v mvdan.cc/gofumpt@latest + go install -v github.com/daixiang0/gci@latest + +lint: + golangci-lint run ./... + +lint_install: + go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest + +test: + go test -v ./... \ No newline at end of file diff --git a/format.go b/format.go deleted file mode 100644 index 37faa45..0000000 --- a/format.go +++ /dev/null @@ -1,7 +0,0 @@ -package main - -//go:generate go install -v mvdan.cc/gofumpt@latest -//go:generate go install -v github.com/daixiang0/gci@latest -//go:generate gofumpt -l -w . -//go:generate gofmt -s -w . -//go:generate gci write . diff --git a/go.mod b/go.mod index 8b2ef31..d712f4f 100644 --- a/go.mod +++ b/go.mod @@ -1,13 +1,12 @@ -module sing-geosite +module github.com/sagernet/sing-geosite go 1.18 require ( github.com/google/go-github/v45 v45.2.0 - github.com/sagernet/sing v0.2.17 - github.com/sagernet/sing-box v1.6.4 - github.com/sirupsen/logrus v1.9.3 - github.com/v2fly/v2ray-core/v5 v5.11.0 + github.com/sagernet/sing v0.2.18-0.20231129075305-eb56a60214be + github.com/sagernet/sing-box v1.6.8-0.20231129123339-5a56487cf544 + github.com/v2fly/v2ray-core/v5 v5.12.1 google.golang.org/protobuf v1.31.0 ) @@ -15,11 +14,13 @@ require ( github.com/adrg/xdg v0.4.0 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/google/go-querystring v1.1.0 // indirect - github.com/miekg/dns v1.1.56 // indirect - github.com/sagernet/sing-dns v0.1.10 // indirect + github.com/logrusorgru/aurora v2.0.3+incompatible // indirect + github.com/miekg/dns v1.1.57 // indirect + github.com/sagernet/sing-dns v0.1.11 // indirect + go4.org/netipx v0.0.0-20230824141953-6213f710f925 // indirect golang.org/x/crypto v0.15.0 // indirect - golang.org/x/mod v0.13.0 // indirect + golang.org/x/mod v0.14.0 // indirect golang.org/x/net v0.18.0 // indirect golang.org/x/sys v0.14.0 // indirect - golang.org/x/tools v0.14.0 // indirect + golang.org/x/tools v0.15.0 // indirect ) diff --git a/go.sum b/go.sum index 6be441b..6de2cd6 100644 --- a/go.sum +++ b/go.sum @@ -2,7 +2,6 @@ github.com/adrg/xdg v0.4.0 h1:RzRqFcjH4nE5C6oTAxhBtoE2IRyjBSa62SCbyPidvls= github.com/adrg/xdg v0.4.0/go.mod h1:N6ag73EX4wyxeaoeHctc1mas01KZgsj5tYiAIwqJE/E= 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/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= @@ -13,36 +12,37 @@ github.com/google/go-github/v45 v45.2.0 h1:5oRLszbrkvxDDqBCNj2hjDZMKmvexaZ1xw/FC github.com/google/go-github/v45 v45.2.0/go.mod h1:FObaZJEDSTa/WGCzZ2Z3eoCDXWJKMenWWTrd8jrta28= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= -github.com/miekg/dns v1.1.56 h1:5imZaSeoRNvpM9SzWNhEcP9QliKiz20/dA2QabIGVnE= -github.com/miekg/dns v1.1.56/go.mod h1:cRm6Oo2C8TY9ZS/TqsSrseAcncm74lfK5G+ikN2SWWY= +github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8= +github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= +github.com/miekg/dns v1.1.57 h1:Jzi7ApEIzwEPLHWRcafCN9LZSBbqQpxjt/wpgvg7wcM= +github.com/miekg/dns v1.1.57/go.mod h1:uqRjCRUuEAA6qsOiJvDd+CFo/vW+y5WR6SNmHE55hZk= 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/sagernet/sing v0.2.17 h1:vMPKb3MV0Aa5ws4dCJkRI8XEjrsUcDn810czd0FwmzI= -github.com/sagernet/sing v0.2.17/go.mod h1:OL6k2F0vHmEzXz2KW19qQzu172FDgSbUSODylighuVo= -github.com/sagernet/sing-box v1.6.4 h1:4cz6kQSVehLlRzjfwYrQT52/W1nNYxulSDm7Hd+NHG8= -github.com/sagernet/sing-box v1.6.4/go.mod h1:JEvY+zKVPCxiiEuri2mw6bu2YZh38WCd6Iv9TlHzuOM= -github.com/sagernet/sing-dns v0.1.10 h1:iIU7nRBlUYj+fF2TaktGIvRiTFFrHwSMedLQsvlTZCI= -github.com/sagernet/sing-dns v0.1.10/go.mod h1:vtUimtf7Nq9EdvD5WTpfCr69KL1M7bcgOVKiYBiAY/c= -github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= -github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/sagernet/sing v0.2.18-0.20231129075305-eb56a60214be h1:FigAM9kq7RRXmHvgn8w2a8tqCY5CMV5GIk0id84dI0o= +github.com/sagernet/sing v0.2.18-0.20231129075305-eb56a60214be/go.mod h1:OL6k2F0vHmEzXz2KW19qQzu172FDgSbUSODylighuVo= +github.com/sagernet/sing-box v1.6.8-0.20231129123339-5a56487cf544 h1:kHe9kQpKMEmGJbTdDntXA0rl1BdQWQZtkDaxmZkAPC4= +github.com/sagernet/sing-box v1.6.8-0.20231129123339-5a56487cf544/go.mod h1:C5Gcyr9BsHs1Iq7eAY53hAlh/j+5fjJVsLA18z/7ZL4= +github.com/sagernet/sing-dns v0.1.11 h1:PPrMCVVrAeR3f5X23I+cmvacXJ+kzuyAsBiWyUKhGSE= +github.com/sagernet/sing-dns v0.1.11/go.mod h1:zJ/YjnYB61SYE+ubMcMqVdpaSvsyQ2iShQGO3vuLvvE= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/v2fly/v2ray-core/v5 v5.11.0 h1:+fTB6LdCf+pAyRn4IRXU0kAKCkFaBQW1rCCW2HgNMps= -github.com/v2fly/v2ray-core/v5 v5.11.0/go.mod h1:o4G6VGWp7uLp96YE9V6CxJcNOVqepwbWHBEA1vXE5TU= +github.com/v2fly/v2ray-core/v5 v5.12.1 h1:y7xdWEjQcjcNRjBbvFqWx9fdM/uMAp5kvy7xg45GQWk= +github.com/v2fly/v2ray-core/v5 v5.12.1/go.mod h1:97vMnLdw9DdKPR+ZmHL1Qd7By5jMzE5vW5936et9nI0= +go4.org/netipx v0.0.0-20230824141953-6213f710f925 h1:eeQDDVKFkx0g4Hyy8pHgmZaK0EqB4SD6rvKbUdN3ziQ= +go4.org/netipx v0.0.0-20230824141953-6213f710f925/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y= golang.org/x/crypto v0.15.0 h1:frVn1TEaCEaZcn3Tmd7Y2b5KKPaZ+I32Q2OA3kYp5TA= golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g= -golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= -golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= +golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.18.0 h1:mIYleuAkSbHh0tCv7RvjL3F6ZVbLjq4+R7zbOn3Kokg= golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ= -golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= +golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= -golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= +golang.org/x/tools v0.15.0 h1:zdAyfUGbYmuVokhzVmghFl2ZJh5QhcfebBgmVPFYA+8= +golang.org/x/tools v0.15.0/go.mod h1:hpksKq4dtpQWS1uQ61JkdqWM3LscIS6Slf+VVkm+wQk= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= diff --git a/main.go b/main.go index fc97ade..6d9ec67 100644 --- a/main.go +++ b/main.go @@ -10,11 +10,15 @@ import ( "path/filepath" "strings" - "github.com/google/go-github/v45/github" "github.com/sagernet/sing-box/common/geosite" + "github.com/sagernet/sing-box/common/srs" + C "github.com/sagernet/sing-box/constant" + "github.com/sagernet/sing-box/option" "github.com/sagernet/sing/common" E "github.com/sagernet/sing/common/exceptions" - "github.com/sirupsen/logrus" + + "github.com/google/go-github/v45/github" + "github.com/sagernet/sing-box/log" "github.com/v2fly/v2ray-core/v5/app/router/routercommon" "google.golang.org/protobuf/proto" ) @@ -43,7 +47,7 @@ func fetch(from string) (*github.RepositoryRelease, error) { } func get(downloadURL *string) ([]byte, error) { - logrus.Info("download ", *downloadURL) + log.Info("download ", *downloadURL) response, err := http.Get(*downloadURL) if err != nil { return nil, err @@ -165,7 +169,7 @@ func parse(vGeositeData []byte) (map[string][]geosite.Item, error) { return domainMap, nil } -func generate(release *github.RepositoryRelease, output string) error { +func generate(release *github.RepositoryRelease, output string, ruleSetOutput string) error { outputFile, err := os.Create(output) if err != nil { return err @@ -181,29 +185,65 @@ func generate(release *github.RepositoryRelease, output string) error { } outputPath, _ := filepath.Abs(output) os.Stderr.WriteString("write " + outputPath + "\n") - return geosite.Write(outputFile, domainMap) + err = geosite.Write(outputFile, domainMap) + if err != nil { + return err + } + os.RemoveAll(ruleSetOutput) + err = os.MkdirAll(ruleSetOutput, 0o755) + if err != nil { + return err + } + for code, domains := range domainMap { + var headlessRule option.DefaultHeadlessRule + defaultRule := geosite.Compile(domains) + headlessRule.Domain = defaultRule.Domain + headlessRule.DomainSuffix = defaultRule.DomainSuffix + headlessRule.DomainKeyword = defaultRule.DomainKeyword + headlessRule.DomainRegex = defaultRule.DomainRegex + var plainRuleSet option.PlainRuleSet + plainRuleSet.Rules = []option.HeadlessRule{ + { + Type: C.RuleTypeDefault, + DefaultOptions: headlessRule, + }, + } + srsPath, _ := filepath.Abs(filepath.Join(ruleSetOutput, "geosite-"+code+".srs")) + os.Stderr.WriteString("write " + srsPath + "\n") + outputRuleSet, err := os.Create(srsPath) + if err != nil { + return err + } + err = srs.Write(outputRuleSet, plainRuleSet) + if err != nil { + outputRuleSet.Close() + return err + } + outputRuleSet.Close() + } + return nil } func setActionOutput(name string, content string) { os.Stdout.WriteString("::set-output name=" + name + "::" + content + "\n") } -func release(source string, destination string, output string) error { +func release(source string, destination string, output string, ruleSetOutput string) error { sourceRelease, err := fetch(source) if err != nil { return err } destinationRelease, err := fetch(destination) if err != nil { - logrus.Warn("missing destination latest release") + log.Warn("missing destination latest release") } else { if os.Getenv("NO_SKIP") != "true" && strings.Contains(*destinationRelease.Name, *sourceRelease.Name) { - logrus.Info("already latest") + log.Info("already latest") setActionOutput("skip", "true") return nil } } - err = generate(sourceRelease, output) + err = generate(sourceRelease, output, ruleSetOutput) if err != nil { return err } @@ -212,8 +252,8 @@ func release(source string, destination string, output string) error { } func main() { - err := release("v2fly/domain-list-community", "sagernet/sing-geosite", "geosite.db") + err := release("v2fly/domain-list-community", "sagernet/sing-geosite", "geosite.db", "rule-set") if err != nil { - logrus.Fatal(err) + log.Fatal(err) } }