server: consolidate files
This commit is contained in:
parent
609ea0d0f0
commit
9fbbdbbe0f
|
@ -1,70 +0,0 @@
|
||||||
# Basecoin
|
|
||||||
|
|
||||||
This is the "Basecoin" example application built on the Cosmos-Sdk. This
|
|
||||||
"Basecoin" is not affiliated with [Coinbase](http://www.getbasecoin.com/), nor
|
|
||||||
the [stable coin](http://www.getbasecoin.com/).
|
|
||||||
|
|
||||||
Assuming you've run `make get_tools && make get_vendor_deps` from the root of
|
|
||||||
this repository, run `make build` here to build the `basecoind` and `basecli`
|
|
||||||
binaries.
|
|
||||||
|
|
||||||
If you want to create a new application, start by copying the Basecoin app.
|
|
||||||
|
|
||||||
|
|
||||||
# Building your own Blockchain
|
|
||||||
|
|
||||||
Basecoin is the equivalent of an ERC20 token contract for blockchains. In order
|
|
||||||
to deploy your own application all you need to do is clone `examples/basecoin`
|
|
||||||
and run it. Now you are already running your own blockchain. In the following
|
|
||||||
I will explain how to add functionality to your blockchain. This is akin to
|
|
||||||
defining your own vesting schedule within a contract or setting a specific
|
|
||||||
multisig. You are just extending the base layer with extra functionality here
|
|
||||||
and there.
|
|
||||||
|
|
||||||
## Structure of Basecoin
|
|
||||||
|
|
||||||
Basecoin is build with the cosmos-sdk. It is a sample application that works
|
|
||||||
with any engine that implements the ABCI protocol. Basecoin defines multiple
|
|
||||||
unique modules as well as uses modules directly from the sdk. If you want
|
|
||||||
to modify Basecoin, you either remove or add modules according to your wishes.
|
|
||||||
|
|
||||||
|
|
||||||
## Modules
|
|
||||||
|
|
||||||
A module is a fundamental unit in the cosmos-sdk. A module defines its own
|
|
||||||
transaction, handles its own state as well as its own state transition logic.
|
|
||||||
Globally, in the `app/app.go` file you just have to define a key for that
|
|
||||||
module to access some parts of the state, as well as initialise the module
|
|
||||||
object and finally add it to the transaction router. The router ensures that
|
|
||||||
every module only gets its own messages.
|
|
||||||
|
|
||||||
|
|
||||||
## Transactions
|
|
||||||
|
|
||||||
A user can send a transaction to the running blockchain application. This
|
|
||||||
transaction can be of any of the ones that are supported by any of the
|
|
||||||
registered modules.
|
|
||||||
|
|
||||||
### CheckTx
|
|
||||||
|
|
||||||
Once a user has submitted their transaction to the engine,
|
|
||||||
the engine will first run `checkTx` to confirm that it is a valid transaction.
|
|
||||||
The module has to define a handler that knows how to handle every transaction
|
|
||||||
type. The corresponding handler gets invoked with the checkTx flag set to true.
|
|
||||||
This means that the handler shouldn't do any expensive operations, but it can
|
|
||||||
and should write to the checkTx state.
|
|
||||||
|
|
||||||
### DeliverTx
|
|
||||||
|
|
||||||
The engine calls `deliverTx` when a new block has been agreed upon in
|
|
||||||
consensus. Again, the corresponding module will have its handler invoked
|
|
||||||
and the state and context is passed in. During deliverTx execution the
|
|
||||||
transaction needs to be processed fully and the results are written to the
|
|
||||||
application state.
|
|
||||||
|
|
||||||
|
|
||||||
## CLI
|
|
||||||
|
|
||||||
The cosmos-sdk contains a number of helper libraries in `clients/` to build cli
|
|
||||||
and RPC interfaces for your specific application.
|
|
||||||
|
|
|
@ -1,70 +0,0 @@
|
||||||
# Democoin
|
|
||||||
|
|
||||||
This is the "Democoin" example application built on the Cosmos-Sdk. This
|
|
||||||
"Democoin" is not affiliated with [Coinbase](http://www.getdemocoin.com/), nor
|
|
||||||
the [stable coin](http://www.getdemocoin.com/).
|
|
||||||
|
|
||||||
Assuming you've run `make get_tools && make get_vendor_deps` from the root of
|
|
||||||
this repository, run `make build` here to build the `democoind` and `basecli`
|
|
||||||
binaries.
|
|
||||||
|
|
||||||
If you want to create a new application, start by copying the Democoin app.
|
|
||||||
|
|
||||||
|
|
||||||
# Building your own Blockchain
|
|
||||||
|
|
||||||
Democoin is the equivalent of an ERC20 token contract for blockchains. In order
|
|
||||||
to deploy your own application all you need to do is clone `examples/democoin`
|
|
||||||
and run it. Now you are already running your own blockchain. In the following
|
|
||||||
I will explain how to add functionality to your blockchain. This is akin to
|
|
||||||
defining your own vesting schedule within a contract or setting a specific
|
|
||||||
multisig. You are just extending the base layer with extra functionality here
|
|
||||||
and there.
|
|
||||||
|
|
||||||
## Structure of Democoin
|
|
||||||
|
|
||||||
Democoin is build with the cosmos-sdk. It is a sample application that works
|
|
||||||
with any engine that implements the ABCI protocol. Democoin defines multiple
|
|
||||||
unique modules as well as uses modules directly from the sdk. If you want
|
|
||||||
to modify Democoin, you either remove or add modules according to your wishes.
|
|
||||||
|
|
||||||
|
|
||||||
## Modules
|
|
||||||
|
|
||||||
A module is a fundamental unit in the cosmos-sdk. A module defines its own
|
|
||||||
transaction, handles its own state as well as its own state transition logic.
|
|
||||||
Globally, in the `app/app.go` file you just have to define a key for that
|
|
||||||
module to access some parts of the state, as well as initialise the module
|
|
||||||
object and finally add it to the transaction router. The router ensures that
|
|
||||||
every module only gets its own messages.
|
|
||||||
|
|
||||||
|
|
||||||
## Transactions
|
|
||||||
|
|
||||||
A user can send a transaction to the running blockchain application. This
|
|
||||||
transaction can be of any of the ones that are supported by any of the
|
|
||||||
registered modules.
|
|
||||||
|
|
||||||
### CheckTx
|
|
||||||
|
|
||||||
Once a user has submitted their transaction to the engine,
|
|
||||||
the engine will first run `checkTx` to confirm that it is a valid transaction.
|
|
||||||
The module has to define a handler that knows how to handle every transaction
|
|
||||||
type. The corresponding handler gets invoked with the checkTx flag set to true.
|
|
||||||
This means that the handler shouldn't do any expensive operations, but it can
|
|
||||||
and should write to the checkTx state.
|
|
||||||
|
|
||||||
### DeliverTx
|
|
||||||
|
|
||||||
The engine calls `deliverTx` when a new block has been agreed upon in
|
|
||||||
consensus. Again, the corresponding module will have its handler invoked
|
|
||||||
and the state and context is passed in. During deliverTx execution the
|
|
||||||
transaction needs to be processed fully and the results are written to the
|
|
||||||
application state.
|
|
||||||
|
|
||||||
|
|
||||||
## CLI
|
|
||||||
|
|
||||||
The cosmos-sdk contains a number of helper libraries in `clients/` to build cli
|
|
||||||
and RPC interfaces for your specific application.
|
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
package server
|
|
||||||
|
|
||||||
import (
|
|
||||||
cfg "github.com/tendermint/tendermint/config"
|
|
||||||
"github.com/tendermint/tmlibs/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Context struct {
|
|
||||||
Config *cfg.Config
|
|
||||||
Logger log.Logger
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewContext(config *cfg.Config, logger log.Logger) *Context {
|
|
||||||
return &Context{config, logger}
|
|
||||||
}
|
|
|
@ -8,10 +8,13 @@ import (
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
|
"github.com/tendermint/go-crypto/keys"
|
||||||
|
"github.com/tendermint/go-crypto/keys/words"
|
||||||
cfg "github.com/tendermint/tendermint/config"
|
cfg "github.com/tendermint/tendermint/config"
|
||||||
"github.com/tendermint/tendermint/p2p"
|
"github.com/tendermint/tendermint/p2p"
|
||||||
tmtypes "github.com/tendermint/tendermint/types"
|
tmtypes "github.com/tendermint/tendermint/types"
|
||||||
cmn "github.com/tendermint/tmlibs/common"
|
cmn "github.com/tendermint/tmlibs/common"
|
||||||
|
dbm "github.com/tendermint/tmlibs/db"
|
||||||
)
|
)
|
||||||
|
|
||||||
// testnetInformation contains the info necessary
|
// testnetInformation contains the info necessary
|
||||||
|
@ -25,6 +28,11 @@ type testnetInformation struct {
|
||||||
NodeID p2p.ID `json:"node_id"`
|
NodeID p2p.ID `json:"node_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type initCmd struct {
|
||||||
|
genAppState GenAppState
|
||||||
|
context *Context
|
||||||
|
}
|
||||||
|
|
||||||
// InitCmd will initialize all files for tendermint,
|
// InitCmd will initialize all files for tendermint,
|
||||||
// along with proper app_state.
|
// along with proper app_state.
|
||||||
// The application can pass in a function to generate
|
// The application can pass in a function to generate
|
||||||
|
@ -43,35 +51,6 @@ func InitCmd(gen GenAppState, ctx *Context) *cobra.Command {
|
||||||
return &cobraCmd
|
return &cobraCmd
|
||||||
}
|
}
|
||||||
|
|
||||||
// GenAppState takes the command line args, as well
|
|
||||||
// as an address and coin denomination.
|
|
||||||
// It returns a default app_state to be included in
|
|
||||||
// in the genesis file.
|
|
||||||
// This is application-specific
|
|
||||||
type GenAppState func(args []string, addr sdk.Address, coinDenom string) (json.RawMessage, error)
|
|
||||||
|
|
||||||
// DefaultGenAppState expects two args: an account address
|
|
||||||
// and a coin denomination, and gives lots of coins to that address.
|
|
||||||
func DefaultGenAppState(args []string, addr sdk.Address, coinDenom string) (json.RawMessage, error) {
|
|
||||||
opts := fmt.Sprintf(`{
|
|
||||||
"accounts": [{
|
|
||||||
"address": "%s",
|
|
||||||
"coins": [
|
|
||||||
{
|
|
||||||
"denom": "%s",
|
|
||||||
"amount": 9007199254740992
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}]
|
|
||||||
}`, addr.String(), coinDenom)
|
|
||||||
return json.RawMessage(opts), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type initCmd struct {
|
|
||||||
genAppState GenAppState
|
|
||||||
context *Context
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c initCmd) run(cmd *cobra.Command, args []string) error {
|
func (c initCmd) run(cmd *cobra.Command, args []string) error {
|
||||||
// Store testnet information as we go
|
// Store testnet information as we go
|
||||||
var testnetInfo testnetInformation
|
var testnetInfo testnetInformation
|
||||||
|
@ -174,6 +153,34 @@ func (c initCmd) initTendermintFiles(config *cfg.Config, info *testnetInformatio
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
|
||||||
|
// GenAppState takes the command line args, as well
|
||||||
|
// as an address and coin denomination.
|
||||||
|
// It returns a default app_state to be included in
|
||||||
|
// in the genesis file.
|
||||||
|
// This is application-specific
|
||||||
|
type GenAppState func(args []string, addr sdk.Address, coinDenom string) (json.RawMessage, error)
|
||||||
|
|
||||||
|
// DefaultGenAppState expects two args: an account address
|
||||||
|
// and a coin denomination, and gives lots of coins to that address.
|
||||||
|
func DefaultGenAppState(args []string, addr sdk.Address, coinDenom string) (json.RawMessage, error) {
|
||||||
|
opts := fmt.Sprintf(`{
|
||||||
|
"accounts": [{
|
||||||
|
"address": "%s",
|
||||||
|
"coins": [
|
||||||
|
{
|
||||||
|
"denom": "%s",
|
||||||
|
"amount": 9007199254740992
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}]
|
||||||
|
}`, addr.String(), coinDenom)
|
||||||
|
return json.RawMessage(opts), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
|
||||||
// GenesisDoc involves some tendermint-specific structures we don't
|
// GenesisDoc involves some tendermint-specific structures we don't
|
||||||
// want to parse, so we just grab it into a raw object format,
|
// want to parse, so we just grab it into a raw object format,
|
||||||
// so we can add one line.
|
// so we can add one line.
|
||||||
|
@ -199,3 +206,30 @@ func addGenesisState(filename string, appState json.RawMessage) error {
|
||||||
|
|
||||||
return ioutil.WriteFile(filename, out, 0600)
|
return ioutil.WriteFile(filename, out, 0600)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
|
||||||
|
// GenerateCoinKey returns the address of a public key,
|
||||||
|
// along with the secret phrase to recover the private key.
|
||||||
|
// You can give coins to this address and return the recovery
|
||||||
|
// phrase to the user to access them.
|
||||||
|
func GenerateCoinKey() (sdk.Address, string, error) {
|
||||||
|
// construct an in-memory key store
|
||||||
|
codec, err := words.LoadCodec("english")
|
||||||
|
if err != nil {
|
||||||
|
return nil, "", err
|
||||||
|
}
|
||||||
|
keybase := keys.New(
|
||||||
|
dbm.NewMemDB(),
|
||||||
|
codec,
|
||||||
|
)
|
||||||
|
|
||||||
|
// generate a private key, with recovery phrase
|
||||||
|
info, secret, err := keybase.Create("name", "pass", keys.AlgoEd25519)
|
||||||
|
if err != nil {
|
||||||
|
return nil, "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
addr := info.PubKey.Address()
|
||||||
|
return addr, secret, nil
|
||||||
|
}
|
||||||
|
|
|
@ -1,34 +0,0 @@
|
||||||
package server
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/tendermint/go-crypto/keys"
|
|
||||||
"github.com/tendermint/go-crypto/keys/words"
|
|
||||||
dbm "github.com/tendermint/tmlibs/db"
|
|
||||||
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
||||||
)
|
|
||||||
|
|
||||||
// GenerateCoinKey returns the address of a public key,
|
|
||||||
// along with the secret phrase to recover the private key.
|
|
||||||
// You can give coins to this address and return the recovery
|
|
||||||
// phrase to the user to access them.
|
|
||||||
func GenerateCoinKey() (sdk.Address, string, error) {
|
|
||||||
// construct an in-memory key store
|
|
||||||
codec, err := words.LoadCodec("english")
|
|
||||||
if err != nil {
|
|
||||||
return nil, "", err
|
|
||||||
}
|
|
||||||
keybase := keys.New(
|
|
||||||
dbm.NewMemDB(),
|
|
||||||
codec,
|
|
||||||
)
|
|
||||||
|
|
||||||
// generate a private key, with recovery phrase
|
|
||||||
info, secret, err := keybase.Create("name", "pass", keys.AlgoEd25519)
|
|
||||||
if err != nil {
|
|
||||||
return nil, "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
addr := info.PubKey.Address()
|
|
||||||
return addr, secret, nil
|
|
||||||
}
|
|
|
@ -1,27 +0,0 @@
|
||||||
package server
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
|
|
||||||
tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands"
|
|
||||||
)
|
|
||||||
|
|
||||||
// UnsafeResetAllCmd - extension of the tendermint command, resets initialization
|
|
||||||
func UnsafeResetAllCmd(ctx *Context) *cobra.Command {
|
|
||||||
cmd := resetAll{ctx}
|
|
||||||
return &cobra.Command{
|
|
||||||
Use: "unsafe_reset_all",
|
|
||||||
Short: "Reset all blockchain data",
|
|
||||||
RunE: cmd.run,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type resetAll struct {
|
|
||||||
context *Context
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r resetAll) run(cmd *cobra.Command, args []string) error {
|
|
||||||
cfg := r.context.Config
|
|
||||||
tcmd.ResetAll(cfg.DBDir(), cfg.PrivValidatorFile(), r.context.Logger)
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
package server
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
|
|
||||||
"github.com/tendermint/tendermint/p2p"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ShowNodeIDCmd - ported from Tendermint, dump node ID to stdout
|
|
||||||
func ShowNodeIDCmd(ctx *Context) *cobra.Command {
|
|
||||||
cmd := showNodeId{ctx}
|
|
||||||
return &cobra.Command{
|
|
||||||
Use: "show_node_id",
|
|
||||||
Short: "Show this node's ID",
|
|
||||||
RunE: cmd.run,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type showNodeId struct {
|
|
||||||
context *Context
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s showNodeId) run(cmd *cobra.Command, args []string) error {
|
|
||||||
cfg := s.context.Config
|
|
||||||
nodeKey, err := p2p.LoadOrGenNodeKey(cfg.NodeKeyFile())
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
fmt.Println(nodeKey.ID())
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
package server
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
|
|
||||||
"github.com/tendermint/go-wire/data"
|
|
||||||
"github.com/tendermint/tendermint/types"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ShowValidator - ported from Tendermint, show this node's validator info
|
|
||||||
func ShowValidatorCmd(ctx *Context) *cobra.Command {
|
|
||||||
cmd := showValidator{ctx}
|
|
||||||
return &cobra.Command{
|
|
||||||
Use: "show_validator",
|
|
||||||
Short: "Show this node's validator info",
|
|
||||||
RunE: cmd.run,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type showValidator struct {
|
|
||||||
context *Context
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s showValidator) run(cmd *cobra.Command, args []string) error {
|
|
||||||
cfg := s.context.Config
|
|
||||||
privValidator := types.LoadOrGenPrivValidatorFS(cfg.PrivValidatorFile())
|
|
||||||
pubKeyJSONBytes, err := data.ToJSON(privValidator.PubKey)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
fmt.Println(string(pubKeyJSONBytes))
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
|
"github.com/tendermint/go-wire/data"
|
||||||
|
tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands"
|
||||||
|
"github.com/tendermint/tendermint/p2p"
|
||||||
|
"github.com/tendermint/tendermint/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ShowNodeIDCmd - ported from Tendermint, dump node ID to stdout
|
||||||
|
func ShowNodeIDCmd(ctx *Context) *cobra.Command {
|
||||||
|
cmd := showNodeId{ctx}
|
||||||
|
return &cobra.Command{
|
||||||
|
Use: "show_node_id",
|
||||||
|
Short: "Show this node's ID",
|
||||||
|
RunE: cmd.run,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type showNodeId struct {
|
||||||
|
context *Context
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s showNodeId) run(cmd *cobra.Command, args []string) error {
|
||||||
|
cfg := s.context.Config
|
||||||
|
nodeKey, err := p2p.LoadOrGenNodeKey(cfg.NodeKeyFile())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fmt.Println(nodeKey.ID())
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// ShowValidator - ported from Tendermint, show this node's validator info
|
||||||
|
func ShowValidatorCmd(ctx *Context) *cobra.Command {
|
||||||
|
cmd := showValidator{ctx}
|
||||||
|
return &cobra.Command{
|
||||||
|
Use: "show_validator",
|
||||||
|
Short: "Show this node's validator info",
|
||||||
|
RunE: cmd.run,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type showValidator struct {
|
||||||
|
context *Context
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s showValidator) run(cmd *cobra.Command, args []string) error {
|
||||||
|
cfg := s.context.Config
|
||||||
|
privValidator := types.LoadOrGenPrivValidatorFS(cfg.PrivValidatorFile())
|
||||||
|
pubKeyJSONBytes, err := data.ToJSON(privValidator.PubKey)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fmt.Println(string(pubKeyJSONBytes))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// UnsafeResetAllCmd - extension of the tendermint command, resets initialization
|
||||||
|
func UnsafeResetAllCmd(ctx *Context) *cobra.Command {
|
||||||
|
cmd := resetAll{ctx}
|
||||||
|
return &cobra.Command{
|
||||||
|
Use: "unsafe_reset_all",
|
||||||
|
Short: "Reset all blockchain data",
|
||||||
|
RunE: cmd.run,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type resetAll struct {
|
||||||
|
context *Context
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r resetAll) run(cmd *cobra.Command, args []string) error {
|
||||||
|
cfg := r.context.Config
|
||||||
|
tcmd.ResetAll(cfg.DBDir(), cfg.PrivValidatorFile(), r.context.Logger)
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -14,6 +14,17 @@ import (
|
||||||
"github.com/tendermint/tmlibs/log"
|
"github.com/tendermint/tmlibs/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type Context struct {
|
||||||
|
Config *cfg.Config
|
||||||
|
Logger log.Logger
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewContext(config *cfg.Config, logger log.Logger) *Context {
|
||||||
|
return &Context{config, logger}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
|
||||||
// PersistentPreRunEFn returns a PersistentPreRunE function for cobra
|
// PersistentPreRunEFn returns a PersistentPreRunE function for cobra
|
||||||
// that initailizes the passed in context with a properly configured
|
// that initailizes the passed in context with a properly configured
|
||||||
// logger and config objecy
|
// logger and config objecy
|
Loading…
Reference in New Issue