...

Source file src/cmd/buildid/buildid.go

     1	// Copyright 2017 The Go Authors. All rights reserved.
     2	// Use of this source code is governed by a BSD-style
     3	// license that can be found in the LICENSE file.
     4	
     5	package main
     6	
     7	import (
     8		"flag"
     9		"fmt"
    10		"log"
    11		"os"
    12		"strings"
    13	
    14		"cmd/internal/buildid"
    15	)
    16	
    17	func usage() {
    18		fmt.Fprintf(os.Stderr, "usage: go tool buildid [-w] file\n")
    19		flag.PrintDefaults()
    20		os.Exit(2)
    21	}
    22	
    23	var wflag = flag.Bool("w", false, "write build ID")
    24	
    25	// taken from cmd/go/internal/work/buildid.go
    26	func hashToString(h [32]byte) string {
    27		const b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
    28		const chunks = 5
    29		var dst [chunks * 4]byte
    30		for i := 0; i < chunks; i++ {
    31			v := uint32(h[3*i])<<16 | uint32(h[3*i+1])<<8 | uint32(h[3*i+2])
    32			dst[4*i+0] = b64[(v>>18)&0x3F]
    33			dst[4*i+1] = b64[(v>>12)&0x3F]
    34			dst[4*i+2] = b64[(v>>6)&0x3F]
    35			dst[4*i+3] = b64[v&0x3F]
    36		}
    37		return string(dst[:])
    38	}
    39	
    40	func main() {
    41		log.SetPrefix("buildid: ")
    42		log.SetFlags(0)
    43		flag.Usage = usage
    44		flag.Parse()
    45		if flag.NArg() != 1 {
    46			usage()
    47		}
    48	
    49		file := flag.Arg(0)
    50		id, err := buildid.ReadFile(file)
    51		if err != nil {
    52			log.Fatal(err)
    53		}
    54		if !*wflag {
    55			fmt.Printf("%s\n", id)
    56			return
    57		}
    58	
    59		// Keep in sync with src/cmd/go/internal/work/buildid.go:updateBuildID
    60	
    61		f, err := os.Open(file)
    62		if err != nil {
    63			log.Fatal(err)
    64		}
    65		matches, hash, err := buildid.FindAndHash(f, id, 0)
    66		if err != nil {
    67			log.Fatal(err)
    68		}
    69		f.Close()
    70	
    71		newID := id[:strings.LastIndex(id, "/")] + "/" + hashToString(hash)
    72		if len(newID) != len(id) {
    73			log.Fatalf("%s: build ID length mismatch %q vs %q", file, id, newID)
    74		}
    75	
    76		if len(matches) == 0 {
    77			return
    78		}
    79	
    80		f, err = os.OpenFile(file, os.O_WRONLY, 0)
    81		if err != nil {
    82			log.Fatal(err)
    83		}
    84		if err := buildid.Rewrite(f, matches, newID); err != nil {
    85			log.Fatal(err)
    86		}
    87		if err := f.Close(); err != nil {
    88			log.Fatal(err)
    89		}
    90	}
    91	

View as plain text