Compare commits

..

4 commits

Author SHA1 Message Date
5fb296c176 🐛 Verify valid shows.yml
Fix nil pointer derference
2025-07-02 15:47:22 -05:00
dc9e6f59db Support yt-dlp shows 2025-07-02 14:15:32 -05:00
186bf5fcba 🚨 Update linter and fix new warnings 2025-07-02 14:14:04 -05:00
24436ce28b 🐛 Deduplicate recipes 2025-05-02 18:22:16 -05:00
6 changed files with 112 additions and 36 deletions

View file

@ -1,7 +1,8 @@
version: "2"
linters:
enable:
- errcheck
- gosimple
- govet
- ineffassign
- staticcheck
@ -22,18 +23,17 @@ linters:
- gosec
- perfsprint
- testifylint
linters-settings:
testifylint:
enable-all: true
disable:
- require-error
gocognit:
min-complexity: 16
gocyclo:
min-complexity: 15
gocritic:
enable-all: true
settings:
hugeParam:
sizeThreshold: 255
settings:
testifylint:
enable-all: true
disable:
- require-error
gocognit:
min-complexity: 16
gocyclo:
min-complexity: 15
gocritic:
enable-all: true
settings:
hugeParam:
sizeThreshold: 255

View file

@ -16,6 +16,7 @@ func main() {
m, err := ic.NewMerger(os.Args[1:])
e.HandleErr(err)
//nolint:errcheck // I don't care about this
defer m.Close()
err = m.ParseFiles()

View file

@ -1,6 +1,8 @@
package convids
import (
"bufio"
"cmp"
"context"
"errors"
"fmt"
@ -16,7 +18,16 @@ import (
"gopkg.in/yaml.v3"
)
type ShowWalker func(show *Show, path string) error
type GroupPrinter func(name string, group Shows)
var ErrNoFiles = errors.New("no files processed")
var ErrSkipped = errors.New("skipped")
var ErrMissingConfig = errors.New("missing config")
var ErrMissingShows = errors.New("missing shows")
func NewData(path string) (*Data, error) {
//nolint:gosec // I don't care if this is user input
f, err := os.Open(path)
if err != nil {
return nil, err
@ -24,7 +35,17 @@ func NewData(path string) (*Data, error) {
ydec := yaml.NewDecoder(f)
var data Data
err = ydec.Decode(&data)
return &data, err
if err != nil {
return nil, err
}
if data.Config == nil {
return nil, ErrMissingConfig
}
if data.Shows == nil || len(*(data.Shows)) == 0 {
return nil, ErrMissingShows
}
return &data, nil
}
func ensureExtRe(c *Config) (err error) {
@ -35,12 +56,6 @@ func ensureExtRe(c *Config) (err error) {
return
}
type ShowWalker func(show *Show, path string) error
type GroupPrinter func(name string, group Shows)
var ErrNoFiles = errors.New("no files processed")
var ErrSkipped = errors.New("skipped")
type processInput struct {
file os.DirEntry
source string
@ -152,8 +167,8 @@ func WalkFiles(d *Data, stopOnError bool, gp GroupPrinter, cb ShowWalker) (err e
func DryRun(out io.Writer) ShowWalker {
return func(s *Show, path string) error {
fmt.Fprintf(out, "Saving %s to %s\n", path, s.Folder)
return ErrSkipped
_, err := fmt.Fprintf(out, "Saving %s to %s\n", path, s.Folder)
return cmp.Or(err, ErrSkipped)
}
}
@ -163,18 +178,53 @@ func GetShow(ctx context.Context) ShowWalker {
func GetShowWithIO(ctx context.Context, stdin io.Reader, stdout, stderr io.Writer) ShowWalker {
return func(s *Show, path string) error {
//nolint:gosec // I don't care if this is using user input
cmd := exec.CommandContext(ctx, "get-shows", s.Folder, path)
cmd.Stdin = stdin
cmd.Stdout = stdout
cmd.Stderr = stderr
return cmd.Run()
}
if !s.Url {
return runGetShowsCmd(ctx, s.Folder, path, stdin, stdout, stderr)
}
orig := path
//nolint:gosec // I don't care if this is user input
readFile, err := os.Open(orig)
if err != nil {
return err
}
//nolint:errcheck // I don't care
defer readFile.Close()
fileScan := bufio.NewScanner(readFile)
fileScan.Split(bufio.ScanLines)
for fileScan.Scan() {
path = fileScan.Text()
err := runGetShowsCmd(ctx, s.Folder, path, stdin, stdout, stderr)
if err != nil {
return err
}
}
if s.Backup != "" {
err = os.Rename(orig, fp.Join(s.Backup, fp.Base(orig)))
if err != nil {
_, _ = fmt.Fprintf(stdout, "Moved %s to %s\n", orig, s.Backup)
}
} else {
err = os.Remove(orig)
}
return err
}
}
func runGetShowsCmd(ctx context.Context, folder, path string, stdin io.Reader, stdout, stderr io.Writer) error {
//nolint:gosec // I don't care if this is using user input
cmd := exec.CommandContext(ctx, "get-shows", folder, path)
cmd.Stdin = stdin
cmd.Stdout = stdout
cmd.Stderr = stderr
return cmd.Run()
}
func PrintGroupName(out io.Writer) GroupPrinter {
return func(name string, group Shows) {
fmt.Fprintf(out, "Checking %s shows\n\n", name)
_, _ = fmt.Fprintf(out, "Checking %s shows\n\n", name)
}
}

View file

@ -25,6 +25,8 @@ type Show struct {
Pattern string
Name string
Anime bool
Url bool
Backup string
Sources []string
re *regexp.Regexp

View file

@ -7,6 +7,7 @@ import (
"encoding/json"
"errors"
"os"
"slices"
_ "github.com/glebarez/go-sqlite"
"github.com/jmoiron/sqlx"
@ -196,13 +197,35 @@ func (m *Merger) getRecipes(ctx context.Context, items []Item) (err error) {
if recs, found = rm[items[idx].Id]; found {
items[idx].Recipes = make([][]int32, 0, len(recs))
for _, rec := range recs {
items[idx].Recipes = append(items[idx].Recipes, rec)
addRecs(&(items[idx].Recipes), rec)
}
}
}
return
}
func addRecs(recs *[][]int32, rec []int32) {
slices.Sort(rec)
if !slices.ContainsFunc(*recs, recSorter(rec)) {
*recs = append(*recs, rec)
}
}
func recSorter(rec []int32) func([]int32) bool {
return func(v []int32) bool {
slices.Sort(v)
if !(len(v) == len(rec)) {
return false
}
for idx, i := range v {
if !(i == rec[idx]) {
return false
}
}
return true
}
}
func (m *Merger) Merge(ctx context.Context) (g Game, err error) {
if err = m.getGameDetails(ctx, &g); err != nil {
return

View file

@ -50,11 +50,11 @@ func (a *App) run(ctx context.Context) error {
}
func (a *App) runInLoop(ctx context.Context) error {
fmt.Fprintln(a.stdout, "Looping")
_, _ = fmt.Fprintln(a.stdout, "Looping")
var err error
for err == nil {
err = a.run(ctx)
fmt.Fprintln(a.stdout, err)
_, _ = fmt.Fprintln(a.stdout, err)
}
return err
}