Compare commits

...

4 commits

Author SHA1 Message Date
Lilian Jónsdóttir aaaad3e348 version++ 2024-02-12 10:20:34 -08:00
Lilian Jónsdóttir 5f7df27d76 add cli flag to remove mods without zip files from the list
also refactor modlist a bit
  - modlist knows about its own directory
  - AddModsNotInList and RemoveModsNotInFolder use said directory instead of taking one as an argument
2024-02-12 10:20:15 -08:00
Lilian Jónsdóttir c9eaba2737 add cli flag to add missing mods in enabled state 2024-02-12 09:45:25 -08:00
Lilian Jónsdóttir 636c6f9143 add go install to justfile 2024-02-11 20:23:32 -08:00
3 changed files with 102 additions and 36 deletions

View file

@ -17,6 +17,7 @@ type config struct {
modsdir, infile, outfile string modsdir, infile, outfile string
mods modlist.Modlist mods modlist.Modlist
clobber, addmissing bool clobber, addmissing bool
missingstate, ignoreuninstalled bool
} }
var cfg config var cfg config
@ -44,7 +45,7 @@ func main() {
app := &cli.App{ app := &cli.App{
Name: "fml", Name: "fml",
Usage: "very simple modlist editor for factorio", Usage: "very simple modlist editor for factorio",
Version: "v0.0.1", Version: "v0.0.2",
Authors: []*cli.Author{{ Authors: []*cli.Author{{
Name: "Lilian Jónsdóttir", Name: "Lilian Jónsdóttir",
Email: "lilian.jonsdottir@gmail.com", Email: "lilian.jonsdottir@gmail.com",
@ -79,6 +80,18 @@ func main() {
Required: false, Required: false,
Usage: "don't automatically add mods missing from infile", Usage: "don't automatically add mods missing from infile",
}, },
&cli.BoolFlag{
Name: "enable-missing",
Aliases: []string{"e"},
Required: false,
Usage: "Missing mods are added in enabled state",
},
&cli.BoolFlag{
Name: "ignore-uninstalled",
Aliases: []string{"u"},
Required: false,
Usage: "Missing mod archives are ignored",
},
}, },
Before: func(ctx *cli.Context) error { Before: func(ctx *cli.Context) error {
// Setup logger // Setup logger
@ -93,6 +106,8 @@ func main() {
// Bool flags // Bool flags
cfg.clobber = ctx.Bool("clobber") cfg.clobber = ctx.Bool("clobber")
cfg.addmissing = !ctx.Bool("no-add-missing") cfg.addmissing = !ctx.Bool("no-add-missing")
cfg.missingstate = ctx.Bool("enable-missing")
cfg.ignoreuninstalled = ctx.Bool("ignore-uninstalled")
// Deal with in/out file // Deal with in/out file
var in = ctx.String("infile") var in = ctx.String("infile")
@ -118,13 +133,20 @@ func main() {
Action: func(ctx *cli.Context) error { Action: func(ctx *cli.Context) error {
var err error var err error
cfg.mods, err = modlist.ReadFromFile(cfg.infile) cfg.mods, err = modlist.ReadFromFile(cfg.infile, cfg.modsdir)
if err != nil { if err != nil {
return err return err
} }
if cfg.addmissing { if cfg.addmissing {
err = modlist.AddModsNotInList(cfg.modsdir, &cfg.mods) err = cfg.mods.AddModsNotInList(cfg.missingstate)
if err != nil {
return err
}
}
if !cfg.ignoreuninstalled {
err = cfg.mods.RemoveModsNotInFolder()
if err != nil { if err != nil {
return err return err
} }

View file

@ -22,6 +22,7 @@ type Mod struct {
// Modlist holds a slice of mods. // Modlist holds a slice of mods.
type Modlist struct { type Modlist struct {
dir string
Mods []Mod `json:"mods"` Mods []Mod `json:"mods"`
} }
@ -119,8 +120,73 @@ func (modlist *Modlist) String() {
modlist.Print("mods") modlist.Print("mods")
} }
// AddModsNotInList finds mod archives in the mod folder that aren't in the modlist, and adds them.
func (modlist *Modlist) AddModsNotInList(state bool) error {
r := regexp.MustCompile(fileRegex)
files, err := os.ReadDir(modlist.dir)
if err != nil {
return err
}
for _, file := range files {
if strings.HasSuffix(file.Name(), ".zip") && !file.IsDir() {
groups := r.FindAllStringSubmatch(file.Name(), -1)
name := groups[0][1]
version := groups[0][2]
if !modlist.HasMod(name) {
log.Infof("Found %s not in modlist, adding v%s in disabled state.", name, version)
modlist.Mods = append(modlist.Mods, Mod{
Name: name,
Enabled: state,
})
}
}
}
return nil
}
// RemoveModsNotInFolder removes mods from the modlist if a corresponding
// zip file cannot be found in the mods dir.
func (modlist *Modlist) RemoveModsNotInFolder() error {
for i, mod := range modlist.Mods {
in, err := isModInFolder(mod.Name, modlist.dir)
if !in && err == nil {
log.Warnf("Zip file for %s could not be found, removing!", mod.Name)
// mods.Mods[i] = nil
modlist.Mods = append(modlist.Mods[:i], modlist.Mods[i+1:]...)
} else if err != nil {
return err
}
}
return nil
}
/// Functions related to the modlist but that shouldn't be attached to the types /// Functions related to the modlist but that shouldn't be attached to the types
func isModInFolder(modname, modsdir string) (bool, error) {
if modname == "base" {
return true, nil
}
// TODO: try for less O(n)
files, err := os.ReadDir(modsdir)
if err != nil {
return false, err
}
for _, file := range files {
if strings.HasPrefix(file.Name(), modname) {
return true, nil
}
}
return false, nil
}
// WriteToFile writes the modlist to the given filename. // WriteToFile writes the modlist to the given filename.
func WriteToFile(filename string, mods *Modlist) error { func WriteToFile(filename string, mods *Modlist) error {
data, err := json.MarshalIndent(&mods, "", " ") data, err := json.MarshalIndent(&mods, "", " ")
@ -134,8 +200,10 @@ func WriteToFile(filename string, mods *Modlist) error {
} }
// ReadFromFile reads the modlist from the given filename. // ReadFromFile reads the modlist from the given filename.
func ReadFromFile(filename string) (Modlist, error) { func ReadFromFile(filename, modsdir string) (Modlist, error) {
var mods Modlist = Modlist{} var mods Modlist = Modlist{
dir: modsdir,
}
data, err := os.ReadFile(filename) data, err := os.ReadFile(filename)
if err != nil { if err != nil {
@ -150,31 +218,3 @@ func ReadFromFile(filename string) (Modlist, error) {
log.Infof("Read modlist from file %s.", filename) log.Infof("Read modlist from file %s.", filename)
return mods, nil return mods, nil
} }
// AddModsNotInList finds mod archives in the mod folder that aren't in the modlist, and adds them.
func AddModsNotInList(modsdir string, mods *Modlist) error {
r := regexp.MustCompile(fileRegex)
files, err := os.ReadDir(modsdir)
if err != nil {
return err
}
for _, file := range files {
if strings.HasSuffix(file.Name(), ".zip") && !file.IsDir() {
groups := r.FindAllStringSubmatch(file.Name(), -1)
name := groups[0][1]
version := groups[0][2]
if !mods.HasMod(name) {
log.Info("Found %s not in modlist, adding v%s in disabled state.", name, version)
mods.Mods = append(mods.Mods, Mod{
Name: name,
Enabled: false,
})
}
}
}
return nil
}

View file

@ -22,6 +22,10 @@ run-binary: build
run-args args: run-args args:
go run {{cmd}} {{args}} go run {{cmd}} {{args}}
# install binary into $GOPATH
install:
go install {{cmd}}
# clean up after yourself # clean up after yourself
clean: clean:
rm {{output}} rm {{output}}