dev/import-beats/icons.go (137 lines of code) (raw):

// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one // or more contributor license agreements. Licensed under the Elastic License; // you may not use this file except in compliance with the Elastic License. package main import ( "bufio" "io/ioutil" "log" "os" "path" "path/filepath" "regexp" "strings" "github.com/pkg/errors" ) const ( tutorialsPath = "src/plugins/home/server/tutorials" kibanaLogosPath = "src/plugins/home/public/assets/logos" ) var ( errIconNotFound = errors.New("icon not found") iconRe = regexp.MustCompile(`euiIconType: '[^']+'`) aliasedModuleNames = map[string]string{ "redisenterprise": "redis", "php_fpm": "php", "postgresql": "postgres", "appsearch": "app_search", "googlecloud": "gcp", } ) type iconRepository struct { icons map[string]string } func newIconRepository(euiDir, kibanaDir string) (*iconRepository, error) { icons, err := populateIconRepository(euiDir, kibanaDir) if err != nil { return nil, errors.Wrapf(err, "populating icon repository failed") } return &iconRepository{icons: icons}, nil } func populateIconRepository(euiDir, kibanaDir string) (map[string]string, error) { log.Println("Populate icon registry") kibanaIconRefs, err := retrieveIconPathFromTutorials(kibanaDir) if err != nil { return nil, errors.Wrapf(err, "retrieving icon references failed") } euiRefs, err := retrieveIconPathFromEUI(euiDir) if err != nil { return nil, errors.Wrapf(err, "collecting icon data failed") } refs := map[string]string{} for k, v := range kibanaIconRefs { refs[k] = v } for k, v := range euiRefs { refs[k] = v } return refs, nil } func retrieveIconPathFromTutorials(kibanaDir string) (map[string]string, error) { refs := map[string]string{} tutorialsPath := filepath.Join(kibanaDir, tutorialsPath) tutorialFilePaths, err := filepath.Glob(filepath.Join(tutorialsPath, "*_*", "index.ts")) if err != nil { return nil, errors.Wrapf(err, "globbing tutorial files failed (path: %s)", tutorialsPath) } for _, tutorialFilePath := range tutorialFilePaths { log.Printf("Scan tutorial file: %s", tutorialFilePath) tutorialFile, err := ioutil.ReadFile(tutorialFilePath) if err != nil { return nil, errors.Wrapf(err, "reading tutorial file failed (path: %s)", tutorialFile) } m := iconRe.Find(tutorialFile) if m == nil { log.Printf("\t%s: icon not found", tutorialFilePath) continue } s := strings.Split(string(m), `'`) val := s[1] // Extracting module name from tutorials path // e.g. ./src/plugins/home/server/tutorials//php_fpm_metrics/index.ts -> php_fpm moduleName := filepath.Base(filepath.Dir(tutorialFilePath)) moduleName = moduleName[:strings.LastIndex(moduleName, "_")] if filepath.IsAbs(val) { iconFileName := filepath.Base(val) val = path.Join(kibanaDir, kibanaLogosPath, iconFileName) refs[moduleName] = val } } return refs, nil } func retrieveIconPathFromEUI(euiDir string) (map[string]string, error) { refs := map[string]string{} iconMapPath := filepath.Join(euiDir, "src/components/icon/icon.tsx") iconMapFile, err := os.Open(iconMapPath) if err != nil { return nil, errors.Wrapf(err, "opening icon map file failed (path: %s)", iconMapPath) } scanner := bufio.NewScanner(iconMapFile) var mapFound bool for scanner.Scan() { line := scanner.Text() if mapFound { line = strings.TrimLeft(line, " ") if strings.HasPrefix(line, "logo") { s := strings.Split(line, `'`) fileName := s[1] fileNameWithExt := fileName + ".svg" filePath := filepath.Join(euiDir, "src/components/icon/assets", fileNameWithExt) moduleName := fileName[strings.Index(fileName, "_")+1:] refs[moduleName] = filePath } } else if strings.HasPrefix(line, `const typeToPathMap = {`) { mapFound = true } } return refs, nil } func (ir *iconRepository) iconForModule(moduleName string) (imageContent, error) { source, ok := ir.icons[aliasModuleName(moduleName)] if !ok { return imageContent{}, errIconNotFound } return imageContent{source: source}, nil } func aliasModuleName(moduleName string) string { if v, ok := aliasedModuleNames[moduleName]; ok { return v } return moduleName } func createIcons(iconRepository *iconRepository, moduleName string) (imageContentArray, error) { anIcon, err := iconRepository.iconForModule(moduleName) if err == errIconNotFound { log.Printf("\t%s: icon not found", moduleName) return []imageContent{}, nil } if err != nil { return nil, errors.Wrapf(err, "fetching icon for module failed (moduleName: %s)", moduleName) } return []imageContent{anIcon}, nil }