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

     1  // Copyright 2015 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 filesystem
    16  
    17  import (
    18  	"os"
    19  	"path"
    20  	"path/filepath"
    21  	"strings"
    22  
    23  	"go.chromium.org/luci/common/errors"
    24  )
    25  
    26  type luciPath string
    27  
    28  func newLUCIPath(toks ...string) luciPath {
    29  	return luciPath(path.Join(toks...))
    30  }
    31  
    32  func (l luciPath) explode() []string {
    33  	return strings.Split(l.s(), "/")
    34  }
    35  
    36  func (l luciPath) s() string {
    37  	return string(l)
    38  }
    39  
    40  // TODO(vadimsh): Consolidate this with config.Set.
    41  type configSet struct{ luciPath }
    42  
    43  func newConfigSet(toks ...string) configSet {
    44  	return configSet{newLUCIPath(toks...)}
    45  }
    46  
    47  func (c configSet) isProject() bool {
    48  	return strings.Count(c.s(), "/") == 1 && c.hasPrefix("projects/")
    49  }
    50  
    51  func (c configSet) hasPrefix(prefix luciPath) bool {
    52  	return strings.HasPrefix(c.s(), prefix.s())
    53  }
    54  
    55  func (c configSet) id() string {
    56  	return strings.Split(c.s(), "/")[1]
    57  }
    58  
    59  func (c configSet) validate() error {
    60  	if !c.hasPrefix("projects/") && !c.hasPrefix("services/") {
    61  		return errors.Reason("configSet.validate: bad prefix %q", c.s()).Err()
    62  	}
    63  	return nil
    64  }
    65  
    66  type nativePath string
    67  
    68  func (n nativePath) explode() []string {
    69  	return strings.Split(n.s(), string(filepath.Separator))
    70  }
    71  
    72  func (n nativePath) readlink() (nativePath, error) {
    73  	ret, err := os.Readlink(n.s())
    74  	if filepath.IsAbs(ret) {
    75  		return nativePath(ret), err
    76  	}
    77  	return nativePath(filepath.Join(filepath.Dir(n.s()), ret)), err
    78  }
    79  
    80  func (n nativePath) rel(other nativePath) (nativePath, error) {
    81  	ret, err := filepath.Rel(n.s(), other.s())
    82  	return nativePath(ret), err
    83  }
    84  
    85  func (n nativePath) read() ([]byte, error) {
    86  	return os.ReadFile(n.s())
    87  }
    88  
    89  func (n nativePath) toLUCI() luciPath {
    90  	return luciPath(filepath.ToSlash(n.s()))
    91  }
    92  
    93  func (n nativePath) s() string {
    94  	return string(n)
    95  }