Skip to content

Commit

Permalink
Merge #56965
Browse files Browse the repository at this point in the history
56965: dev: introduce a general purpose dev-tool for crdb engineers r=irfansharif a=irfansharif

Our Makefile UX has grown organically over the last six years, and is
now home to various scripts that are orthogonal to simply building the
crdb binary. These include the ability to run linters, building various
useful binaries (such as roachprod, roachtest), running different kinds
of tests (unit tests, logic tests, acceptance tests), and much more.

Now that we're exploring a move towards Bazel for our build system
(#55687), we have a chance to tuck away Bazel specific under a general
purpose dev-tool, larva.

The intent here is to house all day-to-day dev operations under this
tool, written in Go. This will be the component that actually replaces
our Makefile in its entirety. It'll be (predictably) powered by bazel
underneath, but with much nicer UX. It should capturing all common usage
patterns in high-level docs.

Strawman UX (I've only really deliberated on the `test` subcommand):
```
	larva test --pkg=kv/kvserver --filter=TestReplicaGC* -v -show-logs --timeout=1m
	larva test --stress --race ...
	larva test --logic --files=prepare|fk --subtests=20042 --config=local
	larva test --fuzz --pkg=... --filter=Decimal`
	larva bench --pkg=sql/parser --filter=BenchmarkParse
	larva build cockroach --tags=deadlock
	larva build cockroach-oss
	larva build {opt,exec}gen
	larva generate bazel
	larva generate protobuf
	larva generate {opt,exec}gen
        larva lint --filter=TestLowercaseFunctionNames --short --timeout=1m
```

---

Aside: The naming here is cause of this tool's infancy, relation to
cockroaches, and it starting with the letter "l" (which is featured
prominently in "bazel"/"blaze"). Whatever.

Release note: None

Co-authored-by: irfan sharif <[email protected]>
  • Loading branch information
craig[bot] and irfansharif committed Dec 31, 2020
2 parents bdd0b93 + a04c929 commit b93fd53
Show file tree
Hide file tree
Showing 9 changed files with 573 additions and 0 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -1695,6 +1695,7 @@ bins = \
bin/github-pull-request-make \
bin/gossipsim \
bin/langgen \
bin/dev \
bin/protoc-gen-gogoroach \
bin/publish-artifacts \
bin/publish-provisional-artifacts \
Expand Down
28 changes: 28 additions & 0 deletions pkg/cmd/dev/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")

go_library(
name = "dev_lib",
srcs = [
"bench.go",
"build.go",
"generate.go",
"lint.go",
"main.go",
"test.go",
"util.go",
],
importpath = "github.com/cockroachdb/cockroach/pkg/cmd/dev",
visibility = ["//visibility:private"],
deps = [
"//pkg/util/log",
"@com_github_cockroachdb_errors//:errors",
"@com_github_cockroachdb_redact//:redact",
"@com_github_spf13_cobra//:cobra",
],
)

go_binary(
name = "dev",
embed = [":dev_lib"],
visibility = ["//visibility:public"],
)
32 changes: 32 additions & 0 deletions pkg/cmd/dev/bench.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright 2020 The Cockroach Authors.
//
// Use of this software is governed by the Business Source License
// included in the file licenses/BSL.txt.
//
// As of the Change Date specified in that file, in accordance with
// the Business Source License, use of this software will be governed
// by the Apache License, Version 2.0, included in the file
// licenses/APL.txt.

package main

import (
"github.com/cockroachdb/errors"
"github.com/spf13/cobra"
)

// benchCmd runs the specified cockroachdb benchmarks.
var benchCmd = &cobra.Command{
Use: "bench",
Short: `Run the specified benchmarks`,
Long: `Run the specified benchmarks.`,
Example: `
dev bench --pkg=sql/parser --filter=BenchmarkParse`,
Args: cobra.NoArgs,
RunE: runBench,
}

func runBench(cmd *cobra.Command, args []string) error {
// TODO(irfansharif): Flesh out the example usage patterns.
return errors.New("unimplemented")
}
78 changes: 78 additions & 0 deletions pkg/cmd/dev/build.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// Copyright 2020 The Cockroach Authors.
//
// Use of this software is governed by the Business Source License
// included in the file licenses/BSL.txt.
//
// As of the Change Date specified in that file, in accordance with
// the Business Source License, use of this software will be governed
// by the Apache License, Version 2.0, included in the file
// licenses/APL.txt.

package main

import (
"context"

"github.com/cockroachdb/cockroach/pkg/util/log"
"github.com/cockroachdb/errors"
"github.com/spf13/cobra"
)

// buildCmd builds the specified binaries.
var buildCmd = &cobra.Command{
Use: "build <binary>",
Short: "Build the specified binaries",
Long: "Build the specified binaries.",
// TODO(irfansharif): Flesh out the example usage patterns.
Example: `
dev build cockroach --tags=deadlock
dev build cockroach-{short,oss}
dev build {opt,exec}gen`,
Args: cobra.MinimumNArgs(0),
RunE: runBuild,
}

var buildTargetMapping = map[string]string{
"cockroach": "@cockroach//pkg/cmd/cockroach",
"cockroach-oss": "@cockroach//pkg/cmd/cockroach-oss",
"cockroach-short": "@cockroach//pkg/cmd/cockroach-short",
"dev": "@cockroach//pkg/cmd/dev",
"docgen": "@cockroach//pkg/cmd/docgen",
"execgen": "@cockroach//pkg/sql/colexec/execgen/cmd/execgen",
"optgen": "@cockroach//pkg/sql/opt/optgen/cmd/optgen",
"optfmt": "@cockroach//pkg/sql/opt/optgen/cmd/optfmt",
"langgen": "@cockroach//pkg/sql/opt/optgen/cmd/langgen",
"roachprod": "@cockroach//pkg/cmd/roachprod",
"roachprod-stress": "@cockroach//pkg/cmd/roachprod-stress",
"workload": "@cockroach//pkg/cmd/workload",
"roachtest": "@cockroach//pkg/cmd/roachtest",
}

func runBuild(cmd *cobra.Command, targets []string) error {
ctx := context.Background()

if len(targets) == 0 {
// Default to building the cockroach binary.
targets = append(targets, "cockroach")
}

// TODO(irfansharif): Add grouping shorthands like "all" or "bins", etc.
// TODO(irfansharif): Extract built binaries out of the bazel sandbox.
// TODO(irfansharif): Make sure all the relevant binary targets are defined
// above, and in usage docs.

var args []string
args = append(args, "build")
args = append(args, "--color=yes")

for _, target := range targets {
buildTarget, ok := buildTargetMapping[target]
if !ok {
log.Errorf(ctx, "unrecognized target: %s", target)
return errors.Newf("unrecognized target")
}

args = append(args, buildTarget)
}
return execute(ctx, "bazel", args...)
}
79 changes: 79 additions & 0 deletions pkg/cmd/dev/generate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Copyright 2020 The Cockroach Authors.
//
// Use of this software is governed by the Business Source License
// included in the file licenses/BSL.txt.
//
// As of the Change Date specified in that file, in accordance with
// the Business Source License, use of this software will be governed
// by the Apache License, Version 2.0, included in the file
// licenses/APL.txt.

package main

import (
"context"

"github.com/cockroachdb/cockroach/pkg/util/log"
"github.com/cockroachdb/errors"
"github.com/spf13/cobra"
)

// generateCmd generates the specified files.
var generateCmd = &cobra.Command{
Use: "generate [target..]",
Aliases: []string{"gen"},
Short: `Generate the specified files`,
Long: `Generate the specified files.`,
Example: `
dev generate
dev generate bazel
dev generate protobuf
dev generate {exec,opt}gen`,
Args: cobra.MinimumNArgs(0),
// TODO(irfansharif): Errors but default just eaten up. Let's wrap these
// invocations in something that prints out the appropriate error log
// (especially considering we've SilenceErrors-ed things away).
RunE: runGenerate,
}

// TODO(irfansharif): Flesh out the remaining targets.
type generator func(ctx context.Context, cmd *cobra.Command) error

var generators = []generator{
generateBazel,
}

func runGenerate(cmd *cobra.Command, targets []string) error {
ctx := context.Background()

if len(targets) == 0 {
// Generate all targets.
for _, gen := range generators {
if err := gen(ctx, cmd); err != nil {
return err
}
}
return nil
}

for _, target := range targets {
var gen generator
switch target {
case "bazel":
gen = generateBazel
default:
log.Errorf(ctx, "unrecognized target: %s", target)
return errors.Newf("unrecognized target")
}

if err := gen(ctx, cmd); err != nil {
return err
}
}

return nil
}

func generateBazel(ctx context.Context, cmd *cobra.Command) error {
return execute(ctx, "bazel", "run", "@cockroach//:gazelle", "--color=yes")
}
32 changes: 32 additions & 0 deletions pkg/cmd/dev/lint.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright 2020 The Cockroach Authors.
//
// Use of this software is governed by the Business Source License
// included in the file licenses/BSL.txt.
//
// As of the Change Date specified in that file, in accordance with
// the Business Source License, use of this software will be governed
// by the Apache License, Version 2.0, included in the file
// licenses/APL.txt.

package main

import (
"github.com/cockroachdb/errors"
"github.com/spf13/cobra"
)

// lintCmd runs the specified linters.
var lintCmd = &cobra.Command{
Use: "lint",
Short: `Run the specified linters`,
Long: `Run the specified linters.`,
Example: `
dev lint --filter=TestLowercaseFunctionNames --short --timeout=1m`,
Args: cobra.NoArgs,
RunE: runLint,
}

func runLint(cmd *cobra.Command, args []string) error {
// TODO(irfansharif): Flesh out the example usage patterns.
return errors.New("unimplemented")
}
88 changes: 88 additions & 0 deletions pkg/cmd/dev/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// Copyright 2020 The Cockroach Authors.
//
// Use of this software is governed by the Business Source License
// included in the file licenses/BSL.txt.
//
// As of the Change Date specified in that file, in accordance with
// the Business Source License, use of this software will be governed
// by the Apache License, Version 2.0, included in the file
// licenses/APL.txt.

package main

import (
"context"
"os"
"os/exec"

"github.com/cockroachdb/cockroach/pkg/util/log"
"github.com/spf13/cobra"
)

var devCmd = &cobra.Command{
Use: "dev [command] (flags)",
Short: "Dev is the general-purpose dev tool for folks working on cockroachdb/cockroach.",
Version: "v0.0",
Long: `
Dev is the general-purpose dev tool for folks working cockroachdb/cockroach. It
lets engineers do a few things:
- build various binaries (cockroach, optgen, ...)
- run arbitrary tests (unit tests, logic tests, ...)
- run tests under arbitrary configurations (under stress, using race builds, ...)
- generate code (bazel files, protobufs, ...)
...and much more.
(PS: Almost none of the above is implemented yet, haha.)
`,
// Disable automatic printing of usage information whenever an error
// occurs. We presume that most errors will not the result of bad command
// invocation; they'll be due to legitimate build/test errors. Printing out
// the usage information in these cases obscures the real cause of the
// error. Commands should manually print usage information when the error
// is, in fact, a result of a bad invocation, e.g. too many arguments.
SilenceUsage: true,
// Disable automatic printing of the error. We want to also print
// details and hints, which cobra does not do for us. Instead
// we do the printing in the command implementation.
SilenceErrors: true,
}

var bazel = "bazel"

func init() {
devCmd.AddCommand(
benchCmd,
buildCmd,
generateCmd,
lintCmd,
testCmd,
)

// Hide the `help` sub-command.
devCmd.SetHelpCommand(&cobra.Command{
Use: "noop-help",
Hidden: true,
})
}

func runDev(ctx context.Context) error {
_, err := exec.LookPath(bazel)
if err != nil {
log.Errorf(ctx, "expected to find bazel in $PATH")
return err
}

if err := devCmd.Execute(); err != nil {
return err
}
return nil
}

func main() {
ctx := context.Background()
if err := runDev(ctx); err != nil {
os.Exit(1)
}
}
Loading

0 comments on commit b93fd53

Please sign in to comment.