github.com/ActiveState/cli@v0.0.0-20240508170324-6801f60cd051/internal/runbits/activation/activation.go (about)

     1  package activation
     2  
     3  import (
     4  	"os"
     5  	"path/filepath"
     6  	rt "runtime"
     7  
     8  	"github.com/ActiveState/cli/internal/analytics"
     9  	anaConst "github.com/ActiveState/cli/internal/analytics/constants"
    10  	"github.com/ActiveState/cli/internal/config"
    11  	"github.com/ActiveState/cli/internal/constants"
    12  	"github.com/ActiveState/cli/internal/fileevents"
    13  	"github.com/ActiveState/cli/internal/locale"
    14  	"github.com/ActiveState/cli/internal/logging"
    15  	"github.com/ActiveState/cli/internal/output"
    16  	"github.com/ActiveState/cli/internal/process"
    17  	"github.com/ActiveState/cli/internal/sighandler"
    18  	"github.com/ActiveState/cli/internal/subshell"
    19  	"github.com/ActiveState/cli/internal/virtualenvironment"
    20  	"github.com/ActiveState/cli/pkg/project"
    21  )
    22  
    23  func ActivateAndWait(
    24  	proj *project.Project,
    25  	venv *virtualenvironment.VirtualEnvironment,
    26  	out output.Outputer,
    27  	ss subshell.SubShell,
    28  	cfg *config.Instance,
    29  	an analytics.Dispatcher,
    30  	changeDirectory bool) error {
    31  
    32  	logging.Debug("Activating and waiting")
    33  
    34  	projectDir := filepath.Dir(proj.Source().Path())
    35  	if changeDirectory {
    36  		err := os.Chdir(projectDir)
    37  		if err != nil {
    38  			return err
    39  		}
    40  	}
    41  
    42  	ve, err := venv.GetEnv(false, true, projectDir, proj.Namespace().String())
    43  	if err != nil {
    44  		return locale.WrapError(err, "error_could_not_activate_venv", "Could not retrieve environment information.")
    45  	}
    46  
    47  	if _, exists := os.LookupEnv(constants.DisableErrorTipsEnvVarName); exists {
    48  		// If this exists, it came from the installer. It should not exist in an activated environment
    49  		// otherwise.
    50  		ve[constants.DisableErrorTipsEnvVarName] = "false"
    51  	}
    52  
    53  	// ignore interrupts in State Tool on Windows
    54  	if rt.GOOS == "windows" {
    55  		bs := sighandler.NewBackgroundSignalHandler(func(_ os.Signal) {}, os.Interrupt)
    56  		sighandler.Push(bs)
    57  	}
    58  	defer func() {
    59  		if rt.GOOS == "windows" {
    60  			_ = sighandler.Pop() // Overwriting the returned error can mess up error code reporting
    61  		}
    62  	}()
    63  
    64  	if err := ss.SetEnv(ve); err != nil {
    65  		return locale.WrapError(err, "err_subshell_setenv")
    66  	}
    67  	if err := ss.Activate(proj, cfg, out); err != nil {
    68  		return locale.WrapError(err, "error_could_not_activate_subshell", "Could not activate a new subshell.")
    69  	}
    70  
    71  	a, err := process.NewActivation(cfg, os.Getpid())
    72  	if err != nil {
    73  		return locale.WrapError(err, "error_could_not_mark_process", "Could not mark process as activated.")
    74  	}
    75  	defer a.Close()
    76  
    77  	fe, err := fileevents.New(proj)
    78  	if err != nil {
    79  		return locale.WrapError(err, "err_activate_fileevents", "Could not start file event watcher.")
    80  	}
    81  	defer fe.Close()
    82  
    83  	an.Event(anaConst.CatActivationFlow, "before-subshell")
    84  
    85  	err = <-ss.Errors()
    86  	if err != nil {
    87  		return locale.WrapError(err, "error_in_active_subshell", "Failure encountered in active subshell")
    88  	}
    89  
    90  	return nil
    91  }