...
Source file src/cmd/buildid/buildid.go
1
2
3
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
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
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