From 6dbfda7e9981fc0f5f03e6001526c7b8b5938257 Mon Sep 17 00:00:00 2001 From: Luc Talatinian <102624213+lucix-aws@users.noreply.github.com> Date: Fri, 19 Apr 2024 18:53:39 -0400 Subject: [PATCH] add crosslink script generator (#2616) --- internal/repotools/cmd/gencrosslink/main.go | 197 ++++++++++++++++++++ 1 file changed, 197 insertions(+) create mode 100644 internal/repotools/cmd/gencrosslink/main.go diff --git a/internal/repotools/cmd/gencrosslink/main.go b/internal/repotools/cmd/gencrosslink/main.go new file mode 100644 index 00000000000..06ab0fdea17 --- /dev/null +++ b/internal/repotools/cmd/gencrosslink/main.go @@ -0,0 +1,197 @@ +// package main is the cmd +package main + +import ( + "encoding/json" + "flag" + "fmt" + "io" + "io/ioutil" + "os" + "path" + "strings" +) + +type shapeType string + +const ( + shapeTypeService shapeType = "service" + // ... +) + +type smithyModel struct { + Shapes map[string]smithyShape `json:"shapes"` +} + +func (m *smithyModel) Service() *serviceShape { + for _, s := range m.Shapes { + if s.typ == shapeTypeService { + return s.asService() + } + } + panic("no service shape found") +} + +type smithyShape struct { + typ shapeType + raw []byte +} + +func (s *smithyShape) UnmarshalJSON(p []byte) error { + var head = struct { + Type shapeType `json:"type"` + }{} + if err := json.Unmarshal(p, &head); err != nil { + return nil + } + + s.typ = head.Type + s.raw = p + return nil +} + +func (s *smithyShape) asService() *serviceShape { + var shape serviceShape + if err := json.Unmarshal(s.raw, &shape); err != nil { + panic(err) + } + + return &shape +} + +type serviceShape struct { + Version string `json:"version"` + Traits smithyTraits `json:"traits"` +} + +type smithyTraits map[string]json.RawMessage + +func (ts smithyTraits) ServiceTrait() (*serviceTrait, bool) { + const traitID = "aws.api#service" + + raw, ok := ts[traitID] + if !ok { + return nil, false + } + + var v serviceTrait + if err := json.Unmarshal(raw, &v); err != nil { + panic(err) + } + + return &v, true +} + +type serviceTrait struct { + SdkID string `json:"sdkId"` + DocID string `json:"docId"` +} + +func loadModels(dir string) ([]smithyModel, error) { + files, err := ioutil.ReadDir(dir) + if err != nil { + return nil, fmt.Errorf("read models dir: %w", err) + } + + var models []smithyModel + for _, file := range files { + f, err := os.Open(path.Join(dir, file.Name())) + if err != nil { + return nil, fmt.Errorf("open %s: %w", file.Name(), err) + } + + p, err := io.ReadAll(f) + if err != nil { + return nil, fmt.Errorf("read %s: %w", file.Name(), err) + } + + var model smithyModel + if err := json.Unmarshal(p, &model); err != nil { + return nil, fmt.Errorf("unmarshal %s: %w", file.Name(), err) + } + + models = append(models, model) + } + return models, nil +} + +func mtoc(model *smithyModel) (docID, pkgName string) { + service := model.Service() + serviceTrait, ok := service.Traits.ServiceTrait() + if !ok { + panic("no service trait") + } + + pkgName = topkg(serviceTrait.SdkID) + docID = serviceTrait.DocID + if docID == "" { + docID = fmt.Sprintf("%s-%s", normalize2(serviceTrait.SdkID), service.Version) + } + return +} + +func topkg(sdkID string) (pkg string) { + pkg = strings.ToLower(sdkID) + pkg = strings.Replace(pkg, " ", "", -1) + pkg = strings.Replace(pkg, "-", "", -1) + return +} + +func normalize2(sdkID string) (v string) { + v = strings.ToLower(sdkID) + v = strings.Replace(v, " ", "-", -1) + return +} + +func main() { + var modelsDir string + flag.StringVar(&modelsDir, "modelsDir", "", "full path to aws-models directory") + flag.Parse() + if modelsDir == "" { + panic("modelsDir not set") + } + + models, err := loadModels(modelsDir) + if err != nil { + panic(err) + } + + docToPkg := map[string]string{} + for _, model := range models { + doc, pkg := mtoc(&model) + docToPkg[doc] = pkg + } + + var mapping string + for k, v := range docToPkg { + mapping += fmt.Sprintf(" '%s': '%s',\n", k, v) + } + + page := ` + + +` + + fmt.Println(page) +}