<commit_before>// SPDX-License-Identifier: Apache-2.0
// Copyright Authors of Cilium

package main

import (
	"fmt"
	"os"
	"regexp"
	"text/tabwriter"

	"github.com/blang/semver/v4"
	"github.com/spf13/cobra"
)

var rootCmd = &cobra.Command{
	Args:  cobra.NoArgs,
	Short: "Check development setup",
	Run:   rootCmdRun,
}

var (
	backportingChecks *bool
	nfsFirewallChecks *bool
)

func init() {
	flags := rootCmd.Flags()
	backportingChecks = flags.Bool("backporting", false, "run backporting checks")
	nfsFirewallChecks = flags.Bool("nfs-firewall", false, "run extra NFS firewall checks, requires root privileges")
}

func rootCmdRun(cmd *cobra.Command, args []string) {
	minGoVersion, err := semver.ParseTolerant(minGoVersionStr)
	if err != nil {
		panic(fmt.Sprintf("cannot parse minGoVersionStr: %q", minGoVersionStr))
	}

	checks := []check{
		osArchCheck{},
		unameCheck{},
		rootDirCheck{
			rootDir: goPath() + "/src/github.com/cilium/cilium",
		},
		&binaryCheck{
			name:          "make",
			ifNotFound:    checkError,
			versionArgs:   []string{"--version"},
			versionRegexp: regexp.MustCompile(`GNU\s+Make\s+(\d+\.\d+\S*)`),
		},
		&binaryCheck{
			name:          "go",
			ifNotFound:    checkError,
			versionArgs:   []string{"version"},
			versionRegexp: regexp.MustCompile(`go version go(\d+\.\d+\S*)`),
			minVersion:    &minGoVersion,
		},
		&binaryCheck{
			name:          "tparse",
			ifNotFound:    checkWarning,
			versionArgs:   []string{"-v"},
			versionRegexp: regexp.MustCompile(`tparse version: v(\d+\.\d+\.\d+)`),
			hint:          `Run "go install github.com/mfridman/tparse@latest"`,
		},
		&binaryCheck{
			name:          "clang",
			ifNotFound:    checkError,
			versionArgs:   []string{"--version"},
			versionRegexp: regexp.MustCompile(`clang version (\d+\.\d+\.\d+)`),
			minVersion:    &semver.Version{Major: 10, Minor: 0, Patch: 0},
		},
		&binaryCheck{
			name:          "docker-server",
			command:       "docker",
			ifNotFound:    checkWarning,
			versionArgs:   []string{"version", "--format", "{{ .Server.Version }}"},
			versionRegexp: regexp.MustCompile(`(\d+\.\d+\.\d+)`),
		},
		&binaryCheck{
			name:          "docker-client",
			command:       "docker",
			ifNotFound:    checkWarning,
			versionArgs:   []string{"version", "--format", "{{ .Client.Version }}"},
			versionRegexp: regexp.MustCompile(`(\d+\.\d+\.\d+)`),
		},
		&binaryCheck{
			name:          "docker-buildx",
			command:       "docker",
			ifNotFound:    checkWarning,
			versionArgs:   []string{"buildx", "version"},
			versionRegexp: regexp.MustCompile(`github\.com/docker/buildx v(\d+\.\d+\.\d+)`),
			hint:          "see https://docs.docker.com/buildx/working-with-buildx/",
		},
		&binaryCheck{
			name:          "ginkgo",
			ifNotFound:    checkWarning,
			versionArgs:   []string{"version"},
			versionRegexp: regexp.MustCompile(`Ginkgo Version (\d+\.\d+\S*)`),
			minVersion:    &semver.Version{Major: 1, Minor: 4, Patch: 0},
			maxVersion:    &semver.Version{Major: 2, Minor: 0, Patch: 0},
			hint:          `Run "go install github.com/onsi/ginkgo/ginkgo@latest".`,
		},
		// FIXME add gomega check?
		&binaryCheck{
			name:          "golangci-lint",
			ifNotFound:    checkWarning,
			versionArgs:   []string{"version"},
			versionRegexp: regexp.MustCompile(`(\d+\.\d+\S*)`),
			minVersion:    &semver.Version{Major: 1, Minor: 27, Patch: 0},
			hint:          "See https://golangci-lint.run/usage/install/#local-installation.",
		},
		&binaryCheck{
			name:          "docker",
			ifNotFound:    checkError,
			versionArgs:   []string{"--version"},
			versionRegexp: regexp.MustCompile(`Docker version (\d+\.\d+\.\d+)`),
		},
		&binaryCheck{
			name:          "helm",
			ifNotFound:    checkWarning,
			versionArgs:   []string{"version"},
			versionRegexp: regexp.MustCompile(`Version:"v(\d+\.\d+\.\d+)"`),
			minVersion:    &semver.Version{Major: 3, Minor: 0, Patch: 0},
		},
		&binaryCheck{
			name:          "llc",
			ifNotFound:    checkWarning,
			versionArgs:   []string{"--version"},
			versionRegexp: regexp.MustCompile(`LLVM\s+version\s+(\d+\.\d+\S*)`),<commit_msg>dev-doctor: Update minimum helm version<commit_after>// SPDX-License-Identifier: Apache-2.0
// Copyright Authors of Cilium

package main

import (
	"fmt"
	"os"
	"regexp"
	"text/tabwriter"

	"github.com/blang/semver/v4"
	"github.com/spf13/cobra"
)

var rootCmd = &cobra.Command{
	Args:  cobra.NoArgs,
	Short: "Check development setup",
	Run:   rootCmdRun,
}

var (
	backportingChecks *bool
	nfsFirewallChecks *bool
)

func init() {
	flags := rootCmd.Flags()
	backportingChecks = flags.Bool("backporting", false, "run backporting checks")
	nfsFirewallChecks = flags.Bool("nfs-firewall", false, "run extra NFS firewall checks, requires root privileges")
}

func rootCmdRun(cmd *cobra.Command, args []string) {
	minGoVersion, err := semver.ParseTolerant(minGoVersionStr)
	if err != nil {
		panic(fmt.Sprintf("cannot parse minGoVersionStr: %q", minGoVersionStr))
	}

	checks := []check{
		osArchCheck{},
		unameCheck{},
		rootDirCheck{
			rootDir: goPath() + "/src/github.com/cilium/cilium",
		},
		&binaryCheck{
			name:          "make",
			ifNotFound:    checkError,
			versionArgs:   []string{"--version"},
			versionRegexp: regexp.MustCompile(`GNU\s+Make\s+(\d+\.\d+\S*)`),
		},
		&binaryCheck{
			name:          "go",
			ifNotFound:    checkError,
			versionArgs:   []string{"version"},
			versionRegexp: regexp.MustCompile(`go version go(\d+\.\d+\S*)`),
			minVersion:    &minGoVersion,
		},
		&binaryCheck{
			name:          "tparse",
			ifNotFound:    checkWarning,
			versionArgs:   []string{"-v"},
			versionRegexp: regexp.MustCompile(`tparse version: v(\d+\.\d+\.\d+)`),
			hint:          `Run "go install github.com/mfridman/tparse@latest"`,
		},
		&binaryCheck{
			name:          "clang",
			ifNotFound:    checkError,
			versionArgs:   []string{"--version"},
			versionRegexp: regexp.MustCompile(`clang version (\d+\.\d+\.\d+)`),
			minVersion:    &semver.Version{Major: 10, Minor: 0, Patch: 0},
		},
		&binaryCheck{
			name:          "docker-server",
			command:       "docker",
			ifNotFound:    checkWarning,
			versionArgs:   []string{"version", "--format", "{{ .Server.Version }}"},
			versionRegexp: regexp.MustCompile(`(\d+\.\d+\.\d+)`),
		},
		&binaryCheck{
			name:          "docker-client",
			command:       "docker",
			ifNotFound:    checkWarning,
			versionArgs:   []string{"version", "--format", "{{ .Client.Version }}"},
			versionRegexp: regexp.MustCompile(`(\d+\.\d+\.\d+)`),
		},
		&binaryCheck{
			name:          "docker-buildx",
			command:       "docker",
			ifNotFound:    checkWarning,
			versionArgs:   []string{"buildx", "version"},
			versionRegexp: regexp.MustCompile(`github\.com/docker/buildx v(\d+\.\d+\.\d+)`),
			hint:          "see https://docs.docker.com/buildx/working-with-buildx/",
		},
		&binaryCheck{
			name:          "ginkgo",
			ifNotFound:    checkWarning,
			versionArgs:   []string{"version"},
			versionRegexp: regexp.MustCompile(`Ginkgo Version (\d+\.\d+\S*)`),
			minVersion:    &semver.Version{Major: 1, Minor: 4, Patch: 0},
			maxVersion:    &semver.Version{Major: 2, Minor: 0, Patch: 0},
			hint:          `Run "go install github.com/onsi/ginkgo/ginkgo@latest".`,
		},
		// FIXME add gomega check?
		&binaryCheck{
			name:          "golangci-lint",
			ifNotFound:    checkWarning,
			versionArgs:   []string{"version"},
			versionRegexp: regexp.MustCompile(`(\d+\.\d+\S*)`),
			minVersion:    &semver.Version{Major: 1, Minor: 27, Patch: 0},
			hint:          "See https://golangci-lint.run/usage/install/#local-installation.",
		},
		&binaryCheck{
			name:          "docker",
			ifNotFound:    checkError,
			versionArgs:   []string{"--version"},
			versionRegexp: regexp.MustCompile(`Docker version (\d+\.\d+\.\d+)`),
		},
		&binaryCheck{
			name:          "helm",
			ifNotFound:    checkWarning,
			versionArgs:   []string{"version"},
			versionRegexp: regexp.MustCompile(`Version:"v(\d+\.\d+\.\d+)"`),
			minVersion:    &semver.Version{Major: 3, Minor: 6, Patch: 0},
		},
		&binaryCheck{
			name:          "llc",
			ifNotFound:    checkWarning,
			versionArgs:   []string{"--version"},
			versionRegexp: regexp.MustCompile(`LLVM\s+version\s+(\d+\.\d+\S*)`),
{'fraction_non_alphanumeric': 0.18354430379746836, 'fraction_numerical': 0.005355404089581304, 'mean_word_length': 3.1374622356495467, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 4, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3368018', 'n_tokens_mistral': 3326, 'n_tokens_neox': 2883, 'n_words': 531}