github.com/docker/libcompose@v0.4.1-0.20210616120443-2a046c0bdbf2/lookup/file.go (about)

     1  package lookup
     2  
     3  import (
     4  	"io/ioutil"
     5  	"os"
     6  	"path"
     7  	"path/filepath"
     8  	"strings"
     9  
    10  	"github.com/sirupsen/logrus"
    11  )
    12  
    13  // relativePath returns the proper relative path for the given file path. If
    14  // the relativeTo string equals "-", then it means that it's from the stdin,
    15  // and the returned path will be the current working directory. Otherwise, if
    16  // file is really an absolute path, then it will be returned without any
    17  // changes. Otherwise, the returned path will be a combination of relativeTo
    18  // and file.
    19  func relativePath(file, relativeTo string) string {
    20  	// stdin: return the current working directory if possible.
    21  	if relativeTo == "-" {
    22  		if cwd, err := os.Getwd(); err == nil {
    23  			return filepath.Join(cwd, file)
    24  		}
    25  	}
    26  
    27  	// If the given file is already an absolute path, just return it.
    28  	// Otherwise, the returned path will be relative to the given relativeTo
    29  	// path.
    30  	if filepath.IsAbs(file) {
    31  		return file
    32  	}
    33  
    34  	abs, err := filepath.Abs(filepath.Join(path.Dir(relativeTo), file))
    35  	if err != nil {
    36  		logrus.Errorf("Failed to get absolute directory: %s", err)
    37  		return file
    38  	}
    39  	return abs
    40  }
    41  
    42  // FileResourceLookup is a "bare" structure that implements the project.ResourceLookup interface
    43  type FileResourceLookup struct {
    44  }
    45  
    46  // Lookup returns the content and the actual filename of the file that is "built" using the
    47  // specified file and relativeTo string. file and relativeTo are supposed to be file path.
    48  // If file starts with a slash ('/'), it tries to load it, otherwise it will build a
    49  // filename using the folder part of relativeTo joined with file.
    50  func (f *FileResourceLookup) Lookup(file, relativeTo string) ([]byte, string, error) {
    51  	file = relativePath(file, relativeTo)
    52  	logrus.Debugf("Reading file %s", file)
    53  	bytes, err := ioutil.ReadFile(file)
    54  	return bytes, file, err
    55  }
    56  
    57  // ResolvePath returns the path to be used for the given path volume. This
    58  // function already takes care of relative paths.
    59  func (f *FileResourceLookup) ResolvePath(path, relativeTo string) string {
    60  	vs := strings.SplitN(path, ":", 2)
    61  	if len(vs) != 2 || filepath.IsAbs(vs[0]) {
    62  		return path
    63  	}
    64  	vs[0] = relativePath(vs[0], relativeTo)
    65  	return strings.Join(vs, ":")
    66  }