1
0
mirror of https://github.com/prometheus-community/postgres_exporter.git synced 2025-08-08 04:42:07 +03:00

Add cross-compilation Makefile targets and tar-based releases.

Revamp the build system to be more inline with other Prometheus exporters.
Notably add Darwin and Windows build targets, and add support for releases
using tar files.
This commit is contained in:
Will Rouesnel
2017-11-30 03:15:53 +11:00
parent 61b93a17a6
commit 5b9fea01ee
98 changed files with 10599 additions and 1487 deletions

View File

@@ -12,7 +12,6 @@ import (
"go/parser"
"go/token"
"go/types"
"io"
"os"
"path/filepath"
"regexp"
@@ -29,19 +28,15 @@ import (
"github.com/mvdan/lint"
)
func UnusedParams(tests, debug bool, args ...string) ([]string, error) {
func UnusedParams(tests bool, args ...string) ([]string, error) {
wd, err := os.Getwd()
if err != nil {
return nil, err
}
c := &Checker{
wd: wd,
tests: tests,
wd: wd, tests: tests,
cachedDeclCounts: make(map[string]map[string]int),
}
if debug {
c.debugLog = os.Stderr
}
return c.lines(args...)
}
@@ -51,8 +46,7 @@ type Checker struct {
wd string
tests bool
debugLog io.Writer
tests bool
cachedDeclCounts map[string]map[string]int
}
@@ -107,12 +101,6 @@ func (c *Checker) ProgramSSA(prog *ssa.Program) {
c.prog = prog
}
func (c *Checker) debug(format string, a ...interface{}) {
if c.debugLog != nil {
fmt.Fprintf(c.debugLog, format, a...)
}
}
func (c *Checker) Check() ([]lint.Issue, error) {
wantPkg := make(map[*types.Package]*loader.PackageInfo)
for _, info := range c.lprog.InitialPackages() {
@@ -133,9 +121,7 @@ funcLoop:
if info == nil { // not part of given pkgs
continue
}
c.debug("func %s\n", fn.String())
if dummyImpl(fn.Blocks[0]) { // panic implementation
c.debug(" skip - dummy implementation\n")
continue
}
for _, edge := range cg.Nodes[fn].In {
@@ -144,29 +130,24 @@ funcLoop:
default:
// called via a parameter or field, type
// is set in stone.
c.debug(" skip - type is required via call\n")
continue funcLoop
}
}
if c.multipleImpls(info, fn) {
c.debug(" skip - multiple implementations via build tags\n")
continue
}
for i, par := range fn.Params {
if i == 0 && fn.Signature.Recv() != nil { // receiver
continue
}
c.debug("%s\n", par.String())
switch par.Object().Name() {
case "", "_": // unnamed
c.debug(" skip - unnamed\n")
continue
}
reason := "is unused"
if cv := receivesSameValue(cg.Nodes[fn].In, par, i); cv != nil {
reason = fmt.Sprintf("always receives %v", cv)
} else if anyRealUse(par, i) {
c.debug(" skip - used somewhere in the func body\n")
continue
}
issues = append(issues, Issue{
@@ -177,25 +158,15 @@ funcLoop:
}
// TODO: replace by sort.Slice once we drop Go 1.7 support
sort.Sort(byNamePos{c.prog.Fset, issues})
sort.Sort(byPos(issues))
return issues, nil
}
type byNamePos struct {
fset *token.FileSet
l []lint.Issue
}
type byPos []lint.Issue
func (p byNamePos) Len() int { return len(p.l) }
func (p byNamePos) Swap(i, j int) { p.l[i], p.l[j] = p.l[j], p.l[i] }
func (p byNamePos) Less(i, j int) bool {
p1 := p.fset.Position(p.l[i].Pos())
p2 := p.fset.Position(p.l[j].Pos())
if p1.Filename == p2.Filename {
return p1.Offset < p2.Offset
}
return p1.Filename < p2.Filename
}
func (p byPos) Len() int { return len(p) }
func (p byPos) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
func (p byPos) Less(i, j int) bool { return p[i].Pos() < p[j].Pos() }
func receivesSameValue(in []*callgraph.Edge, par *ssa.Parameter, pos int) constant.Value {
if ast.IsExported(par.Parent().Name()) {
@@ -221,47 +192,27 @@ func receivesSameValue(in []*callgraph.Edge, par *ssa.Parameter, pos int) consta
func anyRealUse(par *ssa.Parameter, pos int) bool {
refLoop:
for _, ref := range *par.Referrers() {
switch x := ref.(type) {
case *ssa.Call:
if x.Call.Value != par.Parent() {
return true // not a recursive call
}
for i, arg := range x.Call.Args {
if arg != par {
continue
}
if i == pos {
// reused directly in a recursive call
continue refLoop
}
}
return true
case *ssa.Store:
if insertedStore(x) {
continue // inserted by go/ssa, not from the code
}
return true
default:
call, ok := ref.(*ssa.Call)
if !ok {
return true
}
if call.Call.Value != par.Parent() {
return true // not a recursive call
}
for i, arg := range call.Call.Args {
if arg != par {
continue
}
if i == pos {
// reused directly in a recursive call
continue refLoop
}
}
return true
}
return false
}
func insertedStore(instr ssa.Instruction) bool {
if instr.Pos() != token.NoPos {
return false
}
store, ok := instr.(*ssa.Store)
if !ok {
return false
}
alloc, ok := store.Addr.(*ssa.Alloc)
// we want exactly one use of this alloc value for it to be
// inserted by ssa and dummy - the alloc instruction itself.
return ok && len(*alloc.Referrers()) == 1
}
var rxHarmlessCall = regexp.MustCompile(`(?i)\b(log(ger)?|errors)\b|\bf?print`)
// dummyImpl reports whether a block is a dummy implementation. This is
@@ -270,15 +221,11 @@ var rxHarmlessCall = regexp.MustCompile(`(?i)\b(log(ger)?|errors)\b|\bf?print`)
func dummyImpl(blk *ssa.BasicBlock) bool {
var ops [8]*ssa.Value
for _, instr := range blk.Instrs {
if insertedStore(instr) {
continue // inserted by go/ssa, not from the code
}
for _, val := range instr.Operands(ops[:0]) {
switch x := (*val).(type) {
case nil, *ssa.Const, *ssa.ChangeType, *ssa.Alloc,
*ssa.MakeInterface, *ssa.Function,
*ssa.Global, *ssa.IndexAddr, *ssa.Slice,
*ssa.UnOp:
*ssa.Global, *ssa.IndexAddr, *ssa.Slice:
case *ssa.Call:
if rxHarmlessCall.MatchString(x.Call.Value.String()) {
continue