| OLD | NEW |
| (Empty) | |
| 1 // Copyright 2016 The LUCI Authors. All rights reserved. |
| 2 // Use of this source code is governed under the Apache License, Version 2.0 |
| 3 // that can be found in the LICENSE file. |
| 4 |
| 5 // Package format implements a config client Backend that performs formatting |
| 6 // on items. |
| 7 // |
| 8 // This must be used in conjuncton with a cfgclient.FormatterRegistry to |
| 9 // register Formatter instances. |
| 10 package format |
| 11 |
| 12 import ( |
| 13 "github.com/luci/luci-go/common/errors" |
| 14 "github.com/luci/luci-go/luci_config/server/cfgclient" |
| 15 "github.com/luci/luci-go/luci_config/server/cfgclient/backend" |
| 16 |
| 17 "golang.org/x/net/context" |
| 18 ) |
| 19 |
| 20 // Backend is a backend.B implementation that applies Formatter |
| 21 // transformations to the various Items that pass through it. |
| 22 // |
| 23 // Formatter transformations are registered explicitly to the Resolver |
| 24 // descriptions of the types that they operate on. If an Item is already |
| 25 // formatted, no further transformations will be applied. |
| 26 type Backend struct { |
| 27 // B is the underlying Backend that this Backend will pull data |
| 28 // from. |
| 29 backend.B |
| 30 |
| 31 // GetRegistry returns the FormatterRegistry to use. If it returns nil, |
| 32 // no formatting will be done. |
| 33 GetRegistry func(context.Context) *cfgclient.FormatterRegistry |
| 34 } |
| 35 |
| 36 // Get implements backend.B. |
| 37 func (b *Backend) Get(c context.Context, configSet, path string, p backend.Param
s) (*backend.Item, error) { |
| 38 item, err := b.B.Get(c, configSet, path, p) |
| 39 if err != nil { |
| 40 return nil, err |
| 41 } |
| 42 |
| 43 if !p.FormatSpec.Unformatted() { |
| 44 formatter, err := b.getFormatter(c, p.FormatSpec.Formatter) |
| 45 if err != nil { |
| 46 return nil, errors.Annotate(err).Reason("failed to get f
ormatter for %(format)q"). |
| 47 D("format", p.FormatSpec).Err() |
| 48 } |
| 49 |
| 50 if err := b.formatItem(item, formatter, p.FormatSpec); err != ni
l { |
| 51 return nil, errors.Annotate(err).Reason("failed to forma
t item to %(format)q, data %(data)q"). |
| 52 D("format", p.FormatSpec).Err() |
| 53 } |
| 54 } |
| 55 return item, nil |
| 56 } |
| 57 |
| 58 // GetAll implements backend.B. |
| 59 func (b *Backend) GetAll(c context.Context, t backend.GetAllTarget, path string,
p backend.Params) ( |
| 60 []*backend.Item, error) { |
| 61 |
| 62 items, err := b.B.GetAll(c, t, path, p) |
| 63 if err != nil { |
| 64 return nil, err |
| 65 } |
| 66 |
| 67 if !p.FormatSpec.Unformatted() { |
| 68 formatter, err := b.getFormatter(c, p.FormatSpec.Formatter) |
| 69 if err != nil { |
| 70 return nil, errors.Annotate(err).Reason("failed to get f
ormatter for %(format)q, data %(data)q"). |
| 71 D("format", p.FormatSpec).Err() |
| 72 } |
| 73 |
| 74 lme := errors.NewLazyMultiError(len(items)) |
| 75 for i, item := range items { |
| 76 if err := b.formatItem(item, formatter, p.FormatSpec); e
rr != nil { |
| 77 lme.Assign(i, err) |
| 78 } |
| 79 } |
| 80 |
| 81 if err := lme.Get(); err != nil { |
| 82 return nil, errors.Annotate(err).Reason("failed to forma
t items to %(format)q, data %(data)q"). |
| 83 D("format", p.FormatSpec).Err() |
| 84 } |
| 85 } |
| 86 return items, nil |
| 87 } |
| 88 |
| 89 func (b *Backend) getFormatter(c context.Context, f string) (cfgclient.Formatter
, error) { |
| 90 if b.GetRegistry == nil { |
| 91 return nil, errors.New("no formatter registry function installed
") |
| 92 } |
| 93 |
| 94 reg := b.GetRegistry(c) |
| 95 if reg == nil { |
| 96 return nil, errors.New("formatter registry function returned nil
registry") |
| 97 } |
| 98 formatter := reg.Get(f) |
| 99 if formatter == nil { |
| 100 return nil, errors.Reason("unknown formatter: %(formatter)q").D(
"formatter", f).Err() |
| 101 } |
| 102 return formatter, nil |
| 103 } |
| 104 |
| 105 func (b *Backend) formatItem(it *backend.Item, formatter cfgclient.Formatter, fs
backend.FormatSpec) error { |
| 106 if !it.FormatSpec.Unformatted() { |
| 107 // Item is already formatted. |
| 108 return nil |
| 109 } |
| 110 |
| 111 // Item is not formatted, so format it. |
| 112 content, err := formatter.FormatItem(it.Content, fs.Data) |
| 113 if err != nil { |
| 114 return errors.Annotate(err).Reason("failed to format item").Err(
) |
| 115 } |
| 116 it.Content = content |
| 117 it.FormatSpec = fs |
| 118 return nil |
| 119 } |
| OLD | NEW |