func (ws *WorkspaceStore) Workspace(ctx context.Context, c resource.SecretClient, tr resource.Terraformed, ts Setup, cfg config.Resource) (*Workspace, error) {
	dir := filepath.Join(ws.fs.GetTempDir(""), string(tr.GetUID()))
	if err := ws.fs.MkdirAll(dir, os.ModePerm); err != nil {
		return nil, errors.Wrap(err, "cannot create directory for workspace")
	}
	fp, err := NewFileProducer(ctx, c, dir, tr, ts, WithConfig(cfg))
	if err != nil {
		return nil, errors.Wrap(err, "cannot create a new file producer")
	}
	_, err = ws.fs.Stat(filepath.Join(fp.Dir, "terraform.tfstate"))
	if xpresource.Ignore(os.IsNotExist, err) != nil {
		return nil, errors.Wrap(err, "cannot stat terraform.tfstate file")
	}
	if os.IsNotExist(err) {
		if err := fp.WriteTFState(); err != nil {
			return nil, errors.Wrap(err, "cannot reproduce tfstate file")
		}
	}
	if err := fp.WriteMainTF(); err != nil {
		return nil, errors.Wrap(err, "cannot write main tf file")
	}
	l := ws.logger.WithValues("workspace", dir)
	ws.mu.Lock()
	w, ok := ws.store[tr.GetUID()]
	if !ok {
		ws.store[tr.GetUID()] = NewWorkspace(dir, WithLogger(l))
		w = ws.store[tr.GetUID()]
	}
	ws.mu.Unlock()
	_, err = ws.fs.Stat(filepath.Join(dir, ".terraform.lock.hcl"))
	if xpresource.Ignore(os.IsNotExist, err) != nil {
		return nil, errors.Wrap(err, "cannot stat init lock file")
	}
	w.env = ts.Env
	if !os.IsNotExist(err) {
		return w, nil
	}
	cmd := exec.CommandContext(ctx, "terraform", "init", "-input=false")
	cmd.Dir = w.dir
	out, err := cmd.CombinedOutput()
	l.Debug("init ended", "out", string(out))
	return w, errors.Wrapf(err, "cannot init workspace: %s", string(out))
}
Workspace makes sure the Terraform workspace for the given resource is ready
to be used and returns the Workspace object configured to work in that
workspace folder in the filesystem.
package terraform
import (
	"context"
	"os"
	"os/exec"
	"path/filepath"
	"sync"
	"github.com/crossplane/crossplane-runtime/pkg/logging"
	xpresource "github.com/crossplane/crossplane-runtime/pkg/resource"
	"github.com/pkg/errors"
	"github.com/spf13/afero"
	"k8s.io/apimachinery/pkg/types"
	"sigs.k8s.io/controller-runtime/pkg/client"
	"github.com/crossplane-contrib/terrajet/pkg/config"
	"github.com/crossplane-contrib/terrajet/pkg/resource"
)
type SetupFn func(ctx context.Context, client client.Client, mg xpresource.Managed) (Setup, error)
type ProviderRequirement struct {
	Source  string
	Version string
}
type ProviderConfiguration map[string]interface{}
type Setup struct {
	Version       string
	Requirement   ProviderRequirement
	Configuration ProviderConfiguration
	Env           []string
}
type WorkspaceStoreOption func(*WorkspaceStore)
func WithFs(fs afero.Fs) WorkspaceStoreOption {
	return func(ws *WorkspaceStore) {
		ws.fs = afero.Afero{Fs: fs}
	}
}
func NewWorkspaceStore(l logging.Logger, opts ...WorkspaceStoreOption) *WorkspaceStore {
	ws := &WorkspaceStore{
		store:  map[types.UID]*Workspace{},
		logger: l,
		mu:     sync.Mutex{},
		fs:     afero.Afero{Fs: afero.NewOsFs()},
	}
	for _, f := range opts {
		f(ws)
	}
	return ws
}
type WorkspaceStore struct {
	store  map[types.UID]*Workspace
	logger logging.Logger
	mu sync.Mutex
	fs afero.Afero
}