github.com/bluenviron/gomavlib/v2@v2.2.1-0.20240308101627-2c07e3da629c/cmd/dialects-gen/main.go (about) 1 // dialects-gen command. 2 package main 3 4 import ( 5 "encoding/json" 6 "fmt" 7 "net/http" 8 "os" 9 "os/exec" 10 "path/filepath" 11 "strings" 12 "text/template" 13 ) 14 15 var tplTest = template.Must(template.New("").Parse( 16 `//autogenerated:yes 17 //nolint:revive 18 package dialects 19 20 import ( 21 "testing" 22 "encoding" 23 "reflect" 24 25 "github.com/stretchr/testify/require" 26 27 "github.com/bluenviron/gomavlib/v2/pkg/dialect" 28 {{- range .Dialects }} 29 "github.com/bluenviron/gomavlib/v2/pkg/dialects/{{ . }}" 30 {{- end }} 31 ) 32 33 func TestDialects(t *testing.T) { 34 {{- range .Dialects }} 35 func() { 36 _, err := dialect.NewReadWriter({{ . }}.Dialect) 37 require.NoError(t, err) 38 }() 39 {{- end }} 40 } 41 42 var casesEnum = []struct { 43 name string 44 dec encoding.TextMarshaler 45 enc string 46 }{ 47 { 48 "bitmask", 49 common.POSITION_TARGET_TYPEMASK_VX_IGNORE | common.POSITION_TARGET_TYPEMASK_VY_IGNORE, 50 "POSITION_TARGET_TYPEMASK_VX_IGNORE | POSITION_TARGET_TYPEMASK_VY_IGNORE", 51 }, 52 { 53 "value", 54 common.GPS_FIX_TYPE_NO_FIX, 55 "GPS_FIX_TYPE_NO_FIX", 56 }, 57 } 58 59 func TestEnumUnmarshalText(t *testing.T) { 60 for _, ca := range casesEnum { 61 t.Run(ca.name, func(t *testing.T) { 62 dec := reflect.New(reflect.TypeOf(ca.dec)).Interface().(encoding.TextUnmarshaler) 63 err := dec.UnmarshalText([]byte(ca.enc)) 64 require.NoError(t, err) 65 require.Equal(t, ca.dec, reflect.ValueOf(dec).Elem().Interface()) 66 }) 67 } 68 } 69 70 func TestEnumMarshalText(t *testing.T) { 71 for _, ca := range casesEnum { 72 t.Run(ca.name, func(t *testing.T) { 73 byts, err := ca.dec.MarshalText() 74 require.NoError(t, err) 75 require.Equal(t, ca.enc, string(byts)) 76 }) 77 } 78 } 79 `)) 80 81 func writeTemplate(fpath string, tpl *template.Template, args map[string]interface{}) error { 82 f, err := os.Create(fpath) 83 if err != nil { 84 return err 85 } 86 defer f.Close() 87 88 return tpl.Execute(f, args) 89 } 90 91 func shellCommand(cmdstr string) error { 92 fmt.Fprintf(os.Stderr, "%s\n", cmdstr) 93 cmd := exec.Command("sh", "-c", cmdstr) 94 cmd.Stderr = os.Stderr 95 cmd.Stdout = os.Stdout 96 return cmd.Run() 97 } 98 99 func downloadJSON(addr string, data interface{}) error { 100 req, err := http.NewRequest("GET", addr, nil) 101 if err != nil { 102 return err 103 } 104 105 res, err := http.DefaultClient.Do(req) 106 if err != nil { 107 return err 108 } 109 defer res.Body.Close() 110 111 return json.NewDecoder(res.Body).Decode(data) 112 } 113 114 func processDialect(commit string, name string) error { 115 fmt.Fprintf(os.Stderr, "[%s]\n", name) 116 117 err := shellCommand(fmt.Sprintf("go run ../../cmd/dialect-import --link %s", 118 "https://raw.githubusercontent.com/mavlink/mavlink/"+commit+"/message_definitions/v1.0/"+name+".xml", 119 )) 120 if err != nil { 121 return err 122 } 123 124 fmt.Fprintf(os.Stderr, "\n") 125 return nil 126 } 127 128 func run() error { 129 err := shellCommand("rm -rf pkg/dialects/*/") 130 if err != nil { 131 return err 132 } 133 134 os.Mkdir(filepath.Join("pkg", "dialects"), 0o755) 135 os.Chdir(filepath.Join("pkg", "dialects")) 136 137 var res struct { 138 Sha string `json:"sha"` 139 } 140 err = downloadJSON("https://api.github.com/repos/mavlink/mavlink/commits/master", &res) 141 if err != nil { 142 return err 143 } 144 145 var files []struct { 146 Name string `json:"name"` 147 } 148 err = downloadJSON("https://api.github.com/repos/mavlink/mavlink/contents/message_definitions/v1.0?ref="+res.Sha, 149 &files) 150 if err != nil { 151 return err 152 } 153 154 var dialects []string //nolint:prealloc 155 156 for _, f := range files { 157 if !strings.HasSuffix(f.Name, ".xml") { 158 continue 159 } 160 name := f.Name[:len(f.Name)-len(".xml")] 161 162 err = processDialect(res.Sha, name) 163 if err != nil { 164 return err 165 } 166 167 dialects = append(dialects, strings.ReplaceAll(strings.ToLower(name), "_", "")) 168 } 169 170 err = writeTemplate( 171 "package_test.go", 172 tplTest, 173 map[string]interface{}{ 174 "Dialects": dialects, 175 }) 176 if err != nil { 177 return err 178 } 179 180 return nil 181 } 182 183 func main() { 184 err := run() 185 if err != nil { 186 fmt.Fprintf(os.Stderr, "ERR: %s\n", err) 187 os.Exit(1) 188 } 189 }