Skip to content

Commit f2a7249

Browse files
authored
Update main.go
1 parent 1b1043e commit f2a7249

File tree

1 file changed

+284
-0
lines changed

1 file changed

+284
-0
lines changed

source-code/main.go

Lines changed: 284 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,285 @@
1+
package main
2+
3+
import (
4+
"bufio"
5+
"fmt"
6+
"io"
7+
"net/http"
8+
"os"
9+
"os/exec"
10+
"path/filepath"
11+
"strings"
12+
13+
"github.com/spf13/cobra"
14+
)
15+
16+
var baseDir string
17+
18+
func init() {
19+
home, err := os.UserHomeDir()
20+
if err != nil {
21+
panic(err)
22+
}
23+
baseDir = filepath.Join(home, ".hackeros", "hacker-lang")
24+
os.MkdirAll(filepath.Join(baseDir, "libs"), 0755)
25+
os.MkdirAll(filepath.Join(baseDir, "plugins"), 0755)
26+
os.MkdirAll(filepath.Join(baseDir, "sources"), 0755)
27+
}
28+
29+
const (
30+
libRepoURL = "https://raw.githubusercontent.com/Bytes-Repository/bytes.io/main/repository/bytes.io"
31+
pluginRepoURL = "https://raw.githubusercontent.com/Bytes-Repository/bytes.io/main/repository/plugins-repo.hacker"
32+
sourceRepoURL = "https://raw.githubusercontent.com/Bytes-Repository/bytes.io/main/repository/source-repo.hacker"
33+
)
34+
35+
func getRepoContent(url string) (string, error) {
36+
resp, err := http.Get(url)
37+
if err != nil {
38+
return "", err
39+
}
40+
defer resp.Body.Close()
41+
body, err := io.ReadAll(resp.Body)
42+
if err != nil {
43+
return "", err
44+
}
45+
return string(body), nil
46+
}
47+
48+
func parseRepo(content string) map[string]string {
49+
repo := make(map[string]string)
50+
scanner := bufio.NewScanner(strings.NewReader(content))
51+
var section string
52+
for scanner.Scan() {
53+
line := strings.TrimSpace(scanner.Text())
54+
if line == "" {
55+
continue
56+
}
57+
if strings.HasSuffix(line, ":") {
58+
section = strings.TrimSpace(line[:len(line)-1])
59+
continue
60+
}
61+
if strings.Contains(line, ":") && section != "" {
62+
parts := strings.SplitN(line, ":", 2)
63+
key := strings.Trim(parts[0], " \t\"")
64+
value := strings.Trim(parts[1], " \t\"")
65+
repo[key] = value
66+
}
67+
}
68+
return repo
69+
}
70+
71+
func downloadFile(url, path string) error {
72+
resp, err := http.Get(url)
73+
if err != nil {
74+
return err
75+
}
76+
defer resp.Body.Close()
77+
f, err := os.Create(path)
78+
if err != nil {
79+
return err
80+
}
81+
defer f.Close()
82+
_, err = io.Copy(f, resp.Body)
83+
return err
84+
}
85+
86+
var installCmd = &cobra.Command{
87+
Use: "install [library]",
88+
Short: "Install a library",
89+
Args: cobra.ExactArgs(1),
90+
RunE: func(cmd *cobra.Command, args []string) error {
91+
name := args[0]
92+
content, err := getRepoContent(libRepoURL)
93+
if err != nil {
94+
return err
95+
}
96+
repo := parseRepo(content)
97+
url, ok := repo[name]
98+
if !ok {
99+
return fmt.Errorf("library %s not found", name)
100+
}
101+
filename := filepath.Base(url)
102+
path := filepath.Join(baseDir, "libs", filename)
103+
if err := downloadFile(url, path); err != nil {
104+
return err
105+
}
106+
fmt.Printf("Installed %s to %s\n", name, path)
107+
return nil
108+
},
109+
}
110+
111+
var removeCmd = &cobra.Command{
112+
Use: "remove [library]",
113+
Short: "Remove a library",
114+
Args: cobra.ExactArgs(1),
115+
RunE: func(cmd *cobra.Command, args []string) error {
116+
name := args[0]
117+
content, err := getRepoContent(libRepoURL)
118+
if err != nil {
119+
return err
120+
}
121+
repo := parseRepo(content)
122+
url, ok := repo[name]
123+
if !ok {
124+
return fmt.Errorf("library %s not found", name)
125+
}
126+
filename := filepath.Base(url)
127+
path := filepath.Join(baseDir, "libs", filename)
128+
if err := os.Remove(path); err != nil {
129+
if os.IsNotExist(err) {
130+
fmt.Printf("%s not installed\n", name)
131+
return nil
132+
}
133+
return err
134+
}
135+
fmt.Printf("Removed %s\n", name)
136+
return nil
137+
},
138+
}
139+
140+
var pluginCmd = &cobra.Command{
141+
Use: "plugin",
142+
Short: "Manage plugins",
143+
}
144+
145+
var pluginInstallCmd = &cobra.Command{
146+
Use: "install [plugin]",
147+
Short: "Install a plugin",
148+
Args: cobra.ExactArgs(1),
149+
RunE: func(cmd *cobra.Command, args []string) error {
150+
name := args[0]
151+
content, err := getRepoContent(pluginRepoURL)
152+
if err != nil {
153+
return err
154+
}
155+
repo := parseRepo(content)
156+
url, ok := repo[name]
157+
if !ok {
158+
return fmt.Errorf("plugin %s not found", name)
159+
}
160+
filename := filepath.Base(url)
161+
path := filepath.Join(baseDir, "plugins", filename)
162+
if err := downloadFile(url, path); err != nil {
163+
return err
164+
}
165+
fmt.Printf("Installed plugin %s to %s\n", name, path)
166+
return nil
167+
},
168+
}
169+
170+
var pluginRemoveCmd = &cobra.Command{
171+
Use: "remove [plugin]",
172+
Short: "Remove a plugin",
173+
Args: cobra.ExactArgs(1),
174+
RunE: func(cmd *cobra.Command, args []string) error {
175+
name := args[0]
176+
content, err := getRepoContent(pluginRepoURL)
177+
if err != nil {
178+
return err
179+
}
180+
repo := parseRepo(content)
181+
url, ok := repo[name]
182+
if !ok {
183+
return fmt.Errorf("plugin %s not found", name)
184+
}
185+
filename := filepath.Base(url)
186+
path := filepath.Join(baseDir, "plugins", filename)
187+
if err := os.Remove(path); err != nil {
188+
if os.IsNotExist(err) {
189+
fmt.Printf("%s not installed\n", name)
190+
return nil
191+
}
192+
return err
193+
}
194+
fmt.Printf("Removed plugin %s\n", name)
195+
return nil
196+
},
197+
}
198+
199+
var sourceCmd = &cobra.Command{
200+
Use: "source",
201+
Short: "Manage sources",
202+
}
203+
204+
var sourceInstallCmd = &cobra.Command{
205+
Use: "install [source]",
206+
Short: "Install a source",
207+
Args: cobra.ExactArgs(1),
208+
RunE: func(cmd *cobra.Command, args []string) error {
209+
name := args[0]
210+
noBuild, err := cmd.Flags().GetBool("no-build")
211+
if err != nil {
212+
return err
213+
}
214+
content, err := getRepoContent(sourceRepoURL)
215+
if err != nil {
216+
return err
217+
}
218+
repo := parseRepo(content)
219+
url, ok := repo[name]
220+
if !ok {
221+
return fmt.Errorf("source %s not found", name)
222+
}
223+
path := filepath.Join(baseDir, "sources", name)
224+
if _, err := os.Stat(path); err == nil {
225+
return fmt.Errorf("source %s already exists", name)
226+
}
227+
cloneCmd := exec.Command("git", "clone", url, path)
228+
if output, err := cloneCmd.CombinedOutput(); err != nil {
229+
return fmt.Errorf("git clone failed: %v\n%s", err, output)
230+
}
231+
if !noBuild {
232+
buildFile := filepath.Join(path, "build.hacker")
233+
if _, err := os.Stat(buildFile); err == nil {
234+
runCmd := exec.Command("hackerc", "run", buildFile)
235+
runCmd.Dir = path
236+
if output, err := runCmd.CombinedOutput(); err != nil {
237+
return fmt.Errorf("hackerc run failed: %v\n%s", err, output)
238+
}
239+
} else {
240+
fmt.Printf("build.hacker not found, skipping build\n")
241+
}
242+
}
243+
fmt.Printf("Installed source %s to %s\n", name, path)
244+
return nil
245+
},
246+
}
247+
248+
var sourceRemoveCmd = &cobra.Command{
249+
Use: "remove [source]",
250+
Short: "Remove a source",
251+
Args: cobra.ExactArgs(1),
252+
RunE: func(cmd *cobra.Command, args []string) error {
253+
name := args[0]
254+
path := filepath.Join(baseDir, "sources", name)
255+
if err := os.RemoveAll(path); err != nil {
256+
if os.IsNotExist(err) {
257+
fmt.Printf("%s not installed\n", name)
258+
return nil
259+
}
260+
return err
261+
}
262+
fmt.Printf("Removed source %s\n", name)
263+
return nil
264+
},
265+
}
266+
267+
func main() {
268+
rootCmd := &cobra.Command{
269+
Use: "bytes",
270+
Short: "Bytes Manager CLI for Hacker Lang",
271+
}
272+
rootCmd.AddCommand(installCmd)
273+
rootCmd.AddCommand(removeCmd)
274+
pluginCmd.AddCommand(pluginInstallCmd)
275+
pluginCmd.AddCommand(pluginRemoveCmd)
276+
rootCmd.AddCommand(pluginCmd)
277+
sourceInstallCmd.Flags().Bool("no-build", false, "Skip running build.hacker after cloning")
278+
sourceCmd.AddCommand(sourceInstallCmd)
279+
sourceCmd.AddCommand(sourceRemoveCmd)
280+
rootCmd.AddCommand(sourceCmd)
281+
if err := rootCmd.Execute(); err != nil {
282+
os.Exit(1)
283+
}
284+
}
1285

0 commit comments

Comments
 (0)