package main import ( "flag" "fmt" "log/slog" "os" "path/filepath" "strings" "time" "github.com/go-git/go-git/v5" ) type RepoDir struct { Name string Description string Owner string LastCommit time.Time } func errAndExit(msg string, args ...any) { fmt.Fprintf(os.Stderr, msg, args...) os.Exit(1) } func main() { indexFlag := flag.Bool("index", false, "set to true if you want to generate the index") repoFlag := flag.String("repo", "", "the repository path to generate the static files from") debugFlag := flag.Bool("debug", false, "print debug information") flag.Parse() if *debugFlag { slog.SetLogLoggerLevel(slog.LevelDebug) } switch { case *indexFlag: if len(flag.Args()) == 0 { errAndExit("Usage of -index:\n %s -index [repositories]\n", os.Args[0]) } slog.Debug("Generating index", "args", flag.Args()) if err := generateIndex(flag.Args()); err != nil { errAndExit("ERROR: %s\n", err) } case *repoFlag != "": slog.Debug("Generating repository", "path", *repoFlag) if err := generateRepo(*repoFlag); err != nil { errAndExit("ERROR: %s\n", err) } default: flag.Usage() } } func readFile(path string) (string, error) { if fi, err := os.Stat(path); err == nil && !fi.IsDir() { b, err := os.ReadFile(path) if err != nil { return "", fmt.Errorf("cannot read contents of file %q: %w", path, err) } return strings.TrimSpace(string(b)), nil } return "", nil } func readRepoFile(dirname, name string) (contents string, err error) { contents, err = readFile(filepath.Join(dirname, ".git", name)) if err != nil { return } if contents == "" { contents, err = readFile(filepath.Join(dirname, name)) return } return } func generateIndex(args []string) error { repoDirs := []*RepoDir{} for _, dirname := range args { slog.Debug("Processing directory", "dirname", dirname) reponame := strings.TrimSuffix(filepath.Base(dirname), ".git") repoDir := &RepoDir{Name: reponame} description, err := readRepoFile(dirname, "description") if err != nil { return fmt.Errorf("cannot read description for repository %q: %w", dirname, err) } repoDir.Description = description owner, err := readRepoFile(dirname, "owner") if err != nil { return fmt.Errorf("cannot read owner for repository %q: %w", dirname, err) } repoDir.Owner = owner // get last commit date repo, err := git.PlainOpen(dirname) if err != nil { return fmt.Errorf("cannot open repository %q: %w", dirname, err) } head, err := repo.Head() if err != nil { return fmt.Errorf("cannot get repository head for %q: %w", dirname, err) } c, err := repo.CommitObject(head.Hash()) if err != nil { return fmt.Errorf("cannot get commit %q for repository %q: %w", head.Hash(), dirname, err) } repoDir.LastCommit = c.Author.When repoDirs = append(repoDirs, repoDir) } // ToDo: pass repoDirs to a template and generate index.htlm // ToDo: remove this for _, rd := range repoDirs { slog.Info("Repo", "name", rd.Name, "desc", rd.Description, "owner", rd.Owner, "lastcommit", rd.LastCommit) } return nil } func generateRepo(path string) error { return nil }