github.com/iaas-resource-provision/iaas-rpc@v1.0.7-0.20211021023331-ed21f798c408/internal/command/meta_dependencies.go (about)

     1  package command
     2  
     3  import (
     4  	"os"
     5  
     6  	"github.com/iaas-resource-provision/iaas-rpc/internal/depsfile"
     7  	"github.com/iaas-resource-provision/iaas-rpc/internal/tfdiags"
     8  )
     9  
    10  // dependenclyLockFilename is the filename of the dependency lock file.
    11  //
    12  // This file should live in the same directory as the .tf files for the
    13  // root module of the configuration, alongside the .iaas-rpc.directory
    14  // as long as that directory's path isn't overridden by the TF_DATA_DIR
    15  // environment variable.
    16  //
    17  // We always expect to find this file in the current working directory
    18  // because that should also be the root module directory.
    19  //
    20  // Some commands have legacy command line arguments that make the root module
    21  // directory something other than the root module directory; when using those,
    22  // the lock file will be written in the "wrong" place (the current working
    23  // directory instead of the root module directory) but we do that intentionally
    24  // to match where the ".terraform" directory would also be written in that
    25  // case. Eventually we will phase out those legacy arguments in favor of the
    26  // global -chdir=... option, which _does_ preserve the intended invariant
    27  // that the root module directory is always the current working directory.
    28  const dependencyLockFilename = ".iaas-rpc.lock"
    29  
    30  // lockedDependencies reads the dependency lock information from the lock file
    31  // in the current working directory.
    32  //
    33  // If the lock file doesn't exist at the time of the call, lockedDependencies
    34  // indicates success and returns an empty Locks object. If the file does
    35  // exist then the result is either a representation of the contents of that
    36  // file at the instant of the call or error diagnostics explaining some way
    37  // in which the lock file is invalid.
    38  //
    39  // The result is a snapshot of the locked dependencies at the time of the call
    40  // and does not update as a result of calling replaceLockedDependencies
    41  // or any other modification method.
    42  func (m *Meta) lockedDependencies() (*depsfile.Locks, tfdiags.Diagnostics) {
    43  	// We check that the file exists first, because the underlying HCL
    44  	// parser doesn't distinguish that error from other error types
    45  	// in a machine-readable way but we want to treat that as a success
    46  	// with no locks. There is in theory a race condition here in that
    47  	// the file could be created or removed in the meantime, but we're not
    48  	// promising to support two concurrent dependency installation processes.
    49  	_, err := os.Stat(dependencyLockFilename)
    50  	if os.IsNotExist(err) {
    51  		return depsfile.NewLocks(), nil
    52  	}
    53  
    54  	return depsfile.LoadLocksFromFile(dependencyLockFilename)
    55  }
    56  
    57  // replaceLockedDependencies creates or overwrites the lock file in the
    58  // current working directory to contain the information recorded in the given
    59  // locks object.
    60  func (m *Meta) replaceLockedDependencies(new *depsfile.Locks) tfdiags.Diagnostics {
    61  	return depsfile.SaveLocksToFile(new, dependencyLockFilename)
    62  }