-
Notifications
You must be signed in to change notification settings - Fork 11
chore: init variable manager template #662
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,82 @@ | ||
| package variable | ||
|
|
||
| import ( | ||
| "context" | ||
| "sync" | ||
| "workspace-engine/pkg/model" | ||
| "workspace-engine/pkg/model/resource" | ||
| ) | ||
|
|
||
| type DeploymentVariable interface { | ||
| GetID() string | ||
| GetDeploymentID() string | ||
| GetKey() string | ||
| Resolve(ctx context.Context, resource *resource.Resource) (string, error) | ||
| } | ||
|
|
||
| var _ model.Repository[DeploymentVariable] = (*DeploymentVariableRepository)(nil) | ||
|
|
||
| type DeploymentVariableRepository struct { | ||
| variables map[string]*DeploymentVariable | ||
| mu sync.RWMutex | ||
| } | ||
|
|
||
| func NewDeploymentVariableRepository() *DeploymentVariableRepository { | ||
| return &DeploymentVariableRepository{variables: make(map[string]*DeploymentVariable)} | ||
| } | ||
|
|
||
| func (r *DeploymentVariableRepository) GetAll(ctx context.Context) []*DeploymentVariable { | ||
| r.mu.RLock() | ||
| defer r.mu.RUnlock() | ||
|
|
||
| return nil | ||
| } | ||
|
|
||
| func (r *DeploymentVariableRepository) GetAllByDeploymentID(ctx context.Context, deploymentID string) []*DeploymentVariable { | ||
| r.mu.RLock() | ||
| defer r.mu.RUnlock() | ||
|
|
||
| return nil | ||
| } | ||
|
|
||
| func (r *DeploymentVariableRepository) GetByDeploymentIDAndKey(ctx context.Context, deploymentID, key string) *DeploymentVariable { | ||
| r.mu.RLock() | ||
| defer r.mu.RUnlock() | ||
|
|
||
| return nil | ||
| } | ||
|
|
||
| func (r *DeploymentVariableRepository) Get(ctx context.Context, id string) *DeploymentVariable { | ||
| r.mu.RLock() | ||
| defer r.mu.RUnlock() | ||
|
|
||
| return nil | ||
| } | ||
|
|
||
| func (r *DeploymentVariableRepository) Create(ctx context.Context, variable *DeploymentVariable) error { | ||
| r.mu.Lock() | ||
| defer r.mu.Unlock() | ||
|
|
||
| return nil | ||
| } | ||
|
|
||
| func (r *DeploymentVariableRepository) Update(ctx context.Context, variable *DeploymentVariable) error { | ||
| r.mu.Lock() | ||
| defer r.mu.Unlock() | ||
|
|
||
| return nil | ||
| } | ||
|
|
||
| func (r *DeploymentVariableRepository) Delete(ctx context.Context, id string) error { | ||
| r.mu.Lock() | ||
| defer r.mu.Unlock() | ||
|
|
||
| return nil | ||
| } | ||
|
|
||
| func (r *DeploymentVariableRepository) Exists(ctx context.Context, id string) bool { | ||
| r.mu.RLock() | ||
| defer r.mu.RUnlock() | ||
|
|
||
| return false | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| package variable | ||
|
|
||
| import ( | ||
| "context" | ||
| "fmt" | ||
| "workspace-engine/pkg/model/resource" | ||
| ) | ||
|
|
||
| var _ VariableManager = (*DeploymentVariableManager)(nil) | ||
|
|
||
| type DeploymentVariableManager struct { | ||
| deploymentVariables *DeploymentVariableRepository | ||
| } | ||
|
|
||
| func NewDeploymentVariableManager(deploymentVariables *DeploymentVariableRepository) *DeploymentVariableManager { | ||
| return &DeploymentVariableManager{ | ||
| deploymentVariables: deploymentVariables, | ||
| } | ||
| } | ||
|
|
||
| func (m *DeploymentVariableManager) Resolve(ctx context.Context, resource *resource.Resource, deploymentID string, key string) (*string, error) { | ||
| deploymentVariablePtr := m.deploymentVariables.GetByDeploymentIDAndKey(ctx, deploymentID, key) | ||
| if deploymentVariablePtr == nil || *deploymentVariablePtr == nil { | ||
| return nil, nil | ||
| } | ||
|
|
||
| deploymentVariable := *deploymentVariablePtr | ||
|
|
||
| resolved, err := deploymentVariable.Resolve(ctx, resource) | ||
| if err != nil { | ||
| return nil, fmt.Errorf("failed to resolve deployment variable for key: %s, deploymentID: %s, err: %w", key, deploymentID, err) | ||
| } | ||
|
|
||
| return &resolved, nil | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,35 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| package variable | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "context" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "fmt" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "workspace-engine/pkg/model/resource" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var _ VariableManager = (*ResourceVariableManager)(nil) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type ResourceVariableManager struct { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| resourceVariables *ResourceVariableRepository | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| func NewResourceVariableManager(resourceVariables *ResourceVariableRepository) *ResourceVariableManager { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return &ResourceVariableManager{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| resourceVariables: resourceVariables, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| func (m *ResourceVariableManager) Resolve(ctx context.Context, resource *resource.Resource, deploymentID string, key string) (*string, error) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| resourceVariablePtr := m.resourceVariables.GetByResourceIDAndKey(ctx, resource.GetID(), key) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if resourceVariablePtr == nil || *resourceVariablePtr == nil { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return nil, nil | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| resourceVariable := *resourceVariablePtr | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| resolved, err := resourceVariable.Resolve(ctx) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return nil, fmt.Errorf("failed to resolve resource variable for key: %s, resource: %s, err: %w", key, resource.GetID(), err) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return &resolved, nil | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+21
to
+35
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nil deref risk when resource is nil Resolve dereferences resource twice: once to fetch resource.GetID() and again in the error message. This will panic if callers pass a nil resource. Apply this guard and make the error path nil-safe: func (m *ResourceVariableManager) Resolve(ctx context.Context, resource *resource.Resource, deploymentID string, key string) (*string, error) {
- resourceVariablePtr := m.resourceVariables.GetByResourceIDAndKey(ctx, resource.GetID(), key)
+ if resource == nil {
+ return nil, fmt.Errorf("resource is nil while resolving key: %s", key)
+ }
+ resourceVariablePtr := m.resourceVariables.GetByResourceIDAndKey(ctx, resource.GetID(), key)
@@
- if err != nil {
- return nil, fmt.Errorf("failed to resolve resource variable for key: %s, resource: %s, err: %w", key, resource.GetID(), err)
- }
+ if err != nil {
+ return nil, fmt.Errorf("failed to resolve resource variable for key: %s, resource: %s, err: %w", key, resource.GetID(), err)
+ }📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,47 @@ | ||||||||||||||||||||||
| package variable | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| import ( | ||||||||||||||||||||||
| "context" | ||||||||||||||||||||||
| "fmt" | ||||||||||||||||||||||
| "workspace-engine/pkg/model/resource" | ||||||||||||||||||||||
| ) | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| type VariableManager interface { | ||||||||||||||||||||||
| Resolve(ctx context.Context, resource *resource.Resource, deploymentID string, key string) (*string, error) | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| type WorkspaceVariableManager struct { | ||||||||||||||||||||||
| getKeys func(ctx context.Context, deploymentID string) []string | ||||||||||||||||||||||
| managers []VariableManager | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| func NewWorkspaceVariableManager( | ||||||||||||||||||||||
| getKeys func(ctx context.Context, deploymentID string) []string, | ||||||||||||||||||||||
| managers []VariableManager, | ||||||||||||||||||||||
| ) *WorkspaceVariableManager { | ||||||||||||||||||||||
| return &WorkspaceVariableManager{ | ||||||||||||||||||||||
| getKeys: getKeys, | ||||||||||||||||||||||
| managers: managers, | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| func (v *WorkspaceVariableManager) ResolveDeploymentVariables(ctx context.Context, resource *resource.Resource, deploymentID string) (map[string]string, error) { | ||||||||||||||||||||||
| resolvedVariables := make(map[string]string) | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| keys := v.getKeys(ctx, deploymentID) | ||||||||||||||||||||||
| for _, key := range keys { | ||||||||||||||||||||||
| for _, manager := range v.managers { | ||||||||||||||||||||||
| resolvedValue, err := manager.Resolve(ctx, resource, deploymentID, key) | ||||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||||
| return nil, fmt.Errorf("failed to resolve for key: %s, resource: %s, err: %w", key, resource.GetID(), err) | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
Comment on lines
+35
to
+37
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nil deref risk in error formatting The error path unconditionally calls resource.GetID(). If Resolve was invoked with a nil resource, this will panic before the error can be returned. Apply a nil-safe resource ID for error messages: - return nil, fmt.Errorf("failed to resolve for key: %s, resource: %s, err: %w", key, resource.GetID(), err)
+ rid := "<nil>"
+ if resource != nil {
+ rid = resource.GetID()
+ }
+ return nil, fmt.Errorf("failed to resolve for key: %s, resource: %s, err: %w", key, rid, err)📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||
|
|
||||||||||||||||||||||
| if resolvedValue != nil { | ||||||||||||||||||||||
| resolvedVariables[key] = *resolvedValue | ||||||||||||||||||||||
| break | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| return resolvedVariables, nil | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Repository methods are no-ops; managers will never resolve anything
Every method currently returns zero values. As a result, getKeys returns no keys and Resolve paths will never find variables. Provide a minimal in-memory implementation to make the template usable and testable.
Apply a minimal implementation:
📝 Committable suggestion
🤖 Prompt for AI Agents