1// Copyright 2018 The Bazel Authors. All rights reserved. 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 15package res 16 17import ( 18 "errors" 19 "fmt" 20 "path" 21 "strings" 22) 23 24// ErrNotResPath the provided path does not seem to point to a resource file 25var ErrNotResPath = errors.New("Not a resource path") 26 27// ErrSkipResPath the provided path does needs to be skipped. 28var ErrSkipResPath = errors.New("resource path that does needs to be skipped") 29 30// PathInfo contains all information about a resource that can be derived from its location on the filesystem. 31type PathInfo struct { 32 Path string 33 ResDir string 34 TypeDir string 35 Type Type 36 Qualifier string 37 Density Density 38} 39 40// ParsePath converts a path string into a PathInfo object if the string points to a resource file. 41func ParsePath(p string) (PathInfo, error) { 42 parent := path.Dir(p) 43 resDir := path.Dir(parent) 44 typeDir := path.Base(parent) 45 46 if strings.HasPrefix(path.Base(p), ".") { 47 return PathInfo{}, ErrSkipResPath 48 } 49 50 resType, err := ParseValueOrType(strings.Split(typeDir, "-")[0]) 51 qualifier := extractQualifier(typeDir) 52 if err != nil { 53 return PathInfo{}, ErrNotResPath 54 } 55 var density Density 56 for _, q := range strings.Split(qualifier, "-") { 57 var err error 58 density, err = ParseDensity(q) 59 if err != nil { 60 return PathInfo{}, err 61 } 62 if density != UnspecifiedDensity { 63 break 64 } 65 } 66 return PathInfo{ 67 Path: p, 68 ResDir: resDir, 69 TypeDir: typeDir, 70 Type: resType, 71 Qualifier: qualifier, 72 Density: density, 73 }, nil 74} 75 76// MakePathInfo converts a path string into a PathInfo object. 77func MakePathInfo(p string) (*PathInfo, error) { 78 pi, err := ParsePath(p) 79 if err != nil { 80 return nil, fmt.Errorf("ParsePath failed to parse %q: %v", p, err) 81 } 82 return &pi, nil 83} 84 85// MakePathInfos converts a list of path strings into a list of PathInfo objects. 86func MakePathInfos(paths []string) ([]*PathInfo, error) { 87 pis := make([]*PathInfo, 0, len(paths)) 88 for _, p := range paths { 89 if strings.HasPrefix(path.Base(p), ".") { 90 continue 91 } 92 pi, err := MakePathInfo(p) 93 if err != nil { 94 return nil, err 95 } 96 pis = append(pis, pi) 97 } 98 return pis, nil 99} 100 101func extractQualifier(s string) string { 102 base := path.Base(s) 103 parts := strings.SplitN(base, "-", 2) 104 if len(parts) > 1 { 105 return parts[1] 106 } 107 return "" 108} 109