Skip to content

Commit

Permalink
Merge pull request #26 from grafana/redefine-cli-commands
Browse files Browse the repository at this point in the history
Redefine cli commands
  • Loading branch information
pablochacin authored Aug 27, 2024
2 parents 777ef8e + a673868 commit e95d61b
Show file tree
Hide file tree
Showing 5 changed files with 162 additions and 141 deletions.
133 changes: 63 additions & 70 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ Build k6 using one of the supported builders.
## Commands

* [k6build cache](#k6build-cache) - k6 cache server
* [k6build client](#k6build-client) - build k6 using a remote build server
* [k6build local](#k6build-local) - build using a local builder
* [k6build local](#k6build-local) - build custom k6 binary locally
* [k6build remote](#k6build-remote) - build a custom k6 using a remote build server
* [k6build server](#k6build-server) - k6 build service

---
Expand Down Expand Up @@ -72,141 +72,134 @@ curl http://external.url:9000/cache/objectID/download
* [k6build](#k6build) - Build k6 with various builders.

---
# k6build client
# k6build local

build k6 using a remote build server
build custom k6 binary locally

## Synopsis


k6build client connects to a remote build server
k6build local builder creates a custom k6 binary artifacts that satisfies certain
dependencies. Requires the golang toolchain and git.


```
k6build client [flags]
k6build local [flags]
```

## Examples

```
# build k6 v0.51.0 with latest version of k6/x/kubernetes
k6build local -k v0.51.0 -d k6/x/kubernetes
platform: linux/amd64
k6: v0.51.0
k6/x/kubernetes: v0.9.0
checksum: 7f06720503c80153816b4ef9f58571c2fce620e0447fba1bb092188ff87e322d
# build k6 v0.51.0 with k6/x/kubernetes v0.8.0 and k6/x/output-kafka v0.7.0
k6build client -s http://localhost:8000 \
-k v0.51.0 \
-p linux/amd64
k6build local -k v0.51.0 \
-d k6/x/kubernetes:v0.8.0 \
-d k6/x/output-kafka:v0.7.0
{
"id": "62d08b13fdef171435e2c6874eaad0bb35f2f9c7",
"url": "http://localhost:8000/cache/62d08b13fdef171435e2c6874eaad0bb35f2f9c7/download",
"dependencies": {
"k6": "v0.51.0",
"k6/x/kubernetes": "v0.9.0",
"k6/x/output-kafka": "v0.7.0"
},
"platform": "linux/amd64",
"checksum": "f4af178bb2e29862c0fc7d481076c9ba4468572903480fe9d6c999fea75f3793"
}
# build k6 v0.51 with k6/x/output-kafka v0.7.0 and download to 'build/k6'
k6build client -s http://localhost:8000
-p linux/amd64
-k v0.51.0 -d k6/x/output-kafka:v0.7.0
-o build/k6 -q
# check binary
build/k6 version
k6 v0.51.0 (go1.22.2, linux/amd64)
Extensions:
github.com/grafana/xk6-output-kafka v0.7.0, xk6-kafka [output]
platform: linux/amd64
k6: v0.51.0
k6/x/kubernetes: v0.8.0
k6/x/output-kafka": v0.7.0
checksum: f4af178bb2e29862c0fc7d481076c9ba4468572903480fe9d6c999fea75f3793
# build k6 v0.50.0 with latest version of k6/x/kubernetes using a custom catalog
k6build local -k v0.50.0 -d k6/x/kubernetes \
-c /path/to/catalog.json -q
# build latest version of k6 with a version of k6/x/kubernetes greater than v0.8.0
k6build client -s http://localhost:8000 \
-p linux/amd64 \
-k v0.50.0 -d 'k6/x/kubernetes:>v0.8.0'
{
"id": "18035a12975b262430b55988ffe053098d020034",
"url": "http://localhost:8000/cache/18035a12975b262430b55988ffe053098d020034/download",
"dependencies": {
"k6": "v0.50.0",
"k6/x/kubernetes": "v0.9.0"
},
"platform": "linux/amd64",
"checksum": "255e5d62852af5e4109a0ac6f5818936a91c986919d12d8437e97fb96919847b"
}
# build k6 v0.50.0 using a custom GOPROXY
k6build local -k v0.50.0 -e GOPROXY=http://localhost:80 -q
```

## Flags

```
-f, --cache-dir string cache dir (default "/tmp/buildservice")
-c, --catalog string dependencies catalog (default "catalog.json")
-g, --copy-go-env copy go environment (default true)
-d, --dependency stringArray list of dependencies in form package:constrains
-h, --help help for client
-e, --env stringToString build environment variables (default [])
-h, --help help for local
-k, --k6 string k6 version constrains (default "*")
-o, --output string path to download the artifact as an executable. If not specified, the artifact is not downloaded.
-o, --output string path to put the binary as an executable. (default "k6")
-p, --platform string target platform (default GOOS/GOARCH)
-q, --quiet don't print artifact's details
-s, --server string url for build server (default "http://localhost:8000")
-v, --verbose print build process output
```

## SEE ALSO

* [k6build](#k6build) - Build k6 with various builders.

---
# k6build local
# k6build remote

build using a local builder
build a custom k6 using a remote build server

## Synopsis


k6build local builder returns artifacts that satisfies certain dependencies
Builds custom k6 binaries using a k6build server returning the details of the
binary artifact and optionally download it.


```
k6build local [flags]
k6build remote [flags]
```

## Examples

```
# build k6 v0.50.0 with latest version of k6/x/kubernetes
k6build local -k v0.50.0 -d k6/x/kubernetes
# build k6 v0.51.0 with k6/x/kubernetes v0.8.0 and k6/x/output-kafka v0.7.0
k6build local -k v0.51.0 \
k6build remote -s http://localhost:8000 \
-k v0.51.0 \
-p linux/amd64 \
-d k6/x/kubernetes:v0.8.0 \
-d k6/x/output-kafka:v0.7.0
# build latest version of k6 with a version of k6/x/kubernetes greater than v0.8.0
k6build local -k v0.50.0 -d 'k6/x/kubernetes:>v0.8.0'
id: 62d08b13fdef171435e2c6874eaad0bb35f2f9c7
platform: linux/amd64
k6: v0.51.0
k6/x/kubernetes: v0.9.0
k6/x/output-kafka": v0.7.0
checksum: f4af178bb2e29862c0fc7d481076c9ba4468572903480fe9d6c999fea75f3793
url: http://localhost:8000/cache/62d08b13fdef171435e2c6874eaad0bb35f2f9c7/download
# build k6 v0.50.0 with latest version of k6/x/kubernetes using a custom catalog
k6build local -k v0.50.0 -d k6/x/kubernetes \
-c /path/to/catalog.json
# build k6 v0.50.0 using a custom GOPROXY
k6build local -k v0.50.0 -e GOPROXY=http://localhost:80
# build k6 v0.51 with k6/x/output-kafka v0.7.0 and download as 'build/k6'
k6build remote -s http://localhost:8000 \
-p linux/amd64 \
-k v0.51.0 -d k6/x/output-kafka:v0.7.0 \
-o build/k6 -q
# check downloaded binary
build/k6 version
k6 v0.51.0 (go1.22.2, linux/amd64)
Extensions:
github.com/grafana/xk6-output-kafka v0.7.0, xk6-kafka [output]
```

## Flags

```
-f, --cache-dir string cache dir (default "/tmp/buildservice")
-c, --catalog string dependencies catalog (default "catalog.json")
-g, --copy-go-env copy go environment (default true)
-d, --dependency stringArray list of dependencies in form package:constrains
-e, --env stringToString build environment variables (default [])
-h, --help help for local
-h, --help help for remote
-k, --k6 string k6 version constrains (default "*")
-o, --output string path to download the custom binary as an executable. If not specified, the artifact is not downloaded.
-p, --platform string target platform (default GOOS/GOARCH)
-v, --verbose print build process output
-q, --quiet don't print artifact's details
-s, --server string url for build server (default "http://localhost:8000")
```

## SEE ALSO
Expand Down
29 changes: 24 additions & 5 deletions build.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,33 @@ type Artifact struct {

// String returns a text serialization of the Artifact
func (a Artifact) String() string {
return a.toString(true, " ")
}

// Print returns a string with a pretty print of the artifact
func (a Artifact) Print() string {
return a.toString(true, "\n")
}

// PrintSummary returns a string with a pretty print of the artifact
func (a Artifact) PrintSummary() string {
return a.toString(false, "\n")
}

// Print returns a text serialization of the Artifact
func (a Artifact) toString(details bool, sep string) string {
buffer := &bytes.Buffer{}
buffer.WriteString(fmt.Sprintf(" id: %s", a.ID))
buffer.WriteString(fmt.Sprintf("platform: %s", a.Platform))
if details {
buffer.WriteString(fmt.Sprintf("id: %s%s", a.ID, sep))
}
buffer.WriteString(fmt.Sprintf("platform: %s%s", a.Platform, sep))
for dep, version := range a.Dependencies {
buffer.WriteString(fmt.Sprintf(" %s:%q", dep, version))
buffer.WriteString(fmt.Sprintf("%s:%q%s", dep, version, sep))
}
buffer.WriteString(fmt.Sprintf("checksum: %s%s", a.Checksum, sep))
if details {
buffer.WriteString(fmt.Sprintf("url: %s%s", a.URL, sep))
}
buffer.WriteString(fmt.Sprintf(" checksum: %s", a.Checksum))
buffer.WriteString(fmt.Sprintf(" url: %s", a.URL))
return buffer.String()
}

Expand Down
4 changes: 2 additions & 2 deletions cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import (
"github.com/spf13/cobra"

"github.com/grafana/k6build/cmd/cache"
"github.com/grafana/k6build/cmd/client"
"github.com/grafana/k6build/cmd/local"
"github.com/grafana/k6build/cmd/remote"
"github.com/grafana/k6build/cmd/server"
)

Expand All @@ -23,7 +23,7 @@ func New() *cobra.Command {
}

root.AddCommand(cache.New())
root.AddCommand(client.New())
root.AddCommand(remote.New())
root.AddCommand(local.New())
root.AddCommand(server.New())

Expand Down
64 changes: 49 additions & 15 deletions cmd/local/local.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
package local

import (
"encoding/json"
"errors"
"fmt"
"io"
"net/url"
"os"
"strings"

Expand All @@ -18,42 +19,54 @@ var ErrTargetPlatformUndefined = errors.New("target platform is required") //nol

const (
long = `
k6build local builder returns artifacts that satisfies certain dependencies
k6build local builder creates a custom k6 binary artifacts that satisfies certain
dependencies. Requires the golang toolchain and git.
`

example = `
# build k6 v0.50.0 with latest version of k6/x/kubernetes
k6build local -k v0.50.0 -d k6/x/kubernetes
# build k6 v0.51.0 with latest version of k6/x/kubernetes
k6build local -k v0.51.0 -d k6/x/kubernetes
platform: linux/amd64
k6: v0.51.0
k6/x/kubernetes: v0.9.0
checksum: 7f06720503c80153816b4ef9f58571c2fce620e0447fba1bb092188ff87e322d
# build k6 v0.51.0 with k6/x/kubernetes v0.8.0 and k6/x/output-kafka v0.7.0
k6build local -k v0.51.0 \
-d k6/x/kubernetes:v0.8.0 \
-d k6/x/output-kafka:v0.7.0
# build latest version of k6 with a version of k6/x/kubernetes greater than v0.8.0
k6build local -k v0.50.0 -d 'k6/x/kubernetes:>v0.8.0'
platform: linux/amd64
k6: v0.51.0
k6/x/kubernetes: v0.8.0
k6/x/output-kafka": v0.7.0
checksum: f4af178bb2e29862c0fc7d481076c9ba4468572903480fe9d6c999fea75f3793
# build k6 v0.50.0 with latest version of k6/x/kubernetes using a custom catalog
k6build local -k v0.50.0 -d k6/x/kubernetes \
-c /path/to/catalog.json
-c /path/to/catalog.json -q
# build k6 v0.50.0 using a custom GOPROXY
k6build local -k v0.50.0 -e GOPROXY=http://localhost:80
k6build local -k v0.50.0 -e GOPROXY=http://localhost:80 -q
`
)

// New creates new cobra command for local build command.
func New() *cobra.Command {
func New() *cobra.Command { //nolint:funlen
var (
config local.BuildServiceConfig
deps []string
k6 string
output string
platform string
config local.BuildServiceConfig
quiet bool
)

cmd := &cobra.Command{
Use: "local",
Short: "build using a local builder",
Short: "build custom k6 binary locally",
Long: long,
Example: example,
// prevent the usage help to printed to stderr when an error is reported by a subcommand
Expand All @@ -80,11 +93,30 @@ func New() *cobra.Command {
return fmt.Errorf("building %w", err)
}

encoder := json.NewEncoder(os.Stdout)
encoder.SetIndent("", " ")
err = encoder.Encode(artifact)
if !quiet {
fmt.Println(artifact.PrintSummary())
}

binaryURL, err := url.Parse(artifact.URL)
if err != nil {
return fmt.Errorf("malformed URL %w", err)
}
artifactBinary, err := os.Open(binaryURL.Path)
if err != nil {
return fmt.Errorf("opening output file %w", err)
}
defer func() {
_ = artifactBinary.Close()
}()

binary, err := os.OpenFile(output, os.O_WRONLY|os.O_CREATE, 0o755) //nolint:gosec
if err != nil {
return fmt.Errorf("opening output file %w", err)
}

_, err = io.Copy(binary, artifactBinary)
if err != nil {
return fmt.Errorf("processing object %w", err)
return fmt.Errorf("copying artifact %w", err)
}

return nil
Expand All @@ -100,6 +132,8 @@ func New() *cobra.Command {
cmd.Flags().BoolVarP(&config.Verbose, "verbose", "v", false, "print build process output")
cmd.Flags().BoolVarP(&config.CopyGoEnv, "copy-go-env", "g", true, "copy go environment")
cmd.Flags().StringToStringVarP(&config.BuildEnv, "env", "e", nil, "build environment variables")
cmd.Flags().StringVarP(&output, "output", "o", "k6", "path to put the binary as an executable.")
cmd.Flags().BoolVarP(&quiet, "quiet", "q", false, "don't print artifact's details")

return cmd
}
Loading

0 comments on commit e95d61b

Please sign in to comment.