This repository was archived by the owner on Jun 21, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinstall.go
148 lines (123 loc) · 3.27 KB
/
install.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
147
148
package controllers
import (
"archive/tar"
"compress/gzip"
"fmt"
"io"
"net/http"
"os"
"path/filepath"
"runtime"
"strings"
"gitlab.com/bjerke-tek/gov/utils"
)
/**********************************************************/
/* This is not finsihed, macOS is not properly supported. */
/* The shitty code quality must be address as well */
/**********************************************************/
func InstallGoVersion(version string) {
if version == "latest" {
fmt.Println("Fetching the latest Go version...")
version = utils.GetLatestVersion("go")
}
if IsInstalled(version) {
fmt.Printf("Go version %s is already installed.\nUse 'gov reinstall %s' to reinstall it.\n", version, version)
return
}
fmt.Printf("Downloading Go version %s...\n", version)
osArch := runtime.GOARCH
var url string
switch runtime.GOOS {
case "linux":
url = fmt.Sprintf("https://golang.org/dl/go%s.%s-%s.tar.gz", version, runtime.GOOS, osArch)
case "darwin":
url = fmt.Sprintf("https://golang.org/dl/go%s.%s-%s.tar.gz", version, runtime.GOOS, osArch)
default:
fmt.Println("Unsupported OS")
os.Exit(1)
}
resp, err := http.Get(url)
if err != nil || resp.StatusCode != http.StatusOK {
fmt.Println("Error downloading Go version.")
os.Exit(1)
}
defer resp.Body.Close()
homeDir, err := os.UserHomeDir()
if err != nil {
fmt.Println("Error getting user home directory.")
os.Exit(1)
}
installDir := filepath.Join(homeDir, "go-versions", version)
os.MkdirAll(installDir, os.ModePerm)
fmt.Printf("Installing Go version %s...\n", version)
gzipReader, err := gzip.NewReader(resp.Body)
if err != nil {
fmt.Println("Error extracting Go archive.")
os.Exit(1)
}
defer gzipReader.Close()
tarReader := tar.NewReader(gzipReader)
for {
header, err := tarReader.Next()
if err == io.EOF {
break
}
if err != nil {
fmt.Println("Error extracting Go archive.")
os.Exit(1)
}
header.Name = strings.TrimPrefix(header.Name, "go/")
targetPath := filepath.Join(installDir, header.Name)
if header.FileInfo().IsDir() {
os.MkdirAll(targetPath, os.ModePerm)
} else {
file, err := os.Create(targetPath)
if err != nil {
fmt.Println("Error extracting Go archive.")
os.Exit(1)
}
defer file.Close()
_, err = io.Copy(file, tarReader)
if err != nil {
fmt.Println("Error extracting Go archive.")
os.Exit(1)
}
if isExecutable(header) {
if err := os.Chmod(targetPath, 0755); err != nil {
fmt.Println("Error setting executable permission on binary file:", err)
os.Exit(1)
}
}
}
}
fmt.Printf("Go version %s installed successfully!\n", version)
}
func isExecutable(header *tar.Header) bool {
return header.Mode&0111 != 0
}
func IsInstalled(version string) bool {
homeDir, err := os.UserHomeDir()
if err != nil {
fmt.Println("Error getting user home directory.")
os.Exit(1)
}
dir := "go-versions"
versionsDir := filepath.Join(homeDir, dir)
if _, err := os.Stat(versionsDir); os.IsNotExist(err) {
return false
} else if err != nil {
fmt.Println("Error checking directory:", err)
os.Exit(1)
}
subDirs, err := os.ReadDir(versionsDir)
if err != nil {
fmt.Println("Error listing versions:", err)
os.Exit(1)
}
for _, subDir := range subDirs {
if subDir.Name() == version {
return true
}
}
return false
}