github.com/msales/pkg/v3@v3.24.0/clix/context.go (about)

     1  package clix
     2  
     3  import (
     4  	"context"
     5  	"io"
     6  
     7  	"github.com/msales/pkg/v3/log"
     8  	"github.com/msales/pkg/v3/stats"
     9  	"gopkg.in/urfave/cli.v1"
    10  )
    11  
    12  // ContextFunc configures the Context.
    13  type ContextFunc func(ctx *Context)
    14  
    15  // WithLogger sets the logger instance on the Context.
    16  func WithLogger(l log.Logger) ContextFunc {
    17  	return func(ctx *Context) {
    18  		ctx.logger = l
    19  	}
    20  }
    21  
    22  // WithStats set the stats instance on the Context.
    23  func WithStats(s stats.Stats) ContextFunc {
    24  	return func(ctx *Context) {
    25  		ctx.stats = s
    26  	}
    27  }
    28  
    29  type ctxContext context.Context
    30  
    31  // Context represents an application context.
    32  type Context struct {
    33  	*cli.Context
    34  	ctxContext
    35  
    36  	logger log.Logger
    37  	stats  stats.Stats
    38  }
    39  
    40  // NewContext creates a new Context from the CLI Context.
    41  func NewContext(c *cli.Context, opts ...ContextFunc) (*Context, error) {
    42  	ctx := &Context{
    43  		Context:    c,
    44  		ctxContext: context.Background(),
    45  	}
    46  
    47  	for _, opt := range opts {
    48  		opt(ctx)
    49  	}
    50  
    51  	if ctx.logger == nil {
    52  		l, err := NewLogger(ctx.Context)
    53  		if err != nil {
    54  			return nil, err
    55  		}
    56  
    57  		ctx.logger = l
    58  	}
    59  
    60  	if ctx.stats == nil {
    61  		s, err := NewStats(ctx.Context, ctx.logger) // guaranteed to have a logger instance here
    62  		if err != nil {
    63  			return nil, err
    64  		}
    65  
    66  		WithStats(s)(ctx)
    67  	}
    68  
    69  	ctx.ctxContext = log.WithLogger(ctx.ctxContext, ctx.logger)
    70  	ctx.ctxContext = stats.WithStats(ctx.ctxContext, ctx.stats)
    71  
    72  	return ctx, nil
    73  }
    74  
    75  // Close closes the context.
    76  func (c *Context) Close() error {
    77  	if err := c.stats.Close(); err != nil {
    78  		return err
    79  	}
    80  
    81  	if l, ok := c.logger.(io.Closer); ok {
    82  		return l.Close()
    83  	}
    84  
    85  	return nil
    86  }