entry, lang: core: embedded: provisioner: Allow more than one entry
This changes the entry API slightly to allow for more than one entry registered, which makes building, testing and user tooling easier.
This commit is contained in:
@@ -45,27 +45,27 @@ import (
|
|||||||
"github.com/alexflint/go-arg"
|
"github.com/alexflint/go-arg"
|
||||||
)
|
)
|
||||||
|
|
||||||
// registeredData is the single "registered" entry point that we built with. You
|
// registeredData is the map of "registered" entry points that we built with.
|
||||||
// cannot have more than one currently.
|
// You can have more than one registered. Each will appear under the top-level
|
||||||
// TODO: In the future we could have more than one registered and each could
|
// binary name as a subcommand.
|
||||||
// appear under a top-level "embedded" subcommand if we decided not to have a
|
var registeredData = make(map[string]*Data) // must initialize
|
||||||
// "default" singleton registered.
|
|
||||||
var registeredData *Data
|
|
||||||
|
|
||||||
// Register takes input data and stores it for lookup by the top-level main
|
// Register takes a data struct and stores a reference to it in our entry system
|
||||||
// function. Register is commonly called in the init() method of the module that
|
// along with a name. Future lookups to that name will pull out that data.
|
||||||
// defined it, which happens at program startup. Build flags should be used to
|
// Register is commonly called in the init() method of the module that defined
|
||||||
// determine which Register gets to run. Only one entry can be registered at a
|
// it, which happens at program startup. Build flags should be used to determine
|
||||||
// time. There is no matching Unregister function at this time.
|
// which Register functions should run. Multiple entry data struct can be
|
||||||
func Register(data *Data) {
|
// registered at a time. There is no matching Unregister function at this time.
|
||||||
if registeredData != nil {
|
func Register(name string, data *Data) {
|
||||||
panic("an entry is already registered")
|
if _, exists := registeredData[name]; exists {
|
||||||
|
panic(fmt.Sprintf("an entry named %s is already registered", name))
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := data.Validate(); err != nil {
|
if err := data.Validate(); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
registeredData = data
|
registeredData[name] = data
|
||||||
}
|
}
|
||||||
|
|
||||||
// Data is what a prospective standalone entry program must specify to our API.
|
// Data is what a prospective standalone entry program must specify to our API.
|
||||||
@@ -128,15 +128,21 @@ func (obj *Data) Validate() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lookup returns the runner that implements the complex plumbing to kick off
|
// Lookup takes a name and returns the runner that implements the complex
|
||||||
// the run. If one has not been registered, then this will error.
|
// plumbing to kick off the run. If one has not been registered under that name,
|
||||||
func Lookup() (*Runner, error) {
|
// then this will error.
|
||||||
if registeredData == nil {
|
func Lookup(name string) (*Runner, error) {
|
||||||
return nil, fmt.Errorf("could not find a registered entry")
|
data, exists := registeredData[name]
|
||||||
|
if !exists {
|
||||||
|
return nil, fmt.Errorf("could not lookup entry named: %s", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
if data == nil {
|
||||||
|
return nil, fmt.Errorf("registered entry data was nil")
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Runner{
|
return &Runner{
|
||||||
data: registeredData, // *Data
|
data: data, // *Data
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
// additional permission if he deems it necessary to achieve the goals of this
|
// additional permission if he deems it necessary to achieve the goals of this
|
||||||
// additional permission.
|
// additional permission.
|
||||||
|
|
||||||
//go:build embedded_provisioner
|
//go:build !noembedded_provisioner
|
||||||
|
|
||||||
package coreembedded
|
package coreembedded
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
// additional permission if he deems it necessary to achieve the goals of this
|
// additional permission if he deems it necessary to achieve the goals of this
|
||||||
// additional permission.
|
// additional permission.
|
||||||
|
|
||||||
//go:build embedded_provisioner
|
//go:build !noembedded_provisioner
|
||||||
|
|
||||||
package coreprovisioner
|
package coreprovisioner
|
||||||
|
|
||||||
@@ -434,7 +434,7 @@ func init() {
|
|||||||
localArgs: a.(*localArgs), // force the correct type
|
localArgs: a.(*localArgs), // force the correct type
|
||||||
}
|
}
|
||||||
|
|
||||||
entry.Register(&entry.Data{
|
entry.Register(ModuleName, &entry.Data{
|
||||||
Program: ModuleName,
|
Program: ModuleName,
|
||||||
Version: Version, // TODO: get from git?
|
Version: Version, // TODO: get from git?
|
||||||
|
|
||||||
|
|||||||
6
main.go
6
main.go
@@ -91,8 +91,12 @@ func main() {
|
|||||||
Args: os.Args,
|
Args: os.Args,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
name := ""
|
||||||
|
if len(data.Args) > 1 {
|
||||||
|
name = data.Args[1]
|
||||||
|
}
|
||||||
// is there an alternate entry point for the cli?
|
// is there an alternate entry point for the cli?
|
||||||
if cli, err := entry.Lookup(); err == nil && len(data.Args) > 1 && cli.Name() == data.Args[1] {
|
if cli, err := entry.Lookup(name); err == nil && cli.Name() == name {
|
||||||
data.Args = data.Args[1:] // pop off "argv[0]"
|
data.Args = data.Args[1:] // pop off "argv[0]"
|
||||||
if err := cli.CLI(context.Background(), data); err != nil {
|
if err := cli.CLI(context.Background(), data); err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
|
|||||||
Reference in New Issue
Block a user