github.com/ActiveState/cli@v0.0.0-20240508170324-6801f60cd051/pkg/platform/runtime/setup/implementations/camel/apy_install_lin_win.go (about) 1 //go:build !darwin 2 // +build !darwin 3 4 package camel 5 6 import ( 7 "os/exec" 8 "path/filepath" 9 "strings" 10 11 "github.com/ActiveState/cli/internal/constants" 12 "github.com/ActiveState/cli/internal/errs" 13 "github.com/ActiveState/cli/internal/fileutils" 14 "github.com/ActiveState/cli/internal/locale" 15 "github.com/ActiveState/cli/internal/logging" 16 "github.com/ActiveState/cli/internal/multilog" 17 "github.com/ActiveState/cli/internal/rollbar" 18 ) 19 20 // InstallFromArchive will unpack the installer archive, locate the install script, and then use the installer 21 // script to install an ActivePython runtime to the configured runtime dir. Any failures 22 // during this process will result in a failed installation and the install-dir being removed. 23 func (m *MetaData) pythonRelocationDir(installRoot string) (string, error) { 24 python, err := locatePythonExecutable(installRoot) 25 if err != nil { 26 return "", err 27 } 28 29 prefix, err := extractPythonRelocationPrefix(installRoot, python) 30 if err != nil { 31 return "", err 32 } 33 34 // relocate python 35 return prefix, nil 36 } 37 38 // locatePythonExecutable will locate the path to the python binary in the runtime dir. 39 func locatePythonExecutable(installDir string) (string, error) { 40 binPath := filepath.Join(installDir, "bin") 41 python2 := filepath.Join(installDir, "bin", constants.ActivePython2Executable) 42 python3 := filepath.Join(installDir, "bin", constants.ActivePython3Executable) 43 44 var executable string 45 var executablePath string 46 if fileutils.FileExists(python3) { 47 executable = constants.ActivePython3Executable 48 executablePath = python3 49 } else if fileutils.FileExists(python2) { 50 executable = constants.ActivePython2Executable 51 executablePath = python2 52 } else { 53 return "", locale.NewError("installer_err_runtime_no_executable", "", binPath, constants.ActivePython2Executable, constants.ActivePython3Executable) 54 } 55 56 if !fileutils.IsExecutable(executablePath) { 57 return "", &ErrNotExecutable{locale.NewError("installer_err_runtime_executable_not_exec", "", binPath, executable)} 58 } 59 return executablePath, nil 60 } 61 62 // extractRelocationPrefix will extract the prefix that needs to be replaced for this installation. 63 func extractPythonRelocationPrefix(installDir string, python string) (string, error) { 64 prefixBytes, err := exec.Command(python, "-c", "import activestate; print('\\n'.join(activestate.prefixes))").Output() 65 logging.Debug("bin: %s", python) 66 logging.Debug("OUTPUT: %s", string(prefixBytes)) 67 if err != nil { 68 if _, isExitError := err.(*exec.ExitError); isExitError { 69 multilog.Log(logging.ErrorNoStacktrace, rollbar.Error)("obtaining relocation prefixes: %v : %s", err, string(prefixBytes)) 70 return "", &ErrNoPrefixes{locale.NewError("installer_err_fail_obtain_prefixes", "", installDir)} 71 } 72 return "", errs.Wrap(err, "python import prefixes failed") 73 } 74 if strings.TrimSpace(string(prefixBytes)) == "" { 75 return "", &ErrNoPrefixes{locale.NewError("installer_err_fail_obtain_prefixes", "", installDir)} 76 } 77 return strings.Split(string(prefixBytes), "\n")[0], nil 78 }