From 0e24d07fce9b50aff33076163b86c3c7556b48f8 Mon Sep 17 00:00:00 2001 From: Mark DeCrane Date: Mon, 6 May 2024 11:15:47 -0400 Subject: [PATCH] Add deprecation info in diagnostic extra field for SRO parsing --- internal/configs/module_deprecations.go | 53 +++++++++++++++++++++---- internal/initwd/module_install.go | 31 ++++++++++----- 2 files changed, 65 insertions(+), 19 deletions(-) diff --git a/internal/configs/module_deprecations.go b/internal/configs/module_deprecations.go index 1bb73f923349..8a43ad397961 100644 --- a/internal/configs/module_deprecations.go +++ b/internal/configs/module_deprecations.go @@ -5,6 +5,8 @@ package configs import ( "fmt" + + "github.com/hashicorp/hcl/v2" ) type WorkspaceDeprecationInfo struct { @@ -24,7 +26,15 @@ type RegistryModuleDeprecation struct { } type ModuleDeprecationDiagnosticExtra struct { - MessageCode string `json:"message_code"` + MessageCode string `json:"message_code"` + Deprecations []*ModuleDeprecationDiagnosticExtraDeprecationItem `json:"deprecations"` +} + +type ModuleDeprecationDiagnosticExtraDeprecationItem struct { + Version string `json:"version"` + SourceName string `json:"source_name"` + DeprecationMessage string `json:"deprecation_message"` + Link string `json:"link"` } func (i *WorkspaceDeprecationInfo) HasDeprecations() bool { @@ -51,11 +61,13 @@ func (i *ModuleDeprecationInfo) hasDeprecations() bool { return false } -func (i *WorkspaceDeprecationInfo) BuildDeprecationWarningString() string { +// Deprecation info is placed as an string in the Diagnostic Detail for console view, +// as well as placed in the Diagnostic Extra for parsing for the SRO view in HCP Terraform +func (i *WorkspaceDeprecationInfo) BuildDeprecationWarning() *hcl.Diagnostic { modDeprecationStrings := []string{} + var deprecationList []*ModuleDeprecationDiagnosticExtraDeprecationItem for _, modDeprecationInfo := range i.ModuleDeprecationInfos { if modDeprecationInfo != nil && modDeprecationInfo.RegistryDeprecation != nil { - // mdTODO: Add highlighting here, look up other examples where it's present modDeprecation := fmt.Sprintf("\x1b[1mVersion %s of %s\x1b[0m", modDeprecationInfo.RegistryDeprecation.Version, modDeprecationInfo.SourceName) // Link and Message are optional fields, if unset they are an empty string by default if modDeprecationInfo.RegistryDeprecation.Message != "" { @@ -64,20 +76,37 @@ func (i *WorkspaceDeprecationInfo) BuildDeprecationWarningString() string { if modDeprecationInfo.RegistryDeprecation.Link != "" { modDeprecation = modDeprecation + fmt.Sprintf("\n\nLink for more information: %s", modDeprecationInfo.RegistryDeprecation.Link) } + deprecationList = append(deprecationList, &ModuleDeprecationDiagnosticExtraDeprecationItem{ + Version: modDeprecationInfo.RegistryDeprecation.Version, + SourceName: modDeprecationInfo.SourceName, + DeprecationMessage: modDeprecationInfo.RegistryDeprecation.Message, + Link: modDeprecationInfo.RegistryDeprecation.Link, + }) modDeprecationStrings = append(modDeprecationStrings, modDeprecation) } - modDeprecationStrings = append(modDeprecationStrings, buildChildDeprecationWarnings(modDeprecationInfo.ExternalDependencies, []string{modDeprecationInfo.SourceName})...) + deprecationStrings, deprecationStructs := buildChildModuleDeprecations(modDeprecationInfo.ExternalDependencies, []string{modDeprecationInfo.SourceName}) + deprecationList = append(deprecationList, deprecationStructs...) + modDeprecationStrings = append(modDeprecationStrings, deprecationStrings...) } deprecationsMessage := "" for _, deprecationString := range modDeprecationStrings { deprecationsMessage += deprecationString + "\n\n" } - return deprecationsMessage + return &hcl.Diagnostic{ + Severity: hcl.DiagWarning, + Summary: "Deprecated modules found, consider installing updated versions. The following are affected:", + Detail: deprecationsMessage, + Extra: &ModuleDeprecationDiagnosticExtra{ + MessageCode: "module_deprecation_warning", + Deprecations: deprecationList, + }, + } } -func buildChildDeprecationWarnings(modDeprecations []*ModuleDeprecationInfo, parentMods []string) []string { +func buildChildModuleDeprecations(modDeprecations []*ModuleDeprecationInfo, parentMods []string) ([]string, []*ModuleDeprecationDiagnosticExtraDeprecationItem) { modDeprecationStrings := []string{} + var deprecationList []*ModuleDeprecationDiagnosticExtraDeprecationItem for _, deprecation := range modDeprecations { if deprecation.RegistryDeprecation != nil { // mdTODO: Add highlighting here, look up other examples where it's present @@ -91,10 +120,18 @@ func buildChildDeprecationWarnings(modDeprecations []*ModuleDeprecationInfo, par } modDeprecationStrings = append(modDeprecationStrings, modDeprecation) } + deprecationList = append(deprecationList, &ModuleDeprecationDiagnosticExtraDeprecationItem{ + Version: deprecation.RegistryDeprecation.Version, + SourceName: deprecation.SourceName, + DeprecationMessage: deprecation.RegistryDeprecation.Message, + Link: deprecation.RegistryDeprecation.Link, + }) newParentMods := append(parentMods, deprecation.SourceName) - modDeprecationStrings = append(modDeprecationStrings, buildChildDeprecationWarnings(deprecation.ExternalDependencies, newParentMods)...) + deprecationStrings, deprecationStructs := buildChildModuleDeprecations(deprecation.ExternalDependencies, newParentMods) + modDeprecationStrings = append(modDeprecationStrings, deprecationStrings...) + deprecationList = append(deprecationList, deprecationStructs...) } - return modDeprecationStrings + return modDeprecationStrings, deprecationList } func buildModHierarchy(parentMods []string, modName string) string { diff --git a/internal/initwd/module_install.go b/internal/initwd/module_install.go index 0710a3ab4dfb..71def33c2d40 100644 --- a/internal/initwd/module_install.go +++ b/internal/initwd/module_install.go @@ -59,6 +59,22 @@ func NewModuleInstaller(modsDir string, loader *configload.Loader, reg *registry } } +func injectMockDeprecations(modules *response.ModuleVersions) { + if modules == nil || modules.Modules == nil { + log.Println("modules or modules.Modules is nil") + return // Exit the function to avoid the panic + } + for _, module := range modules.Modules { + for _, version := range module.Versions { + // Inject a mock deprecation into each version + version.Deprecation = &response.Deprecation{ + Reason: "Mock deprecation message: Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.", + Link: "https://example.com/mock-deprecation", + } + } + } +} + // InstallModules analyses the root module in the given directory and installs // all of its direct and transitive dependencies into the given modules // directory, which must already exist. @@ -140,16 +156,8 @@ func (i *ModuleInstaller) InstallModules(ctx context.Context, rootDir, testsDir cfg, instDiags, workspaceDeprecations := i.installDescendentModules(ctx, rootMod, manifest, walker, installErrsOnly) diags = append(diags, instDiags...) if workspaceDeprecations.HasDeprecations() { - deprecationString := workspaceDeprecations.BuildDeprecationWarningString() - diags = diags.Append(&hcl.Diagnostic{ - Severity: hcl.DiagWarning, - Summary: "Deprecated modules found, consider installing updated versions. The following are affected:", - Detail: deprecationString, - Extra: &configs.ModuleDeprecationDiagnosticExtra{ - MessageCode: "module_deprecation_warning", - }, - }) - + moduleDeprecationWarning := workspaceDeprecations.BuildDeprecationWarning() + diags = diags.Append(moduleDeprecationWarning) } return cfg, diags @@ -278,7 +286,7 @@ func (i *ModuleInstaller) moduleInstallWalker(manifest modsdir.Manifest, upgrade regsrcAddr := regsrc.ModuleFromRegistryPackageAddr(addr.Package) resp, err := regClient.ModuleVersions(ctx, regsrcAddr) - + injectMockDeprecations(resp) if err != nil { log.Printf("[DEBUG] Deprecation for %s could not be checked: call to registry failed", addr.Package.Namespace) @@ -494,6 +502,7 @@ func (i *ModuleInstaller) installRegistryModule(ctx context.Context, req *config var err error log.Printf("[DEBUG] %s listing available versions of %s at %s", key, addr, hostname) resp, err = reg.ModuleVersions(ctx, regsrcAddr) + injectMockDeprecations(resp) if err != nil { if registry.IsModuleNotFound(err) { diags = diags.Append(&hcl.Diagnostic{