blob: a8b704eb689c55504311769779b297c1b8eb7995 [file] [log] [blame]
// Copyright 2020 The LUCI Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package cfgclient
import (
"context"
"sort"
"github.com/golang/protobuf/jsonpb"
"github.com/golang/protobuf/proto"
luciProto "go.chromium.org/luci/common/proto"
"go.chromium.org/luci/config"
)
// Destination receives a raw config file body, deserializes and stores it.
//
// See Get(...).
type Destination func(string) error
// Bytes can be used to put the received config body into a byte slice.
func Bytes(out *[]byte) Destination {
return func(body string) error {
*out = []byte(body)
return nil
}
}
// String can be used to put the received config body into a string.
func String(out *string) Destination {
return func(body string) error {
*out = body
return nil
}
}
// ProtoText can be used to deserialize the received config body as a text proto
// message.
func ProtoText(msg proto.Message) Destination {
return func(body string) error {
return luciProto.UnmarshalTextML(body, msg)
}
}
// ProtoJSON can be used to deserialize the received config body as a JSONPB
// message.
func ProtoJSON(msg proto.Message) Destination {
return func(body string) error {
return jsonpb.UnmarshalString(body, msg)
}
}
// Get fetches and optionally deserializes a single config file.
//
// It is a convenience wrapper over Client(ctx).GetConfig(...). If you need
// something more advanced, use the client directly.
//
// If `dest` is given, it is used to deserialize and store the fetched config.
// If it is nil, the config body is ignored (but its metadata is still fetched).
//
// If `meta` is given, it receives the metadata about the config.
//
// Returns an error if the config can't be fetched or deserialized.
func Get(ctx context.Context, cs config.Set, path string, dest Destination, meta *config.Meta) error {
cfg, err := Client(ctx).GetConfig(ctx, cs, path, dest == nil)
if err != nil {
return err
}
if dest != nil {
if err := dest(cfg.Content); err != nil {
return err
}
}
if meta != nil {
*meta = cfg.Meta
}
return nil
}
// ProjectsWithConfig returns a list of LUCI projects that have the given
// configuration file.
//
// It is a convenience wrapper over Client(ctx).GetProjectConfigs(...). If you
// need something more advanced, use the client directly.
func ProjectsWithConfig(ctx context.Context, path string) ([]string, error) {
cfgs, err := Client(ctx).GetProjectConfigs(ctx, path, true)
if err != nil {
return nil, err
}
projects := make([]string, 0, len(cfgs))
for _, cfg := range cfgs {
if proj := cfg.ConfigSet.Project(); proj != "" {
projects = append(projects, proj)
}
}
sort.Strings(projects)
return projects, nil
}