diff --git a/vm.go b/vm.go index f9402ba2..08013d2c 100644 --- a/vm.go +++ b/vm.go @@ -237,8 +237,11 @@ func (vm *VM) evaluateSnippet(diagnosticFileName ast.DiagnosticFileName, filenam return output, nil } -func getAbsPath(path string) (string, error) { +func getAbsPath(path string, canonicalPaths bool) (string, error) { var absPath string + + var err error + if filepath.IsAbs(path) { absPath = path } else { @@ -248,14 +251,18 @@ func getAbsPath(path string) (string, error) { } absPath = strings.Join([]string{wd, path}, string(filepath.Separator)) } - cleanedAbsPath, err := filepath.EvalSymlinks(absPath) - if err != nil { - return "", err + + if canonicalPaths { + absPath, err = filepath.EvalSymlinks(absPath) + if err != nil { + return "", err + } } - return cleanedAbsPath, nil + + return absPath, nil } -func (vm *VM) findDependencies(filePath string, node *ast.Node, dependencies map[string]struct{}, stackTrace *[]TraceFrame) (err error) { +func (vm *VM) findDependencies(filePath string, node *ast.Node, dependencies map[string]struct{}, stackTrace *[]TraceFrame, canonicalPaths bool) (err error) { var cleanedAbsPath string switch i := (*node).(type) { case *ast.Import: @@ -266,7 +273,7 @@ func (vm *VM) findDependencies(filePath string, node *ast.Node, dependencies map } cleanedAbsPath = foundAt if _, isFileImporter := vm.importer.(*FileImporter); isFileImporter { - cleanedAbsPath, err = getAbsPath(foundAt) + cleanedAbsPath, err = getAbsPath(foundAt, canonicalPaths) if err != nil { *stackTrace = append([]TraceFrame{{Loc: *i.Loc()}}, *stackTrace...) return err @@ -277,7 +284,7 @@ func (vm *VM) findDependencies(filePath string, node *ast.Node, dependencies map return nil } dependencies[cleanedAbsPath] = struct{}{} - err = vm.findDependencies(foundAt, &node, dependencies, stackTrace) + err = vm.findDependencies(foundAt, &node, dependencies, stackTrace, canonicalPaths) if err != nil { *stackTrace = append([]TraceFrame{{Loc: *i.Loc()}}, *stackTrace...) return err @@ -290,7 +297,7 @@ func (vm *VM) findDependencies(filePath string, node *ast.Node, dependencies map } cleanedAbsPath = foundAt if _, isFileImporter := vm.importer.(*FileImporter); isFileImporter { - cleanedAbsPath, err = getAbsPath(foundAt) + cleanedAbsPath, err = getAbsPath(foundAt, canonicalPaths) if err != nil { *stackTrace = append([]TraceFrame{{Loc: *i.Loc()}}, *stackTrace...) return err @@ -305,7 +312,7 @@ func (vm *VM) findDependencies(filePath string, node *ast.Node, dependencies map } cleanedAbsPath = foundAt if _, isFileImporter := vm.importer.(*FileImporter); isFileImporter { - cleanedAbsPath, err = getAbsPath(foundAt) + cleanedAbsPath, err = getAbsPath(foundAt, canonicalPaths) if err != nil { *stackTrace = append([]TraceFrame{{Loc: *i.Loc()}}, *stackTrace...) return err @@ -314,7 +321,7 @@ func (vm *VM) findDependencies(filePath string, node *ast.Node, dependencies map dependencies[cleanedAbsPath] = struct{}{} default: for _, node := range parser.Children(i) { - err = vm.findDependencies(filePath, &node, dependencies, stackTrace) + err = vm.findDependencies(filePath, &node, dependencies, stackTrace, canonicalPaths) if err != nil { return err } @@ -455,10 +462,28 @@ func (vm *VM) EvaluateFileMulti(filename string) (files map[string]string, forma return output, nil } +type findDepsConfig struct { + canonicalPaths bool +} + +type FindDepsOption func(c *findDepsConfig) + +func WithCanonicalPaths(canonicalize bool) FindDepsOption { + return func(c *findDepsConfig) { c.canonicalPaths = canonicalize } +} + // FindDependencies returns a sorted array of unique transitive dependencies (via import/importstr/importbin) // from all the given `importedPaths` which are themselves excluded from the returned array. // The `importedPaths` are parsed as if they were imported from a Jsonnet file located at `importedFrom`. -func (vm *VM) FindDependencies(importedFrom string, importedPaths []string) ([]string, error) { +func (vm *VM) FindDependencies(importedFrom string, importedPaths []string, opts ...FindDepsOption) ([]string, error) { + config := findDepsConfig{ + canonicalPaths: true, + } + + for _, f := range opts { + f(&config) + } + var nodes []*ast.Node var stackTrace []TraceFrame filePaths := make([]string, len(importedPaths)) @@ -472,7 +497,7 @@ func (vm *VM) FindDependencies(importedFrom string, importedPaths []string) ([]s } cleanedAbsPath := foundAt if _, isFileImporter := vm.importer.(*FileImporter); isFileImporter { - cleanedAbsPath, err = getAbsPath(foundAt) + cleanedAbsPath, err = getAbsPath(foundAt, config.canonicalPaths) if err != nil { return nil, err } @@ -487,7 +512,7 @@ func (vm *VM) FindDependencies(importedFrom string, importedPaths []string) ([]s } for i, filePath := range filePaths { - err := vm.findDependencies(filePath, nodes[i], deps, &stackTrace) + err := vm.findDependencies(filePath, nodes[i], deps, &stackTrace, config.canonicalPaths) if err != nil { err = makeRuntimeError(err.Error(), stackTrace) return nil, errors.New(vm.ErrorFormatter.Format(err))