Skip to content

Commit 5405efb

Browse files
committed
feat(script): Generate setup script for installing packages
Handle installation from Official repository and AUR seperately
1 parent 06dd00b commit 5405efb

File tree

2 files changed

+177
-23
lines changed

2 files changed

+177
-23
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
outputs/

main.go

Lines changed: 176 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package main
22

33
import (
4+
"encoding/json"
45
"fmt"
56
"os"
67
"os/exec"
@@ -10,38 +11,50 @@ import (
1011

1112
func main() {
1213
osType := runtime.GOOS
13-
fmt.Println("Detected OS Type:",osType)
14+
fmt.Println("Detected OS Type:", osType)
1415

15-
switch(osType){
16+
switch osType {
1617
case "darwin":
1718
fmt.Println("MacOS is not supported")
1819
case "windows":
1920
fmt.Println("Windows is not supported")
2021
case "linux":
21-
distro, base_distro := fetchLinusDistro()
22-
if(distro=="unknown" && base_distro=="unknown"){fmt.Println("Failed to fetch the details of your distro")}
22+
distro, base_distro := fetchLinuxDistro()
23+
if distro == "unknown" && base_distro == "unknown" {
24+
fmt.Println("Failed to fetch the details of your distro")
25+
}
2326
fmt.Println("Distribution:", distro)
2427
fmt.Println("Built On:", base_distro)
25-
fmt.Println(fetchPackages(base_distro))
28+
packages := fetchPackages(base_distro)
29+
jsonObj, err := buildSystemJSON(osType, distro, base_distro, packages)
30+
if err != nil {
31+
fmt.Println("Error marshalling JSON:", err)
32+
} else {
33+
os.MkdirAll("outputs/sys", 0744)
34+
os.WriteFile("outputs/sys/package_info.json", jsonObj, 0744)
35+
os.MkdirAll("outputs/scripts", 0744)
36+
generateInstallScript(base_distro, packages, "outputs/scripts/setup.sh")
37+
}
2638
default:
2739
fmt.Println("OS not supported")
28-
2940
}
3041
}
3142

32-
func fetchLinusDistro() (string, string) {
43+
func fetchLinuxDistro() (string, string) {
3344
data, err := os.ReadFile("/etc/os-release")
3445

35-
if (err != nil) {return "unknown", "unknown"}
46+
if err != nil {
47+
return "unknown", "unknown"
48+
}
3649
var distro, base_distro string
3750

38-
lines:= strings.Split(string(data),"\n")
51+
lines := strings.Split(string(data), "\n")
3952
for _, line := range lines {
40-
if strings.HasPrefix(line, "ID="){
41-
distro =strings.Trim(strings.SplitN(line,"=",2)[1],`"`)
53+
if strings.HasPrefix(line, "ID=") {
54+
distro = strings.Trim(strings.SplitN(line, "=", 2)[1], `"`)
4255
}
43-
if (strings.HasPrefix(line, "ID_LIKE=")){
44-
base_distro = strings.Trim(strings.SplitN(line, "=",2)[1],`"`)
56+
if strings.HasPrefix(line, "ID_LIKE=") {
57+
base_distro = strings.Trim(strings.SplitN(line, "=", 2)[1], `"`)
4558
}
4659
}
4760

@@ -50,25 +63,165 @@ func fetchLinusDistro() (string, string) {
5063

5164
func fetchPackages(base_distro string) []string {
5265
var cmd *exec.Cmd
53-
switch(base_distro) {
66+
var cmdYay *exec.Cmd
67+
switch base_distro {
5468
case "debian":
5569
cmd = exec.Command("dpkg", "--get-selections")
5670
case "arch":
57-
cmd = exec.Command("pacman", "-Q")
71+
cmd = exec.Command("pacman", "-Qn")
72+
cmdYay = exec.Command("pacman", "-Qm")
5873
case "rhel", "fedora":
5974
cmd = exec.Command("rpm", "-qa")
6075
case "void":
6176
cmd = exec.Command("xbps-query", "-l")
62-
default :
77+
default:
6378
fmt.Println("Your distro is unsupported, cannot identify package manager !")
6479
return []string{"unknown"}
6580
}
6681

67-
output, err := cmd.CombinedOutput()
68-
if (err != nil) {
69-
fmt.Println("Error in retrieving packages: ", err)
82+
if base_distro != "arch" {
83+
84+
output, err := cmd.CombinedOutput()
85+
if err != nil {
86+
fmt.Println("Error in retrieving packages: ", err)
87+
}
88+
fmt.Println("Installed Packages: ")
89+
packages := strings.Split(string(output), "\n")
90+
return packages
91+
}
92+
93+
outputPacman, err := cmd.CombinedOutput()
94+
outPutYay, errYay := cmdYay.CombinedOutput()
95+
96+
if err != nil {
97+
fmt.Println("Error in retrieving Pacman packages: ", err)
98+
}
99+
if errYay != nil {
100+
fmt.Println("Error in retrieving Yay packages: ", errYay)
101+
}
102+
103+
pacmanPackages := strings.Split(string(outputPacman), "\n")
104+
yayPackages := strings.Split(string(outPutYay), "\n")
105+
106+
yayPackages = append([]string{"YayPackages"}, yayPackages...)
107+
108+
return append(pacmanPackages, yayPackages...)
109+
}
110+
111+
func buildSystemJSON(osType, distro, base_distro string, packages []string) ([]byte, error) {
112+
type ArchPackages struct {
113+
Official []string `json:"official_packages"`
114+
AUR []string `json:"aur_packages"`
115+
}
116+
117+
type SystemInfo struct {
118+
OS string `json:"os"`
119+
Distro string `json:"distro"`
120+
BaseDistro string `json:"base_distro"`
121+
Packages interface{} `json:"packages"`
122+
}
123+
124+
if base_distro == "arch" {
125+
official := []string{}
126+
aur := []string{}
127+
isAUR := false
128+
for _, pkg := range packages {
129+
if pkg == "YayPackages" {
130+
isAUR = true
131+
continue
132+
}
133+
if isAUR {
134+
aur = append(aur, pkg)
135+
} else {
136+
official = append(official, pkg)
137+
}
138+
}
139+
archPkgs := ArchPackages{Official: official, AUR: aur}
140+
info := SystemInfo{
141+
OS: osType,
142+
Distro: distro,
143+
BaseDistro: base_distro,
144+
Packages: archPkgs,
145+
}
146+
return json.MarshalIndent(info, "", " ")
147+
}
148+
149+
info := SystemInfo{
150+
OS: osType,
151+
Distro: distro,
152+
BaseDistro: base_distro,
153+
Packages: packages,
154+
}
155+
return json.MarshalIndent(info, "", " ")
156+
}
157+
158+
func generateInstallScript(base_distro string, packages []string, scriptPath string) {
159+
f, err := os.Create(scriptPath)
160+
if err != nil {
161+
fmt.Println("Error creating script:", err)
162+
return
163+
}
164+
defer f.Close()
165+
166+
f.WriteString("#!/bin/bash\n")
167+
f.WriteString("set -e\n")
168+
f.WriteString("echo 'Starting package installation...'\n")
169+
170+
var installCmd string
171+
switch base_distro {
172+
case "debian":
173+
installCmd = "sudo apt-get install -y"
174+
case "arch":
175+
installCmd = "sudo pacman -S --noconfirm"
176+
case "rhel", "fedora":
177+
installCmd = "sudo dnf install -y"
178+
case "void":
179+
installCmd = "sudo xbps-install -y"
180+
default:
181+
f.WriteString("echo 'Unsupported distro for script generation.'\n")
182+
return
183+
}
184+
185+
if base_distro == "arch" {
186+
official := []string{}
187+
aur := []string{}
188+
isAUR := false
189+
for _, pkg := range packages {
190+
if pkg == "YayPackages" {
191+
isAUR = true
192+
continue
193+
}
194+
if isAUR {
195+
aur = append(aur, pkg)
196+
} else {
197+
official = append(official, pkg)
198+
}
199+
}
200+
f.WriteString("echo 'Installing official packages with pacman...'\n")
201+
for _, pkg := range official {
202+
if pkg == "" {
203+
continue
204+
}
205+
f.WriteString(fmt.Sprintf("%s %s || true\n", installCmd, pkg))
206+
}
207+
f.WriteString("if ! command -v yay >/dev/null; then\n echo 'yay not found, installing yay...'\n sudo pacman -S --noconfirm yay\nfi\n")
208+
f.WriteString("echo 'Installing AUR packages with yay...'\n")
209+
for _, pkg := range aur {
210+
if pkg == "" {
211+
continue
212+
}
213+
f.WriteString(fmt.Sprintf("yay -S --noconfirm %s || true\n", pkg))
214+
}
215+
fmt.Println("Script generated successfully")
216+
return
70217
}
71-
fmt.Println("Installed Packages: ")
72-
packages:=strings.Split(string(output), "\n")
73-
return packages
74-
}
218+
219+
f.WriteString(fmt.Sprintf("echo 'Installing packages with %s...'\n", installCmd))
220+
for _, pkg := range packages {
221+
if pkg == "" {
222+
continue
223+
}
224+
f.WriteString(fmt.Sprintf("%s %s || true\n", installCmd, pkg))
225+
}
226+
fmt.Println("Script generated successfully")
227+
}

0 commit comments

Comments
 (0)