52 lines
1.7 KiB
Go
52 lines
1.7 KiB
Go
package external
|
||
|
||
import (
|
||
"fmt"
|
||
"os"
|
||
"path/filepath"
|
||
)
|
||
|
||
// LoadDir сканирует директорию modules.d/ — по одной поддиректории на
|
||
// модуль, каждая с manifest.json и бинарниками под все заявленные
|
||
// архитектуры. Отсутствие бинарника под конкретную архитектуру — не
|
||
// фатально на этапе загрузки (модуль может использоваться только для
|
||
// хостов другой архитектуры), но резолвится в ошибку в момент деплоя.
|
||
func LoadDir(dir string) ([]*Module, error) {
|
||
entries, err := os.ReadDir(dir)
|
||
if os.IsNotExist(err) {
|
||
return nil, nil // modules.d/ отсутствует — это нормально, внешних модулей просто нет
|
||
}
|
||
if err != nil {
|
||
return nil, fmt.Errorf("читаю %s: %w", dir, err)
|
||
}
|
||
|
||
var modules []*Module
|
||
for _, e := range entries {
|
||
if !e.IsDir() {
|
||
continue
|
||
}
|
||
moduleDir := filepath.Join(dir, e.Name())
|
||
manifestPath := filepath.Join(moduleDir, "manifest.json")
|
||
if _, err := os.Stat(manifestPath); err != nil {
|
||
continue // директория без manifest.json — не модуль, пропускаем молча
|
||
}
|
||
m, err := LoadManifest(manifestPath)
|
||
if err != nil {
|
||
return nil, fmt.Errorf("модуль в %s: %w", moduleDir, err)
|
||
}
|
||
|
||
binPaths := map[string]string{}
|
||
for _, arch := range m.Architectures {
|
||
p := binaryPath(moduleDir, m.Name, arch)
|
||
if _, err := os.Stat(p); err == nil {
|
||
binPaths[arch] = p
|
||
}
|
||
}
|
||
|
||
modules = append(modules, &Module{
|
||
Manifest: *m,
|
||
BinPath: binPaths,
|
||
})
|
||
}
|
||
return modules, nil
|
||
}
|