github.com/grailbio/bigslice@v0.0.0-20230519005545-30c4c12152ad/cmd/bigslice/bigslicecmd/load.go (about)

     1  // Copyright 2019 GRAIL, Inc. All rights reserved.
     2  // Use of this source code is governed by the Apache 2.0
     3  // license that can be found in the LICENSE file.
     4  
     5  package bigslicecmd
     6  
     7  import (
     8  	"encoding/json"
     9  	"log"
    10  	"os"
    11  	"os/exec"
    12  	"time"
    13  )
    14  
    15  // packageInfo is copied from "go help list"
    16  type packageInfo struct {
    17  	Dir           string         // directory containing package sources
    18  	ImportPath    string         // import path of package in dir
    19  	ImportComment string         // path in import comment on package statement
    20  	Name          string         // package name
    21  	Doc           string         // package documentation string
    22  	Target        string         // install path
    23  	Shlib         string         // the shared library that contains this package (only set when -linkshared)
    24  	Goroot        bool           // is this package in the Go root?
    25  	Standard      bool           // is this package part of the standard Go library?
    26  	Stale         bool           // would 'go install' do anything for this package?
    27  	StaleReason   string         // explanation for Stale==true
    28  	Root          string         // Go root or Go path dir containing this package
    29  	ConflictDir   string         // this directory shadows Dir in $GOPATH
    30  	BinaryOnly    bool           // binary-only package: cannot be recompiled from sources
    31  	ForTest       string         // package is only for use in named test
    32  	Export        string         // file containing export data (when using -export)
    33  	Module        *packageModule // info about package's containing module, if any (can be nil)
    34  	Match         []string       // command-line patterns matching this package
    35  	DepOnly       bool           // package is only a dependency, not explicitly listed
    36  
    37  	// Source files
    38  	GoFiles         []string // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles)
    39  	CgoFiles        []string // .go source files that import "C"
    40  	CompiledGoFiles []string // .go files presented to compiler (when using -compiled)
    41  	IgnoredGoFiles  []string // .go source files ignored due to build constraints
    42  	CFiles          []string // .c source files
    43  	CXXFiles        []string // .cc, .cxx and .cpp source files
    44  	MFiles          []string // .m source files
    45  	HFiles          []string // .h, .hh, .hpp and .hxx source files
    46  	FFiles          []string // .f, .F, .for and .f90 Fortran source files
    47  	SFiles          []string // .s source files
    48  	SwigFiles       []string // .swig files
    49  	SwigCXXFiles    []string // .swigcxx files
    50  	SysoFiles       []string // .syso object files to add to archive
    51  	TestGoFiles     []string // _test.go files in package
    52  	XTestGoFiles    []string // _test.go files outside package
    53  
    54  	// Cgo directives
    55  	CgoCFLAGS    []string // cgo: flags for C compiler
    56  	CgoCPPFLAGS  []string // cgo: flags for C preprocessor
    57  	CgoCXXFLAGS  []string // cgo: flags for C++ compiler
    58  	CgoFFLAGS    []string // cgo: flags for Fortran compiler
    59  	CgoLDFLAGS   []string // cgo: flags for linker
    60  	CgoPkgConfig []string // cgo: pkg-config names
    61  
    62  	// Dependency information
    63  	Imports      []string          // import paths used by this package
    64  	ImportMap    map[string]string // map from source import to ImportPath (identity entries omitted)
    65  	Deps         []string          // all (recursively) imported dependencies
    66  	TestImports  []string          // imports from TestGoFiles
    67  	XTestImports []string          // imports from XTestGoFiles
    68  
    69  	// Error information
    70  	Incomplete bool            // this package or a dependency has an error
    71  	Error      *packageError   // error loading package
    72  	DepsErrors []*packageError // errors loading dependencies
    73  }
    74  
    75  // packageError is copied from "go help list"
    76  type packageError struct {
    77  	ImportStack []string // shortest path from package named on command line to this one
    78  	Pos         string   // position of error (if present, file:line:col)
    79  	Err         string   // the error itself
    80  }
    81  
    82  // packageModule is copied from "go help list"
    83  type packageModule struct {
    84  	Path     string              // module path
    85  	Version  string              // module version
    86  	Versions []string            // available module versions (with -versions)
    87  	Replace  *packageModule      // replaced by this module
    88  	Time     *time.Time          // time version was created
    89  	Update   *packageModule      // available update, if any (with -u)
    90  	Main     bool                // is this the main module?
    91  	Indirect bool                // is this module only an indirect dependency of main module?
    92  	Dir      string              // directory holding files for this module, if any
    93  	GoMod    string              // path to go.mod file for this module, if any
    94  	Error    *packageModuleError // error loading module
    95  }
    96  
    97  // packageModuleError is copied from "go help list"
    98  type packageModuleError struct {
    99  	Err string // the error itself
   100  }
   101  
   102  func mustLoad(path string) *packageInfo {
   103  	cmd := exec.Command("go", "list", "-json", path)
   104  	cmd.Stderr = os.Stderr
   105  	data, err := cmd.Output()
   106  	if err != nil {
   107  		log.Fatalf("load %s: %v", path, err)
   108  	}
   109  	info := new(packageInfo)
   110  	if err := json.Unmarshal(data, info); err != nil {
   111  		log.Fatalf("load %s: %v", path, err)
   112  	}
   113  	if info.Error != nil {
   114  		log.Fatalf("load %s: %v", path, info.Error.Err)
   115  	}
   116  	if info.Module == nil {
   117  		log.Fatalf("load %s: package does not define a module", path)
   118  	}
   119  	return info
   120  }