-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpyenv.go
146 lines (128 loc) · 3.39 KB
/
pyenv.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
package pyenv
import (
"errors"
"fmt"
"log"
"os"
"os/exec"
"path/filepath"
"strings"
)
type PyEnvOptions struct {
ParentPath string
// distributions: darwin/amd64 darwin/arm64 linux/arm64 linux/amd64 windows/386 windows/amd64
Distribution string
Compressed bool
}
type Installer interface {
Install() error
}
type Executor interface {
AddDependencies(string) error
ExecutePython(...string) (*exec.Cmd, error)
}
type PyEnv struct {
EnvOptions PyEnvOptions
Installer
Executor
}
type (
DarwinPyEnv struct{ EnvOptions *PyEnvOptions }
LinuxPyEnv struct{ EnvOptions *PyEnvOptions }
WindowsPyEnv struct{ EnvOptions *PyEnvOptions }
)
func NewPyEnv(path string, dist string) (*PyEnv, error) {
homedir, err := os.UserHomeDir()
if err != nil {
return nil, fmt.Errorf("error getting $HOME directory: %v", err)
}
if path == homedir {
err := fmt.Errorf("path cannot be homedir\npath given: %s\nhomedir: %s", path, homedir)
return nil, err
}
pyEnv := PyEnv{
EnvOptions: PyEnvOptions{
ParentPath: path,
Distribution: dist,
Compressed: false,
},
}
osArchError := fmt.Errorf("this os/arch distribution is not supported: %v", dist)
switch {
case strings.Contains(dist, "darwin"):
if dist != "darwin/amd64" && dist != "darwin/arm64" {
return nil, osArchError
}
pyEnv.Installer = &DarwinPyEnv{&pyEnv.EnvOptions}
pyEnv.Executor = &DarwinPyEnv{&pyEnv.EnvOptions}
case strings.Contains(dist, "linux"):
if dist != "linux/amd64" && dist != "linux/arm64" {
return nil, osArchError
}
pyEnv.Installer = &LinuxPyEnv{&pyEnv.EnvOptions}
pyEnv.Executor = &LinuxPyEnv{&pyEnv.EnvOptions}
case strings.Contains(dist, "windows"):
if dist != "windows/amd64" && dist != "windows/386" {
return nil, osArchError
}
pyEnv.Installer = &WindowsPyEnv{&pyEnv.EnvOptions}
pyEnv.Executor = &WindowsPyEnv{&pyEnv.EnvOptions}
default:
return nil, osArchError
}
return &pyEnv, nil
}
func (env *PyEnvOptions) DistExists() (*bool, error) {
t := true
f := false
_, err := os.Stat(DistDirPath(env))
if err == nil {
return &t, nil
}
if errors.Is(err, os.ErrNotExist) {
_, err = os.Stat(DistZipPath(env))
if err == nil {
return &t, nil
}
if errors.Is(err, os.ErrNotExist) {
return &f, nil
}
return nil, err
}
return nil, err
}
func (env *PyEnvOptions) CompressDist() error {
if env.Compressed {
return fmt.Errorf("dist is already compressed")
}
if err := compressDir(DistDirPath(env), DistZipPath(env)); err != nil {
return fmt.Errorf("error compressing python environment: %v", err)
}
env.Compressed = true
if err := os.RemoveAll(DistDirPath(env)); err != nil {
return fmt.Errorf("error removing old uncompressed evironment: %v", err)
}
log.Printf("removed %v\n", DistDirPath(env))
return nil
}
func (env *PyEnvOptions) DecompressDist() error {
if !env.Compressed {
log.Println("dist is already decompressed")
return nil
}
env.Compressed = false
if err := unzipSource(DistZipPath(env), DistDirPath(env)); err != nil {
return fmt.Errorf("error unzipping compressed evironment: %v", err)
}
if err := os.RemoveAll(DistZipPath(env)); err != nil {
return fmt.Errorf("error removing old compressed evironment: %v", err)
}
log.Printf("removed %v\n", DistZipPath(env))
return nil
}
func DistDirPath(env *PyEnvOptions) string {
return filepath.Join(env.ParentPath, "dist")
}
func DistZipPath(env *PyEnvOptions) string {
return DistDirPath(env) + ZIP_FILE_EXT
}