github.com/f-secure-foundry/tamago@v0.0.0-20220307101044-d73fcdd7f11b/_dev/gen_import_report.go (about) 1 // TamaGo import report 2 // Based on https://github.com/trashhalo/tinygo-import-report.git 3 4 package main 5 6 import ( 7 "fmt" 8 "io/ioutil" 9 "os" 10 "os/exec" 11 "sort" 12 "strings" 13 "sync" 14 "text/template" 15 ) 16 17 const mainTemplate = ` 18 package main 19 20 import ( 21 _ "unsafe" 22 _ "{{.}}" 23 ) 24 25 //go:linkname getRandomData runtime.getRandomData 26 func getRandomData(b []byte) { 27 } 28 29 //go:linkname printk runtime.printk 30 func printk(byte) { 31 return 32 } 33 34 //go:linkname hwinit runtime.hwinit 35 func hwinit() { 36 return 37 } 38 39 //go:linkname initRNG runtime.initRNG 40 func initRNG() { 41 return 42 } 43 44 //go:linkname nanotime1 runtime.nanotime1 45 func nanotime1() (ns int64) { 46 return 47 } 48 49 //go:linkname stackOffset runtime.stackOffset 50 var stackOffset uint32 51 52 func main() { 53 } 54 ` 55 56 const readmeTemplate = ` 57 # Tamago Import Report 58 This project imports each package in the stdlib and reports if it imports cleanly in tamago. 59 A package with a check may work a package with a x will definately not currently work. 60 61 | Package | Imported? | 62 | --- | --- |{{ range $key, $value := .}} 63 | {{$value.Name}} | {{if $value.Imported}} ok {{else}} [failed](#{{$value.Link}}) {{end}} | {{ end }} 64 65 66 {{ range $key, $value := .}} 67 ## {{$value.Name}} 68 69 BTBTBT 70 {{$value.Output}} 71 BTBTBT 72 73 {{ end }} 74 ` 75 76 type Result struct { 77 Name string 78 Imported bool 79 Output string 80 Link string 81 } 82 83 func main() { 84 tamagoGo := os.Getenv("TAMAGO") 85 86 if tamagoGo == "" { 87 panic("You need to set the TAMAGO variable to a compiled version of https://github.com/f-secure-foundry/tamago-go") 88 } 89 90 content, err := ioutil.ReadFile("imports") 91 92 if err != nil { 93 panic(err) 94 } 95 96 lines := strings.Split(string(content), "\n") 97 maint := template.Must(template.New("main").Parse(mainTemplate)) 98 readmet := template.Must(template.New("readme").Parse(strings.Replace(readmeTemplate, "BTBTBT", "```", -1))) 99 results := make(chan Result) 100 101 wg := &sync.WaitGroup{} 102 resultsArr := []Result{} 103 104 sem := make(chan struct{}, 4) 105 106 go func() { 107 for r := range results { 108 resultsArr = append(resultsArr, r) 109 println(r.Name) 110 111 wg.Done() 112 } 113 }() 114 115 for _, line := range lines { 116 wg.Add(1) 117 118 go func(line string) { 119 sem <- struct{}{} 120 defer func() { 121 <-sem 122 }() 123 124 noslash := strings.Replace(line, "/", "_", -1) 125 dirsafe := fmt.Sprintf("tests/%v", noslash) 126 os.Mkdir(dirsafe, 0755) 127 f, err := os.Create(fmt.Sprintf("%v/main.go", dirsafe)) 128 129 if err != nil { 130 panic(err) 131 } 132 defer f.Close() 133 134 err = maint.Execute(f, line) 135 136 if err != nil { 137 panic(err) 138 } 139 140 cmd := exec.Command(tamagoGo, "build", fmt.Sprintf("tests/%v/main.go", noslash)) 141 stdoutStderr, err := cmd.CombinedOutput() 142 143 results <- Result{ 144 line, 145 err == nil, 146 string(stdoutStderr), 147 strings.Replace(line, "/", "", -1), 148 } 149 }(line) 150 } 151 152 wg.Wait() 153 close(results) 154 155 sort.Slice(resultsArr, func(i, j int) bool { 156 return resultsArr[i].Name < resultsArr[j].Name 157 }) 158 159 f, err := os.Create("import_report.md") 160 161 if err != nil { 162 panic(err) 163 } 164 defer f.Close() 165 166 err = readmet.Execute(f, resultsArr) 167 168 if err != nil { 169 panic(err) 170 } 171 }