// resolve expands a single go:embed pattern into a list of files that should
// be included in embedsrcs. Directory paths are not included in the returned
// list. This means there's no way to embed an empty directory.
resolve expands a single go:embed pattern into a list of files that should
be included in embedsrcs. Directory paths are not included in the returned
list. This means there's no way to embed an empty directory.
// resolve expands a single go : embed pattern into a list of files that should // be included in embedsrcs . Directory paths are not included in the returned // list . This means there ' s no way to embed an empty directory .
func (er *embedResolver) resolve(embed fileEmbed) (list []string, err error) {
	defer func() {
		if err != nil {
			err = fmt.Errorf("%v: pattern %s: %w", embed.pos, embed.path, err)
		}
	}()
	if _, err := path.Match(embed.path, ""); err != nil || !validEmbedPattern(embed.path) {
		return nil, fmt.Errorf("invalid pattern syntax")
	}
	 For example, the pattern "*" matches "a", ".b", and "_c". If "a" is a
	 directory, we would include "a/d", even though it doesn't match "*". We
	 would not include "a/.e".
	 There may be many patterns, so we avoid I/O here. Instead, the list is
	 in depth-first pre-order, so iterating over it is analogous to
	 filepath.Walk. We still use a recursive function, advance, to keep track
	 of whether we're embedding all files in the current directory. Each call
	 to advance increments i.
	i := 0
	var advance func(bool)
	advance = func(add bool) {
		f := er.files[i]
		i++
		if !f.isDir {
			if add {
				list = append(list, f.path)
			}
			return
		}
		prefix := f.path + "/"
		for i < len(er.files) && strings.HasPrefix(er.files[i].path, prefix) {
			base := er.files[i].path[len(prefix):]
			hidden := base[0] == '.' || base[0] == '_'
			advance(add && !hidden)
		}
	}
	for i < len(er.files) {
		matched, _ := path.Match(embed.path, er.files[i].path)
		advance(matched)
	}
	if len(list) == 0 {
		return nil, fmt.Errorf("matched no files")
	}
	return list, nil
}
func ( er * embedResolver ) resolve ( embed fileEmbed ) ( list [ ] string , err error ) { defer func ( ) { if err != nil { err = fmt . Errorf ( " " , embed . pos , embed . path , err ) } } ( ) if _ , err := path . Match ( embed . path , " " ) ; err != nil || ! validEmbedPattern ( embed . path ) { return nil , fmt . Errorf ( " " ) } i := 0 var advance func ( bool ) advance = func ( add bool ) { f := er . files [ i ] i ++ if ! f . isDir { if add { list = append ( list , f . path ) } return } prefix := f . path + " " for i < len ( er . files ) && strings . HasPrefix ( er . files [ i ] . path , prefix ) { base := er . files [ i ] . path [ len ( prefix ) : ] hidden := base [ 0 ] == '.' || base [ 0 ] == '_' advance ( add && ! hidden ) } } for i < len ( er . files ) { matched , _ := path . Match ( embed . path , er . files [ i ] . path ) advance ( matched ) } if len ( list ) == 0 { return nil , fmt . Errorf ( " " ) } return list , nil }
resolve expands a single go:embed pattern into a list of files that should
be included in embedsrcs.
resolve expands a single go : embed pattern into a list of files that should be included in embedsrcs .
// Check whether the pattern is valid at all. // Match the pattern against each path in the list. If the pattern matches a // directory, we need to include each file in that directory, even if the file // doesn't match the pattern separate, unless it is a hidden file (starting // with . or _). // // For example, the pattern "*" matches "a", ".b", and "_c". If "a" is a // directory, we would include "a/d", even though it doesn't match "*". We // would not include "a/.e". // // There may be many patterns, so we avoid I/O here. Instead, the list is // in depth-first pre-order, so iterating over it is analogous to // filepath.Walk. We still use a recursive function, advance, to keep track // of whether we're embedding all files in the current directory. Each call // to advance increments i.