add analytics cli commands
This commit is contained in:
@ -62,8 +62,14 @@ func SetupDI(ctx context.Context, cfgpath string, verbose bool, logAsJSON bool)
|
|||||||
writer = os.Stdout
|
writer = os.Stdout
|
||||||
}
|
}
|
||||||
|
|
||||||
log := zerolog.New(writer).With().Timestamp().Str("app", "converter").Logger()
|
log := zerolog.
|
||||||
|
New(writer).
|
||||||
|
With().
|
||||||
|
Timestamp().
|
||||||
|
Str("app", "converter").
|
||||||
|
Logger()
|
||||||
if verbose {
|
if verbose {
|
||||||
|
|
||||||
return log.Level(zerolog.DebugLevel), nil
|
return log.Level(zerolog.DebugLevel), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
150
cmd/cli/main.go
150
cmd/cli/main.go
@ -54,6 +54,14 @@ func runcli(ctx context.Context) (err error) {
|
|||||||
|
|
||||||
func setupDI() cli.BeforeFunc {
|
func setupDI() cli.BeforeFunc {
|
||||||
return func(ctx context.Context, cmd *cli.Command) error {
|
return func(ctx context.Context, cmd *cli.Command) error {
|
||||||
|
if out := cmd.String("output"); out != "" {
|
||||||
|
var err error
|
||||||
|
cmd.Writer, err = os.Create(out)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("setting writer: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cfgpath := cmd.String("config")
|
cfgpath := cmd.String("config")
|
||||||
debugLevel := cmd.Bool("verbose")
|
debugLevel := cmd.Bool("verbose")
|
||||||
jsonFormat := cmd.Bool("json")
|
jsonFormat := cmd.Bool("json")
|
||||||
@ -69,6 +77,13 @@ func setupDI() cli.BeforeFunc {
|
|||||||
|
|
||||||
func releaseDI() cli.AfterFunc {
|
func releaseDI() cli.AfterFunc {
|
||||||
return func(ctx context.Context, c *cli.Command) error {
|
return func(ctx context.Context, c *cli.Command) error {
|
||||||
|
if f, ok := c.Writer.(*os.File); ok {
|
||||||
|
err := f.Close()
|
||||||
|
if err != nil {
|
||||||
|
println("unable to close output file:", err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return components.Shutdown()
|
return components.Shutdown()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -95,6 +110,12 @@ func setupCLI() *cli.Command {
|
|||||||
Usage: "enables json log format",
|
Usage: "enables json log format",
|
||||||
Persistent: true,
|
Persistent: true,
|
||||||
},
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "output",
|
||||||
|
Aliases: []string{"o"},
|
||||||
|
Usage: "Defines output for commands",
|
||||||
|
TakesFile: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
Before: setupDI(),
|
Before: setupDI(),
|
||||||
@ -348,10 +369,30 @@ func newViewItemsCmd() *cli.Command {
|
|||||||
Commands: []*cli.Command{
|
Commands: []*cli.Command{
|
||||||
newViewItemsGetCmd(),
|
newViewItemsGetCmd(),
|
||||||
newViewItemsCountCmd(),
|
newViewItemsCountCmd(),
|
||||||
|
newViewItemsUniqueParams(),
|
||||||
|
newViewItemsParamsKnownValues(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newViewItemsUniqueParams() *cli.Command {
|
||||||
|
return &cli.Command{
|
||||||
|
Name: "unique-params",
|
||||||
|
Usage: "Show all stored unique param values",
|
||||||
|
Description: "This command iterates over each item and collect keys of params in a dict and then" +
|
||||||
|
" print it to the output. It's useful to find all unique parameters",
|
||||||
|
Action: decorateAction(viewItemsUniqueParamsAction),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func newViewItemsParamsKnownValues() *cli.Command {
|
||||||
|
return &cli.Command{
|
||||||
|
Name: "params-values",
|
||||||
|
Usage: "Show all values of requested parameters",
|
||||||
|
Action: decorateAction(viewItemsParamsKnownValuesAction),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func newViewItemsCountCmd() *cli.Command {
|
func newViewItemsCountCmd() *cli.Command {
|
||||||
return &cli.Command{
|
return &cli.Command{
|
||||||
Name: "count",
|
Name: "count",
|
||||||
@ -437,6 +478,115 @@ func viewItemsGetAction(ctx context.Context, c *cli.Command) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func viewItemsUniqueParamsAction(ctx context.Context, c *cli.Command) error {
|
||||||
|
repository, err := components.GetRepository()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("getting repository: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
knownParams := map[string]struct{}{}
|
||||||
|
iter, err := repository.GoodsItem().ListIter(ctx, 1)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("getting list iter: %w", err)
|
||||||
|
}
|
||||||
|
for item := range iter {
|
||||||
|
for k := range item.Parameters {
|
||||||
|
knownParams[k] = struct{}{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bw := bufio.NewWriter(c.Writer)
|
||||||
|
for paramName := range knownParams {
|
||||||
|
_, err = bw.WriteString(paramName + "\n")
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to write: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return bw.Flush()
|
||||||
|
}
|
||||||
|
|
||||||
|
type chanIter[T any] struct {
|
||||||
|
in <-chan T
|
||||||
|
err error
|
||||||
|
next T
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *chanIter[T]) Next() (ok bool) {
|
||||||
|
if i.err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
i.next, ok = <-i.in
|
||||||
|
if !ok {
|
||||||
|
i.err = errors.New("channel closed")
|
||||||
|
}
|
||||||
|
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *chanIter[T]) Get() T {
|
||||||
|
return i.next
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *chanIter[T]) Err() error {
|
||||||
|
return i.err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *chanIter[T]) Close() {
|
||||||
|
for range i.in {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getItemsIter(ctx context.Context, r entity.GoodsItemRepository) *chanIter[entity.GoodsItem] {
|
||||||
|
in, err := r.ListIter(ctx, 3)
|
||||||
|
|
||||||
|
return &chanIter[entity.GoodsItem]{
|
||||||
|
in: in,
|
||||||
|
err: err,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func viewItemsParamsKnownValuesAction(ctx context.Context, c *cli.Command) error {
|
||||||
|
repository, err := components.GetRepository()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("getting repository: %w", err)
|
||||||
|
}
|
||||||
|
log, err := components.GetLogger()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("getting logger: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
params := c.Args().Slice()
|
||||||
|
requestedValues := make(map[string]map[string]struct{}, len(params))
|
||||||
|
for _, param := range params {
|
||||||
|
log.Debug().Str("param", param).Msg("registering param")
|
||||||
|
requestedValues[param] = make(map[string]struct{}, 16)
|
||||||
|
}
|
||||||
|
|
||||||
|
iter := getItemsIter(ctx, repository.GoodsItem())
|
||||||
|
for iter.Next() {
|
||||||
|
item := iter.Get()
|
||||||
|
for k, v := range item.Parameters {
|
||||||
|
if _, ok := requestedValues[k]; ok {
|
||||||
|
requestedValues[k][v] = struct{}{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tbl := table.New("key", "values").WithWriter(c.Writer)
|
||||||
|
for k, v := range requestedValues {
|
||||||
|
values := make([]string, 0, len(v))
|
||||||
|
for value := range v {
|
||||||
|
values = append(values, strconv.Quote(value))
|
||||||
|
}
|
||||||
|
tbl.AddRow(k, values)
|
||||||
|
}
|
||||||
|
tbl.Print()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func viewItemsCountAction(ctx context.Context, c *cli.Command) error {
|
func viewItemsCountAction(ctx context.Context, c *cli.Command) error {
|
||||||
r, err := components.GetRepository()
|
r, err := components.GetRepository()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@ -35,10 +35,11 @@ func Open(ctx context.Context, path string, debug bool, log zerolog.Logger) (*ba
|
|||||||
log: log.With().Str("db", "badger").Logger(),
|
log: log.With().Str("db", "badger").Logger(),
|
||||||
}
|
}
|
||||||
|
|
||||||
level := badger.INFO
|
level := badger.WARNING
|
||||||
if debug {
|
if debug {
|
||||||
level = badger.DEBUG
|
level = badger.DEBUG
|
||||||
}
|
}
|
||||||
|
|
||||||
opts := badger.DefaultOptions(path).
|
opts := badger.DefaultOptions(path).
|
||||||
WithLogger(bl).
|
WithLogger(bl).
|
||||||
WithLoggingLevel(level).
|
WithLoggingLevel(level).
|
||||||
|
|||||||
Reference in New Issue
Block a user