bridge.go

  1package core
  2
  3import (
  4	"fmt"
  5	"os/exec"
  6	"strings"
  7
  8	"github.com/MichaelMure/git-bug/cache"
  9	"github.com/MichaelMure/git-bug/repository"
 10	"github.com/pkg/errors"
 11)
 12
 13var ErrImportNorSupported = errors.New("import is not supported")
 14var ErrExportNorSupported = errors.New("export is not supported")
 15
 16// Bridge is a wrapper around a BridgeImpl that will bind low-level
 17// implementation with utility code to provide high-level functions.
 18type Bridge struct {
 19	impl BridgeImpl
 20	conf Configuration
 21}
 22
 23func NewBridge(impl BridgeImpl) *Bridge {
 24	return &Bridge{
 25		impl: impl,
 26	}
 27}
 28
 29func (b *Bridge) Configure(repo repository.RepoCommon) error {
 30	conf, err := b.impl.Configure(repo)
 31	if err != nil {
 32		return err
 33	}
 34
 35	return b.storeConfig(repo, conf)
 36}
 37
 38func (b *Bridge) storeConfig(repo repository.RepoCommon, conf Configuration) error {
 39	for key, val := range conf {
 40		storeKey := fmt.Sprintf("git-bug.%s.%s", b.impl.Name(), key)
 41
 42		cmd := exec.Command("git", "config", "--replace-all", storeKey, val)
 43		cmd.Dir = repo.GetPath()
 44
 45		out, err := cmd.CombinedOutput()
 46		if err != nil {
 47			return fmt.Errorf("error while storing bridge configuration: %s", out)
 48		}
 49	}
 50
 51	return nil
 52}
 53
 54func (b Bridge) getConfig(repo repository.RepoCommon) (Configuration, error) {
 55	var err error
 56	if b.conf == nil {
 57		b.conf, err = b.loadConfig(repo)
 58		if err != nil {
 59			return nil, err
 60		}
 61	}
 62
 63	return b.conf, nil
 64}
 65
 66func (b Bridge) loadConfig(repo repository.RepoCommon) (Configuration, error) {
 67	key := fmt.Sprintf("git-bug.%s", b.impl.Name())
 68	cmd := exec.Command("git", "config", "--get-regexp", key)
 69	cmd.Dir = repo.GetPath()
 70
 71	out, err := cmd.CombinedOutput()
 72	if err != nil {
 73		return nil, fmt.Errorf("error while reading bridge configuration: %s", out)
 74	}
 75
 76	lines := strings.Split(string(out), "\n")
 77
 78	result := make(Configuration, len(lines))
 79	for _, line := range lines {
 80		if strings.TrimSpace(line) == "" {
 81			continue
 82		}
 83
 84		parts := strings.Fields(line)
 85		if len(parts) != 2 {
 86			return nil, fmt.Errorf("bad bridge configuration: %s", line)
 87		}
 88
 89		result[parts[0]] = parts[1]
 90	}
 91
 92	return result, nil
 93}
 94
 95func (b Bridge) ImportAll(repo *cache.RepoCache) error {
 96	importer := b.impl.Importer()
 97	if importer == nil {
 98		return ErrImportNorSupported
 99	}
100
101	conf, err := b.getConfig(repo)
102	if err != nil {
103		return err
104	}
105
106	return b.impl.Importer().ImportAll(repo, conf)
107}
108
109func (b Bridge) Import(repo *cache.RepoCache, id string) error {
110	importer := b.impl.Importer()
111	if importer == nil {
112		return ErrImportNorSupported
113	}
114
115	conf, err := b.getConfig(repo)
116	if err != nil {
117		return err
118	}
119
120	return b.impl.Importer().Import(repo, conf, id)
121}
122
123func (b Bridge) ExportAll(repo *cache.RepoCache) error {
124	exporter := b.impl.Exporter()
125	if exporter == nil {
126		return ErrExportNorSupported
127	}
128
129	conf, err := b.getConfig(repo)
130	if err != nil {
131		return err
132	}
133
134	return b.impl.Exporter().ExportAll(repo, conf)
135}
136
137func (b Bridge) Export(repo *cache.RepoCache, id string) error {
138	exporter := b.impl.Exporter()
139	if exporter == nil {
140		return ErrExportNorSupported
141	}
142
143	conf, err := b.getConfig(repo)
144	if err != nil {
145		return err
146	}
147
148	return b.impl.Exporter().Export(repo, conf, id)
149}