127 lines
5.3 KiB
Go
127 lines
5.3 KiB
Go
/*
|
|
Copyright 2021 Qiniu Cloud (qiniu.com)
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
package build
|
|
|
|
import (
|
|
"crypto/sha256"
|
|
"fmt"
|
|
"path"
|
|
"time"
|
|
)
|
|
|
|
// declareCoverVars attaches the required cover variables names
|
|
// to the files, to be used when annotating the files.
|
|
func declareCoverVars(p *Package) map[string]*FileVar {
|
|
coverVars := make(map[string]*FileVar)
|
|
coverIndex := 0
|
|
// We create the cover counters as new top-level variables in the package.
|
|
// We need to avoid collisions with user variables (GoCover_0 is unlikely but still)
|
|
// and more importantly with dot imports of other covered packages,
|
|
// so we append 12 hex digits from the SHA-256 of the import path.
|
|
// The point is only to avoid accidents, not to defeat users determined to
|
|
// break things.
|
|
sum := sha256.Sum256([]byte(p.ImportPath))
|
|
h := fmt.Sprintf("%x", sum[:6])
|
|
for _, file := range p.GoFiles {
|
|
// These names appear in the cmd/cover HTML interface.
|
|
var longFile = path.Join(p.ImportPath, file)
|
|
coverVars[file] = &FileVar{
|
|
File: longFile,
|
|
Var: fmt.Sprintf("GoCover_%d_%x", coverIndex, h),
|
|
}
|
|
coverIndex++
|
|
}
|
|
|
|
for _, file := range p.CgoFiles {
|
|
// These names appear in the cmd/cover HTML interface.
|
|
var longFile = path.Join(p.ImportPath, file)
|
|
coverVars[file] = &FileVar{
|
|
File: longFile,
|
|
Var: fmt.Sprintf("GoCover_%d_%x", coverIndex, h),
|
|
}
|
|
coverIndex++
|
|
}
|
|
|
|
return coverVars
|
|
}
|
|
|
|
// PackageCover holds all the generate coverage variables of a package
|
|
type PackageCover struct {
|
|
Package *Package
|
|
Vars map[string]*FileVar
|
|
}
|
|
|
|
// FileVar holds the name of the generated coverage variables targeting the named file.
|
|
type FileVar struct {
|
|
File string // 这里其实不是文件名,是 importpath + filename
|
|
Var string
|
|
}
|
|
|
|
// Package map a package output by go list
|
|
// this is subset of package struct in: https://github.com/golang/go/blob/master/src/cmd/go/internal/load/pkg.go#L58
|
|
type Package struct {
|
|
Dir string `json:"Dir"` // directory containing package sources
|
|
ImportPath string `json:"ImportPath"` // import path of package in dir
|
|
Name string `json:"Name"` // package name
|
|
Target string `json:",omitempty"` // installed target for this package (may be executable)
|
|
Root string `json:",omitempty"` // Go root, Go path dir, or module root dir containing this package
|
|
|
|
Module *ModulePublic `json:",omitempty"` // info about package's module, if any
|
|
Goroot bool `json:"Goroot,omitempty"` // is this package in the Go root?
|
|
Standard bool `json:"Standard,omitempty"` // is this package part of the standard Go library?
|
|
DepOnly bool `json:"DepOnly,omitempty"` // package is only a dependency, not explicitly listed
|
|
|
|
// Source files
|
|
GoFiles []string `json:"GoFiles,omitempty"` // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles)
|
|
CgoFiles []string `json:"CgoFiles,omitempty"` // .go source files that import "C"
|
|
|
|
// Dependency information
|
|
Deps []string `json:"Deps,omitempty"` // all (recursively) imported dependencies
|
|
Imports []string `json:",omitempty"` // import paths used by this package
|
|
ImportMap map[string]string `json:",omitempty"` // map from source import to ImportPath (identity entries omitted)
|
|
|
|
// Error information
|
|
Incomplete bool `json:"Incomplete,omitempty"` // this package or a dependency has an error
|
|
Error *PackageError `json:"Error,omitempty"` // error loading package
|
|
DepsErrors []*PackageError `json:"DepsErrors,omitempty"` // errors loading dependencies
|
|
}
|
|
|
|
// ModulePublic represents the package info of a module
|
|
type ModulePublic struct {
|
|
Path string `json:",omitempty"` // module path
|
|
Version string `json:",omitempty"` // module version
|
|
Versions []string `json:",omitempty"` // available module versions
|
|
Replace *ModulePublic `json:",omitempty"` // replaced by this module
|
|
Time *time.Time `json:",omitempty"` // time version was created
|
|
Update *ModulePublic `json:",omitempty"` // available update (with -u)
|
|
Main bool `json:",omitempty"` // is this the main module?
|
|
Indirect bool `json:",omitempty"` // module is only indirectly needed by main module
|
|
Dir string `json:",omitempty"` // directory holding local copy of files, if any
|
|
GoMod string `json:",omitempty"` // path to go.mod file describing module, if any
|
|
GoVersion string `json:",omitempty"` // go version used in module
|
|
Error *ModuleError `json:",omitempty"` // error loading module
|
|
}
|
|
|
|
// ModuleError represents the error loading module
|
|
type ModuleError struct {
|
|
Err string // error text
|
|
}
|
|
|
|
// PackageError is the error info for a package when list failed
|
|
type PackageError struct {
|
|
ImportStack []string // shortest path from package named on command line to this one
|
|
Pos string // position of error (if present, file:line:col)
|
|
Err string // the error itself
|
|
}
|