Files
zeta-reconstructor/internal/registry/registry.go
T

68 lines
1.7 KiB
Go

// Package registry provides a global registry of package-format frontends.
//
// Frontends self-register via init() from their own packages, so a future
// format (e.g. Gentoo ebuild, void-src) only needs a new package that imports
// this one — nothing else changes.
package registry
import (
"fmt"
"sort"
"sync"
)
// Options carries per-conversion settings shared by all frontends.
type Options struct {
Output string // directory to write converted output into
Repo string // repository base URL (binary frontend)
Arch string // target architecture (source frontend)
}
// Frontend converts one input of a specific package format to Zeta.
type Frontend interface {
// Name returns the frontend's CLI subcommand name.
Name() string
// Convert converts input into Zeta format under opts.Output.
Convert(input string, opts Options) error
}
var (
mu sync.RWMutex
frontends = make(map[string]Frontend)
)
// Register adds f to the global registry. It panics if a frontend with the
// same Name is already registered.
func Register(f Frontend) {
mu.Lock()
defer mu.Unlock()
name := f.Name()
if name == "" {
panic("registry: frontend with empty name")
}
if _, dup := frontends[name]; dup {
panic(fmt.Sprintf("registry: duplicate frontend %q", name))
}
frontends[name] = f
}
// List returns the names of all registered frontends, sorted.
func List() []string {
mu.RLock()
defer mu.RUnlock()
names := make([]string, 0, len(frontends))
for name := range frontends {
names = append(names, name)
}
sort.Strings(names)
return names
}
// Get returns the frontend registered under name.
func Get(name string) (Frontend, bool) {
mu.RLock()
defer mu.RUnlock()
f, ok := frontends[name]
return f, ok
}