Giter VIP home page Giter VIP logo

gophercon-cli's Introduction

gophercon-cli

If you encounter any issues through this tutorial, you can see the add-joker branch for an implementation

1. Create initial functionality

  1. Initialize go.mod: go mod init github.com/dfreilich/gophercon-cli
  2. Create a cmd directory: mkdir -p cmd/
  3. Get cobra: go get github.com/spf13/cobra
  4. Create a file in the cmd/ directory with the contents:
func NewJokerCmd() *cobra.Command {
	return &cobra.Command{
		Use:     "joker",
		Aliases: []string{"joke"},
		Short:   "This returns GPT3 Dad jokes!",
		Version: "0.0.1",
		RunE: func(cmd *cobra.Command, args []string) error {
			fmt.Println("Hello Gophercon!")
			return nil
		},
	}
}
  1. Initialize the main.go file to run the command:
func main() {
	root := cmd.NewJokerCmd()
	if err := root.Execute(); err != nil {
		_, _ = fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
}
  1. Create a Makefile with the contents:
GOCMD?=go
NAME?=joker

build:
	$(GOCMD) build -o $(NAME)

test:
	$(GOCMD) test ./... -v

run:
	$(GOCMD) run ./...

.PHONY: build test run
  1. Write initial test in root_test.go:
func TestNewJokerCmd(t *testing.T) {
	cmd := NewJokerCmd()
	buf := &bytes.Buffer{}
	cmd.SetOut(buf)
	err := cmd.Execute()
	require.NoError(t, err)
	require.NotEmpty(t, buf.String())
}

2. Sprinkle Some AI

  1. Get library for GPT3: go get github.com/sashabaranov/go-gpt3
  2. Make API Key here and set it as an environment variable export OPEN_AI_KEY=MY_KEY
  3. Use GPT3 in root.go:
// Note: For this, you need to make an API KEY at https://beta.openai.com/account/api-keys
c := gogpt.NewClient(os.Getenv("OPEN_AI_KEY"))
ctx := context.Background()

req := gogpt.CompletionRequest{
    Model:            gogpt.GPT3TextDavinci003,
    MaxTokens:        maxTokens,
    Temperature:      1,
    Prompt:           "Tell me a corny dad joke",
    TopP:             1,
    FrequencyPenalty: 1,
    PresencePenalty:  1,
}
resp, err := c.CreateCompletion(ctx, req)
if err != nil {
    return err
}

3. Add Some Style

  1. Get a nice rendering library: go get github.com/charmbracelet/lipgloss
  2. Make the output ✨ fabulous ✨ :
style := lipgloss.NewStyle().
    Bold(true).
    BorderStyle(lipgloss.RoundedBorder()).
    BorderForeground(lipgloss.Color("12")). // Light Blue
    Foreground(lipgloss.Color("5")) // Magenta

fmt.Println(style.Render(strings.TrimSpace(resp.Choices[0].Text)))

4. Add Mocking/Interface

  1. Go get assertion library: go get github.com/stretchr/testify/require
  2. Install mockgen : go install github.com/golang/mock/[email protected] and go get github.com/golang/mock/mockgen/model
  3. Create the interface and annotations:
//go:generate mockgen -package mocks -destination ../test/mocks/mock_asker.go github.com/dfreilich/gophercon-cli/cmd Asker
type Asker interface {
	CreateCompletion(ctx context.Context, request gogpt.CompletionRequest) (response gogpt.CompletionResponse, err error)
}
  1. Change the Command to use it:
func NewJokerCmd(asker Asker) *cobra.Command {
...
    resp, err := asker.CreateCompletion(ctx, req)
  1. Change the main to se it:
	c := gogpt.NewClient(os.Getenv("OPEN_AI_KEY"))
	root := cmd.NewJokerCmd(c)
  1. Change the test to use it:
func TestNewJokerCmd(t *testing.T) {
	ctrl := gomock.NewController(t)
	testActor := mocks.NewMockAsker(ctrl)
	cmd := NewJokerCmd(testActor)
	testActor.EXPECT().CreateCompletion(gomock.Any(), gomock.Any()).Return(gogpt.CompletionResponse{
		Choices: []gogpt.CompletionChoice{{Text: "Some funny joke!"}},
	}, nil)
	buf := &bytes.Buffer{}
	cmd.SetOut(buf)
	err := cmd.Execute()
	require.NoError(t, err)
	require.NotEmpty(t, buf.String())
	require.Contains(t, buf.String(), "Some funny joke!")
}

5. Run

asciicast

6. Next Steps

For more, check out the Cobra documentation here, and look at how some major CLIs are using it.

One project you can check out is the Cloud Native Buildpacks pack CLI. You can see how they generate the Root Command here, define subcommands here, and create an interface of their client here

gophercon-cli's People

Contributors

dfreilich avatar

Stargazers

 avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.