mirror of
https://github.com/Jguer/yay.git
synced 2026-02-20 15:21:18 +01:00
* support ini config * support user ini config * Update pkg/settings/ini.go --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
363 lines
9.3 KiB
Go
363 lines
9.3 KiB
Go
package settings
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestConfigurationLoadINI(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
t.Run("load nonexistent file returns nil", func(t *testing.T) {
|
|
t.Parallel()
|
|
cfg := DefaultConfig("test")
|
|
|
|
err := cfg.loadINI("/nonexistent/path/yay.conf")
|
|
assert.NoError(t, err)
|
|
})
|
|
|
|
t.Run("load valid INI file", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
content := `# System-wide yay configuration
|
|
[options]
|
|
AurUrl = https://custom.aur.org
|
|
BuildDir = /var/cache/yay
|
|
Editor = vim
|
|
Devel = true
|
|
SudoLoop = yes
|
|
RequestSplitN = 200
|
|
BottomUp = false
|
|
|
|
; This is also a comment
|
|
CleanAfter = 1
|
|
`
|
|
tmpDir := t.TempDir()
|
|
iniPath := filepath.Join(tmpDir, "yay.conf")
|
|
require.NoError(t, os.WriteFile(iniPath, []byte(content), 0o644))
|
|
|
|
cfg := DefaultConfig("test")
|
|
err := cfg.loadINI(iniPath)
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, "https://custom.aur.org", cfg.AURURL)
|
|
assert.Equal(t, "/var/cache/yay", cfg.BuildDir)
|
|
assert.Equal(t, "vim", cfg.Editor)
|
|
assert.True(t, cfg.Devel)
|
|
assert.True(t, cfg.SudoLoop)
|
|
assert.Equal(t, 200, cfg.RequestSplitN)
|
|
assert.False(t, cfg.BottomUp)
|
|
assert.True(t, cfg.CleanAfter)
|
|
})
|
|
|
|
t.Run("load INI file with all option types", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
content := `
|
|
# String options
|
|
AurUrl = https://aur.example.com
|
|
AurRpcUrl = https://aur.example.com/rpc
|
|
BuildDir = /tmp/build
|
|
Editor = nvim
|
|
EditorFlags = -p
|
|
MakepkgBin = /usr/bin/makepkg
|
|
MakepkgConf = /etc/makepkg.conf
|
|
PacmanBin = /usr/bin/pacman
|
|
PacmanConf = /etc/pacman.conf
|
|
GitBin = /usr/bin/git
|
|
GpgBin = /usr/bin/gpg
|
|
GpgFlags = --keyserver-options
|
|
MFlags = -s
|
|
SortBy = votes
|
|
SearchBy = name
|
|
GitFlags = --depth=1
|
|
RemoveMake = yes
|
|
SudoBin = doas
|
|
SudoFlags = -n
|
|
ReDownload = all
|
|
AnswerClean = All
|
|
AnswerDiff = None
|
|
AnswerEdit = None
|
|
AnswerUpgrade = None
|
|
ReBuild = all
|
|
|
|
# Integer options
|
|
RequestSplitN = 100
|
|
CompletionInterval = 3
|
|
MaxConcurrentDownloads = 4
|
|
|
|
# Boolean options
|
|
BottomUp = true
|
|
SudoLoop = false
|
|
TimeUpdate = yes
|
|
Devel = no
|
|
CleanAfter = true
|
|
KeepSrc = false
|
|
Provides = true
|
|
PgpFetch = false
|
|
CleanMenu = yes
|
|
DiffMenu = no
|
|
EditMenu = true
|
|
CombinedUpgrade = false
|
|
UseAsk = true
|
|
BatchInstall = false
|
|
SingleLineResults = true
|
|
SeparateSources = false
|
|
Debug = no
|
|
Rpc = yes
|
|
DoubleConfirm = false
|
|
`
|
|
tmpDir := t.TempDir()
|
|
iniPath := filepath.Join(tmpDir, "yay.conf")
|
|
require.NoError(t, os.WriteFile(iniPath, []byte(content), 0o644))
|
|
|
|
cfg := DefaultConfig("test")
|
|
err := cfg.loadINI(iniPath)
|
|
require.NoError(t, err)
|
|
|
|
// String options
|
|
assert.Equal(t, "https://aur.example.com", cfg.AURURL)
|
|
assert.Equal(t, "https://aur.example.com/rpc", cfg.AURRPCURL)
|
|
assert.Equal(t, "/tmp/build", cfg.BuildDir)
|
|
assert.Equal(t, "nvim", cfg.Editor)
|
|
assert.Equal(t, "-p", cfg.EditorFlags)
|
|
assert.Equal(t, "/usr/bin/makepkg", cfg.MakepkgBin)
|
|
assert.Equal(t, "/etc/makepkg.conf", cfg.MakepkgConf)
|
|
assert.Equal(t, "/usr/bin/pacman", cfg.PacmanBin)
|
|
assert.Equal(t, "/etc/pacman.conf", cfg.PacmanConf)
|
|
assert.Equal(t, "/usr/bin/git", cfg.GitBin)
|
|
assert.Equal(t, "/usr/bin/gpg", cfg.GpgBin)
|
|
assert.Equal(t, "--keyserver-options", cfg.GpgFlags)
|
|
assert.Equal(t, "-s", cfg.MFlags)
|
|
assert.Equal(t, "votes", cfg.SortBy)
|
|
assert.Equal(t, "name", cfg.SearchBy)
|
|
assert.Equal(t, "--depth=1", cfg.GitFlags)
|
|
assert.Equal(t, "yes", cfg.RemoveMake)
|
|
assert.Equal(t, "doas", cfg.SudoBin)
|
|
assert.Equal(t, "-n", cfg.SudoFlags)
|
|
assert.Equal(t, "all", cfg.ReDownload)
|
|
assert.Equal(t, "All", cfg.AnswerClean)
|
|
assert.Equal(t, "None", cfg.AnswerDiff)
|
|
assert.Equal(t, "None", cfg.AnswerEdit)
|
|
assert.Equal(t, "None", cfg.AnswerUpgrade)
|
|
assert.Equal(t, "all", string(cfg.ReBuild))
|
|
|
|
// Integer options
|
|
assert.Equal(t, 100, cfg.RequestSplitN)
|
|
assert.Equal(t, 3, cfg.CompletionInterval)
|
|
assert.Equal(t, 4, cfg.MaxConcurrentDownloads)
|
|
|
|
// Boolean options
|
|
assert.True(t, cfg.BottomUp)
|
|
assert.False(t, cfg.SudoLoop)
|
|
assert.True(t, cfg.TimeUpdate)
|
|
assert.False(t, cfg.Devel)
|
|
assert.True(t, cfg.CleanAfter)
|
|
assert.False(t, cfg.KeepSrc)
|
|
assert.True(t, cfg.Provides)
|
|
assert.False(t, cfg.PGPFetch)
|
|
assert.True(t, cfg.CleanMenu)
|
|
assert.False(t, cfg.DiffMenu)
|
|
assert.True(t, cfg.EditMenu)
|
|
assert.False(t, cfg.CombinedUpgrade)
|
|
assert.True(t, cfg.UseAsk)
|
|
assert.False(t, cfg.BatchInstall)
|
|
assert.True(t, cfg.SingleLineResults)
|
|
assert.False(t, cfg.SeparateSources)
|
|
assert.False(t, cfg.Debug)
|
|
assert.True(t, cfg.UseRPC)
|
|
assert.False(t, cfg.DoubleConfirm)
|
|
})
|
|
|
|
t.Run("load INI without section header", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
content := `# Config without section header
|
|
AurUrl = https://custom.aur.org
|
|
Devel = true
|
|
RequestSplitN = 250
|
|
`
|
|
tmpDir := t.TempDir()
|
|
iniPath := filepath.Join(tmpDir, "yay.conf")
|
|
require.NoError(t, os.WriteFile(iniPath, []byte(content), 0o644))
|
|
|
|
cfg := DefaultConfig("test")
|
|
err := cfg.loadINI(iniPath)
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, "https://custom.aur.org", cfg.AURURL)
|
|
assert.True(t, cfg.Devel)
|
|
assert.Equal(t, 250, cfg.RequestSplitN)
|
|
})
|
|
|
|
t.Run("load INI with boolean keys (no value)", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
content := `# Boolean keys without values are treated as true
|
|
Devel
|
|
SudoLoop
|
|
CleanAfter
|
|
`
|
|
tmpDir := t.TempDir()
|
|
iniPath := filepath.Join(tmpDir, "yay.conf")
|
|
require.NoError(t, os.WriteFile(iniPath, []byte(content), 0o644))
|
|
|
|
cfg := DefaultConfig("test")
|
|
cfg.Devel = false
|
|
cfg.SudoLoop = false
|
|
cfg.CleanAfter = false
|
|
|
|
err := cfg.loadINI(iniPath)
|
|
require.NoError(t, err)
|
|
|
|
assert.True(t, cfg.Devel)
|
|
assert.True(t, cfg.SudoLoop)
|
|
assert.True(t, cfg.CleanAfter)
|
|
})
|
|
|
|
t.Run("unknown options are ignored", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
content := `AurUrl = https://custom.aur.org
|
|
unknownoption = somevalue
|
|
anotherunknown = 123
|
|
`
|
|
tmpDir := t.TempDir()
|
|
iniPath := filepath.Join(tmpDir, "yay.conf")
|
|
require.NoError(t, os.WriteFile(iniPath, []byte(content), 0o644))
|
|
|
|
cfg := DefaultConfig("test")
|
|
err := cfg.loadINI(iniPath)
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, "https://custom.aur.org", cfg.AURURL)
|
|
})
|
|
}
|
|
|
|
func TestSystemConfigPath(t *testing.T) {
|
|
t.Parallel()
|
|
assert.Equal(t, "/etc/yay.conf", SystemConfigPath)
|
|
}
|
|
|
|
func TestConfigurationSaveINI(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
t.Run("save and reload config", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
cfg := DefaultConfig("test")
|
|
cfg.AURURL = "https://custom.aur.org"
|
|
cfg.BuildDir = "/custom/build"
|
|
cfg.Editor = "nvim"
|
|
cfg.Devel = true
|
|
cfg.SudoLoop = true
|
|
cfg.RequestSplitN = 150
|
|
cfg.BottomUp = true
|
|
cfg.CleanAfter = false
|
|
|
|
tmpDir := t.TempDir()
|
|
iniPath := filepath.Join(tmpDir, "yay.conf")
|
|
|
|
err := cfg.SaveINI(iniPath)
|
|
require.NoError(t, err)
|
|
|
|
// Verify file was created
|
|
_, err = os.Stat(iniPath)
|
|
require.NoError(t, err)
|
|
|
|
// Load into new config and verify values
|
|
cfg2 := DefaultConfig("test")
|
|
err = cfg2.loadINI(iniPath)
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, "https://custom.aur.org", cfg2.AURURL)
|
|
assert.Equal(t, "/custom/build", cfg2.BuildDir)
|
|
assert.Equal(t, "nvim", cfg2.Editor)
|
|
assert.True(t, cfg2.Devel)
|
|
assert.True(t, cfg2.SudoLoop)
|
|
assert.Equal(t, 150, cfg2.RequestSplitN)
|
|
assert.True(t, cfg2.BottomUp)
|
|
assert.False(t, cfg2.CleanAfter)
|
|
})
|
|
|
|
t.Run("save creates directory if not exists", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
cfg := DefaultConfig("test")
|
|
cfg.AURURL = "https://test.aur.org"
|
|
|
|
tmpDir := t.TempDir()
|
|
nestedPath := filepath.Join(tmpDir, "nested", "dir", "yay.conf")
|
|
|
|
err := cfg.SaveINI(nestedPath)
|
|
require.NoError(t, err)
|
|
|
|
// Verify file was created
|
|
_, err = os.Stat(nestedPath)
|
|
require.NoError(t, err)
|
|
})
|
|
|
|
t.Run("roundtrip preserves all field types", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
cfg := DefaultConfig("test")
|
|
// String fields
|
|
cfg.AURURL = "https://roundtrip.aur.org"
|
|
cfg.AURRPCURL = "https://roundtrip.aur.org/rpc"
|
|
cfg.BuildDir = "/roundtrip/build"
|
|
cfg.Editor = "emacs"
|
|
cfg.EditorFlags = "-nw"
|
|
cfg.SudoBin = "doas"
|
|
cfg.SudoFlags = "-n"
|
|
cfg.ReDownload = "all"
|
|
cfg.ReBuild = "tree"
|
|
|
|
// Integer fields
|
|
cfg.RequestSplitN = 75
|
|
cfg.CompletionInterval = 5
|
|
cfg.MaxConcurrentDownloads = 8
|
|
|
|
// Boolean fields
|
|
cfg.BottomUp = true
|
|
cfg.SudoLoop = false
|
|
cfg.Devel = true
|
|
cfg.CleanAfter = false
|
|
cfg.UseRPC = true
|
|
cfg.BatchInstall = true
|
|
|
|
tmpDir := t.TempDir()
|
|
iniPath := filepath.Join(tmpDir, "yay.conf")
|
|
|
|
err := cfg.SaveINI(iniPath)
|
|
require.NoError(t, err)
|
|
|
|
cfg2 := DefaultConfig("test")
|
|
err = cfg2.loadINI(iniPath)
|
|
require.NoError(t, err)
|
|
|
|
// Verify all fields
|
|
assert.Equal(t, cfg.AURURL, cfg2.AURURL)
|
|
assert.Equal(t, cfg.AURRPCURL, cfg2.AURRPCURL)
|
|
assert.Equal(t, cfg.BuildDir, cfg2.BuildDir)
|
|
assert.Equal(t, cfg.Editor, cfg2.Editor)
|
|
assert.Equal(t, cfg.EditorFlags, cfg2.EditorFlags)
|
|
assert.Equal(t, cfg.SudoBin, cfg2.SudoBin)
|
|
assert.Equal(t, cfg.SudoFlags, cfg2.SudoFlags)
|
|
assert.Equal(t, cfg.ReDownload, cfg2.ReDownload)
|
|
assert.Equal(t, cfg.ReBuild, cfg2.ReBuild)
|
|
assert.Equal(t, cfg.RequestSplitN, cfg2.RequestSplitN)
|
|
assert.Equal(t, cfg.CompletionInterval, cfg2.CompletionInterval)
|
|
assert.Equal(t, cfg.MaxConcurrentDownloads, cfg2.MaxConcurrentDownloads)
|
|
assert.Equal(t, cfg.BottomUp, cfg2.BottomUp)
|
|
assert.Equal(t, cfg.SudoLoop, cfg2.SudoLoop)
|
|
assert.Equal(t, cfg.Devel, cfg2.Devel)
|
|
assert.Equal(t, cfg.CleanAfter, cfg2.CleanAfter)
|
|
assert.Equal(t, cfg.UseRPC, cfg2.UseRPC)
|
|
assert.Equal(t, cfg.BatchInstall, cfg2.BatchInstall)
|
|
})
|
|
}
|