// This file was originally part of the project "LURE - Linux User REpository", created by Elara Musayelyan. // It has been modified as part of "ALR - Any Linux Repository" by the ALR Authors. // // ALR - Any Linux Repository // Copyright (C) 2025 The ALR Authors // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . package overrides import ( "fmt" "regexp" "strings" "golang.org/x/exp/slices" "golang.org/x/text/language" "gitea.plemya-x.ru/Plemya-x/ALR/internal/cpu" "gitea.plemya-x.ru/Plemya-x/ALR/pkg/distro" ) type Opts struct { Name string Overrides bool LikeDistros bool Languages []string LanguageTags []language.Tag } var DefaultOpts = &Opts{ Overrides: true, LikeDistros: true, Languages: []string{"en"}, } // Resolve generates a slice of possible override names in the order that they should be checked func Resolve(info *distro.OSRelease, opts *Opts) ([]string, error) { if opts == nil { opts = DefaultOpts } if !opts.Overrides { return []string{opts.Name}, nil } langs, err := parseLangs(opts.Languages, opts.LanguageTags) if err != nil { return nil, err } architectures, err := cpu.CompatibleArches(cpu.Arch()) if err != nil { return nil, err } distros := []string{info.ID} if opts.LikeDistros { distros = append(distros, info.Like...) } var out []string for _, lang := range langs { for _, distro := range distros { for _, arch := range architectures { out = append(out, opts.Name+"_"+arch+"_"+distro+"_"+lang) } out = append(out, opts.Name+"_"+distro+"_"+lang) } for _, arch := range architectures { out = append(out, opts.Name+"_"+arch+"_"+lang) } out = append(out, opts.Name+"_"+lang) } for _, distro := range distros { for _, arch := range architectures { out = append(out, opts.Name+"_"+arch+"_"+distro) } out = append(out, opts.Name+"_"+distro) } for _, arch := range architectures { out = append(out, opts.Name+"_"+arch) } out = append(out, opts.Name) for index, item := range out { out[index] = strings.TrimPrefix(item, "_") } return out, nil } func (o *Opts) WithName(name string) *Opts { out := &Opts{} *out = *o out.Name = name return out } func (o *Opts) WithOverrides(v bool) *Opts { out := &Opts{} *out = *o out.Overrides = v return out } func (o *Opts) WithLikeDistros(v bool) *Opts { out := &Opts{} *out = *o out.LikeDistros = v return out } func (o *Opts) WithLanguages(langs []string) *Opts { out := &Opts{} *out = *o out.Languages = langs return out } func (o *Opts) WithLanguageTags(langs []string) *Opts { out := &Opts{} *out = *o out.Languages = langs return out } func parseLangs(langs []string, tags []language.Tag) ([]string, error) { out := make([]string, len(tags)+len(langs)) for i, tag := range tags { base, _ := tag.Base() out[i] = base.String() } for i, lang := range langs { tag, err := language.Parse(lang) if err != nil { return nil, err } base, _ := tag.Base() out[len(tags)+i] = base.String() } slices.Sort(out) out = slices.Compact(out) return out, nil } func ReleasePlatformSpecific(release int, info *distro.OSRelease) string { if info.ID == "altlinux" { return fmt.Sprintf("alt%d", release) } if info.ID == "fedora" || slices.Contains(info.Like, "fedora") { re := regexp.MustCompile(`platform:(\S+)`) match := re.FindStringSubmatch(info.PlatformID) if len(match) > 1 { return fmt.Sprintf("%d.%s", release, match[1]) } } return fmt.Sprintf("%d", release) }