diff options
Diffstat (limited to 'pkg')
| -rw-r--r-- | pkg/config/config.go | 115 | ||||
| -rw-r--r-- | pkg/config/config_test.go | 14 | ||||
| -rw-r--r-- | pkg/git/git.go | 42 | ||||
| -rw-r--r-- | pkg/handler/about/handler.go (renamed from pkg/handler/about.go) | 18 | ||||
| -rw-r--r-- | pkg/handler/config/handler.go (renamed from pkg/handler/status.go) | 29 | ||||
| -rw-r--r-- | pkg/handler/git/handler.go (renamed from pkg/handler/git.go) | 20 | ||||
| -rw-r--r-- | pkg/handler/router.go | 38 | ||||
| -rw-r--r-- | pkg/handler/static/handler.go (renamed from pkg/handler/static.go) | 2 | ||||
| -rw-r--r-- | pkg/service/git.go | 26 | 
9 files changed, 214 insertions, 90 deletions
| diff --git a/pkg/config/config.go b/pkg/config/config.go index 9b6acce..419d49d 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -1,27 +1,126 @@  package config  import ( +	"errors"  	"fmt"  	"io" +	"os" +	"path"  	"strconv"  	"git.gabrielgio.me/cerrado/pkg/u"  	"git.sr.ht/~emersion/go-scfg"  ) +var ( +	ScanPathErr = errors.New("Scan path does not exist") +	RepoPathErr = errors.New("Repository path does not exist") +) +  type ( -	Scan struct { + +	// scan represents piece of the scan from the configuration file. +	scan struct {  		Path   string  		Public bool  	} -	Configuration struct { -		Scan       *Scan +	// configuration represents file configuration. +	configuration struct { +		Scan       *scan  		RootReadme string  	} + +	// This is a per repository configuration. +	GitRepositoryConfiguration struct { +		Name   string +		Path   string +		Public bool +	} + +	// ConfigurationRepository represents the configuration repository (as in +	// database repositories). +	// This holds all the function necessary to ask for configuration +	// information. +	ConfigurationRepository struct { +		rootReadme   string +		repositories []*GitRepositoryConfiguration +	}  ) -func Parse(r io.Reader) (*Configuration, error) { +func LoadConfigurationRepository(configPath string) (*ConfigurationRepository, error) { +	f, err := os.Open(configPath) +	if err != nil { +		return nil, err +	} + +	config, err := parse(f) +	if err != nil { +		return nil, err +	} + +	repo := &ConfigurationRepository{ +		rootReadme: config.RootReadme, +	} + +	err = repo.expandOnScanPath(config.Scan.Path, config.Scan.Public) +	if err != nil { +		return nil, err +	} +	return repo, nil + +} + +// GetRootReadme returns root read path +func (c *ConfigurationRepository) GetRootReadme() string { +	return c.rootReadme +} + +// GetByName returns configuration of repository for a given name. +// It returns nil if there is not match for it. +func (c *ConfigurationRepository) GetByName(name string) *GitRepositoryConfiguration { +	for _, r := range c.repositories { +		if r.Name == name { +			return r +		} +	} +	return nil +} + +// List returns all the configuration for all repositories. +func (c *ConfigurationRepository) List() []*GitRepositoryConfiguration { +	return c.repositories +} + +// expandOnScanPath scans the scanPath for folders taking them as repositories +// and applying them default configuration. +func (c *ConfigurationRepository) expandOnScanPath(scanPath string, public bool) error { +	if !u.FileExist(scanPath) { +		return ScanPathErr +	} + +	entries, err := os.ReadDir(scanPath) +	if err != nil { +		return err +	} + +	c.repositories = make([]*GitRepositoryConfiguration, 0) +	for _, e := range entries { +		if !e.IsDir() { +			continue +		} + +		fullPath := path.Join(scanPath, e.Name()) +		c.repositories = append(c.repositories, &GitRepositoryConfiguration{ +			Name:   e.Name(), +			Path:   fullPath, +			Public: public, +		}) +	} +	return nil +} + +func parse(r io.Reader) (*configuration, error) {  	block, err := scfg.Read(r)  	if err != nil {  		return nil, err @@ -42,9 +141,9 @@ func Parse(r io.Reader) (*Configuration, error) {  	return config, nil  } -func defaultConfiguration() *Configuration { -	return &Configuration{ -		Scan: &Scan{ +func defaultConfiguration() *configuration { +	return &configuration{ +		Scan: &scan{  			Public: true,  			Path:   "",  		}, @@ -57,7 +156,7 @@ func setRootReadme(block scfg.Block, readme *string) error {  	return setString(scanDir, readme)  } -func setScan(block scfg.Block, scan *Scan) error { +func setScan(block scfg.Block, scan *scan) error {  	scanDir := block.Get("scan")  	err := setString(scanDir, &scan.Path)  	if err != nil { diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go index c8cd887..7afbaef 100644 --- a/pkg/config/config_test.go +++ b/pkg/config/config_test.go @@ -8,17 +8,17 @@ import (  	"github.com/google/go-cmp/cmp"  ) -func TestConfig(t *testing.T) { +func TestFileParsing(t *testing.T) {  	testCases := []struct {  		name           string  		config         string -		expectedConfig *Configuration +		expectedConfig *configuration  	}{  		{  			name:   "minimal scan",  			config: `scan "/srv/git"`, -			expectedConfig: &Configuration{ -				Scan: &Scan{ +			expectedConfig: &configuration{ +				Scan: &scan{  					Public: true,  					Path:   "/srv/git",  				}, @@ -29,8 +29,8 @@ func TestConfig(t *testing.T) {  			config: `scan "/srv/git" {  	public false  }`, -			expectedConfig: &Configuration{ -				Scan: &Scan{ +			expectedConfig: &configuration{ +				Scan: &scan{  					Public: false,  					Path:   "/srv/git",  				}, @@ -41,7 +41,7 @@ func TestConfig(t *testing.T) {  	for _, tc := range testCases {  		t.Run(tc.name, func(t *testing.T) {  			r := strings.NewReader(tc.config) -			config, err := Parse(r) +			config, err := parse(r)  			if err != nil {  				t.Fatalf("Error parsing config %s", err.Error())  			} diff --git a/pkg/git/git.go b/pkg/git/git.go index 85a3b95..b9ab235 100644 --- a/pkg/git/git.go +++ b/pkg/git/git.go @@ -2,63 +2,29 @@ package git  import (  	"errors" -	"os" -	"path" -	"git.gabrielgio.me/cerrado/pkg/u"  	"github.com/go-git/go-git/v5"  	"github.com/go-git/go-git/v5/plumbing/object"  ) +var () +  var ( -	ScanPathErr    = errors.New("Scan path does not exist") -	RepoPathErr    = errors.New("Repository path does not exist") -	missingHeadErr = errors.New("Head not found") +	MissingHeadErr = errors.New("Head not found")  )  type ( -	GitServerRepository struct { -		scanPath string -	} -  	GitRepository struct {  		path string  	}  ) -func NewGitServerRepository(scanPath string) *GitServerRepository { -	return &GitServerRepository{scanPath} -} -  func NewGitRepository(dir string) *GitRepository {  	return &GitRepository{  		path: dir,  	}  } -func (g *GitServerRepository) List() ([]*GitRepository, error) { -	if !u.FileExist(g.scanPath) { -		return nil, ScanPathErr -	} - -	entries, err := os.ReadDir(g.scanPath) -	if err != nil { -		return nil, err -	} - -	repos := make([]*GitRepository, 0) -	for _, e := range entries { -		if !e.IsDir() { -			continue -		} - -		fullPath := path.Join(g.scanPath, e.Name()) -		repos = append(repos, NewGitRepository(fullPath)) -	} - -	return repos, nil -} -  func (g *GitRepository) Path() string {  	return g.path  } @@ -71,7 +37,7 @@ func (g *GitRepository) LastCommit() (*object.Commit, error) {  	ref, err := repo.Head()  	if err != nil { -		return nil, errors.Join(missingHeadErr, err) +		return nil, errors.Join(MissingHeadErr, err)  	}  	c, err := repo.CommitObject(ref.Hash()) diff --git a/pkg/handler/about.go b/pkg/handler/about/handler.go index 3ab2de8..a2caa4e 100644 --- a/pkg/handler/about.go +++ b/pkg/handler/about/handler.go @@ -1,4 +1,4 @@ -package handler +package about  import (  	"io" @@ -13,12 +13,18 @@ import (  	"git.gabrielgio.me/cerrado/templates"  ) -type AboutHandler struct { -	readmePath string -} +type ( +	AboutHandler struct { +		readmePath string +	} + +	configurationRepository interface { +		GetRootReadme() string +	} +) -func NewAboutHandler(readmePath string) *AboutHandler { -	return &AboutHandler{readmePath} +func NewAboutHandler(configRepo configurationRepository) *AboutHandler { +	return &AboutHandler{configRepo.GetRootReadme()}  }  func (g *AboutHandler) About(w http.ResponseWriter, _ *http.Request) { diff --git a/pkg/handler/status.go b/pkg/handler/config/handler.go index 9baac2c..c278e35 100644 --- a/pkg/handler/status.go +++ b/pkg/handler/config/handler.go @@ -1,11 +1,10 @@ -package handler +package config  import (  	"bytes"  	"encoding/json"  	"log/slog"  	"net/http" -	"os"  	"github.com/alecthomas/chroma/v2/formatters/html"  	"github.com/alecthomas/chroma/v2/lexers" @@ -15,21 +14,25 @@ import (  	"git.gabrielgio.me/cerrado/templates"  ) -func ConfigFile(configPath string) func(http.ResponseWriter, *http.Request) { +type ( +	configurationRepository interface { +		GetRootReadme() string +		List() []*config.GitRepositoryConfiguration +	} +) + +func ConfigFile(configRepo configurationRepository) func(http.ResponseWriter, *http.Request) {  	return func(w http.ResponseWriter, _ *http.Request) { -		f, err := os.Open(configPath) -		if err != nil { -			slog.Error("Error openning config file", "error", err, "path", configPath) -			return -		} -		c, err := config.Parse(f) -		if err != nil { -			slog.Error("Error parsing config", "error", err, "path", configPath) -			return +		config := struct { +			RootReadme   string +			Repositories []*config.GitRepositoryConfiguration +		}{ +			RootReadme:   configRepo.GetRootReadme(), +			Repositories: configRepo.List(),  		} -		b, err := json.MarshalIndent(c, "", "	") +		b, err := json.MarshalIndent(config, "", "  ")  		if err != nil {  			slog.Error("Error parsing json", "error", err)  			return diff --git a/pkg/handler/git.go b/pkg/handler/git/handler.go index 1ed2c49..236ac41 100644 --- a/pkg/handler/git.go +++ b/pkg/handler/git/handler.go @@ -1,4 +1,4 @@ -package handler +package git  import (  	"log/slog" @@ -8,12 +8,20 @@ import (  	"git.gabrielgio.me/cerrado/templates"  ) -type GitHandler struct { -	gitService *service.GitService -} +type ( +	GitHandler struct { +		gitService gitService +	} + +	gitService interface { +		ListRepositories() ([]*service.Repository, error) +	} +) -func NewGitHandler(gitService *service.GitService) *GitHandler { -	return &GitHandler{gitService} +func NewGitHandler(gitService gitService) *GitHandler { +	return &GitHandler{ +		gitService: gitService, +	}  }  func (g *GitHandler) List(w http.ResponseWriter, _ *http.Request) { diff --git a/pkg/handler/router.go b/pkg/handler/router.go new file mode 100644 index 0000000..a8c9c6f --- /dev/null +++ b/pkg/handler/router.go @@ -0,0 +1,38 @@ +package handler + +import ( +	"net/http" + +	serverconfig "git.gabrielgio.me/cerrado/pkg/config" +	"git.gabrielgio.me/cerrado/pkg/handler/about" +	"git.gabrielgio.me/cerrado/pkg/handler/config" +	"git.gabrielgio.me/cerrado/pkg/handler/git" +	"git.gabrielgio.me/cerrado/pkg/handler/static" +	"git.gabrielgio.me/cerrado/pkg/service" +) + +// Mount handler gets the requires service and repository to build the handlers +// This functons wraps the whole handler package and wraps it into one part so +// its sub package don't leak in other places. +func MountHandler( +	gitService *service.GitService, +	configRepo *serverconfig.ConfigurationRepository, +) (http.Handler, error) { +	var ( +		gitHandler   = git.NewGitHandler(gitService) +		aboutHandler = about.NewAboutHandler(configRepo) +		configHander = config.ConfigFile(configRepo) +	) + +	staticHandler, err := static.NewStaticHander("/static/") +	if err != nil { +		return nil, err +	} + +	mux := http.NewServeMux() +	mux.Handle("/static/", staticHandler) +	mux.HandleFunc("/config", configHander) +	mux.HandleFunc("/about", aboutHandler.About) +	mux.HandleFunc("/", gitHandler.List) +	return mux, nil +} diff --git a/pkg/handler/static.go b/pkg/handler/static/handler.go index 9f312f4..6a826cc 100644 --- a/pkg/handler/static.go +++ b/pkg/handler/static/handler.go @@ -1,4 +1,4 @@ -package handler +package static  import (  	"io/fs" diff --git a/pkg/service/git.go b/pkg/service/git.go index 94ca75e..2b1fe25 100644 --- a/pkg/service/git.go +++ b/pkg/service/git.go @@ -3,44 +3,48 @@ package service  import (  	"path" +	"git.gabrielgio.me/cerrado/pkg/config"  	"git.gabrielgio.me/cerrado/pkg/git"  )  type ( -	GitService struct { -		server *git.GitServerRepository -	}  	Repository struct {  		Name              string  		Title             string  		LastCommitMessage string  		LastCommitDate    string  	} + +	GitService struct { +		configRepo configurationRepository +	} + +	configurationRepository interface { +		List() []*config.GitRepositoryConfiguration +	}  )  // TODO: make it configurable  const timeFormat = "2006.01.02 15:04:05" -func NewGitService(server *git.GitServerRepository) *GitService { +func NewGitService(configRepo configurationRepository) *GitService {  	return &GitService{ -		server: server, +		configRepo: configRepo,  	}  }  func (g *GitService) ListRepositories() ([]*Repository, error) { -	rs, err := g.server.List() -	if err != nil { -		return nil, err -	} +	rs := g.configRepo.List()  	repos := make([]*Repository, len(rs))  	for i, r := range rs { -		obj, err := r.LastCommit() +		repo := git.NewGitRepository(r.Path) +		obj, err := repo.LastCommit()  		if err != nil {  			return nil, err  		} -		baseName := path.Base(r.Path()) +		baseName := path.Base(r.Path)  		repos[i] = &Repository{  			Name:              baseName,  			Title:             baseName, | 
