...

Source file src/cuelang.org/go/cue/load/errors.go

Documentation: cuelang.org/go/cue/load

     1  // Copyright 2018 The CUE 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 load
    16  
    17  import (
    18  	"fmt"
    19  	"path/filepath"
    20  	"strings"
    21  
    22  	"cuelang.org/go/cue/build"
    23  	"cuelang.org/go/cue/errors"
    24  	"cuelang.org/go/cue/token"
    25  )
    26  
    27  // A PackageError describes an error loading information about a package.
    28  type PackageError struct {
    29  	ImportStack    []string  // shortest path from package named on command line to this one
    30  	Pos            token.Pos // position of error
    31  	errors.Message           // the error itself
    32  	IsImportCycle  bool      // the error is an import cycle
    33  }
    34  
    35  func (p *PackageError) Position() token.Pos         { return p.Pos }
    36  func (p *PackageError) InputPositions() []token.Pos { return nil }
    37  func (p *PackageError) Path() []string              { return p.ImportStack }
    38  
    39  func (p *PackageError) fillPos(cwd string, positions []token.Pos) {
    40  	if len(positions) > 0 && !p.Pos.IsValid() {
    41  		p.Pos = positions[0]
    42  	}
    43  }
    44  
    45  // TODO(localize)
    46  func (p *PackageError) Error() string {
    47  	// Import cycles deserve special treatment.
    48  	if p.IsImportCycle {
    49  		return fmt.Sprintf("%s\npackage %s\n", p.Message, strings.Join(p.ImportStack, "\n\timports "))
    50  	}
    51  	if p.Pos.IsValid() {
    52  		// Omit import stack. The full path to the file where the error
    53  		// is the most important thing.
    54  		return p.Pos.String() + ": " + p.Message.Error()
    55  	}
    56  	if len(p.ImportStack) == 0 {
    57  		return p.Message.Error()
    58  	}
    59  	return "package " + strings.Join(p.ImportStack, "\n\timports ") + ": " + p.Message.Error()
    60  }
    61  
    62  // NoFilesError is the error used by Import to describe a directory
    63  // containing no usable source files. (It may still contain
    64  // tool files, files hidden by build tags, and so on.)
    65  type NoFilesError struct {
    66  	Package *build.Instance
    67  
    68  	ignored bool // whether any Go files were ignored due to build tags
    69  }
    70  
    71  func (e *NoFilesError) Position() token.Pos         { return token.NoPos }
    72  func (e *NoFilesError) InputPositions() []token.Pos { return nil }
    73  func (e *NoFilesError) Path() []string              { return nil }
    74  
    75  // TODO(localize)
    76  func (e *NoFilesError) Msg() (string, []interface{}) { return e.Error(), nil }
    77  
    78  // TODO(localize)
    79  func (e *NoFilesError) Error() string {
    80  	// Count files beginning with _, which we will pretend don't exist at all.
    81  	dummy := 0
    82  	for _, f := range e.Package.IgnoredFiles {
    83  		if strings.HasPrefix(filepath.Base(f.Filename), "_") {
    84  			dummy++
    85  		}
    86  	}
    87  
    88  	// path := shortPath(e.Package.Root, e.Package.Dir)
    89  	path := e.Package.DisplayPath
    90  
    91  	if len(e.Package.IgnoredFiles) > dummy {
    92  		b := strings.Builder{}
    93  		b.WriteString("build constraints exclude all CUE files in ")
    94  		b.WriteString(path)
    95  		b.WriteString(":")
    96  		// CUE files exist, but they were ignored due to build constraints.
    97  		for _, f := range e.Package.IgnoredFiles {
    98  			b.WriteString("\n    ")
    99  			b.WriteString(filepath.ToSlash(e.Package.RelPath(f)))
   100  			if f.ExcludeReason != nil {
   101  				b.WriteString(": ")
   102  				b.WriteString(f.ExcludeReason.Error())
   103  			}
   104  		}
   105  		return b.String()
   106  	}
   107  	// if len(e.Package.TestCUEFiles) > 0 {
   108  	// 	// Test CUE files exist, but we're not interested in them.
   109  	// 	// The double-negative is unfortunate but we want e.Package.Dir
   110  	// 	// to appear at the end of error message.
   111  	// 	return "no non-test CUE files in " + e.Package.Dir
   112  	// }
   113  	return "no CUE files in " + path
   114  }
   115  
   116  // MultiplePackageError describes an attempt to build a package composed of
   117  // CUE files from different packages.
   118  type MultiplePackageError struct {
   119  	Dir      string   // directory containing files
   120  	Packages []string // package names found
   121  	Files    []string // corresponding files: Files[i] declares package Packages[i]
   122  }
   123  
   124  func (e *MultiplePackageError) Position() token.Pos         { return token.NoPos }
   125  func (e *MultiplePackageError) InputPositions() []token.Pos { return nil }
   126  func (e *MultiplePackageError) Path() []string              { return nil }
   127  
   128  func (e *MultiplePackageError) Msg() (string, []interface{}) {
   129  	return "found packages %q (%s) and %s (%s) in %q", []interface{}{
   130  		e.Packages[0],
   131  		e.Files[0],
   132  		e.Packages[1],
   133  		e.Files[1],
   134  		e.Dir,
   135  	}
   136  }
   137  
   138  func (e *MultiplePackageError) Error() string {
   139  	// Error string limited to two entries for compatibility.
   140  	format, args := e.Msg()
   141  	return fmt.Sprintf(format, args...)
   142  }
   143  

View as plain text