| // Copyright 2015 The Vanadium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| // Command make_builtin_vdlroot runs at jiri go generate time. It emits a Go |
| // source file called builtin_vdlroot.go containing a gzip'd version of all the |
| // core VDL types required by the VDL tool. This allows the VDL tool to run |
| // 'standalone' (i.e. without access to the Vanadium source code). |
| // |
| // +build ignored |
| |
| package main |
| |
| import ( |
| "archive/tar" |
| "compress/gzip" |
| "fmt" |
| "io" |
| "io/ioutil" |
| "log" |
| "os" |
| "path/filepath" |
| ) |
| |
| const ( |
| outputPreamble = `// Copyright 2015 The Vanadium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| // This file is automatically generated, your changes will be lost. |
| // See make_builtin_vdlroot.go. |
| |
| package main |
| |
| //go:generate jiri go run make_builtin_vdlroot.go |
| |
| const ( |
| // builtinVDLRootData contains the raw bytes for a gzip'd tarball, containing |
| // the vdlroot standard packages required to run the vdl tool. |
| builtinVDLRootData = "` |
| outputFooter = `" |
| ) |
| ` |
| ) |
| |
| // writeBytes writes the given bytes to the given writer, returning an error if |
| // the underlying Write fails or if the number of bytes written is not equal to |
| // len(content). |
| func writeBytes(out io.Writer, content []byte) error { |
| n, err := out.Write(content) |
| if err == nil && n != len(content) { |
| err = fmt.Errorf("wrote an unexpected number of bytes, wanted %d, wrote %d", len(content), n) |
| } |
| return err |
| } |
| |
| // hexWriter writes data as a sequence of \xAB constants. |
| type hexWriter struct { |
| w io.Writer |
| } |
| |
| func (w hexWriter) Write(data []byte) (int, error) { |
| for index, b := range data { |
| if _, err := fmt.Fprintf(w.w, `\x%02X`, b); err != nil { |
| return index, err |
| } |
| } |
| return len(data), nil |
| } |
| |
| // writeVDLRootData creates a gzip'd tar file containing all of the VDL files |
| // in vdlroot. The data is encoded as base64. Does not close out. |
| func writeVDLRootData(out io.Writer) error { |
| jiriRoot := os.Getenv("JIRI_ROOT") |
| if jiriRoot == "" { |
| return fmt.Errorf("JIRI_ROOT is not set") |
| } |
| srcDir := filepath.Join(jiriRoot, "release", "go", "src") |
| vdlroot := filepath.Join(srcDir, "v.io", "v23", "vdlroot") |
| hexWriter := hexWriter{out} |
| gzipWriter := gzip.NewWriter(hexWriter) |
| tarWriter := tar.NewWriter(gzipWriter) |
| walkFn := func(path string, info os.FileInfo, err error) error { |
| if filepath.Ext(path) == ".vdl" || filepath.Base(path) == "vdl.config" { |
| content, err := ioutil.ReadFile(path) |
| if err != nil { |
| return err |
| } |
| relPath, err := filepath.Rel(srcDir, path) |
| if err != nil { |
| return err |
| } |
| header := tar.Header{ |
| Mode: int64(0644), |
| Name: relPath, |
| Size: int64(len(content)), |
| } |
| if err := tarWriter.WriteHeader(&header); err != nil { |
| return err |
| } |
| return writeBytes(tarWriter, content) |
| } |
| return nil |
| } |
| if err := filepath.Walk(vdlroot, walkFn); err != nil { |
| log.Printf("Walk() failed: %v", err) |
| } |
| if err := tarWriter.Close(); err != nil { |
| log.Printf("Close() of tar file failed: %v", err) |
| return err |
| } |
| if err := gzipWriter.Close(); err != nil { |
| log.Printf("Close() of gzip file failed: %v", err) |
| return err |
| } |
| return nil |
| } |
| |
| func main() { |
| filename := "builtin_vdlroot.go" |
| f, err := os.Create(filename) |
| if err != nil { |
| log.Printf("Create(%q) failed: %v", filename, err) |
| os.Exit(1) |
| } |
| defer f.Close() |
| if err := writeBytes(f, []byte(outputPreamble)); err != nil { |
| os.Exit(1) |
| } |
| if err := writeVDLRootData(f); err != nil { |
| os.Exit(1) |
| } |
| if err := writeBytes(f, []byte(outputFooter)); err != nil { |
| os.Exit(1) |
| } |
| } |