Commit b770865
Changed files (8)
blob.go
@@ -141,7 +141,7 @@ func generateBlobs(files []git.Blob, params Params) error {
CSSMarkdown: cssMarkdown(params.Dark),
Name: params.Name,
SiteName: params.SiteName,
- RootHref: rootHref,
+ RootHref: rootHref + params.RootPrefix,
RepoHref: rootHref,
CurrentRefDir: params.Ref.DirName(),
Selected: "code",
@@ -202,7 +202,7 @@ func generateBlobs(files []git.Blob, params Params) error {
Dark: params.Dark,
Name: params.Name,
SiteName: params.SiteName,
- RootHref: rootHref,
+ RootHref: rootHref + params.RootPrefix,
RepoHref: rootHref,
CurrentRefDir: params.Ref.DirName(),
Selected: "code",
branches.go
@@ -52,7 +52,7 @@ func generateBranches(branches []git.Ref, defaultBranch string, params Params) e
Name: params.Name,
SiteName: params.SiteName,
Dark: params.Dark,
- RootHref: rootHref,
+ RootHref: rootHref + params.RootPrefix,
RepoHref: rootHref,
CurrentRefDir: params.DefaultRef.DirName(),
Selected: "branches",
commit.go
@@ -240,7 +240,7 @@ func generateCommitPage(commit git.Commit, params Params) error {
Name: params.Name,
SiteName: params.SiteName,
Dark: params.Dark,
- RootHref: rootHref,
+ RootHref: rootHref + params.RootPrefix,
RepoHref: rootHref,
CurrentRefDir: currentRef.DirName(),
Selected: "commits",
commits_list.go
@@ -66,7 +66,7 @@ func generateLogForBranch(allCommits []git.Commit, params Params) error {
Name: params.Name,
SiteName: params.SiteName,
Dark: params.Dark,
- RootHref: rootHref,
+ RootHref: rootHref + params.RootPrefix,
RepoHref: rootHref,
CurrentRefDir: params.Ref.DirName(),
Selected: "commits",
index.go
@@ -105,7 +105,7 @@ func generateIndex(files []git.Blob, params Params) error {
SiteName: params.SiteName,
Dark: params.Dark,
CSSMarkdown: cssMarkdown(params.Dark),
- RootHref: rootHref,
+ RootHref: rootHref + params.RootPrefix,
RepoHref: rootHref,
CurrentRefDir: params.Ref.DirName(),
Selected: "code",
list.go
@@ -188,7 +188,7 @@ func generateLists(files []git.Blob, params Params) error {
SiteName: params.SiteName,
Dark: params.Dark,
CSSMarkdown: CSSMarkdown,
- RootHref: rootHref,
+ RootHref: rootHref + params.RootPrefix,
RepoHref: rootHref,
CurrentRefDir: params.Ref.DirName(),
Selected: "code",
main.go
@@ -86,15 +86,6 @@ func main() {
flag.Usage = usage
flag.Parse()
- input := "."
- args := flag.Args()
- if len(args) == 1 {
- input = args[0]
- }
- if len(args) > 1 {
- panic("Multiple repos not supported yet")
- }
-
if flagPreviewThemes {
previewThemes()
os.Exit(0)
@@ -105,79 +96,177 @@ func main() {
panic(err)
}
- absInput, err := filepath.Abs(input)
+ styleLight, styleDark, err := resolveTheme(flagTheme, flagThemeLight, flagThemeDark)
if err != nil {
panic(err)
}
- input = absInput
- if flagName == "" {
- flagName = filepath.Base(input)
- flagName = strings.TrimSuffix(flagName, ".git")
+ baseParams := Params{
+ Owner: flagOwner,
+ Style: flagTheme,
+ StyleLight: styleLight,
+ StyleDark: styleDark,
+ Dark: themeStyles[flagTheme] == "dark",
+ InlineStyles: flagInlineStyles,
+ OutputDir: outputDir,
}
- styleLight, styleDark, err := resolveTheme(flagTheme, flagThemeLight, flagThemeDark)
- if err != nil {
- panic(err)
+ var siteName string
+ isMulti := false
+ var generatables []repoGeneration
+
+ if flagConfig != "" {
+ cfg, err := parseConfig(flagConfig)
+ if err != nil {
+ panic(err)
+ }
+ siteName = cfg.SiteName
+
+ if len(cfg.Repos) > 0 {
+ isMulti = true
+ for _, repo := range cfg.Repos {
+ if err := validateRepoPath(repo.Path); err != nil {
+ panic(fmt.Errorf("repos %q: %w", repo.Slug, err))
+ }
+ generatables = append(generatables, repoGeneration{
+ RepoDir: repo.Path,
+ Name: repo.Name,
+ Slug: repo.Slug,
+ Description: repo.Description,
+ DefaultBranch: repo.DefaultBranch,
+ })
+ }
+ } else if cfg.Repo != nil {
+ inputPath, err := repoInputPath()
+ if err != nil {
+ panic(err)
+ }
+ repoPath := inputPath
+ if repoPath == "." {
+ repoPath = cfg.Repo.Path
+ }
+ repoName := flagName
+ if repoName == "" {
+ repoName = cfg.Repo.Name
+ }
+ defaultBranch := flagDefaultBranch
+ if defaultBranch == "" {
+ defaultBranch = cfg.Repo.DefaultBranch
+ }
+ if err := validateRepoPath(repoPath); err != nil {
+ panic(err)
+ }
+ generatables = append(generatables, repoGeneration{
+ RepoDir: repoPath,
+ Name: repoName,
+ DefaultBranch: defaultBranch,
+ })
+ }
+ }
+
+ if len(generatables) == 0 {
+ inputPath, err := repoInputPath()
+ if err != nil {
+ panic(err)
+ }
+ repoName := flagName
+ if repoName == "" {
+ repoName = filepath.Base(inputPath)
+ repoName = strings.TrimSuffix(repoName, ".git")
+ }
+ if err := validateRepoPath(inputPath); err != nil {
+ panic(err)
+ }
+ generatables = append(generatables, repoGeneration{
+ RepoDir: inputPath,
+ Name: repoName,
+ DefaultBranch: flagDefaultBranch,
+ })
+ }
+
+ baseParams.SiteName = siteName
+
+ if !baseParams.InlineStyles {
+ if err := generateCSSFiles(baseParams); err != nil {
+ panic(err)
+ }
+ }
+
+ for _, g := range generatables {
+ params := baseParams
+ params.RepoDir = g.RepoDir
+ params.Name = g.Name
+ params.SiteName = siteName
+ params.RootPrefix = ""
+
+ if isMulti {
+ params.OutputDir = filepath.Join(outputDir, g.Slug)
+ params.RootPrefix = "../"
+ }
+
+ if err := generateRepo(g, params, noFiles, noCommitsList); err != nil {
+ panic(err)
+ }
}
+ if isMulti {
+ if err := generateMultiRepoIndex(cfgReposToEntries(generatables), siteName, baseParams); err != nil {
+ panic(err)
+ }
+ }
+
+ if flagMinify || flagGzip {
+ echo("> post-processing HTML...")
+ if err := postProcessHTML(outputDir, flagMinify, flagGzip); err != nil {
+ panic(err)
+ }
+ }
+}
+
+type repoGeneration struct {
+ RepoDir string
+ Name string
+ Slug string
+ Description string
+ DefaultBranch string
+}
+
+func generateRepo(g repoGeneration, params Params, noFiles, noCommitsList bool) error {
branchesFilter, err := regexp.Compile(flagBranches)
if err != nil {
- panic(err)
+ return err
}
- branches, err := git.Branches(input, branchesFilter, flagDefaultBranch)
+ branches, err := git.Branches(params.RepoDir, branchesFilter, g.DefaultBranch)
if err != nil {
- panic(err)
+ return err
}
- tags, err := git.Tags(input)
+ tags, err := git.Tags(params.RepoDir)
if err != nil {
- panic(err)
+ return err
}
- if flagDefaultBranch == "" {
+ defaultBranch := g.DefaultBranch
+ if defaultBranch == "" {
if containsBranch(branches, "master") {
- flagDefaultBranch = "master"
+ defaultBranch = "master"
} else if containsBranch(branches, "main") {
- flagDefaultBranch = "main"
+ defaultBranch = "main"
} else {
- echo("No default branch found. Specify one using --default-branch flag.")
- os.Exit(1)
+ return fmt.Errorf("no default branch found in %s", params.RepoDir)
}
}
- if !containsBranch(branches, flagDefaultBranch) {
- echo(fmt.Sprintf("Default branch %q not found.", flagDefaultBranch))
- echo("Specify a valid branch using --default-branch flag.")
- os.Exit(1)
+ if !containsBranch(branches, defaultBranch) {
+ return fmt.Errorf("default branch %q not found in %s", defaultBranch, params.RepoDir)
}
if yes, a, b := hasConflictingBranchNames(branches); yes {
- echo(fmt.Sprintf("Conflicting branchs %q and %q, both want to use %q dir name.", a, b, a.DirName()))
- os.Exit(1)
- }
-
- // Start generating pages
-
- params := Params{
- Owner: flagOwner,
- Name: flagName,
- RepoDir: input,
- OutputDir: outputDir,
- Style: flagTheme,
- StyleLight: styleLight,
- StyleDark: styleDark,
- Dark: themeStyles[flagTheme] == "dark",
- DefaultRef: git.NewRef(flagDefaultBranch),
- InlineStyles: flagInlineStyles,
+ return fmt.Errorf("conflicting branch names %q and %q, both want to use %q dir name", a, b, a.DirName())
}
- if !params.InlineStyles {
- if err := generateCSSFiles(params); err != nil {
- panic(err)
- }
- }
+ params.DefaultRef = git.NewRef(defaultBranch)
commits := make(map[string]git.Commit)
commitsFor := make(map[git.Ref][]git.Commit, len(branches))
@@ -185,7 +274,7 @@ func main() {
for _, branch := range branches {
commitsFor[branch], err = git.Commits(branch, params.RepoDir)
if err != nil {
- panic(err)
+ return err
}
for _, commit := range commitsFor[branch] {
@@ -197,14 +286,12 @@ func main() {
}
}
- // Add commits from tags
for _, tag := range tags {
commitsForTag, err := git.Commits(git.NewRef(tag.Name), params.RepoDir)
if err != nil {
- panic(err)
+ return err
}
for _, commit := range commitsForTag {
- // Only add new commits
if alreadyExisting, ok := commits[commit.Hash]; ok && !alreadyExisting.Branch.IsEmpty() {
continue
}
@@ -214,8 +301,8 @@ func main() {
echo(fmt.Sprintf("> %s: %d branches, %d tags, %d commits", params.Name, len(branches), len(tags), len(commits)))
- if err := generateBranches(branches, flagDefaultBranch, params); err != nil {
- panic(err)
+ if err := generateBranches(branches, defaultBranch, params); err != nil {
+ return err
}
var defaultBranchFiles []git.Blob
@@ -227,72 +314,110 @@ func main() {
if !noFiles {
files, err := git.Files(params.Ref, params.RepoDir)
if err != nil {
- panic(err)
+ return err
}
- if branch.String() == flagDefaultBranch {
+ if branch.String() == defaultBranch {
defaultBranchFiles = files
}
err = generateBlobs(files, params)
if err != nil {
- panic(err)
+ return err
}
err = generateLists(files, params)
if err != nil {
- panic(err)
+ return err
}
}
if !noCommitsList {
err = generateLogForBranch(commitsFor[branch], params)
if err != nil {
- panic(err)
+ return err
}
}
}
- // Back to the default branch
- params.Ref = git.NewRef(flagDefaultBranch)
+ params.Ref = git.NewRef(defaultBranch)
- // Commits pages generation
echo("> generating commits...")
err = generateCommits(commits, params)
if err != nil {
- panic(err)
+ return err
}
- // Tags page generation
if err := generateTags(tags, params); err != nil {
- panic(err)
+ return err
}
- // Git dumb protocol files generation
if flagGit {
echo("> generating dumb protocol files...")
- if err := generateDumbProtocol(params, branches, flagDefaultBranch, tags, commitsFor, commits); err != nil {
- panic(err)
+ if err := generateDumbProtocol(params, branches, defaultBranch, tags, commitsFor, commits); err != nil {
+ return err
}
}
- // Index page generation
if !noFiles {
if len(defaultBranchFiles) == 0 {
- panic("No files found for default branch")
+ return fmt.Errorf("no files found for default branch in %s", params.RepoDir)
}
err = generateIndex(defaultBranchFiles, params)
if err != nil {
- panic(err)
+ return err
}
}
- if flagMinify || flagGzip {
- echo("> post-processing HTML...")
- if err := postProcessHTML(params.OutputDir, flagMinify, flagGzip); err != nil {
- panic(err)
+ return nil
+}
+
+func repoInputPath() (string, error) {
+ args := flag.Args()
+ if len(args) == 0 {
+ abs, err := filepath.Abs(".")
+ if err != nil {
+ return "", err
+ }
+ return abs, nil
+ }
+ if len(args) > 1 {
+ return "", fmt.Errorf("multiple positional args not supported with --config; use [[repos]] in config instead")
+ }
+ abs, err := filepath.Abs(args[0])
+ if err != nil {
+ return "", err
+ }
+ return abs, nil
+}
+
+func validateRepoPath(path string) error {
+ info, err := os.Stat(path)
+ if err != nil {
+ return fmt.Errorf("repo path %q: %w", path, err)
+ }
+ if !info.IsDir() {
+ return fmt.Errorf("repo path %q is not a directory", path)
+ }
+ gitDir := filepath.Join(path, ".git")
+ if info, err := os.Stat(gitDir); err != nil || !info.IsDir() {
+ return fmt.Errorf("repo path %q does not contain a .git directory", path)
+ }
+ return nil
+}
+
+func cfgReposToEntries(gs []repoGeneration) []RepoEntry {
+ entries := make([]RepoEntry, len(gs))
+ for i, g := range gs {
+ entries[i] = RepoEntry{
+ Name: g.Name,
+ Slug: g.Slug,
+ Path: g.RepoDir,
+ Description: g.Description,
+ DefaultBranch: g.DefaultBranch,
}
}
+ return entries
}
func usage() {