From 6cfcfc249a8ace6f692ebf9581478506925eae24 Mon Sep 17 00:00:00 2001 From: guyfedwards Date: Sun, 6 Jul 2025 17:23:22 +0100 Subject: [PATCH 1/3] feat: allow multiple backend instances allow multiple instances of miniflux or freshrss BREAKING CHANGE: backends.freshrss and backends.miniflux are now arrays closes #137 --- Makefile | 2 ++ README.md | 12 ++++++------ internal/config/backends.go | 4 ++-- internal/config/config.go | 30 +++++++++++++++++------------- 4 files changed, 27 insertions(+), 21 deletions(-) diff --git a/Makefile b/Makefile index c95d3a4..e68f3b7 100644 --- a/Makefile +++ b/Makefile @@ -15,6 +15,8 @@ sqlite: vhs: docker run --rm -v $PWD:/vhs ghcr.io/charmbracelet/vhs .github/demo.tape +backends: + docker-compose -f backends-compose.yml up # Copied from https://github.com/goreleaser/goreleaser-cross-example/blob/master/Makefile PACKAGE_NAME := github.com/guyfedwards/nom diff --git a/README.md b/README.md index 566c352..f8c3088 100644 --- a/README.md +++ b/README.md @@ -146,13 +146,13 @@ As well as adding feeds directly, you can pull in feeds from another source. You ```yaml backends: miniflux: - host: http://myminiflux.foo - api_key: jafksdljfladjfk + - host: http://myminiflux.foo + api_key: jafksdljfladjfk freshrss: - host: http://myfreshrss.bar - user: admin - password: muchstrong - prefixCats: true # prefix feed name for freshrss entries + - host: http://myfreshrss.bar + user: admin + password: muchstrong + prefixCats: true # prefix feed name for freshrss entries ``` #### FreshRSS diff --git a/internal/config/backends.go b/internal/config/backends.go index a6b7847..feaa925 100644 --- a/internal/config/backends.go +++ b/internal/config/backends.go @@ -24,8 +24,8 @@ type FreshRSSBackend struct { } type Backends struct { - Miniflux *MinifluxBackend `yaml:"miniflux,omitempty"` - FreshRSS *FreshRSSBackend `yaml:"freshrss,omitempty"` + Miniflux []MinifluxBackend `yaml:"miniflux,omitempty"` + FreshRSS []FreshRSSBackend `yaml:"freshrss,omitempty"` } func (mfb *MinifluxBackend) GetFeeds() ([]Feed, error) { diff --git a/internal/config/config.go b/internal/config/config.go index ec7dc75..df18d71 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -161,7 +161,7 @@ func (c *Config) Load() error { var fileConfig Config err = yaml.Unmarshal(rawData, &fileConfig) if err != nil { - return fmt.Errorf("config.Read: %w", err) + return fmt.Errorf("config.Load: %w", err) } c.ShowRead = fileConfig.ShowRead @@ -217,22 +217,26 @@ func (c *Config) Load() error { } if fileConfig.Backends != nil { - if fileConfig.Backends.Miniflux != nil { - mffeeds, err := fileConfig.Backends.Miniflux.GetFeeds() - if err != nil { - return err + if len(fileConfig.Backends.Miniflux) > 0 { + for _, be := range fileConfig.Backends.Miniflux { + mffeeds, err := be.GetFeeds() + if err != nil { + return err + } + + c.Feeds = append(c.Feeds, mffeeds...) } - - c.Feeds = append(c.Feeds, mffeeds...) } - if fileConfig.Backends.FreshRSS != nil { - freshfeeds, err := fileConfig.Backends.FreshRSS.GetFeeds() - if err != nil { - return err - } + if len(fileConfig.Backends.FreshRSS) > 0 { + for _, be := range fileConfig.Backends.FreshRSS { + freshfeeds, err := be.GetFeeds() + if err != nil { + return err + } - c.Feeds = append(c.Feeds, freshfeeds...) + c.Feeds = append(c.Feeds, freshfeeds...) + } } } From 0d273efa6b3694c4ed97e50fa35c2711b995260e Mon Sep 17 00:00:00 2001 From: guyfedwards Date: Tue, 23 Dec 2025 14:29:58 +0000 Subject: [PATCH 2/3] feat: add outdated config notice, docker multi backend --- README.md | 21 +++++++++--------- backends-compose.yml | 45 +++++++++++++++++++++++++++++++++++++++ cmd/nom/main.go | 3 +++ internal/config/config.go | 14 ++++++++++++ 4 files changed, 72 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index f8c3088..00bae12 100644 --- a/README.md +++ b/README.md @@ -11,19 +11,26 @@ ![](./.github/demo.gif) +## Migrating to V3 +**NOTE** When upgrading to V3 if you are using `config.backends` for Miniflux or FreshRSS support, you will need to update your config to be arrays. + ## Install See [releases](https://github.com/guyfedwards/nom/releases) for binaries. E.g. ```sh -curl -L https://github.com/guyfedwards/nom/releases/download/v2.16.2/nom_2.16.2_darwin_amd64.tar.gz | tar -xzvf - +curl -L https://github.com/guyfedwards/nom/releases/download/v3.0.0/nom_3.0.0_darwin_amd64.tar.gz | tar -xzvf - ``` To install the `nom` binary into `/usr/local/bin` (or into the location of your choice) in a single step: ```sh -curl -L https://github.com/guyfedwards/nom/releases/download/v2.16.2/nom_2.16.2_darwin_amd64.tar.gz | - sudo tar -C /usr/local/bin -xvzf - nom +curl -L https://github.com/guyfedwards/nom/releases/download/v3.0.0/nom_3.0.0_darwin_amd64.tar.gz | +sudo tar -C /usr/local/bin -xvzf - nom +``` + +```sh +nom -c my-custom-config.yml ``` ## Usage @@ -34,14 +41,6 @@ nom add nom -h # see all available command and options ``` -## Configuration - -Configuration lives by default in `$XDG_CONFIG_HOME/nom/config.yml` or `$HOME/Library/Application Support/nom/config.yml` on darwin. You can customise the location of the configuration file with the `--config-path` (`-c`) flag: - -```sh -nom -c my-custom-config.yml -``` - ### Feeds Feeds are listed in the `feeds` section of the configuration file. They have a URL, an option name, and an optional list of tags: diff --git a/backends-compose.yml b/backends-compose.yml index 44df71e..22d2d35 100644 --- a/backends-compose.yml +++ b/backends-compose.yml @@ -8,6 +8,23 @@ services: - db environment: - DATABASE_URL=postgres://miniflux:secret@db:5432/miniflux?sslmode=disable + - RUN_MIGRATIONS=1 + - CREATE_ADMIN=1 + - ADMIN_USERNAME=admin + - ADMIN_PASSWORD=miniflux + + miniflux2: + image: miniflux/miniflux:latest + ports: + - "8085:8080" + depends_on: + - db2 + environment: + - DATABASE_URL=postgres://miniflux:secret@db2:5432/miniflux?sslmode=disable + - RUN_MIGRATIONS=1 + - CREATE_ADMIN=1 + - ADMIN_USERNAME=admin + - ADMIN_PASSWORD=miniflux db: image: postgres:15 @@ -21,6 +38,18 @@ services: interval: 10s start_period: 30s + db2: + image: postgres:15 + environment: + - POSTGRES_USER=miniflux + - POSTGRES_PASSWORD=secret + volumes: + - miniflux-db2:/var/lib/postgresql/data + healthcheck: + test: ["CMD", "pg_isready", "-U", "miniflux"] + interval: 10s + start_period: 30s + freshrss: image: freshrss/freshrss container_name: freshrss @@ -36,7 +65,23 @@ services: ports: - "8081:80" + freshrss2: + image: freshrss/freshrss + container_name: freshrss2 + hostname: freshrss2 + restart: unless-stopped + environment: + TZ: Europe/Paris + CRON_MIN: '3,33' + FRESHRSS_ENV: development + ADMIN_EMAIL: admin@example.net + ADMIN_PASSWORD: freshrss + ADMIN_API_PASSWORD: freshrss + ports: + - "8082:80" + volumes: miniflux-db: + miniflux-db2: data: extensions: diff --git a/cmd/nom/main.go b/cmd/nom/main.go index 8909d28..e9290d7 100755 --- a/cmd/nom/main.go +++ b/cmd/nom/main.go @@ -126,15 +126,18 @@ func getCmds() (*commands.Commands, error) { if err = cfg.Load(); err != nil { return nil, err } + var s store.Store if cfg.IsPreviewMode() { s, err = store.NewInMemorySQLiteStore() } else { s, err = store.NewSQLiteStore(cfg.ConfigDir, cfg.Database) } + if err != nil { return nil, fmt.Errorf("main.go: %w", err) } + cmds := commands.New(cfg, s) return cmds, nil } diff --git a/internal/config/config.go b/internal/config/config.go index df18d71..272d5b2 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -6,6 +6,7 @@ import ( "fmt" "os" "path/filepath" + "strings" "gopkg.in/yaml.v3" @@ -14,6 +15,7 @@ import ( var ( ErrFeedAlreadyExists = errors.New("config.AddFeed: feed already exists") + ErrOutdatedConfigV3 = errors.New("outdated config, see docs for v3 changes") DefaultConfigDirName = "nom" DefaultConfigFileName = "config.yml" DefaultDatabaseName = "nom.db" @@ -161,6 +163,10 @@ func (c *Config) Load() error { var fileConfig Config err = yaml.Unmarshal(rawData, &fileConfig) if err != nil { + if isBackendArrayError(err) { + return ErrOutdatedConfigV3 + } + return fmt.Errorf("config.Load: %w", err) } @@ -319,3 +325,11 @@ func (c *Config) ImportFeeds() ([]Feed, error) { return nil, nil } + +const errorPrefix = "cannot unmarshal !!map into " + +// somewhat hacky check for a parsing error on the config.backends node +func isBackendArrayError(e error) bool { + return strings.Contains(e.Error(), errorPrefix+"[]config.FreshRSSBackend") || + strings.Contains(e.Error(), errorPrefix+"[]config.MinifluxBackend") +} From e43aba4df4229d48cd6d4ed958b7a57701c6cf9b Mon Sep 17 00:00:00 2001 From: guyfedwards Date: Tue, 23 Dec 2025 14:35:00 +0000 Subject: [PATCH 3/3] temp --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 00bae12..ce1630b 100644 --- a/README.md +++ b/README.md @@ -147,6 +147,8 @@ backends: miniflux: - host: http://myminiflux.foo api_key: jafksdljfladjfk + - host: http://yourminiflux.foo + api_key: adfhdlsajfsifdi freshrss: - host: http://myfreshrss.bar user: admin