mirror of
https://github.com/opentofu/opentofu.git
synced 2026-02-18 18:17:54 -05:00
handle install errs in installDescendentModules
This will allow us to use the same logic for `get` too.
This commit is contained in:
parent
09d91eb675
commit
f6768de218
4 changed files with 62 additions and 46 deletions
|
|
@ -166,35 +166,12 @@ func DirFromModule(ctx context.Context, loader *configload.Loader, rootDir, modu
|
|||
}
|
||||
fetcher := getmodules.NewPackageFetcher()
|
||||
|
||||
// When attempting to initialize the current directory with a module
|
||||
// source, some use cases may want to ignore configuration errors from the
|
||||
// building of the entire configuration structure, but we still need to
|
||||
// capture installation errors. Because the actual module installation
|
||||
// happens in the ModuleWalkFunc callback while building the config, we
|
||||
// need to create a closure to capture the installation diagnostics
|
||||
// separately.
|
||||
var instDiags hcl.Diagnostics
|
||||
w := inst.moduleInstallWalker(ctx, instManifest, true, wrapHooks, fetcher)
|
||||
walker := configs.ModuleWalkerFunc(func(req *configs.ModuleRequest) (*configs.Module, *version.Version, hcl.Diagnostics) {
|
||||
mod, version, diags := w.LoadModule(req)
|
||||
instDiags = instDiags.Extend(diags)
|
||||
return mod, version, diags
|
||||
})
|
||||
|
||||
_, cDiags := inst.installDescendentModules(fakeRootModule, instManifest, walker)
|
||||
// We can't continue if there was an error during installation, but return
|
||||
// all diagnostics in case there happens to be anything else useful when
|
||||
// debugging the problem.
|
||||
if instDiags.HasErrors() {
|
||||
walker := inst.moduleInstallWalker(ctx, instManifest, true, wrapHooks, fetcher)
|
||||
_, cDiags := inst.installDescendentModules(fakeRootModule, instManifest, walker, true)
|
||||
if cDiags.HasErrors() {
|
||||
return diags.Append(cDiags)
|
||||
}
|
||||
|
||||
// if there are errors here, they must be only from building the config
|
||||
// structures. We don't want to block initialization at this point, so
|
||||
// convert these into warnings. Any actual errors in the configuration will
|
||||
// be raised as soon as the config is loaded again.
|
||||
diags = append(diags, tfdiags.OverrideAll(cDiags, tfdiags.Warning, nil)...)
|
||||
|
||||
// If all of that succeeded then we'll now migrate what was installed
|
||||
// into the final directory structure.
|
||||
err = os.MkdirAll(modulesDir, os.ModePerm)
|
||||
|
|
|
|||
|
|
@ -77,6 +77,12 @@ func NewModuleInstaller(modsDir string, loader *configload.Loader, reg *registry
|
|||
// needs to replace a directory that is already present with a newly-extracted
|
||||
// package.
|
||||
//
|
||||
// installErrsOnly installs modules but converts validation errors from
|
||||
// building the configuration after installation to warnings. This is used by
|
||||
// commands like `get` or `init -from-module` where the established behavior
|
||||
// was only to install the requested module, and extra validation can break
|
||||
// compatibility.
|
||||
//
|
||||
// If the returned diagnostics contains errors then the module installation
|
||||
// may have wholly or partially completed. Modules must be loaded in order
|
||||
// to find their dependencies, so this function does many of the same checks
|
||||
|
|
@ -85,7 +91,7 @@ func NewModuleInstaller(modsDir string, loader *configload.Loader, reg *registry
|
|||
// If successful (the returned diagnostics contains no errors) then the
|
||||
// first return value is the early configuration tree that was constructed by
|
||||
// the installation process.
|
||||
func (i *ModuleInstaller) InstallModules(ctx context.Context, rootDir, testsDir string, upgrade bool, hooks ModuleInstallHooks) (*configs.Config, tfdiags.Diagnostics) {
|
||||
func (i *ModuleInstaller) InstallModules(ctx context.Context, rootDir, testsDir string, upgrade, installErrsOnly bool, hooks ModuleInstallHooks) (*configs.Config, tfdiags.Diagnostics) {
|
||||
log.Printf("[TRACE] ModuleInstaller: installing child modules for %s into %s", rootDir, i.modsDir)
|
||||
var diags tfdiags.Diagnostics
|
||||
|
||||
|
|
@ -129,7 +135,7 @@ func (i *ModuleInstaller) InstallModules(ctx context.Context, rootDir, testsDir
|
|||
}
|
||||
walker := i.moduleInstallWalker(ctx, manifest, upgrade, hooks, fetcher)
|
||||
|
||||
cfg, instDiags := i.installDescendentModules(rootMod, manifest, walker)
|
||||
cfg, instDiags := i.installDescendentModules(rootMod, manifest, walker, installErrsOnly)
|
||||
diags = append(diags, instDiags...)
|
||||
|
||||
return cfg, diags
|
||||
|
|
@ -277,12 +283,45 @@ func (i *ModuleInstaller) moduleInstallWalker(ctx context.Context, manifest mods
|
|||
)
|
||||
}
|
||||
|
||||
func (i *ModuleInstaller) installDescendentModules(rootMod *configs.Module, manifest modsdir.Manifest, installWalker configs.ModuleWalker) (*configs.Config, tfdiags.Diagnostics) {
|
||||
func (i *ModuleInstaller) installDescendentModules(rootMod *configs.Module, manifest modsdir.Manifest, installWalker configs.ModuleWalker, installErrsOnly bool) (*configs.Config, tfdiags.Diagnostics) {
|
||||
var diags tfdiags.Diagnostics
|
||||
|
||||
cfg, cDiags := configs.BuildConfig(rootMod, installWalker)
|
||||
// When attempting to initialize the current directory with a module
|
||||
// source, some use cases may want to ignore configuration errors from the
|
||||
// building of the entire configuration structure, but we still need to
|
||||
// capture installation errors. Because the actual module installation
|
||||
// happens in the ModuleWalkFunc callback while building the config, we
|
||||
// need to create a closure to capture the installation diagnostics
|
||||
// separately.
|
||||
var instDiags hcl.Diagnostics
|
||||
walker := installWalker
|
||||
if installErrsOnly {
|
||||
walker = configs.ModuleWalkerFunc(func(req *configs.ModuleRequest) (*configs.Module, *version.Version, hcl.Diagnostics) {
|
||||
mod, version, diags := installWalker.LoadModule(req)
|
||||
instDiags = instDiags.Extend(diags)
|
||||
return mod, version, diags
|
||||
})
|
||||
}
|
||||
|
||||
cfg, cDiags := configs.BuildConfig(rootMod, walker)
|
||||
diags = diags.Append(cDiags)
|
||||
if installErrsOnly {
|
||||
// We can't continue if there was an error during installation, but
|
||||
// return all diagnostics in case there happens to be anything else
|
||||
// useful when debugging the problem. Any instDiags will be included in
|
||||
// diags already.
|
||||
if instDiags.HasErrors() {
|
||||
return cfg, diags
|
||||
}
|
||||
|
||||
// If there are any errors here, they must be only from building the
|
||||
// config structures. We don't want to block initialization at this
|
||||
// point, so convert these into warnings. Any actual errors in the
|
||||
// configuration will be raised as soon as the config is loaded again.
|
||||
// We continue below because writing the manifest is required to finish
|
||||
// module installation.
|
||||
diags = tfdiags.OverrideAll(diags, tfdiags.Warning, nil)
|
||||
}
|
||||
|
||||
err := manifest.WriteSnapshotToDir(i.modsDir)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ func TestModuleInstaller(t *testing.T) {
|
|||
loader, close := configload.NewLoaderForTests(t)
|
||||
defer close()
|
||||
inst := NewModuleInstaller(modulesDir, loader, nil)
|
||||
_, diags := inst.InstallModules(context.Background(), ".", "tests", false, hooks)
|
||||
_, diags := inst.InstallModules(context.Background(), ".", "tests", false, false, hooks)
|
||||
assertNoDiagnostics(t, diags)
|
||||
|
||||
wantCalls := []testInstallHookCall{
|
||||
|
|
@ -110,7 +110,7 @@ func TestModuleInstaller_error(t *testing.T) {
|
|||
loader, close := configload.NewLoaderForTests(t)
|
||||
defer close()
|
||||
inst := NewModuleInstaller(modulesDir, loader, nil)
|
||||
_, diags := inst.InstallModules(context.Background(), ".", "tests", false, hooks)
|
||||
_, diags := inst.InstallModules(context.Background(), ".", "tests", false, false, hooks)
|
||||
|
||||
if !diags.HasErrors() {
|
||||
t.Fatal("expected error")
|
||||
|
|
@ -131,7 +131,7 @@ func TestModuleInstaller_emptyModuleName(t *testing.T) {
|
|||
loader, close := configload.NewLoaderForTests(t)
|
||||
defer close()
|
||||
inst := NewModuleInstaller(modulesDir, loader, nil)
|
||||
_, diags := inst.InstallModules(context.Background(), ".", "tests", false, hooks)
|
||||
_, diags := inst.InstallModules(context.Background(), ".", "tests", false, false, hooks)
|
||||
|
||||
if !diags.HasErrors() {
|
||||
t.Fatal("expected error")
|
||||
|
|
@ -169,7 +169,7 @@ func TestModuleInstaller_packageEscapeError(t *testing.T) {
|
|||
loader, close := configload.NewLoaderForTests(t)
|
||||
defer close()
|
||||
inst := NewModuleInstaller(modulesDir, loader, nil)
|
||||
_, diags := inst.InstallModules(context.Background(), ".", "tests", false, hooks)
|
||||
_, diags := inst.InstallModules(context.Background(), ".", "tests", false, false, hooks)
|
||||
|
||||
if !diags.HasErrors() {
|
||||
t.Fatal("expected error")
|
||||
|
|
@ -207,7 +207,7 @@ func TestModuleInstaller_explicitPackageBoundary(t *testing.T) {
|
|||
loader, close := configload.NewLoaderForTests(t)
|
||||
defer close()
|
||||
inst := NewModuleInstaller(modulesDir, loader, nil)
|
||||
_, diags := inst.InstallModules(context.Background(), ".", "tests", false, hooks)
|
||||
_, diags := inst.InstallModules(context.Background(), ".", "tests", false, false, hooks)
|
||||
|
||||
if diags.HasErrors() {
|
||||
t.Fatalf("unexpected errors\n%s", diags.Err().Error())
|
||||
|
|
@ -230,7 +230,7 @@ func TestModuleInstaller_ExactMatchPrerelease(t *testing.T) {
|
|||
loader, close := configload.NewLoaderForTests(t)
|
||||
defer close()
|
||||
inst := NewModuleInstaller(modulesDir, loader, registry.NewClient(nil, nil))
|
||||
cfg, diags := inst.InstallModules(context.Background(), ".", "tests", false, hooks)
|
||||
cfg, diags := inst.InstallModules(context.Background(), ".", "tests", false, false, hooks)
|
||||
|
||||
if diags.HasErrors() {
|
||||
t.Fatalf("found unexpected errors: %s", diags.Err())
|
||||
|
|
@ -257,7 +257,7 @@ func TestModuleInstaller_PartialMatchPrerelease(t *testing.T) {
|
|||
loader, close := configload.NewLoaderForTests(t)
|
||||
defer close()
|
||||
inst := NewModuleInstaller(modulesDir, loader, registry.NewClient(nil, nil))
|
||||
cfg, diags := inst.InstallModules(context.Background(), ".", "tests", false, hooks)
|
||||
cfg, diags := inst.InstallModules(context.Background(), ".", "tests", false, false, hooks)
|
||||
|
||||
if diags.HasErrors() {
|
||||
t.Fatalf("found unexpected errors: %s", diags.Err())
|
||||
|
|
@ -280,7 +280,7 @@ func TestModuleInstaller_invalid_version_constraint_error(t *testing.T) {
|
|||
loader, close := configload.NewLoaderForTests(t)
|
||||
defer close()
|
||||
inst := NewModuleInstaller(modulesDir, loader, nil)
|
||||
_, diags := inst.InstallModules(context.Background(), ".", "tests", false, hooks)
|
||||
_, diags := inst.InstallModules(context.Background(), ".", "tests", false, false, hooks)
|
||||
|
||||
if !diags.HasErrors() {
|
||||
t.Fatal("expected error")
|
||||
|
|
@ -306,7 +306,7 @@ func TestModuleInstaller_invalidVersionConstraintGetter(t *testing.T) {
|
|||
loader, close := configload.NewLoaderForTests(t)
|
||||
defer close()
|
||||
inst := NewModuleInstaller(modulesDir, loader, nil)
|
||||
_, diags := inst.InstallModules(context.Background(), ".", "tests", false, hooks)
|
||||
_, diags := inst.InstallModules(context.Background(), ".", "tests", false, false, hooks)
|
||||
|
||||
if !diags.HasErrors() {
|
||||
t.Fatal("expected error")
|
||||
|
|
@ -332,7 +332,7 @@ func TestModuleInstaller_invalidVersionConstraintLocal(t *testing.T) {
|
|||
loader, close := configload.NewLoaderForTests(t)
|
||||
defer close()
|
||||
inst := NewModuleInstaller(modulesDir, loader, nil)
|
||||
_, diags := inst.InstallModules(context.Background(), ".", "tests", false, hooks)
|
||||
_, diags := inst.InstallModules(context.Background(), ".", "tests", false, false, hooks)
|
||||
|
||||
if !diags.HasErrors() {
|
||||
t.Fatal("expected error")
|
||||
|
|
@ -358,7 +358,7 @@ func TestModuleInstaller_symlink(t *testing.T) {
|
|||
loader, close := configload.NewLoaderForTests(t)
|
||||
defer close()
|
||||
inst := NewModuleInstaller(modulesDir, loader, nil)
|
||||
_, diags := inst.InstallModules(context.Background(), ".", "tests", false, hooks)
|
||||
_, diags := inst.InstallModules(context.Background(), ".", "tests", false, false, hooks)
|
||||
assertNoDiagnostics(t, diags)
|
||||
|
||||
wantCalls := []testInstallHookCall{
|
||||
|
|
@ -434,7 +434,7 @@ func TestLoaderInstallModules_registry(t *testing.T) {
|
|||
loader, close := configload.NewLoaderForTests(t)
|
||||
defer close()
|
||||
inst := NewModuleInstaller(modulesDir, loader, registry.NewClient(nil, nil))
|
||||
_, diags := inst.InstallModules(context.Background(), dir, "tests", false, hooks)
|
||||
_, diags := inst.InstallModules(context.Background(), dir, "tests", false, false, hooks)
|
||||
assertNoDiagnostics(t, diags)
|
||||
|
||||
v := version.Must(version.NewVersion("0.0.1"))
|
||||
|
|
@ -597,7 +597,7 @@ func TestLoaderInstallModules_goGetter(t *testing.T) {
|
|||
loader, close := configload.NewLoaderForTests(t)
|
||||
defer close()
|
||||
inst := NewModuleInstaller(modulesDir, loader, registry.NewClient(nil, nil))
|
||||
_, diags := inst.InstallModules(context.Background(), dir, "tests", false, hooks)
|
||||
_, diags := inst.InstallModules(context.Background(), dir, "tests", false, false, hooks)
|
||||
assertNoDiagnostics(t, diags)
|
||||
|
||||
wantCalls := []testInstallHookCall{
|
||||
|
|
@ -715,7 +715,7 @@ func TestModuleInstaller_fromTests(t *testing.T) {
|
|||
loader, close := configload.NewLoaderForTests(t)
|
||||
defer close()
|
||||
inst := NewModuleInstaller(modulesDir, loader, nil)
|
||||
_, diags := inst.InstallModules(context.Background(), ".", "tests", false, hooks)
|
||||
_, diags := inst.InstallModules(context.Background(), ".", "tests", false, false, hooks)
|
||||
assertNoDiagnostics(t, diags)
|
||||
|
||||
wantCalls := []testInstallHookCall{
|
||||
|
|
@ -772,7 +772,7 @@ func TestLoadInstallModules_registryFromTest(t *testing.T) {
|
|||
loader, close := configload.NewLoaderForTests(t)
|
||||
defer close()
|
||||
inst := NewModuleInstaller(modulesDir, loader, registry.NewClient(nil, nil))
|
||||
_, diags := inst.InstallModules(context.Background(), dir, "tests", false, hooks)
|
||||
_, diags := inst.InstallModules(context.Background(), dir, "tests", false, false, hooks)
|
||||
assertNoDiagnostics(t, diags)
|
||||
|
||||
v := version.Must(version.NewVersion("0.0.1"))
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ func LoadConfigForTests(t *testing.T, rootDir string, testsDir string) (*configs
|
|||
loader, cleanup := configload.NewLoaderForTests(t)
|
||||
inst := NewModuleInstaller(loader.ModulesDir(), loader, registry.NewClient(nil, nil))
|
||||
|
||||
_, moreDiags := inst.InstallModules(context.Background(), rootDir, testsDir, true, ModuleInstallHooksImpl{})
|
||||
_, moreDiags := inst.InstallModules(context.Background(), rootDir, testsDir, true, false, ModuleInstallHooksImpl{})
|
||||
diags = diags.Append(moreDiags)
|
||||
if diags.HasErrors() {
|
||||
cleanup()
|
||||
|
|
|
|||
Loading…
Reference in a new issue