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() {
/*