go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/config/impl/resolving/resolving.go (about)

     1  // Copyright 2020 The LUCI Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  // Package resolving implements an interface that resolves ${var} placeholders
    16  // in config set names and file paths before forwarding calls to some other
    17  // interface.
    18  package resolving
    19  
    20  import (
    21  	"context"
    22  
    23  	"go.chromium.org/luci/common/errors"
    24  	"go.chromium.org/luci/config"
    25  	"go.chromium.org/luci/config/vars"
    26  )
    27  
    28  // New creates a config.Interface that resolves ${var} placeholders in config
    29  // set names and file paths before forwarding calls to `next`.
    30  func New(vars *vars.VarSet, next config.Interface) config.Interface {
    31  	return &resolvingInterface{vars, next}
    32  }
    33  
    34  type resolvingInterface struct {
    35  	vars *vars.VarSet
    36  	next config.Interface
    37  }
    38  
    39  func (r *resolvingInterface) configSet(ctx context.Context, cs config.Set) (config.Set, error) {
    40  	out, err := r.vars.RenderTemplate(ctx, string(cs))
    41  	if err != nil {
    42  		return "", errors.Annotate(err, "bad configSet %q", cs).Err()
    43  	}
    44  	return config.Set(out), nil
    45  }
    46  
    47  func (r *resolvingInterface) path(ctx context.Context, p string) (string, error) {
    48  	out, err := r.vars.RenderTemplate(ctx, p)
    49  	if err != nil {
    50  		return "", errors.Annotate(err, "bad path %q", p).Err()
    51  	}
    52  	return out, nil
    53  }
    54  
    55  func (r *resolvingInterface) GetConfig(ctx context.Context, configSet config.Set, path string, metaOnly bool) (*config.Config, error) {
    56  	configSet, err := r.configSet(ctx, configSet)
    57  	if err != nil {
    58  		return nil, err
    59  	}
    60  	path, err = r.path(ctx, path)
    61  	if err != nil {
    62  		return nil, err
    63  	}
    64  	return r.next.GetConfig(ctx, configSet, path, metaOnly)
    65  }
    66  
    67  func (r *resolvingInterface) GetConfigs(ctx context.Context, configSet config.Set, filter func(path string) bool, metaOnly bool) (map[string]config.Config, error) {
    68  	configSet, err := r.configSet(ctx, configSet)
    69  	if err != nil {
    70  		return nil, err
    71  	}
    72  	return r.next.GetConfigs(ctx, configSet, filter, metaOnly)
    73  }
    74  
    75  func (r *resolvingInterface) GetProjectConfigs(ctx context.Context, path string, metaOnly bool) ([]config.Config, error) {
    76  	path, err := r.path(ctx, path)
    77  	if err != nil {
    78  		return nil, err
    79  	}
    80  	return r.next.GetProjectConfigs(ctx, path, metaOnly)
    81  }
    82  
    83  func (r *resolvingInterface) GetProjects(ctx context.Context) ([]config.Project, error) {
    84  	return r.next.GetProjects(ctx)
    85  }
    86  
    87  func (r *resolvingInterface) ListFiles(ctx context.Context, configSet config.Set) ([]string, error) {
    88  	configSet, err := r.configSet(ctx, configSet)
    89  	if err != nil {
    90  		return nil, err
    91  	}
    92  	return r.next.ListFiles(ctx, configSet)
    93  }
    94  
    95  func (r *resolvingInterface) Close() error {
    96  	if r.next != nil {
    97  		return r.next.Close()
    98  	}
    99  	return nil
   100  }