aboutsummaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
authorSlack Coder <slackcoder@server.ky>2024-10-02 16:49:36 -0500
committerSlack Coder <slackcoder@server.ky>2024-10-02 17:01:48 -0500
commit2597c03d1555e00dec59830b7de75e7090208e05 (patch)
tree5642202b4621ea722ee85b322d79bbad17894026 /internal
parentb81d017b42cc814e603de2b49e4b78362ae73f2a (diff)
downloadmirror-2597c03d1555e00dec59830b7de75e7090208e05.tar.xz
config: Use TOML
TOML is simple for users, and it is used in notably projects like rustlang. It also provides comments!
Diffstat (limited to 'internal')
-rw-r--r--internal/github/filesystem.go9
-rw-r--r--internal/github/github.go5
-rw-r--r--internal/service/config.go41
-rw-r--r--internal/service/git.go7
-rw-r--r--internal/service/mirror.go27
-rw-r--r--internal/service/mirror_test.go (renamed from internal/service/service_json_test.go)19
-rw-r--r--internal/service/rsync.go5
-rw-r--r--internal/service/service.go21
-rw-r--r--internal/service/service_json.go64
-rw-r--r--internal/toml.go14
-rw-r--r--internal/url.go21
11 files changed, 105 insertions, 128 deletions
diff --git a/internal/github/filesystem.go b/internal/github/filesystem.go
index 3f069b4..219ec5d 100644
--- a/internal/github/filesystem.go
+++ b/internal/github/filesystem.go
@@ -2,13 +2,14 @@ package github
import (
"fmt"
- "net/url"
"os"
"path"
"strings"
+
+ "git.server.ky/slackcoder/mirror/internal"
)
-func listReleasesByTagName(dst *url.URL) ([]string, error) {
+func listReleasesByTagName(dst *internal.URL) ([]string, error) {
entries, err := os.ReadDir(dst.Path)
if err != nil {
return nil, err
@@ -23,7 +24,7 @@ func listReleasesByTagName(dst *url.URL) ([]string, error) {
}
// The path which project release assets are saved.
-func localReleaseFilePath(dst *url.URL, tagName string) string {
+func localReleaseFilePath(dst *internal.URL, tagName string) string {
return path.Join(dst.Path, tagName)
}
@@ -46,7 +47,7 @@ func releaseSourceFileName(project string, tagName string, ext string) string {
return fmt.Sprintf("%s-%s.%s", project, releaseName(tagName), ext)
}
-func removeRelease(dst *url.URL, tagName string) error {
+func removeRelease(dst *internal.URL, tagName string) error {
fp := localReleaseFilePath(dst, tagName)
return os.RemoveAll(fp)
}
diff --git a/internal/github/github.go b/internal/github/github.go
index bf35a6a..b2b1987 100644
--- a/internal/github/github.go
+++ b/internal/github/github.go
@@ -4,12 +4,13 @@ import (
"fmt"
"io"
"net/http"
- "net/url"
"os"
"path"
"path/filepath"
"regexp"
"time"
+
+ "git.server.ky/slackcoder/mirror/internal"
)
type Client struct {
@@ -192,7 +193,7 @@ func (c *Client) download(dst string, src string) error {
return nil
}
-func (c *Client) MirrorAssets(dst *url.URL, src *url.URL) error {
+func (c *Client) MirrorAssets(dst *internal.URL, src *internal.URL) error {
if src.Hostname() != "github.com" {
return fmt.Errorf("host must be github.com")
}
diff --git a/internal/service/config.go b/internal/service/config.go
index bcb9efc..8105cd5 100644
--- a/internal/service/config.go
+++ b/internal/service/config.go
@@ -1,30 +1,25 @@
package service
import (
- "encoding/json"
"fmt"
"os"
"time"
"dario.cat/mergo"
+ "git.server.ky/slackcoder/mirror/internal"
+ "github.com/BurntSushi/toml"
)
type Duration struct {
time.Duration
}
-func (s Duration) MarshalJSON() ([]byte, error) {
- return json.Marshal(s.Duration.String())
+func (s Duration) MarshalText() ([]byte, error) {
+ return []byte(s.Duration.String()), nil
}
-func (s *Duration) UnmarshalJSON(data []byte) error {
- var str string
- err := json.Unmarshal(data, &str)
- if err != nil {
- return err
- }
-
- v, err := time.ParseDuration(str)
+func (s *Duration) UnmarshalText(text []byte) error {
+ v, err := time.ParseDuration(string(text))
if err != nil {
return err
}
@@ -33,15 +28,26 @@ func (s *Duration) UnmarshalJSON(data []byte) error {
return nil
}
+// Global parameters
+type GlobalConfig struct {
+ MaxInterval Duration `toml:"max-interval"`
+ MinInterval Duration `toml:"min-interval"`
+}
+
type Config struct {
- MaxInterval Duration `json:"max-interval,omitempty"`
- MinInterval Duration `json:"min-interval,omitempty"`
- Mirrors []*Mirror `json:"mirrors,omitempty"`
+ *GlobalConfig `toml:"global"`
+ Mirrors []*Mirror `toml:"mirrors,omitempty"`
+}
+
+func (c *Config) String() string {
+ return internal.MustTOML(c)
}
var DefaultConfig = Config{
- MaxInterval: Duration{24 * time.Hour},
- MinInterval: Duration{time.Hour},
+ GlobalConfig: &GlobalConfig{
+ MaxInterval: Duration{24 * time.Hour},
+ MinInterval: Duration{time.Hour},
+ },
}
func (c *Config) Apply(arg Config) {
@@ -63,11 +69,12 @@ func ApplyFileConfig(cfg *Config, filePath string) error {
}
defer f.Close()
- err = json.NewDecoder(f).Decode(&ret)
+ _, err = toml.NewDecoder(f).Decode(&ret)
if err != nil {
return fmt.Errorf("loading configuration file: %w", err)
}
cfg.Apply(ret)
+
return nil
}
diff --git a/internal/service/git.go b/internal/service/git.go
index ad3a653..b61e332 100644
--- a/internal/service/git.go
+++ b/internal/service/git.go
@@ -3,11 +3,12 @@ package service
import (
"errors"
"fmt"
- "net/url"
"os"
"os/exec"
"path"
"strings"
+
+ "git.server.ky/slackcoder/mirror/internal"
)
const gitDescriptionFile = "description"
@@ -44,7 +45,7 @@ func setDescription(repo string, desc string) error {
}
// Set the remote origin's URL for the projects repository.
-func setRemoteOrigin(repo string, origin *url.URL) error {
+func setRemoteOrigin(repo string, origin *internal.URL) error {
cmd := exec.Command("git", "remote", "get-url", "origin")
cmd.Dir = repo
buf, err := cmd.Output()
@@ -87,7 +88,7 @@ func getRemoteHeadReference(repo string) (string, error) {
return "", errors.New("not found")
}
-func MirrorGit(dst *url.URL, src *url.URL, description string) error {
+func MirrorGit(dst *internal.URL, src *internal.URL, description string) error {
if dst.Scheme != "" && dst.Scheme != "file://" {
return fmt.Errorf("'%s' scheme not supported", dst.Scheme)
}
diff --git a/internal/service/mirror.go b/internal/service/mirror.go
new file mode 100644
index 0000000..12aaa79
--- /dev/null
+++ b/internal/service/mirror.go
@@ -0,0 +1,27 @@
+package service
+
+import (
+ "bytes"
+
+ "git.server.ky/slackcoder/mirror/internal"
+ "github.com/BurntSushi/toml"
+)
+
+type Mirror struct {
+ Method string `toml:"method,omitempty"`
+ From *internal.URL `toml:"from,omitempty"`
+ To *internal.URL `toml:"to,omitempty"`
+ Description string `toml:"description,omitempty"`
+}
+
+func (m *Mirror) Equal(arg *Mirror) bool {
+ return m.Method == arg.Method && m.From.String() == arg.From.String() && m.To.String() == arg.To.String()
+}
+
+func (m *Mirror) String() string {
+ var buf bytes.Buffer
+
+ toml.NewEncoder(&buf).Encode(m)
+
+ return buf.String()
+}
diff --git a/internal/service/service_json_test.go b/internal/service/mirror_test.go
index c8e073a..f9411e2 100644
--- a/internal/service/service_json_test.go
+++ b/internal/service/mirror_test.go
@@ -1,24 +1,15 @@
package service
import (
- "encoding/json"
"testing"
"git.server.ky/slackcoder/mirror/internal"
+ "github.com/BurntSushi/toml"
"github.com/stretchr/testify/require"
)
-func mustJSON(arg interface{}) string {
- buf, err := json.Marshal(arg)
- if err != nil {
- panic(err)
- }
-
- return string(buf)
-}
-
-func TestMirrorUnmarshalJSON(t *testing.T) {
- str := mustJSON(map[string]interface{}{
+func TestMirrorUnmarshalTOML(t *testing.T) {
+ str := internal.MustTOML(map[string]interface{}{
"method": "git",
"from": "https://git.taler.net/merchant.git",
"to": "/mirror/merchant",
@@ -31,7 +22,9 @@ func TestMirrorUnmarshalJSON(t *testing.T) {
}
var s Mirror
- err := json.Unmarshal([]byte(str), &s)
+
+ err := toml.Unmarshal([]byte(str), &s)
+
require.NoError(t, err)
require.Equal(t, exp.String(), s.String())
}
diff --git a/internal/service/rsync.go b/internal/service/rsync.go
index 8298589..c9c7e92 100644
--- a/internal/service/rsync.go
+++ b/internal/service/rsync.go
@@ -3,9 +3,10 @@ package service
import (
"bytes"
"errors"
- "net/url"
"os/exec"
"strings"
+
+ "git.server.ky/slackcoder/mirror/internal"
)
var rsyncOpts = []string{
@@ -19,7 +20,7 @@ var rsyncOpts = []string{
"--times",
}
-func Rsync(dst *url.URL, src *url.URL) error {
+func Rsync(dst *internal.URL, src *internal.URL) error {
src2 := *src
if !strings.HasSuffix(src2.Path, "/.") {
src2.Path = src2.Path + "/."
diff --git a/internal/service/service.go b/internal/service/service.go
index c34bcd3..38cabf8 100644
--- a/internal/service/service.go
+++ b/internal/service/service.go
@@ -1,11 +1,9 @@
package service
import (
- "encoding/json"
"errors"
"fmt"
"math/rand"
- "net/url"
"os"
"strconv"
"strings"
@@ -15,25 +13,6 @@ import (
"git.server.ky/slackcoder/mirror/internal/github"
)
-type Mirror struct {
- Method string `json:"method"`
- From *url.URL `json:"-"`
- To *url.URL `json:"-"`
- Description string `json:"description,omitempty"`
-}
-
-func (m *Mirror) Equal(arg *Mirror) bool {
- return m.Method == arg.Method && m.From.String() == arg.From.String() && m.To.String() == arg.To.String()
-}
-
-func (m *Mirror) String() string {
- buf, err := json.Marshal(m)
- if err != nil {
- panic(err)
- }
- return string(buf)
-}
-
type Service struct {
cfg *Config
diff --git a/internal/service/service_json.go b/internal/service/service_json.go
deleted file mode 100644
index 571eb30..0000000
--- a/internal/service/service_json.go
+++ /dev/null
@@ -1,64 +0,0 @@
-package service
-
-import (
- "encoding/json"
- "net/url"
-)
-
-type JsonURL struct {
- *url.URL
-}
-
-func (m JsonURL) MarshalJSON() ([]byte, error) {
- str := m.String()
- return json.Marshal(str)
-}
-
-func (m *JsonURL) UnmarshalJSON(buf []byte) error {
- var str string
-
- err := json.Unmarshal(buf, &str)
- if err != nil {
- return err
- }
-
- m.URL, err = url.Parse(str)
- return err
-}
-
-func (m Mirror) MarshalJSON() ([]byte, error) {
- type Alias Mirror
-
- m2 := struct {
- *Alias
- From JsonURL `json:"from"`
- To JsonURL `json:"to"`
- }{
- Alias: (*Alias)(&m),
- From: JsonURL{m.From},
- To: JsonURL{m.To},
- }
-
- return json.Marshal(m2)
-}
-
-func (m *Mirror) UnmarshalJSON(buf []byte) error {
- type Alias Mirror
-
- var m2 struct {
- *Alias
- From JsonURL `json:"from"`
- To JsonURL `json:"to"`
- }
-
- m2.Alias = (*Alias)(m)
- err := json.Unmarshal(buf, &m2)
- if err != nil {
- return err
- }
-
- m.From = m2.From.URL
- m.To = m2.To.URL
-
- return nil
-}
diff --git a/internal/toml.go b/internal/toml.go
new file mode 100644
index 0000000..4222921
--- /dev/null
+++ b/internal/toml.go
@@ -0,0 +1,14 @@
+package internal
+
+import (
+ "github.com/BurntSushi/toml"
+)
+
+func MustTOML(arg interface{}) string {
+ buf, err := toml.Marshal(arg)
+ if err != nil {
+ panic(err)
+ }
+
+ return string(buf)
+}
diff --git a/internal/url.go b/internal/url.go
index 3a8d20a..d7a712d 100644
--- a/internal/url.go
+++ b/internal/url.go
@@ -2,10 +2,27 @@ package internal
import "net/url"
-func MustURL(arg string) *url.URL {
+type URL struct {
+ *url.URL
+}
+
+func (u *URL) MarshalText() ([]byte, error) {
+ return []byte(u.URL.String()), nil
+}
+
+func (u *URL) UnmarshalText(buf []byte) error {
+ var err error
+ u.URL, err = url.Parse(string(buf))
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+func MustURL(arg string) *URL {
u, err := url.Parse(arg)
if err != nil {
panic(err)
}
- return u
+ return &URL{u}
}