git-bug/bridge/core/bridge.go

150 lines
3.1 KiB
Go

package core
import (
"fmt"
"os/exec"
"strings"
"github.com/MichaelMure/git-bug/cache"
"github.com/MichaelMure/git-bug/repository"
"github.com/pkg/errors"
)
var ErrImportNorSupported = errors.New("import is not supported")
var ErrExportNorSupported = errors.New("export is not supported")
// Bridge is a wrapper around a BridgeImpl that will bind low-level
// implementation with utility code to provide high-level functions.
type Bridge struct {
impl BridgeImpl
conf Configuration
}
func NewBridge(impl BridgeImpl) *Bridge {
return &Bridge{
impl: impl,
}
}
func (b *Bridge) Configure(repo repository.RepoCommon) error {
conf, err := b.impl.Configure(repo)
if err != nil {
return err
}
return b.storeConfig(repo, conf)
}
func (b *Bridge) storeConfig(repo repository.RepoCommon, conf Configuration) error {
for key, val := range conf {
storeKey := fmt.Sprintf("git-bug.%s.%s", b.impl.Name(), key)
cmd := exec.Command("git", "config", "--replace-all", storeKey, val)
cmd.Dir = repo.GetPath()
out, err := cmd.CombinedOutput()
if err != nil {
return fmt.Errorf("error while storing bridge configuration: %s", out)
}
}
return nil
}
func (b Bridge) getConfig(repo repository.RepoCommon) (Configuration, error) {
var err error
if b.conf == nil {
b.conf, err = b.loadConfig(repo)
if err != nil {
return nil, err
}
}
return b.conf, nil
}
func (b Bridge) loadConfig(repo repository.RepoCommon) (Configuration, error) {
key := fmt.Sprintf("git-bug.%s", b.impl.Name())
cmd := exec.Command("git", "config", "--get-regexp", key)
cmd.Dir = repo.GetPath()
out, err := cmd.CombinedOutput()
if err != nil {
return nil, fmt.Errorf("error while reading bridge configuration: %s", out)
}
lines := strings.Split(string(out), "\n")
result := make(Configuration, len(lines))
for _, line := range lines {
if strings.TrimSpace(line) == "" {
continue
}
parts := strings.Fields(line)
if len(parts) != 2 {
return nil, fmt.Errorf("bad bridge configuration: %s", line)
}
result[parts[0]] = parts[1]
}
return result, nil
}
func (b Bridge) ImportAll(repo *cache.RepoCache) error {
importer := b.impl.Importer()
if importer == nil {
return ErrImportNorSupported
}
conf, err := b.getConfig(repo)
if err != nil {
return err
}
return b.impl.Importer().ImportAll(repo, conf)
}
func (b Bridge) Import(repo *cache.RepoCache, id string) error {
importer := b.impl.Importer()
if importer == nil {
return ErrImportNorSupported
}
conf, err := b.getConfig(repo)
if err != nil {
return err
}
return b.impl.Importer().Import(repo, conf, id)
}
func (b Bridge) ExportAll(repo *cache.RepoCache) error {
exporter := b.impl.Exporter()
if exporter == nil {
return ErrExportNorSupported
}
conf, err := b.getConfig(repo)
if err != nil {
return err
}
return b.impl.Exporter().ExportAll(repo, conf)
}
func (b Bridge) Export(repo *cache.RepoCache, id string) error {
exporter := b.impl.Exporter()
if exporter == nil {
return ErrExportNorSupported
}
conf, err := b.getConfig(repo)
if err != nil {
return err
}
return b.impl.Exporter().Export(repo, conf, id)
}