package cmd import ( "encoding/json" "fmt" "io" "net/http" "os" "os/exec" "strings" ) func isRepoValid(name string, exclude []string) bool { for _, str := range exclude { if strings.Contains(name, str) { return false } } return true } func deleteFolderIfExists(path string) error { // Check if the path exists if _, err := os.Stat(path); os.IsNotExist(err) { // Path does not exist, nothing to do return nil } // Path exists, attempt to delete it err := os.RemoveAll(path) if err != nil { return fmt.Errorf("failed to delete repository: %w", err) } return nil } type Repository struct { Name string `json:"name"` CloneURL string `json:"clone_url"` } func getRepositories(server, username string) ([]Repository, error) { url := fmt.Sprintf("https://%s/api/v1/users/%s/repos", server, username) // Create a new request using http req, err := http.NewRequest("GET", url, nil) if err != nil { return nil, err } // Send the request via a client client := &http.Client{} resp, err := client.Do(req) if err != nil { return nil, err } defer resp.Body.Close() // Read the response body body, err := io.ReadAll(resp.Body) if err != nil { return nil, err } // Check if the response code is OK (200) if resp.StatusCode != http.StatusOK { return nil, fmt.Errorf("failed to retrieve repositories: %s", resp.Status) } // Unmarshal the JSON response into a slice of Repository structs var repos []Repository err = json.Unmarshal(body, &repos) if err != nil { return nil, err } return repos, nil } func fileExists(filename string) bool { info, err := os.Stat(filename) if os.IsNotExist(err) { return false } return !info.IsDir() } // runCommand runs a given command with arguments and streams stdout and stderr in real time. func runCommand(cmdName string, args ...string) error { cmd := exec.Command(cmdName, args...) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr return cmd.Run() } // processFolder takes a folder path, changes to that directory, runs a series of commands, and returns to the initial directory. func processFolder(folder string, commands [][]string) error { // Store the initial directory initialDir, err := os.Getwd() if err != nil { return fmt.Errorf("failed to get current directory: %w", err) } // Change to the target directory err = os.Chdir(folder) if err != nil { return fmt.Errorf("failed to change directory to %s: %w", folder, err) } // Run the specified commands in the folder for _, command := range commands { if len(command) == 0 { continue } cmdName := command[0] cmdArgs := command[1:] fmt.Printf("Running command: %s %v in folder %s\n", cmdName, cmdArgs, folder) if err := runCommand(cmdName, cmdArgs...); err != nil { fmt.Printf("Command %s failed with error: %v\n", cmdName, err) } } // Change back to the initial directory err = os.Chdir(initialDir) if err != nil { return fmt.Errorf("failed to return to initial directory %s: %w", initialDir, err) } return nil } func updatePortInJSONFile(inputFile string, outputFile string, newPort int) (bool, error) { // Read the JSON file file, err := os.ReadFile(inputFile) if err != nil { return false, err } // Unmarshal the JSON into a map[string]interface{} var data map[string]interface{} err = json.Unmarshal(file, &data) if err != nil { return false, err } // Check if the "port" key exists if _, exists := data["port"]; exists { // Update the "port" key with the new value data["port"] = newPort // Marshal the updated map back to JSON updatedJSON, err := json.MarshalIndent(data, "", " ") if err != nil { return false, err } // Write the updated JSON back to the file err = os.WriteFile(outputFile, updatedJSON, os.ModePerm) if err != nil { return false, err } // Return true indicating the "port" key was found and updated return true, nil } // Return false if the "port" key was not found return false, nil } func writeCaddyfile(routes map[string]int, filename string) error { // Create or open the file file, err := os.Create(filename) if err != nil { return fmt.Errorf("failed to create or open file: %w", err) } defer file.Close() // Write the global options or any other required headers _, err = file.WriteString(`{ # Global options auto_https off } :8080 { root * ./web file_server route { `) if err != nil { return fmt.Errorf("failed to write to file: %w", err) } // Iterate over the map and generate the routes for path, port := range routes { routeConfig := fmt.Sprintf(` handle_path /%s/* { rewrite * /oc{path} reverse_proxy localhost:%d } `, path, port) _, err = file.WriteString(routeConfig) if err != nil { return fmt.Errorf("failed to write route to file: %w", err) } } // Write the closing braces _, err = file.WriteString(` } } `) if err != nil { return fmt.Errorf("failed to write closing braces to file: %w", err) } return nil }