protoflag

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 21, 2026 License: Apache-2.0 Imports: 11 Imported by: 0

README

protoflag

protoflag is a tiny Go library that can turn any Protocol Buffer message into a set of command‑line flags. It works both with the standard flag package and with the popular pflag package, handling nested fields, messages, lists and maps automatically.

Go Reference Go Report Card

Looking for a package that works similarly but on any Go type? Check jsonflag.

Adding to project

First, use go get to download and add the latest version of the library to the project.

go get -u github.com/daishe/protoflag

Then include in your source code.

import "github.com/daishe/protoflag"

Usage example (with standard go flag package)

package main

import (
	"flag"
	"fmt"
	"net"
	"net/http"
	"net/http/httputil"
	"net/url"
	"os"
	"strconv"

	"google.golang.org/protobuf/proto"
	"google.golang.org/protobuf/reflect/protoreflect"
	"google.golang.org/protobuf/types/descriptorpb"

	"github.com/daishe/protoflag"
	typesv1 "github.com/daishe/protoflag/examples/simplecurl/types/v1"
)

func main() {
	// config with default values
	config := typesv1.Config_builder{
		Url: typesv1.Url_builder{
			Scheme: "http",
			Host:   "localhost",
			Port:   8080,
		}.Build(),
	}.Build()

	usage := func(path []protoreflect.FieldDescriptor) string {
		opts, ok := path[len(path)-1].Options().(*descriptorpb.FieldOptions)
		if !ok || opts == nil {
			return ""
		}
		usage, ok := proto.GetExtension(opts, typesv1.E_Usage).(string)
		if !ok {
			return ""
		}
		return usage
	}

	fs := flag.NewFlagSet("", flag.ExitOnError) // you can also add it directly to the root flag set
	for _, val := range protoflag.Recursive(config) {
		fs.Var(val, protoflag.JSONName(val.Path()), usage(val.Path()))
	}
	if err := fs.Parse(os.Args[1:]); err != nil {
		fmt.Fprintf(os.Stderr, "Arguments parsing error: %v\n", err)
		os.Exit(1)
	}

	u := url.URL{
		Scheme: config.GetUrl().GetScheme(),
		Host:   net.JoinHostPort(config.GetUrl().GetHost(), strconv.FormatInt(int64(config.GetUrl().GetPort()), 10)),
		Path:   config.GetUrl().GetPath(),
	}

	resp, err := http.Get(u.String()) //nolint:noctx // this is just an example
	if err != nil {
		fmt.Fprintf(os.Stderr, "Doing request error: %v\n", err)
		os.Exit(1)
	}
	defer resp.Body.Close()

	if config.GetVerbose() {
		respBytes, err := httputil.DumpResponse(resp, true)
		if err != nil {
			fmt.Fprintf(os.Stderr, "Dumping response error: %v\n", err)
			os.Exit(1) //nolint:gocritic // this is just an example
		}
		fmt.Printf("%s\n", respBytes)
	}
}

License

The project is released under the Apache License, Version 2.0. See the full LICENSE file for the complete terms and conditions.

Documentation

Overview

Package protoflag is a tiny Go library that can turn any Protocol Buffer message into a set of command‑line flags.

Index

Constants

View Source
const (
	IncludeAndDescend = jsonflag.IncludeAndDescend // indicates that the given flag value should be included, and that recursive value retrieval should descend into sub-values
	IncludeNoDescend  = jsonflag.IncludeNoDescend  // indicates that the given flag value should be included, but that recursive value retrieval should NOT descend into sub-values
	SkipAndDescend    = jsonflag.SkipAndDescend    // indicates that the given flag value should be skipped, but that recursive value retrieval should descend into sub-values
	SkipNoDescend     = jsonflag.SkipNoDescend     // indicates that the given flag value should be skipped, and that recursive value retrieval should NOT descend into sub-values
)

Variables

This section is empty.

Functions

func JSONName

func JSONName(path []protoreflect.FieldDescriptor) string

JSONName creates a new flag name by joining all JSON names of fields along the provided path.

func Name

func Name(path []protoreflect.FieldDescriptor) string

Name creates a new flag name by joining all names of fields along the provided path.

func ShouldDescend

func ShouldDescend(r FilterResult) bool

ShouldDescend informs if the provided filter result indicates that the further recursive values finding should descend into sub-values.

func ShouldInclude

func ShouldInclude(r FilterResult) bool

ShouldInclude informs if the provided filter result indicates that the given flag value should be included.

func TextName

func TextName(path []protoreflect.FieldDescriptor) string

TextName creates a new flag name by joining all text names of fields along the provided path.

Types

type FilterFunc

type FilterFunc func(*Value) FilterResult

FilterFunc is a function that can be used to decide if a flag value should be included in recursive results as well as if flag values finding should descend into the sub-values.

type FilterResult

type FilterResult = jsonflag.FilterResult

FilterResult is a bit field holding filtering decision.

func Filter

func Filter(val *Value, filters ...FilterFunc) (r FilterResult)

Filter applies all filter function to the provided flag value and returns filtering decision.

type Value

type Value struct {
	// contains filtered or unexported fields
}

Value is a value of a flag for some proto message or its field.

func New

func New(base proto.Message) *Value

New returns new flag value for the provided proto message. It returns nil if the message cannot be used as flag value.

func Recursive

func Recursive(base proto.Message, filters ...FilterFunc) []*Value

Recursive returns set of flag values for the provided proto message and all fields within, recursively, according to the provided filters. Function silently skips all the fields that cannot be used as flag values.

func (*Value) EnumDescriptor

func (val *Value) EnumDescriptor() protoreflect.EnumDescriptor

EnumDescriptor returns enum descriptor of the enum associated with the provided value, or nil, if the value is not associated with an enum.

func (*Value) Get

func (val *Value) Get() any

Get returns current underlying value of the provided value. The actual data returned depends on underlying type associated with the value:

  • for scalars function returns their associated Go values directly,
  • for enums function returns enum number (protoreflect.EnumNumber type)
  • for messages function returns their values directly,
  • for lists of scalars function returns slices of their associated Go values,
  • for lists of enums function returns slices of enum numbers (protoreflect.EnumNumber type),
  • for lists of messages function returns slices of proto.Messages,
  • for maps of scalars function returns maps of their associated Go values,
  • for maps of enums function returns maps of enum numbers (protoreflect.EnumNumber type),
  • for maps of messages function returns maps of proto.Messages.

func (*Value) GetValue

func (val *Value) GetValue() protoreflect.Value

GetValue returns current underlying protoreflect value of the provided value.

func (*Value) IsBoolFlag

func (val *Value) IsBoolFlag() bool

IsBoolFlag informs if the underlying value is bool-like (bool field or repeated bool field).

func (*Value) IsList

func (val *Value) IsList() bool

IsList returns true of the type associated with the provided value is a list.

func (*Value) IsMap

func (val *Value) IsMap() bool

IsMap returns true of the type associated with the provided value is a map.

func (*Value) Kind

func (val *Value) Kind() protoreflect.Kind

Kind returns kind of the type described by the value.

func (*Value) MessageDescriptor

func (val *Value) MessageDescriptor() protoreflect.MessageDescriptor

MessageDescriptor returns message descriptor of the message associated with the provided value, or nil, if the value is not associated with a message.

func (*Value) MessageType

func (val *Value) MessageType() protoreflect.MessageType

MessageType returns message type of the message associated with the provided value, or nil, if the value is not associated with a message.

func (*Value) Path

func (val *Value) Path() []protoreflect.FieldDescriptor

Path returns list of field descriptor from the base message up to the field associated with the provided value. It returns empty list if the value is associated with the base message itself.

func (*Value) Set

func (val *Value) Set(to string) error

Set converts the provided string setting the underlying value.

func (*Value) SetDecoder

func (val *Value) SetDecoder(fn func([]byte, protoreflect.Message, protoreflect.FieldDescriptor) error)

SetDecoder allows setting custom decoder of the underlying value.

func (*Value) SetEncoder

func (val *Value) SetEncoder(fn func(protoreflect.Value) ([]byte, error))

SetEncoder allows setting custom encoder of the underlying value.

func (*Value) String

func (val *Value) String() string

String returns string representation of the underlying value.

func (*Value) Type

func (val *Value) Type() string

Type returns type name that should be displayed when using the provided value as a flag.

Directories

Path Synopsis
internal

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL