Changes
diff --git a/main.go b/main.go
index 6292a63..0760b8c 100644
--- a/main.go
+++ b/main.go
@@ -10,6 +10,7 @@ import (
"html/template"
"io"
"log"
+ "net/url"
"os"
"os/exec"
"path/filepath"
@@ -18,7 +19,7 @@ import (
"text/tabwriter"
)
-//go:embed repo.html.tmpl
+//go:embed home.html.tmpl
var rTmpl string
//go:embed branch.html.tmpl
@@ -27,87 +28,12 @@ var bTmpl string
//go:embed commit.html.tmpl
var cTmpl string
-type branch struct {
- Name string
-}
-
type repo struct {
name string
+ base 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) save(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
- }
-
- // NOTE: Maybe the following ought to be a separate method.
- cmd := exec.Command("git", "branch", "-l")
- cmd.Dir = src
- out, err := cmd.Output()
-
- if err != nil {
- return err
- }
-
- all := fmt.Sprintf("%s", out)
-
- // NOTE: Requires go1.18.
- _, main, found := strings.Cut(all, "*")
-
- if !found {
- return fmt.Errorf("unable to locate main branch")
- }
-
- main = strings.TrimSpace(main)
- main = strings.TrimRight(main, "\n")
-
- // NOTE: Not sure why this is added in the original.
- // main = filepath.Join("origin", main)
-
- cmd = exec.Command("git", "checkout", "--detach", 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
-}
-
// https://stackoverflow.com/questions/28322997/how-to-get-a-list-of-values-into-a-flag-in-golang/
type manyflag []string
@@ -246,16 +172,18 @@ func main() {
tab.Flush()
// The repo flag is required at this point.
- // NOTE: Being able to handle non-local repos would be nice.
- if ok := filepath.IsAbs(opt.Repo); !ok {
- flag.Usage()
- os.Exit(1)
- }
-
- // Option considered repo-like if it contains a hidden `.git` dir.
- if _, err := os.Stat(filepath.Join(opt.Repo, ".git")); os.IsNotExist(err) {
- flag.Usage()
- os.Exit(1)
+ if ok := filepath.IsAbs(opt.Repo); ok {
+ // Option considered repo-like if it contains a hidden `.git` dir.
+ if _, err := os.Stat(filepath.Join(opt.Repo, ".git")); os.IsNotExist(err) {
+ flag.Usage()
+ os.Exit(1)
+ }
+ } else {
+ // Allow for URL-looking non-local repos.
+ if _, err := url.ParseRequestURI(opt.Repo); err != nil {
+ flag.Usage()
+ os.Exit(1)
+ }
}
// Make sure `out` exists.
@@ -270,7 +198,9 @@ func main() {
repo := &repo{
name: opt.Project,
- path: out,
+ base: out,
+ // TODO: Change to a temporary directory.
+ path: filepath.Join(out, "repo"),
}
if err := repo.init(opt.Force); err != nil {
@@ -282,10 +212,31 @@ func main() {
log.Fatalf("unable to set up repo: %v", err)
}
- branches, err := findBranches(repo, opt.Branches)
+ branches, err := repo.findBranches(opt.Branches)
if err != nil {
- log.Fatalf("unable to list branches: %v", err)
+ log.Fatalf("unable to filter branches: %v", err)
+ }
+
+ for _, b := range branches {
+ ref := fmt.Sprintf("refs/heads/%s:refs/origin/%s", b, b)
+
+ cmd := exec.Command("git", "fetch", "--force", "origin", ref)
+ cmd.Dir = repo.path
+
+ if _, err := cmd.Output(); err != nil {
+ log.Printf("unable to fetch branch: %v", err)
+
+ continue
+ }
+ }
+
+ // NOTE: Why is this even necessary?
+ cmd := exec.Command("git", "checkout", filepath.Join("origin", branches[0]))
+ cmd.Dir = repo.path
+
+ if err := cmd.Run(); err != nil {
+ log.Printf("unable to checkout default branch: %v", err)
}
// This is the main index or repo home.
@@ -313,41 +264,80 @@ func main() {
}
}
-// TODO: implement!
-func updateBranches(r *repo, branches []string) int {
- /*
- for branch in $BRANCHES
- do
- # Suppress already up to date status messages, but don't use grep -v
- # as that returns 1 if there is no output and causes the script to
- # abort.
- git fetch --force origin "refs/heads/${branch}:refs/origin/${branch}" \
- | gawk '/^Already up-to-date[.]$/ { skip=1; }
- { if (! skip) print; skip=0 }'
- done
- git checkout "origin/$first"
- }
-
- # For each branch and each commit create and extract an archive of the form
- # $TARGET/commits/$commit
- #
- # and a link:
- #
- # $TARGET/branches/$commit -> $TARGET/commits/$commit
-
- # Count the number of branch we want to process to improve reporting.
- bcount=0
- for branch in $BRANCHES
- do
- let ++bcount
- done
- */
- return 0
+func (r *repo) init(f bool) error {
+ dirs := []string{"branch", "commit", "object"}
+
+ for _, dir := range dirs {
+ d := filepath.Join(r.base, 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) save(target string) error {
+ _, err := os.Stat(r.path)
+
+ if os.IsNotExist(err) {
+ if err := exec.Command("git", "clone", target, r.path).Run(); err != nil {
+ return err
+ }
+ } else if err != nil {
+ return err
+ }
+
+ // NOTE: Should this be in a separate method.
+ cmd := exec.Command("git", "branch", "-l")
+ cmd.Dir = r.path
+ out, err := cmd.Output()
+
+ if err != nil {
+ return err
+ }
+
+ all := fmt.Sprintf("%s", out)
+
+ // NOTE: Requires go1.18.
+ _, star, found := strings.Cut(all, "*")
+
+ if !found {
+ return fmt.Errorf("unable to locate the default branch")
+ }
+
+ star = strings.TrimSpace(star)
+ star = strings.TrimRight(star, "\n")
+
+ // NOTE: Not sure why this is added in the original.
+ // star = filepath.Join("origin", star)
+
+ cmd = exec.Command("git", "checkout", "--detach", star)
+ cmd.Dir = r.path
+ err = cmd.Run()
+
+ if err != nil {
+ return err
+ }
+
+ cmd = exec.Command("git", "branch", "-D", star)
+ cmd.Dir = r.path
+ err = cmd.Run()
+
+ return err
}
-func findBranches(r *repo, bf manyflag) ([]string, error) {
+func (r *repo) findBranches(bf manyflag) ([]string, error) {
cmd := exec.Command("git", "branch", "-a")
- cmd.Dir = filepath.Join(r.path, "repo")
+ cmd.Dir = r.path
out, err := cmd.Output()