forked from Plemya-x/ALR
fix parsing overrides
This commit is contained in:
@ -68,10 +68,12 @@ func (o *OverridableField[T]) Resolve(overrides []string) {
|
||||
for _, override := range overrides {
|
||||
if v, ok := o.Has(override); ok {
|
||||
o.SetResolved(v)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Database serialization (JSON)
|
||||
func (f *OverridableField[T]) ToDB() ([]byte, error) {
|
||||
var data map[string]T
|
||||
|
||||
@ -103,6 +105,7 @@ func (f *OverridableField[T]) FromDB(data []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Gob serialization
|
||||
type overridableFieldGobPayload[T any] struct {
|
||||
Data map[string]T
|
||||
Resolved T
|
||||
@ -136,6 +139,48 @@ func (f *OverridableField[T]) GobDecode(data []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type overridableFieldJSONPayload[T any] struct {
|
||||
Resolved *T `json:"resolved,omitempty,omitzero"`
|
||||
Data map[string]T `json:"overrides,omitempty,omitzero"`
|
||||
}
|
||||
|
||||
func (f OverridableField[T]) MarshalJSON() ([]byte, error) {
|
||||
data := make(map[string]T)
|
||||
|
||||
for k, v := range f.data {
|
||||
if k == "" {
|
||||
data["default"] = v
|
||||
} else {
|
||||
data[k] = v
|
||||
}
|
||||
}
|
||||
|
||||
payload := overridableFieldJSONPayload[T]{
|
||||
Data: data,
|
||||
Resolved: &f.resolved,
|
||||
}
|
||||
|
||||
return json.Marshal(payload)
|
||||
}
|
||||
|
||||
func (f *OverridableField[T]) UnmarshalJSON(data []byte) error {
|
||||
var payload overridableFieldJSONPayload[T]
|
||||
if err := json.Unmarshal(data, &payload); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if payload.Data == nil {
|
||||
payload.Data = make(map[string]T)
|
||||
}
|
||||
|
||||
f.data = payload.Data
|
||||
if payload.Resolved != nil {
|
||||
f.resolved = *payload.Resolved
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func OverridableFromMap[T any](data map[string]T) OverridableField[T] {
|
||||
if data == nil {
|
||||
data = make(map[string]T)
|
||||
|
@ -14,9 +14,12 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//go:generate go run ../../generators/alrsh-package
|
||||
|
||||
package alrsh
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
@ -39,38 +42,38 @@ func ParseNames(dec *decoder.Decoder) (*PackageNames, error) {
|
||||
}
|
||||
|
||||
type Package struct {
|
||||
Repository string `xorm:"pk 'repository'"`
|
||||
Name string `xorm:"pk 'name'"`
|
||||
BasePkgName string `xorm:"notnull 'basepkg_name'"`
|
||||
Repository string `xorm:"pk 'repository'" json:"repository"`
|
||||
Name string `xorm:"pk 'name'" json:"name"`
|
||||
BasePkgName string `xorm:"notnull 'basepkg_name'" json:"basepkg_name"`
|
||||
|
||||
Version string `sh:"version" xorm:"notnull 'version'"`
|
||||
Release int `sh:"release" xorm:"notnull 'release'"`
|
||||
Epoch uint `sh:"epoch" xorm:"'epoch'"`
|
||||
Architectures []string `sh:"architectures" xorm:"json 'architectures'"`
|
||||
Licenses []string `sh:"license" xorm:"json 'licenses'"`
|
||||
Provides []string `sh:"provides" xorm:"json 'provides'"`
|
||||
Conflicts []string `sh:"conflicts" xorm:"json 'conflicts'"`
|
||||
Replaces []string `sh:"replaces" xorm:"json 'replaces'"`
|
||||
Version string `sh:"version" xorm:"notnull 'version'" json:"version"`
|
||||
Release int `sh:"release" xorm:"notnull 'release'" json:"release"`
|
||||
Epoch uint `sh:"epoch" xorm:"'epoch'" json:"epoch"`
|
||||
Architectures []string `sh:"architectures" xorm:"json 'architectures'" json:"architectures"`
|
||||
Licenses []string `sh:"license" xorm:"json 'licenses'" json:"license"`
|
||||
Provides []string `sh:"provides" xorm:"json 'provides'" json:"provides"`
|
||||
Conflicts []string `sh:"conflicts" xorm:"json 'conflicts'" json:"conflicts"`
|
||||
Replaces []string `sh:"replaces" xorm:"json 'replaces'" json:"replaces"`
|
||||
|
||||
Summary OverridableField[string] `sh:"summary" xorm:"'summary'"`
|
||||
Description OverridableField[string] `sh:"desc" xorm:"'description'"`
|
||||
Group OverridableField[string] `sh:"group" xorm:"'group_name'"`
|
||||
Homepage OverridableField[string] `sh:"homepage" xorm:"'homepage'"`
|
||||
Maintainer OverridableField[string] `sh:"maintainer" xorm:"'maintainer'"`
|
||||
Depends OverridableField[[]string] `sh:"deps" xorm:"'depends'"`
|
||||
BuildDepends OverridableField[[]string] `sh:"build_deps" xorm:"'builddepends'"`
|
||||
OptDepends OverridableField[[]string] `sh:"opt_deps" xorm:"'optdepends'"`
|
||||
Sources OverridableField[[]string] `sh:"sources" xorm:"-"`
|
||||
Checksums OverridableField[[]string] `sh:"checksums" xorm:"-"`
|
||||
Backup OverridableField[[]string] `sh:"backup" xorm:"-"`
|
||||
Scripts OverridableField[Scripts] `sh:"scripts" xorm:"-"`
|
||||
AutoReq OverridableField[[]string] `sh:"auto_req" xorm:"-"`
|
||||
AutoProv OverridableField[[]string] `sh:"auto_prov" xorm:"-"`
|
||||
AutoReqSkipList OverridableField[[]string] `sh:"auto_req_skiplist" xorm:"-"`
|
||||
AutoProvSkipList OverridableField[[]string] `sh:"auto_prov_skiplist" xorm:"-"`
|
||||
Summary OverridableField[string] `sh:"summary" xorm:"'summary'" json:"summary"`
|
||||
Description OverridableField[string] `sh:"desc" xorm:"'description'" json:"description"`
|
||||
Group OverridableField[string] `sh:"group" xorm:"'group_name'" json:"group"`
|
||||
Homepage OverridableField[string] `sh:"homepage" xorm:"'homepage'" json:"homepage"`
|
||||
Maintainer OverridableField[string] `sh:"maintainer" xorm:"'maintainer'" json:"maintainer"`
|
||||
Depends OverridableField[[]string] `sh:"deps" xorm:"'depends'" json:"deps"`
|
||||
BuildDepends OverridableField[[]string] `sh:"build_deps" xorm:"'builddepends'" json:"build_deps"`
|
||||
OptDepends OverridableField[[]string] `sh:"opt_deps" xorm:"'optdepends'" json:"opt_deps,omitempty"`
|
||||
Sources OverridableField[[]string] `sh:"sources" xorm:"-" json:"sources"`
|
||||
Checksums OverridableField[[]string] `sh:"checksums" xorm:"-" json:"checksums,omitempty"`
|
||||
Backup OverridableField[[]string] `sh:"backup" xorm:"-" json:"backup"`
|
||||
Scripts OverridableField[Scripts] `sh:"scripts" xorm:"-" json:"scripts,omitempty"`
|
||||
AutoReq OverridableField[[]string] `sh:"auto_req" xorm:"-" json:"auto_req"`
|
||||
AutoProv OverridableField[[]string] `sh:"auto_prov" xorm:"-" json:"auto_prov"`
|
||||
AutoReqSkipList OverridableField[[]string] `sh:"auto_req_skiplist" xorm:"-" json:"auto_req_skiplist,omitempty"`
|
||||
AutoProvSkipList OverridableField[[]string] `sh:"auto_prov_skiplist" xorm:"-" json:"auto_prov_skiplist,omitempty"`
|
||||
|
||||
FireJailed OverridableField[bool] `sh:"firejailed" xorm:"-"`
|
||||
FireJailProfiles OverridableField[map[string]string] `sh:"firejail_profiles" xorm:"-"`
|
||||
FireJailed OverridableField[bool] `sh:"firejailed" xorm:"-" json:"firejailed"`
|
||||
FireJailProfiles OverridableField[map[string]string] `sh:"firejail_profiles" xorm:"-" json:"firejail_profiles,omitempty"`
|
||||
}
|
||||
|
||||
type Scripts struct {
|
||||
@ -84,25 +87,70 @@ type Scripts struct {
|
||||
PostTrans string `sh:"posttrans"`
|
||||
}
|
||||
|
||||
func ResolvePackage(p *Package, overrides []string) {
|
||||
val := reflect.ValueOf(p).Elem()
|
||||
typ := val.Type()
|
||||
func (p Package) MarshalJSONWithOptions(includeOverrides bool) ([]byte, error) {
|
||||
// Сначала сериализуем обычным способом для получения базовой структуры
|
||||
type PackageAlias Package
|
||||
baseData, err := json.Marshal(PackageAlias(p))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for i := range val.NumField() {
|
||||
field := val.Field(i)
|
||||
fieldType := typ.Field(i)
|
||||
// Десериализуем в map для модификации
|
||||
var result map[string]json.RawMessage
|
||||
if err := json.Unmarshal(baseData, &result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !field.CanInterface() {
|
||||
// Теперь заменяем OverridableField поля
|
||||
v := reflect.ValueOf(p)
|
||||
t := reflect.TypeOf(p)
|
||||
|
||||
for i := 0; i < v.NumField(); i++ {
|
||||
field := v.Field(i)
|
||||
fieldType := t.Field(i)
|
||||
|
||||
jsonTag := fieldType.Tag.Get("json")
|
||||
if jsonTag == "" || jsonTag == "-" {
|
||||
continue
|
||||
}
|
||||
|
||||
if field.Kind() == reflect.Struct && strings.HasPrefix(fieldType.Type.String(), "alrsh.OverridableField") {
|
||||
of := field.Addr().Interface()
|
||||
if res, ok := of.(interface {
|
||||
Resolve([]string)
|
||||
}); ok {
|
||||
res.Resolve(overrides)
|
||||
fieldName := jsonTag
|
||||
if commaIdx := strings.Index(jsonTag, ","); commaIdx != -1 {
|
||||
fieldName = jsonTag[:commaIdx]
|
||||
}
|
||||
|
||||
if field.Type().Name() == "OverridableField" ||
|
||||
(field.Type().Kind() == reflect.Struct &&
|
||||
strings.Contains(field.Type().String(), "OverridableField")) {
|
||||
|
||||
fieldPtr := field.Addr()
|
||||
|
||||
resolvedMethod := fieldPtr.MethodByName("Resolved")
|
||||
if resolvedMethod.IsValid() {
|
||||
resolved := resolvedMethod.Call(nil)[0]
|
||||
|
||||
fieldData := map[string]interface{}{
|
||||
"resolved": resolved.Interface(),
|
||||
}
|
||||
|
||||
if includeOverrides {
|
||||
allMethod := field.MethodByName("All")
|
||||
if allMethod.IsValid() {
|
||||
overrides := allMethod.Call(nil)[0]
|
||||
if !overrides.IsNil() && overrides.Len() > 0 {
|
||||
fieldData["overrides"] = overrides.Interface()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fieldJSON, err := json.Marshal(fieldData)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result[fieldName] = json.RawMessage(fieldJSON)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return json.Marshal(result)
|
||||
}
|
||||
|
105
pkg/alrsh/package_gen.go
Normal file
105
pkg/alrsh/package_gen.go
Normal file
@ -0,0 +1,105 @@
|
||||
// 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
// DO NOT EDIT MANUALLY. This file is generated.
|
||||
package alrsh
|
||||
|
||||
type packageResolved struct {
|
||||
Repository string `json:"repository"`
|
||||
Name string `json:"name"`
|
||||
BasePkgName string `json:"basepkg_name"`
|
||||
Version string `json:"version"`
|
||||
Release int `json:"release"`
|
||||
Epoch uint `json:"epoch"`
|
||||
Architectures []string `json:"architectures"`
|
||||
Licenses []string `json:"license"`
|
||||
Provides []string `json:"provides"`
|
||||
Conflicts []string `json:"conflicts"`
|
||||
Replaces []string `json:"replaces"`
|
||||
Summary string `json:"summary"`
|
||||
Description string `json:"description"`
|
||||
Group string `json:"group"`
|
||||
Homepage string `json:"homepage"`
|
||||
Maintainer string `json:"maintainer"`
|
||||
Depends []string `json:"deps"`
|
||||
BuildDepends []string `json:"build_deps"`
|
||||
OptDepends []string `json:"opt_deps,omitempty"`
|
||||
Sources []string `json:"sources"`
|
||||
Checksums []string `json:"checksums,omitempty"`
|
||||
Backup []string `json:"backup"`
|
||||
Scripts Scripts `json:"scripts,omitempty"`
|
||||
AutoReq []string `json:"auto_req"`
|
||||
AutoProv []string `json:"auto_prov"`
|
||||
AutoReqSkipList []string `json:"auto_req_skiplist,omitempty"`
|
||||
AutoProvSkipList []string `json:"auto_prov_skiplist,omitempty"`
|
||||
FireJailed bool `json:"firejailed"`
|
||||
FireJailProfiles map[string]string `json:"firejail_profiles,omitempty"`
|
||||
}
|
||||
|
||||
func PackageToResolved(src *Package) packageResolved {
|
||||
return packageResolved{
|
||||
Repository: src.Repository,
|
||||
Name: src.Name,
|
||||
BasePkgName: src.BasePkgName,
|
||||
Version: src.Version,
|
||||
Release: src.Release,
|
||||
Epoch: src.Epoch,
|
||||
Architectures: src.Architectures,
|
||||
Licenses: src.Licenses,
|
||||
Provides: src.Provides,
|
||||
Conflicts: src.Conflicts,
|
||||
Replaces: src.Replaces,
|
||||
Summary: src.Summary.Resolved(),
|
||||
Description: src.Description.Resolved(),
|
||||
Group: src.Group.Resolved(),
|
||||
Homepage: src.Homepage.Resolved(),
|
||||
Maintainer: src.Maintainer.Resolved(),
|
||||
Depends: src.Depends.Resolved(),
|
||||
BuildDepends: src.BuildDepends.Resolved(),
|
||||
OptDepends: src.OptDepends.Resolved(),
|
||||
Sources: src.Sources.Resolved(),
|
||||
Checksums: src.Checksums.Resolved(),
|
||||
Backup: src.Backup.Resolved(),
|
||||
Scripts: src.Scripts.Resolved(),
|
||||
AutoReq: src.AutoReq.Resolved(),
|
||||
AutoProv: src.AutoProv.Resolved(),
|
||||
AutoReqSkipList: src.AutoReqSkipList.Resolved(),
|
||||
AutoProvSkipList: src.AutoProvSkipList.Resolved(),
|
||||
FireJailed: src.FireJailed.Resolved(),
|
||||
FireJailProfiles: src.FireJailProfiles.Resolved(),
|
||||
}
|
||||
}
|
||||
|
||||
func ResolvePackage(pkg *Package, overrides []string) {
|
||||
pkg.Summary.Resolve(overrides)
|
||||
pkg.Description.Resolve(overrides)
|
||||
pkg.Group.Resolve(overrides)
|
||||
pkg.Homepage.Resolve(overrides)
|
||||
pkg.Maintainer.Resolve(overrides)
|
||||
pkg.Depends.Resolve(overrides)
|
||||
pkg.BuildDepends.Resolve(overrides)
|
||||
pkg.OptDepends.Resolve(overrides)
|
||||
pkg.Sources.Resolve(overrides)
|
||||
pkg.Checksums.Resolve(overrides)
|
||||
pkg.Backup.Resolve(overrides)
|
||||
pkg.Scripts.Resolve(overrides)
|
||||
pkg.AutoReq.Resolve(overrides)
|
||||
pkg.AutoProv.Resolve(overrides)
|
||||
pkg.AutoReqSkipList.Resolve(overrides)
|
||||
pkg.AutoProvSkipList.Resolve(overrides)
|
||||
pkg.FireJailed.Resolve(overrides)
|
||||
pkg.FireJailProfiles.Resolve(overrides)
|
||||
}
|
37
pkg/alrsh/view.go
Normal file
37
pkg/alrsh/view.go
Normal file
@ -0,0 +1,37 @@
|
||||
// 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
package alrsh
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
type PackageView struct {
|
||||
pkg Package
|
||||
|
||||
Resolved bool
|
||||
}
|
||||
|
||||
func NewPackageView(v Package) PackageView {
|
||||
return PackageView{pkg: v}
|
||||
}
|
||||
|
||||
func (p PackageView) MarshalJSON() ([]byte, error) {
|
||||
if p.Resolved {
|
||||
return json.Marshal(PackageToResolved(&p.pkg))
|
||||
} else {
|
||||
return json.Marshal(p.pkg)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user