diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c07983a46aa0..814cd8a38826 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,4 +1,4 @@ -name: Test +name: Tests and Checkings on: push: @@ -50,6 +50,25 @@ jobs: fi done + check-format: + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - name: Checkout codebase + uses: actions/checkout@v6 + - name: Set up Go + uses: actions/setup-go@v6 + with: + go-version-file: go.mod + check-latest: true + cache: false + - name: Check Format + run: | + # go install -v github.com/daixiang0/gci@latest + go install -v mvdan.cc/gofumpt@latest + go run ./infra/vformat/main.go -mode dryrun -pwd ./ + test: needs: check-assets permissions: diff --git a/infra/vformat/main.go b/infra/vformat/main.go index 84c63a4203cc..81d29c6bc0d2 100644 --- a/infra/vformat/main.go +++ b/infra/vformat/main.go @@ -12,7 +12,16 @@ import ( "strings" ) -var directory = flag.String("pwd", "", "Working directory of Xray vformat.") +var ( + directory = flag.String("pwd", "", "Working directory of Xray vformat.") + action = flag.String("mode", "format", "Execution mode. Default is 'format'.\n'format' formatting source files and save changes to files.\n'check' list all paths of improper formatted file.\n'dryrun' formatting source files and shows all diffs, but will not make any changes to files.") +) + +var ( + isCheck bool + isDryrun bool + isFormat bool +) // envFile returns the name of the Go environment configuration file. // Copy from https://github.com/golang/go/blob/c4f2a9788a7be04daf931ac54382fbe2cb754938/src/cmd/go/internal/cfg/cfg.go#L150-L166 @@ -90,9 +99,10 @@ func Run(binary string, args []string) ([]byte, error) { return output, nil } -func RunMany(binary string, args, files []string) { - fmt.Println("Processing...") +func RunMany(binary string, args, files []string) bool { + fmt.Println("Processing with", binary, args, "...") + formatRequired := false maxTasks := make(chan struct{}, runtime.NumCPU()) for _, file := range files { maxTasks <- struct{}{} @@ -102,10 +112,12 @@ func RunMany(binary string, args, files []string) { fmt.Println(err) } else if len(output) > 0 { fmt.Println(string(output)) + formatRequired = true } <-maxTasks }(file) } + return formatRequired } func main() { @@ -124,6 +136,19 @@ func main() { *directory = filepath.Join(pwd, *directory) } + switch *action { + case "format": + isFormat = true + case "check": + isCheck = true + case "dryrun": + isCheck = true + isDryrun = true + default: + fmt.Println("Unrecognized 'mode'. Will format all source files and save changes.") + isFormat = true + } + pwd := *directory GOBIN := GetGOBIN() binPath := os.Getenv("PATH") @@ -136,7 +161,7 @@ func main() { suffix = ".exe" } gofmt := "gofumpt" + suffix - goimports := "gci" + suffix + /* goimports := "gci" + suffix */ if gofmtPath, err := exec.LookPath(gofmt); err != nil { fmt.Println("Can not find", gofmt, "in system path or current working directory.") @@ -145,12 +170,12 @@ func main() { gofmt = gofmtPath } - if goimportsPath, err := exec.LookPath(goimports); err != nil { + /* if goimportsPath, err := exec.LookPath(goimports); err != nil { fmt.Println("Can not find", goimports, "in system path or current working directory.") os.Exit(1) } else { goimports = goimportsPath - } + } */ rawFilesSlice := make([]string, 0, 1000) walkErr := filepath.Walk(pwd, func(path string, info os.FileInfo, err error) error { @@ -179,15 +204,61 @@ func main() { os.Exit(1) } - gofmtArgs := []string{ - "-s", "-l", "-e", "-w", - } + if isFormat { + gofmtArgs := []string{ + "-l", "-e", "-w", + } + /* goimportsArgs := []string{ + "write", + } */ - goimportsArgs := []string{ - "write", + fmt.Println("Formatting Go source files...") + RunMany(gofmt, gofmtArgs, rawFilesSlice) + /* (goimports, goimportsArgs, rawFilesSlice) */ + fmt.Println("Do NOT forget to commit file changes.") } - RunMany(gofmt, gofmtArgs, rawFilesSlice) - RunMany(goimports, goimportsArgs, rawFilesSlice) - fmt.Println("Do NOT forget to commit file changes.") + if isCheck { + gofmtListArgs := []string{ + "-l", "-e", + } + /* goimportsListArgs := []string{ + "list", + } */ + + fmt.Println("Checking files thar are not properly formatted...") + formatRequired := RunMany(gofmt, gofmtListArgs, rawFilesSlice) + /* formatImportRequired := RunMany(goimports, goimportsListArgs, rawFilesSlice) */ + if formatRequired { + fmt.Println("Format problem(s) found.") + } + /* if formatImportRequired { + fmt.Println("Format problem(s) in import found.") + } */ + + if isDryrun { + if formatRequired { + gofmtShowArgs := []string{ + "-d", "-e", + } + RunMany(gofmt, gofmtShowArgs, rawFilesSlice) + } + /* formatImportRequired { + goimportsShowArgs := []string{ + "diff", + } + RunMany(goimports, goimportsShowArgs, rawFilesSlice) + } */ + } + + /* if formatRequired || formatImportRequired { */ + if formatRequired { + /* fmt.Println("Please run 'go install -v github.com/daixiang0/gci@latest', 'go install -v mvdan.cc/gofumpt@latest', then run 'go run ./infra/vformat/main.go' to format the Go source files.") + os.Exit(1) */ + fmt.Println("Please run 'go install -v mvdan.cc/gofumpt@latest', then run 'go run ./infra/vformat/main.go' to format the Go source files.") + os.Exit(1) + } else { + fmt.Println("All Go source file format check has been passed.") + } + } }