Skip to content

Commit a17f635

Browse files
committed
refactor(architecture): Restructure project into modular packages and folders
1 parent 5405efb commit a17f635

File tree

8 files changed

+282
-223
lines changed

8 files changed

+282
-223
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
outputs/
1+
dist/

main.go

Lines changed: 3 additions & 222 deletions
Original file line numberDiff line numberDiff line change
@@ -1,227 +1,8 @@
11
package main
22

3-
import (
4-
"encoding/json"
5-
"fmt"
6-
"os"
7-
"os/exec"
8-
"runtime"
9-
"strings"
10-
)
3+
import "github.com/mdgspace/sysreplicate/system"
114

5+
// main is the entry point for the program.
126
func main() {
13-
osType := runtime.GOOS
14-
fmt.Println("Detected OS Type:", osType)
15-
16-
switch osType {
17-
case "darwin":
18-
fmt.Println("MacOS is not supported")
19-
case "windows":
20-
fmt.Println("Windows is not supported")
21-
case "linux":
22-
distro, base_distro := fetchLinuxDistro()
23-
if distro == "unknown" && base_distro == "unknown" {
24-
fmt.Println("Failed to fetch the details of your distro")
25-
}
26-
fmt.Println("Distribution:", distro)
27-
fmt.Println("Built On:", 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-
}
38-
default:
39-
fmt.Println("OS not supported")
40-
}
41-
}
42-
43-
func fetchLinuxDistro() (string, string) {
44-
data, err := os.ReadFile("/etc/os-release")
45-
46-
if err != nil {
47-
return "unknown", "unknown"
48-
}
49-
var distro, base_distro string
50-
51-
lines := strings.Split(string(data), "\n")
52-
for _, line := range lines {
53-
if strings.HasPrefix(line, "ID=") {
54-
distro = strings.Trim(strings.SplitN(line, "=", 2)[1], `"`)
55-
}
56-
if strings.HasPrefix(line, "ID_LIKE=") {
57-
base_distro = strings.Trim(strings.SplitN(line, "=", 2)[1], `"`)
58-
}
59-
}
60-
61-
return distro, base_distro
62-
}
63-
64-
func fetchPackages(base_distro string) []string {
65-
var cmd *exec.Cmd
66-
var cmdYay *exec.Cmd
67-
switch base_distro {
68-
case "debian":
69-
cmd = exec.Command("dpkg", "--get-selections")
70-
case "arch":
71-
cmd = exec.Command("pacman", "-Qn")
72-
cmdYay = exec.Command("pacman", "-Qm")
73-
case "rhel", "fedora":
74-
cmd = exec.Command("rpm", "-qa")
75-
case "void":
76-
cmd = exec.Command("xbps-query", "-l")
77-
default:
78-
fmt.Println("Your distro is unsupported, cannot identify package manager !")
79-
return []string{"unknown"}
80-
}
81-
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
217-
}
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")
7+
system.Run()
2278
}

system/output/json.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package output
2+
3+
import (
4+
"encoding/json"
5+
)
6+
7+
// BuildSystemJSON creates a well-structured JSON object for the system info and packages.
8+
func BuildSystemJSON(osType, distro, baseDistro string, packages []string) ([]byte, error) {
9+
type ArchPackages struct {
10+
Official []string `json:"official_packages"`
11+
AUR []string `json:"aur_packages"`
12+
}
13+
type SystemInfo struct {
14+
OS string `json:"os"`
15+
Distro string `json:"distro"`
16+
BaseDistro string `json:"base_distro"`
17+
Packages interface{} `json:"packages"`
18+
}
19+
if baseDistro == "arch" {
20+
official, aur := SplitArchPackages(packages)
21+
archPkgs := ArchPackages{Official: official, AUR: aur}
22+
info := SystemInfo{
23+
OS: osType,
24+
Distro: distro,
25+
BaseDistro: baseDistro,
26+
Packages: archPkgs,
27+
}
28+
return json.MarshalIndent(info, "", " ")
29+
}
30+
info := SystemInfo{
31+
OS: osType,
32+
Distro: distro,
33+
BaseDistro: baseDistro,
34+
Packages: packages,
35+
}
36+
return json.MarshalIndent(info, "", " ")
37+
}

system/output/script.go

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
package output
2+
3+
import (
4+
"fmt"
5+
"os"
6+
)
7+
8+
// splitArchPackages splits the combined package list into official and AUR packages for Arch-based distros.
9+
func SplitArchPackages(packages []string) (official, aur []string) {
10+
isAUR := false
11+
for _, pkg := range packages {
12+
if pkg == "YayPackages" {
13+
isAUR = true
14+
continue
15+
}
16+
if isAUR {
17+
if pkg != "" {
18+
aur = append(aur, pkg)
19+
}
20+
} else {
21+
if pkg != "" {
22+
official = append(official, pkg)
23+
}
24+
}
25+
}
26+
return
27+
}
28+
29+
// generateInstallScript creates a shell script to install all packages for the given distro.
30+
// Returns an error if the script cannot be created or written.
31+
func GenerateInstallScript(baseDistro string, packages []string, scriptPath string) error {
32+
f, err := os.Create(scriptPath)
33+
if err != nil {
34+
return err
35+
}
36+
defer f.Close()
37+
38+
_, err = f.WriteString("#!/bin/bash\nset -e\necho 'Starting package installation...'\n")
39+
if err != nil {
40+
return err
41+
}
42+
43+
var installCmd string
44+
switch baseDistro {
45+
case "debian":
46+
installCmd = "sudo apt-get install -y"
47+
case "arch":
48+
installCmd = "sudo pacman -S --noconfirm"
49+
case "rhel", "fedora":
50+
installCmd = "sudo dnf install -y"
51+
case "void":
52+
installCmd = "sudo xbps-install -y"
53+
default:
54+
_, _ = f.WriteString("echo 'Unsupported distro for script generation.'\n")
55+
return nil
56+
}
57+
58+
if baseDistro == "arch" {
59+
official, aur := SplitArchPackages(packages)
60+
_, err = f.WriteString("echo 'Installing official packages with pacman...'\n")
61+
if err != nil {
62+
return err
63+
}
64+
for _, pkg := range official {
65+
if pkg == "" {
66+
continue
67+
}
68+
_, err = f.WriteString(fmt.Sprintf("%s %s || true\n", installCmd, pkg))
69+
if err != nil {
70+
return err
71+
}
72+
}
73+
_, err = f.WriteString("if ! command -v yay >/dev/null; then\n echo 'yay not found, installing yay...'\n sudo pacman -S --noconfirm yay\nfi\n")
74+
if err != nil {
75+
return err
76+
}
77+
_, err = f.WriteString("echo 'Installing AUR packages with yay...'\n")
78+
if err != nil {
79+
return err
80+
}
81+
for _, pkg := range aur {
82+
if pkg == "" {
83+
continue
84+
}
85+
_, err = f.WriteString(fmt.Sprintf("yay -S --noconfirm %s || true\n", pkg))
86+
if err != nil {
87+
return err
88+
}
89+
}
90+
return nil
91+
}
92+
93+
_, err = f.WriteString(fmt.Sprintf("echo 'Installing packages with %s...'\n", installCmd))
94+
if err != nil {
95+
return err
96+
}
97+
for _, pkg := range packages {
98+
if pkg == "" {
99+
continue
100+
}
101+
_, err = f.WriteString(fmt.Sprintf("%s %s || true\n", installCmd, pkg))
102+
if err != nil {
103+
return err
104+
}
105+
}
106+
return nil
107+
}

0 commit comments

Comments
 (0)