Changes
8 changed files (+201/-2)
-
-
@@ -35,6 +35,24 @@ repo:# Default value is "go" for backwards compatibility. diff: go # Allows reading bare repository without ".git" suffix. # # A bare repository normally have ".git" suffix in its filename. # Without this option, a visitor always has to add ".git" suffix # (for example "foo.git" rather than "foo") and is not able to use tools # incompatible with ".git" suffix, such as "go mod". # # When this option is enabled, legit searches directory with ".git" # suffix after corresponding is not found. For example, when repositories # directory has "foo.git" then access to "/foo/refs": # - open "foo" # - the directory does not exist # - open "foo.git" # - use that as a repository # # This option is disabled by default for compatibility reasons. trimDotGitSuffix: true # Runtime directories. dirs: # [optional]
-
-
-
@@ -23,6 +23,9 @@ type Config struct {// Diff method. "system" uses system git and "go" uses go-git and go-diff. // Default is "go". Diff string `yaml:"diff"` // TrimDotGitSuffix allows accessing bare repository without ".git" suffix. TrimDotGitSuffix bool `yaml:"trimDotGitSuffix"` } `yaml:"repo"` Dirs struct { Templates string `yaml:"templates"`
-
-
-
@@ -20,6 +20,10 @@ import ("github.com/pocka/legit/renderer/html" ) const ( dotGitSuffix = ".git" ) var ( ErrRepositoryIsIgnored = errors.New("repository is ignored") )
-
@@ -90,10 +94,18 @@ func (core *Core) Template() *template.Template {} // RepositoryPath finds a repository by name and returns its filepath. // name is not supposed to contain slash characters. func (core *Core) RepositoryPath(name string) (string, error) { stat, err := core.ScanDir.Stat(name) if err != nil { return "", err if !core.Config.Repo.TrimDotGitSuffix || strings.HasSuffix(name, dotGitSuffix) { return "", err } stat, err = core.ScanDir.Stat(name + dotGitSuffix) if err != nil { return "", err } } dirname := stat.Name()
-
-
-
@@ -31,6 +31,7 @@ repo:- master - main - trunk trimDotGitSuffix: true meta: title: legit Demo
-
-
-
@@ -10,6 +10,7 @@ import ("path/filepath" "slices" "sort" "strings" gogit "github.com/go-git/go-git/v5"
-
@@ -71,9 +72,15 @@ func (pages *Pages) index(w http.ResponseWriter, r *http.Request) {category = git.GitwebCategory(repo) } dirname := name if pages.core.Config.Repo.TrimDotGitSuffix { // Prefer suffix-less URL when TrimDotGitSuffix is enabled. dirname = strings.TrimSuffix(dirname, ".git") } summaries = append(summaries, templates.RepositorySummary{ DisplayName: pages.core.RepositoryName(path), DirName: name, DirName: dirname, Description: git.GitwebDescription(repo), Category: category, LastCommit: commit,
-
-
-
@@ -96,3 +96,80 @@ func TestServeIndexIgnoreNonGitRepos(t *testing.T) {t.Error("Body not containing magic string") } } func TestIndexTrimDotGitSuffix(t *testing.T) { repos := t.TempDir() _, worktree, err := tests.CreateRepository(repos, "foo") if err != nil { t.Fatal(err) } readme, err := worktree.Filesystem.Create("README.md") if err != nil { t.Fatal(err) } if _, err := readme.Write([]byte("* iawsoiwjfngbhfg812uhjikwe6789asfd")); err != nil { t.Fatal(err) } _ = readme.Close() if _, err := worktree.Add("README.md"); err != nil { t.Fatal(err) } _, err = worktree.Commit("Add README", &git.CommitOptions{ Author: tests.SignatureAlice(), }) if err != nil { t.Fatalf("Unable to commit: %s", err) } if err := tests.CreateBare(repos, "foo"); err != nil { t.Fatalf("Unable to create bare repository: %s", err) } if err := os.RemoveAll(filepath.Join(repos, "foo")); err != nil { t.Fatal(err) } var c config.Config c.Repo.ScanPath = repos c.Repo.Readme = []string{"README.md"} c.Repo.MainBranch = []string{"trunk"} c.Repo.TrimDotGitSuffix = true core, err := core.New(&c) if err != nil { t.Fatal(err) } server := httptest.NewServer(New(core)) defer server.Close() target, err := url.JoinPath(server.URL, "/") if err != nil { t.Fatal(err) } res, err := http.Get(target) if err != nil { t.Fatal(err) } if res.StatusCode != http.StatusOK { t.Fatalf("Expected HTTP %d, Got %d", http.StatusOK, res.StatusCode) } body, err := io.ReadAll(res.Body) res.Body.Close() if err != nil { t.Fatal(err) } if !strings.Contains(string(body), "href=\"/foo\"") { t.Error("Link to a repository not found") } }
-
-
-
@@ -48,6 +48,10 @@ func New(repositoryPath string, innerPath string, core *core.Core) (*Repo, errorvar err error repo := Repo{core: core, innerPath: innerPath, path: repositoryPath, dirname: filepath.Base(repositoryPath)} if core.Config.Repo.TrimDotGitSuffix { repo.dirname = strings.TrimSuffix(repo.dirname, ".git") } repo.r, err = git.PlainOpen(repositoryPath) if err != nil { return nil, fmt.Errorf("opening %s: %w", repositoryPath, err)
-
-
-
@@ -272,3 +272,80 @@ func TestServeRepoIndexPreventIgnoredRepoReveal(t *testing.T) {t.Fatalf("Expected HTTP %d, Got %d", http.StatusNotFound, res.StatusCode) } } func TestRepoIndexTrimDotGitSuffix(t *testing.T) { repos := t.TempDir() _, worktree, err := tests.CreateRepository(repos, "foo") if err != nil { t.Fatal(err) } readme, err := worktree.Filesystem.Create("README.md") if err != nil { t.Fatal(err) } if _, err := readme.Write([]byte("* iawsoiwjfngbhfg812uhjikwe6789asfd")); err != nil { t.Fatal(err) } _ = readme.Close() if _, err := worktree.Add("README.md"); err != nil { t.Fatal(err) } _, err = worktree.Commit("Add README", &git.CommitOptions{ Author: tests.SignatureAlice(), }) if err != nil { t.Fatalf("Unable to commit: %s", err) } if err := tests.CreateBare(repos, "foo"); err != nil { t.Fatalf("Unable to create bare repository: %s", err) } if err := os.RemoveAll(filepath.Join(repos, "foo")); err != nil { t.Fatal(err) } var c config.Config c.Repo.ScanPath = repos c.Repo.Readme = []string{"README.md"} c.Repo.MainBranch = []string{"trunk"} c.Repo.TrimDotGitSuffix = true core, err := core.New(&c) if err != nil { t.Fatal(err) } server := httptest.NewServer(New(core)) defer server.Close() target, err := url.JoinPath(server.URL, "/foo") if err != nil { t.Fatal(err) } res, err := http.Get(target) if err != nil { t.Fatal(err) } if res.StatusCode != http.StatusOK { t.Fatalf("Expected HTTP %d, Got %d", http.StatusOK, res.StatusCode) } body, err := io.ReadAll(res.Body) res.Body.Close() if err != nil { t.Fatal(err) } if !strings.Contains(string(body), "<li>iawsoiwjfngbhfg812uhjikwe6789asfd</li>") { t.Error("Body not containing magic string") } }
-