(dir string)
| 485 | } |
| 486 | |
| 487 | func detectPulumiProject(dir string) (pulumiProjectInfo, error) { |
| 488 | runtime, venv, templateDefaults, err := detectRuntime(dir) |
| 489 | if err != nil { |
| 490 | return pulumiProjectInfo{}, err |
| 491 | } |
| 492 | |
| 493 | project, err := pulumiworkspace.LoadProject(filepath.Join(dir, "Pulumi.yaml")) |
| 494 | if err != nil { |
| 495 | return pulumiProjectInfo{}, fmt.Errorf("loading Pulumi project: %w", err) |
| 496 | } |
| 497 | |
| 498 | stack := resolvePulumiStackName(dir, project.StackConfigDir) |
| 499 | configValues, err := loadPulumiStackConfig(dir, project, stack) |
| 500 | if err != nil { |
| 501 | return pulumiProjectInfo{}, err |
| 502 | } |
| 503 | |
| 504 | // Merge template defaults as a fallback: stack config wins, template defaults fill gaps. |
| 505 | if len(templateDefaults) > 0 { |
| 506 | if configValues == nil { |
| 507 | configValues = make(map[string]string) |
| 508 | } |
| 509 | for key, val := range templateDefaults { |
| 510 | if _, exists := configValues[key]; !exists { |
| 511 | configValues[key] = val |
| 512 | } |
| 513 | } |
| 514 | } |
| 515 | |
| 516 | if len(configValues) > 0 { |
| 517 | fmt.Fprintf(os.Stderr, "Resolved config: %v\n", configValues) |
| 518 | } |
| 519 | |
| 520 | return pulumiProjectInfo{ |
| 521 | Name: string(project.Name), |
| 522 | Runtime: runtime, |
| 523 | Virtualenv: venv, |
| 524 | Stack: stack, |
| 525 | Config: configValues, |
| 526 | }, nil |
| 527 | } |
| 528 | |
| 529 | func resolvePulumiStackName(dir, stackConfigDir string) string { |
| 530 | if stack := strings.TrimSpace(pulumiEstimateStack); stack != "" { |
no test coverage detected