gtx


Branch: develop

Author
thewhodidthis <thewhodidthis@fastmail.com>
Date
Nov. 18 '22 21:08:19
Commit
52232b8daeec7b2a33e25ac20e0bb45475e6fdf1
Parent
476bf79ecb500153ba51c92e81119571aafed49a
Changes
diff --git a/main.go b/main.go
index 53b4acb..fb2adef 100644
--- a/main.go
+++ b/main.go
@@ -5,9 +5,11 @@ import (
 	"encoding/json"
 	"flag"
 	"fmt"
+	"html/template"
 	"io"
 	"log"
 	"os"
+	"os/exec"
 	"path/filepath"
 	"reflect"
 	"strings"
@@ -20,8 +22,110 @@ var rTmpl string
 //go:embed branch.html.tmpl
 var bTmpl string
 
-//go:embed index.html.tmpl
-var iTmpl string
+//go:embed commit.html.tmpl
+var cTmpl string
+
+type branch struct {
+	Name string
+}
+
+type repo struct {
+	name string
+	path string
+}
+
+func (r *repo) init(f bool) error {
+	dirs := []string{"branch", "commit", "object"}
+
+	for _, dir := range dirs {
+		d := filepath.Join(r.path, dir)
+
+		// Clear existing dirs if force true.
+		if f && dir != "branch" {
+			if err := os.RemoveAll(d); err != nil {
+				return fmt.Errorf("unable to remove directory: %v", err)
+			}
+		}
+
+		if err := os.MkdirAll(d, 0750); err != nil {
+			return fmt.Errorf("unable to create directory: %v", err)
+		}
+	}
+
+	return nil
+}
+
+func (r *repo) clone(target string) error {
+	src := filepath.Join(r.path, "repo")
+	_, err := os.Stat(src)
+
+	if os.IsNotExist(err) {
+		if err := exec.Command("git", "clone", target, src).Run(); err != nil {
+			return err
+		}
+	} else if err != nil {
+		return err
+	}
+
+	cmd := exec.Command("git", "branch", "-l")
+	cmd.Dir = src
+	out, err := cmd.Output()
+
+	if err != nil {
+		return err
+	}
+
+	all := fmt.Sprintf("%s", out)
+	_, main, found := strings.Cut(all, "*")
+
+	if !found {
+		return fmt.Errorf("unable to locate main branch")
+	}
+
+	main = strings.Trim(main, " ")
+	main = filepath.Join("origin", main)
+
+	log.Printf("main branch found: %v", main)
+
+	// TODO: This don't seem to be working as expected at present, why?
+	cmd = exec.Command("git", "checkout", main)
+	cmd.Dir = src
+	err = cmd.Run()
+
+	if err != nil {
+		return err
+	}
+
+	cmd = exec.Command("git", "branch", "-D", main)
+	cmd.Dir = src
+	err = cmd.Run()
+
+	return err
+}
+
+func (r *repo) listBranches(bf manyflag) ([]branch, error) {
+	// dir := fmt.Sprintf("git -C %s branch", r.repo)
+	cmd := exec.Command("git", "branch", "-a")
+	cmd.Dir = filepath.Join(r.path, "repo")
+
+	out, err := cmd.Output()
+
+	if err != nil {
+		return nil, err
+	}
+
+	// TODO: Filter to match options.
+	// TODO: Check if `bf` empty, in which case return all.
+	var branches []branch
+
+	for _, b := range bf {
+		fmt.Printf("want: %s\n", b)
+	}
+
+	fmt.Printf("have: %s", out)
+
+	return branches, nil
+}
 
 // https://stackoverflow.com/questions/28322997/how-to-get-a-list-of-values-into-a-flag-in-golang/
 type manyflag []string
@@ -50,16 +154,18 @@ type options struct {
 }
 
 // Helps store options into a JSON config file.
-func (o *options) save(out string) {
+func (o *options) save(out string) error {
 	bs, err := json.MarshalIndent(o, "", "  ")
 
 	if err != nil {
-		log.Fatalf("unable to encode config file: %v", err)
+		return fmt.Errorf("unable to encode config file: %v", err)
 	}
 
 	if err := os.WriteFile(filepath.Join(out, o.name), bs, 0644); err != nil {
-		log.Fatalf("unable to save config file: %v", err)
+		return fmt.Errorf("unable to save config file: %v", err)
 	}
+
+	return nil
 }
 
 func init() {
@@ -177,70 +283,52 @@ func main() {
 	}
 
 	// Save current settings for future use.
-	opt.save(out)
-
-	/*
-	   if test ! -d "$REPOSITORY"
-	   then
-	     echo "Repository \"$REPOSITORY\" does not exists.  Misconfiguration likely."
-	     exit 1
-	   fi
-	*/
-	createDirectories(out, opt.Force)
-	setUpRepo(out, opt)
-
-	cleanBranches := cleanUpBranches(opt.Branches)
+	if err := opt.save(out); err != nil {
+		log.Fatalf("unable to save options: %v", err)
+	}
 
-	fetchBranches(cleanBranches)
-	writeIndex()
-	doTheRealWork()
-	writeIndexFooter()
-}
+	repo := &repo{
+		name: opt.Project,
+		path: out,
+	}
 
-func createDirectories(target string, force bool) {
-	//# Ensure that some directories we need exist.
-	/*
-	   if test x"$force_rebuild" = x1
-	   then
-	     rm -rf "$TARGET/objects" "$TARGET/commits"
-	   fi
+	if err := repo.init(opt.Force); err != nil {
+		log.Fatalf("unable to initialize output directory: %v", err)
+	}
 
-	   if test ! -d "$TARGET/objects"
-	   then
-	     mkdir "$TARGET/objects"
-	   fi
+	if err := repo.clone(opt.Repo); err != nil {
+		log.Fatalf("unable to clone repo: %v", err)
+	}
 
-	   if test ! -e "$TARGET/commits"
-	   then
-	     mkdir "$TARGET/commits"
-	   fi
+	branches, err := repo.listBranches(opt.Branches)
 
-	   if test ! -e "$TARGET/branches"
-	   then
-	     mkdir "$TARGET/branches"
-	   fi
-	*/
+	if err != nil {
+		log.Fatalf("unable to list branches: %v", err)
+	}
 
-	// Repository
-	dirs := []string{"branches", "commits", "objects"}
+	// This is the main index or repo home.
+	ri, err := os.Create(filepath.Join(out, "index.html"))
 
-	for _, dir := range dirs {
-		d := filepath.Join(target, dir)
+	defer ri.Close()
 
-		// Clear existing dirs if force true.
-		if force && dir != "branches" {
-			if err := os.RemoveAll(d); err != nil {
-				log.Printf("unable to remove directory: %v", err)
-			}
-		}
+	if err != nil {
+		log.Fatalf("unable to create repo index: %v", err)
+	}
 
-		if err := os.MkdirAll(d, os.ModePerm); err != nil {
-			log.Printf("unable to create directory: %v", err)
-		}
+	rt := template.Must(template.New("repo").Parse(rTmpl))
+	rd := struct {
+		Branches []branch
+		Link     string
+		Title    string
+	}{
+		Branches: branches,
+		Link:     opt.URL,
+		Title:    opt.Project,
 	}
-}
 
-func setUpRepo(target string, opt *options) {
+	if err := rt.Execute(ri, rd); err != nil {
+		log.Fatalf("unable to fill in repo template: %v", err)
+	}
 }
 
 // TODO: implement!
@@ -305,36 +393,6 @@ func fetchBranches(branches []string) {
 	*/
 }
 
-// TODO: implement!
-func writeIndex() {
-	/*
-	   INDEX="$TARGET/index.html"
-
-	   {
-	     html_header
-
-	     if test -e "$REPOSITORY/description"
-	     then
-	       echo "<h2>Description</h2>"
-	       cat "$REPOSITORY/description"
-	     fi
-
-	     echo "<h2>Repository</h2>"
-	     if test x"$PUBLIC_REPOSITORY" != x
-	     then
-	       echo  "Clone this repository using:" \
-	         "<pre>" \
-	         " git clone $PUBLIC_REPOSITORY" \
-	         "</pre>"
-	     fi
-
-	     echo "<h2>Branches</h2>" \
-	       "<ul>"
-	   } > "$INDEX"
-
-	*/
-}
-
 // TODO: implement!
 func doTheRealWork() {
 	/*