devtools/src/jehanne/cmd/preen/preen.go

158 lines
3.0 KiB
Go

package main
import (
"encoding/json"
"flag"
"io/ioutil"
"log"
"os"
"path/filepath"
)
var config = struct {
Jehanne string
Args []string
Except map[string]bool
CmdName string
FullPath string
Src string
Uroot string
Cwd string
Bbsh string
Goroot string
Gosrcroot string
Arch string
Goos string
Gopath string
TempDir string
Go string
Debug bool
Fail bool
}{
Jehanne: os.Getenv("JEHANNE"),
Except: map[string]bool{"cflags.json": true, "9": true, "libauthcmd.json": true, "awk.json": true, "bzip2": true, "klibc.json": true, "kcmds.json": true, "klib.json": true, "kernel.json": true},
}
type fixup func(string, map[string]interface{})
func cflags(n string, jsmap map[string]interface{}) {
if _, ok := jsmap["Cflags"]; ok {
log.Printf("Deleting Cflags from %v", n)
delete(jsmap, "Cflags")
// TODO: once we have another ARCH, use it.
a := []string{"/arch/amd64/include/cflags.json"}
switch tval := jsmap["Include"].(type) {
case []interface{}:
for _, v := range tval {
a = append(a, v.(string))
}
}
jsmap["Include"] = a
}
}
func removeempty(n string, jsmap map[string]interface{}) {
for key, val := range jsmap {
switch tval := val.(type) {
case map[string]interface{}:
log.Printf("%s: tval %s", n, tval)
if len(tval) == 0 {
delete(jsmap, key)
}
case []interface{}:
if len(tval) == 0 {
delete(jsmap, key)
}
}
}
}
func checkname(n string, jsmap map[string]interface{}) {
if _, ok := jsmap["Name"]; !ok {
log.Print("File %v has no \"Name\" key", n)
}
}
func one(n string, f ...fixup) error {
buf, err := ioutil.ReadFile(n)
if err != nil {
return err
}
var jsmap map[string]interface{}
if err := json.Unmarshal(buf, &jsmap); err != nil {
return err
}
if config.Debug {
log.Printf("%v: %v", n, jsmap)
}
for _, d := range f {
d(n, jsmap)
}
buf, err = json.MarshalIndent(jsmap, "", "\t")
if err != nil {
return err
}
buf = append(buf, '\n')
if config.Debug {
os.Stdout.Write(buf)
} else {
ioutil.WriteFile(n, buf, 0666)
}
return nil
}
func init() {
if config.Jehanne == "" {
log.Fatalf("Please set $JEHANNE")
}
if len(config.Args) == 0 {
config.Args = []string{config.Jehanne}
}
}
func main() {
var err error
flag.BoolVar(&config.Debug, "d", true, "Enable debug prints")
flag.Parse()
config.Args = flag.Args()
for _, n := range config.Args {
err = filepath.Walk(n, func(name string, fi os.FileInfo, err error) error {
if err != nil {
return err
}
if fi.IsDir() {
if config.Except[fi.Name()] {
return filepath.SkipDir
}
return nil
}
n := fi.Name()
if len(n) < 5 || n[len(n)-5:] != ".json" {
return nil
}
todo := []fixup{cflags, removeempty, checkname}
if config.Except[n] {
todo = todo[1:]
}
log.Printf("process %s", name)
err = one(name, todo...)
if err != nil {
log.Printf("%s: %s\n", name, err)
return err
}
return nil
})
if err != nil {
log.Fatal("%v", err)
}
}
}