tempura

package module
v0.0.2 Latest Latest
Warning

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

Go to latest
Published: Jun 10, 2024 License: MIT Imports: 4 Imported by: 0

README

go-tempura

🍤 ebi の天ぷら、あるいは Go の template を使いやすくする仲間たち

en: Go template utilities

Installation

go get github.com/ebi-yade/go-tempura

Usage 1: tempura.MultiLookup

template.FuncMap の値として代入可能な以下のユーティリティを FuncMapValue メソッドとして提供します。

  1. テンプレート側の記述で引数に指定された string の列を受け取ります。
  2. Prefix に応じたコールバックを呼び出し、同期または非同期で値を探索します。
  3. 一番最初のキーで見つかった(関数が返す bool が true になった)値を返します。

論よりコード:

package main

import (
	"fmt"
	"log"
	"os"
	"os/signal"
	"text/template"

	tempura "github.com/ebi-yade/go-tempura"
)

const configYAML = `# This is just an example: please load a file via embed/os package
db_user: {{ param "env/DB_USER" "env/MYSQL_USER" "default/root" }}
db_pass: {{ secret "manager.DB_PASS" "sops.DB_PASS" "default.p@ssword!" }}
`

func main() {
	ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
	defer stop()

	lookupParams := tempura.MultiLookup{
		tempura.SlashPrefix("env"):     tempura.Func(getNonEmptyEnv),
		tempura.SlashPrefix("default"): tempura.Func(getKeyAsValue),
	}
	if err := lookupParams.Validate(); err != nil {
		log.Fatalf("failed to validate lookupParams: %+v", err)
	}

	lookupSecrets := tempura.MultiLookup{
		tempura.DotPrefix("manager"): tempura.FuncWithContextError(fetchCloudSecret),
		tempura.DotPrefix("sops"):    tempura.FuncWithError(getSopsSecret),
		tempura.DotPrefix("default"): tempura.Func(getKeyAsValue),
	}.BindContext(ctx) // DO NOT FORGET TO USE context.Context
	if err := lookupSecrets.Validate(); err != nil {
		log.Fatalf("failed to validate lookupSecrets: %+v", err)
	}

	tpl := template.Must(
		template.New("").Funcs(template.FuncMap{
			"param":  lookupParams.FuncMapValue,
			"secret": lookupSecrets.FuncMapValue,
		}).Parse(configYAML),
	)

	if err := tpl.Execute(os.Stdout, nil); err != nil {
		log.Fatalf("failed to execute template: %+v", err)
	}
}

// ======================================================================
// IMPORTANT NOTE:
//   探索関数が第二返り値で true を返すと、値が見つかったことを意味します。
//   そのため、第一返り値が "" などのゼロ値であっても、tempura はそれを採用します。
// ======================================================================

func getNonEmptyEnv(key string) (string, bool) {
	val := os.Getenv(key)
	if val == "" {
		return "", false
	}
	return val, true
}

func getKeyAsValue(key string) (string, bool) {
	return key, true
}

func fetchCloudSecret(ctx context.Context, key string) (string, bool, error) {
	return "", false, fmt.Errorf("not implemented")
}

func getSopsSecret(key string) (string, bool, error) {
	return "", false, fmt.Errorf("not implemented")
}

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrContextUntypedNil = fmt.Errorf("context.Context is untyped nil")
View Source
var ErrMatchFailed = fmt.Errorf("failed to match between args and prefixes")
View Source
var ErrNoFunctionRegistered = fmt.Errorf("no function registered")
View Source
var ErrNotFound = fmt.Errorf("not found: none of the lookup functions returned true as the second return value")

Functions

This section is empty.

Types

type DotPrefix

type DotPrefix string

func (DotPrefix) Match

func (p DotPrefix) Match(s string) bool

func (DotPrefix) Strip

func (p DotPrefix) Strip(s string) string

type InvalidFunctionError

type InvalidFunctionError struct {
	Type   string
	Prefix Prefix
	Func   any
}

func (InvalidFunctionError) Error

func (e InvalidFunctionError) Error() string

type LookupAny

type LookupAny func(val string) (any, bool)

func Func

func Func[R any](fn func(val string) (R, bool)) LookupAny

type LookupAnyWithContext

type LookupAnyWithContext func(ctx context.Context, val string) (any, bool)

func FuncWithContext

func FuncWithContext[R any](fn func(ctx context.Context, val string) (R, bool)) LookupAnyWithContext

type LookupAnyWithContextError

type LookupAnyWithContextError func(ctx context.Context, val string) (any, bool, error)

func FuncWithContextError

func FuncWithContextError[R any](fn func(ctx context.Context, val string) (R, bool, error)) LookupAnyWithContextError

type LookupAnyWithError

type LookupAnyWithError func(val string) (any, bool, error)

func FuncWithError

func FuncWithError[R any](fn func(val string) (R, bool, error)) LookupAnyWithError

type LookupFunc

type LookupFunc interface {
	// contains filtered or unexported methods
}

LookupFunc は、MultiLookup に登録する個々関数で、prefixを取り除いたキーを文字列として受け取って何かしらの値を返す必要があります。 LookupFunc インタフェースを満たすには、 tempura.FuncXXXX 経由で LookupAnyXXXX 型を生成することが推奨されます。 tempura.FuncXXXX で登場するジェネリック型制約はanyですが、 template パッケージが処理できない型を利用すると実行時エラーになる可能性があります。

LookupFunc represents individual functions registered in MultiLookup, which receive the key as a string, with the prefix removed, and return some value. It is recommended to generate a LookupAnyXXXX type through tempura.FuncXXXX to satisfy the LookupFunc interface. The generic type constraint in tempura.FuncXXXX is 'any', but using types that the template package cannot process might result in runtime errors.

type MultiLookup

type MultiLookup map[Prefix]LookupFunc

MultiLookup は、1つまたは複数の文字列を引数として受け取るアクションにおいて、引数のプレフィックスに応じて異なる探索関数を実行するための機構です。 ただし context.Context を受け取る関数も利用する場合は、 BindContext(ctx) を呼び出して MultiLookupContext を生成する必要があります。

MultiLookup is a mechanism for executing different lookup functions depending on the prefix of the arguments in actions that take one or more strings as arguments. NOTE: If you want to use a function that takes context.Context, you need to call BindContext(ctx) to generate MultiLookupContext.

func (MultiLookup) BindContext

func (m MultiLookup) BindContext(ctx context.Context) *MultiLookupContext

func (MultiLookup) FuncMapValue

func (m MultiLookup) FuncMapValue(args ...string) (any, error)

func (MultiLookup) Validate

func (m MultiLookup) Validate() error

type MultiLookupContext

type MultiLookupContext struct {
	MultiLookup MultiLookup
	Ctx         context.Context
}

MultiLookupContext は context.Context を受け取る関数を利用できる MultiLookup です。 BindContext(ctx) を呼び出して生成してください。

MultiLookupContext is a MultiLookup that can use functions that accept context.Context. Generate it by calling BindContext(ctx).

func (*MultiLookupContext) FuncMapValue

func (m *MultiLookupContext) FuncMapValue(args ...string) (any, error)

func (*MultiLookupContext) Validate

func (m *MultiLookupContext) Validate() error

type Prefix

type Prefix interface {
	Match(string) bool
	Strip(string) string
}

type SlashPrefix

type SlashPrefix string

func (SlashPrefix) Match

func (p SlashPrefix) Match(s string) bool

func (SlashPrefix) Strip

func (p SlashPrefix) Strip(s string) string

Jump to

Keyboard shortcuts

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