// Package modules implements Odoo's module system. // Mirrors: odoo/modules/module.py, odoo/modules/loading.py package modules import ( "fmt" "sync" ) // Module represents an Odoo addon module. // Mirrors: ir.module.module + __manifest__.py type Module struct { Name string // Technical name (e.g., "base", "account", "sale") Description string // Human-readable description Version string // Module version Category string // Module category Depends []string // Required modules (dependency list) AutoInstall bool // Auto-install when all depends are installed Application bool // Show in app list Installable bool // Can be installed Sequence int // Loading order // Init function registers models, fields, and methods. // Called during module loading in dependency order. Init func() // PostInit is called after all modules are loaded. PostInit func() // Data files to load (SQL seed data, etc.) Data []string } // ModuleRegistry holds all registered modules. // Mirrors: odoo/modules/module.py loaded modules var ModuleRegistry = &moduleRegistry{ modules: make(map[string]*Module), } type moduleRegistry struct { mu sync.RWMutex modules map[string]*Module order []string // Registration order } // Register adds a module to the registry. func Register(m *Module) { ModuleRegistry.mu.Lock() defer ModuleRegistry.mu.Unlock() if m.Name == "" { panic("modules: module name is required") } if _, exists := ModuleRegistry.modules[m.Name]; exists { panic(fmt.Sprintf("modules: module %q already registered", m.Name)) } ModuleRegistry.modules[m.Name] = m ModuleRegistry.order = append(ModuleRegistry.order, m.Name) } // Get returns a module by name. func Get(name string) *Module { ModuleRegistry.mu.RLock() defer ModuleRegistry.mu.RUnlock() return ModuleRegistry.modules[name] } // All returns all registered module names. func All() []string { ModuleRegistry.mu.RLock() defer ModuleRegistry.mu.RUnlock() result := make([]string, len(ModuleRegistry.order)) copy(result, ModuleRegistry.order) return result }