No One Can Stop Me Now
This commit is contained in:
132
services/server-manager/internal/config/ini.go
Normal file
132
services/server-manager/internal/config/ini.go
Normal file
@@ -0,0 +1,132 @@
|
||||
// Package config provides INI-style configuration file parsing and editing
|
||||
// for autarch_settings.conf. It preserves comments and formatting.
|
||||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ListSections returns all [section] names from an INI file.
|
||||
func ListSections(path string) ([]string, error) {
|
||||
data, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("read config: %w", err)
|
||||
}
|
||||
|
||||
var sections []string
|
||||
for _, line := range strings.Split(string(data), "\n") {
|
||||
line = strings.TrimSpace(line)
|
||||
if strings.HasPrefix(line, "[") && strings.HasSuffix(line, "]") {
|
||||
sec := line[1 : len(line)-1]
|
||||
sections = append(sections, sec)
|
||||
}
|
||||
}
|
||||
return sections, nil
|
||||
}
|
||||
|
||||
// GetSection returns all key-value pairs from a specific section.
|
||||
func GetSection(path, section string) (keys []string, vals []string, err error) {
|
||||
data, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("read config: %w", err)
|
||||
}
|
||||
|
||||
inSection := false
|
||||
target := "[" + section + "]"
|
||||
|
||||
for _, line := range strings.Split(string(data), "\n") {
|
||||
trimmed := strings.TrimSpace(line)
|
||||
|
||||
// Check for section headers
|
||||
if strings.HasPrefix(trimmed, "[") && strings.HasSuffix(trimmed, "]") {
|
||||
inSection = (trimmed == target)
|
||||
continue
|
||||
}
|
||||
|
||||
if !inSection {
|
||||
continue
|
||||
}
|
||||
|
||||
// Skip comments and empty lines
|
||||
if trimmed == "" || strings.HasPrefix(trimmed, "#") || strings.HasPrefix(trimmed, ";") {
|
||||
continue
|
||||
}
|
||||
|
||||
// Parse key = value
|
||||
eqIdx := strings.Index(trimmed, "=")
|
||||
if eqIdx < 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
key := strings.TrimSpace(trimmed[:eqIdx])
|
||||
val := strings.TrimSpace(trimmed[eqIdx+1:])
|
||||
keys = append(keys, key)
|
||||
vals = append(vals, val)
|
||||
}
|
||||
|
||||
return keys, vals, nil
|
||||
}
|
||||
|
||||
// SetValue updates a single key in a section within the INI content string.
|
||||
// Returns the modified content. If the key doesn't exist, it's appended to the section.
|
||||
func SetValue(content, section, key, value string) string {
|
||||
lines := strings.Split(content, "\n")
|
||||
target := "[" + section + "]"
|
||||
inSection := false
|
||||
found := false
|
||||
|
||||
for i, line := range lines {
|
||||
trimmed := strings.TrimSpace(line)
|
||||
|
||||
if strings.HasPrefix(trimmed, "[") && strings.HasSuffix(trimmed, "]") {
|
||||
// If we were in our target section and didn't find the key, insert before this line
|
||||
if inSection && !found {
|
||||
lines[i] = key + " = " + value + "\n" + line
|
||||
found = true
|
||||
}
|
||||
inSection = (trimmed == target)
|
||||
continue
|
||||
}
|
||||
|
||||
if !inSection {
|
||||
continue
|
||||
}
|
||||
|
||||
// Check if this line matches our key
|
||||
eqIdx := strings.Index(trimmed, "=")
|
||||
if eqIdx < 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
lineKey := strings.TrimSpace(trimmed[:eqIdx])
|
||||
if lineKey == key {
|
||||
lines[i] = key + " = " + value
|
||||
found = true
|
||||
}
|
||||
}
|
||||
|
||||
// If key wasn't found and we're still in section (or section was last), append
|
||||
if !found {
|
||||
if inSection {
|
||||
lines = append(lines, key+" = "+value)
|
||||
}
|
||||
}
|
||||
|
||||
return strings.Join(lines, "\n")
|
||||
}
|
||||
|
||||
// GetValue reads a single value from a section.
|
||||
func GetValue(path, section, key string) (string, error) {
|
||||
keys, vals, err := GetSection(path, section)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
for i, k := range keys {
|
||||
if k == key {
|
||||
return vals[i], nil
|
||||
}
|
||||
}
|
||||
return "", fmt.Errorf("key %q not found in [%s]", key, section)
|
||||
}
|
||||
Reference in New Issue
Block a user