blob: 1381102184e2a4ba838930bbca3bf8fa16c80a52 [file] [log] [blame]
// 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)
}
}