2
0
mirror of https://github.com/acepanel/panel.git synced 2026-02-04 13:47:15 +08:00

feat: 格式化配置文件

This commit is contained in:
2025-12-03 22:30:34 +08:00
parent 62bd8927e3
commit 9319226fd8
4 changed files with 388 additions and 6 deletions

View File

@@ -33,3 +33,149 @@ const DefaultVhostConf = `<VirtualHost *:80>
</Directory>
</VirtualHost>
`
// order 定义 Apache 指令的排序优先级
var order = map[string]int{
"Listen": 0,
"ServerName": 1,
"ServerAlias": 10,
"ServerAdmin": 11,
"DocumentRoot": 100,
"DirectoryIndex": 101,
"Options": 102,
"AllowOverride": 103,
"Require": 104,
"Order": 105,
"Allow": 106,
"Deny": 107,
"LimitRequestBody": 200,
"LimitRequestFields": 201,
"LimitRequestFieldSize": 202,
"LimitRequestLine": 203,
"LimitXMLRequestBody": 204,
"AuthType": 300,
"AuthName": 301,
"AuthUserFile": 302,
"AuthGroupFile": 303,
"AuthBasicProvider": 304,
"SSLEngine": 400,
"SSLCertificateFile": 401,
"SSLCertificateKeyFile": 402,
"SSLCertificateChainFile": 403,
"SSLCACertificateFile": 404,
"SSLCACertificatePath": 405,
"SSLProtocol": 406,
"SSLCipherSuite": 407,
"SSLHonorCipherOrder": 408,
"SSLCompression": 409,
"SSLSessionCache": 410,
"SSLSessionCacheTimeout": 411,
"SSLSessionTickets": 412,
"SSLUseStapling": 413,
"SSLStaplingCache": 414,
"SSLStaplingResponderTimeout": 415,
"SSLStaplingReturnResponderErrors": 416,
"SSLInsecureRenegotiation": 417,
"SSLVerifyClient": 418,
"SSLVerifyDepth": 419,
"SSLOptions": 420,
"Header": 500,
"RequestHeader": 501,
"SetEnvIf": 502,
"SetEnvIfNoCase": 503,
"SetEnv": 504,
"UnsetEnv": 505,
"PassEnv": 506,
"SetOutputFilter": 507,
"SetInputFilter": 508,
"AddOutputFilter": 509,
"AddInputFilter": 510,
"AddType": 511,
"AddHandler": 512,
"AddCharset": 513,
"AddEncoding": 514,
"AddLanguage": 515,
"DefaultType": 516,
"ForceType": 517,
"RemoveType": 518,
"RemoveHandler": 519,
"RemoveCharset": 520,
"RemoveEncoding": 521,
"RemoveLanguage": 522,
"ProxyPass": 600,
"ProxyPassReverse": 601,
"ProxyPassMatch": 602,
"ProxyPassReverseCookieDomain": 603,
"ProxyPassReverseCookiePath": 604,
"ProxyPreserveHost": 605,
"ProxyRequests": 606,
"ProxyVia": 607,
"ProxyTimeout": 608,
"ProxyAddHeaders": 609,
"ProxySet": 610,
"BalancerMember": 611,
"ProxyPassInherit": 612,
"ProxyPassInterpolateEnv": 613,
"RewriteEngine": 700,
"RewriteBase": 701,
"RewriteCond": 702,
"RewriteRule": 703,
"RewriteMap": 704,
"RewriteOptions": 705,
"Redirect": 800,
"RedirectMatch": 801,
"RedirectTemp": 802,
"RedirectPermanent": 803,
"Alias": 900,
"AliasMatch": 901,
"ScriptAlias": 902,
"ScriptAliasMatch": 903,
"ErrorDocument": 1000,
"ExpiresActive": 1100,
"ExpiresDefault": 1101,
"ExpiresByType": 1102,
"DeflateCompressionLevel": 1103,
"DeflateMemLevel": 1104,
"DeflateWindowSize": 1105,
"DeflateBufferSize": 1106,
"DeflateFilterNote": 1107,
"AddOutputFilterByType": 1108,
"PHPIniDir": 1200,
"SetHandler": 1201,
"Directory": 1300,
"DirectoryMatch": 1301,
"Files": 1302,
"FilesMatch": 1303,
"Location": 1304,
"LocationMatch": 1305,
"If": 1306,
"IfDefine": 1307,
"IfModule": 1308,
"Else": 1309,
"ElseIf": 1310,
"Proxy": 1311,
"ProxyMatch": 1312,
"Include": 1400,
"IncludeOptional": 1401,
"ErrorLog": 1500,
"CustomLog": 1501,
"LogLevel": 1502,
"LogFormat": 1503,
"TransferLog": 1504,
}

View File

@@ -2,6 +2,7 @@ package apache
import (
"fmt"
"slices"
"sort"
"strings"
)
@@ -32,7 +33,7 @@ func DefaultExportOptions() *ExportOptions {
return &ExportOptions{
IndentStyle: "spaces",
IndentSize: 4,
SortDirectives: false,
SortDirectives: true,
IncludeComments: true,
PreserveEmptyLines: true,
FormatStyle: "standard",
@@ -79,8 +80,10 @@ func (c *Config) ExportWithOptions(options *ExportOptions) string {
})
}
// 如果需要保持原始顺序,按行号排序
if !options.SortDirectives {
// 排序:如果需要语义排序则按 order 排序,否则按行号排序
if options.SortDirectives {
sortDirectivesSlice(items, order)
} else {
sort.Slice(items, func(i, j int) bool {
return items[i].line < items[j].line
})
@@ -186,8 +189,10 @@ func (v *VirtualHost) ExportWithOptions(options *ExportOptions, indent int) stri
})
}
// 排序
if !options.SortDirectives {
// 排序:如果需要语义排序则按 order 排序,否则按行号排序
if options.SortDirectives {
sortDirectivesSlice(items, order)
} else {
sort.Slice(items, func(i, j int) bool {
return items[i].line < items[j].line
})
@@ -268,8 +273,10 @@ func (b *Block) ExportWithOptions(options *ExportOptions, indent int) string {
}
}
// 按行号排序
// 排序:如果需要语义排序则按 order 排序,否则按行号排序
if options.SortDirectives {
sortDirectivesSlice(allItems, order)
} else {
sort.Slice(allItems, func(i, j int) bool {
return allItems[i].line < allItems[j].line
})
@@ -345,3 +352,67 @@ func shouldAddEmptyLine(current, next exportItem, options *ExportOptions) bool {
return false
}
// sortDirectivesSlice 对指令切片进行语义排序
func sortDirectivesSlice(items []exportItem, orderIndex map[string]int) {
slices.SortFunc(items, func(a, b exportItem) int {
// 跳过注释,注释保持原有位置
if a.typ == "comment" || b.typ == "comment" {
return a.line - b.line
}
var aName, bName string
switch a.typ {
case "directive":
if dir, ok := a.item.(*Directive); ok {
aName = dir.Name
}
case "virtualhost":
if vhost, ok := a.item.(*VirtualHost); ok {
aName = vhost.Name
}
}
switch b.typ {
case "directive":
if dir, ok := b.item.(*Directive); ok {
bName = dir.Name
}
case "virtualhost":
if vhost, ok := b.item.(*VirtualHost); ok {
bName = vhost.Name
}
}
// 按照 order 优先级排序
if orderIndex[aName] != orderIndex[bName] {
return orderIndex[aName] - orderIndex[bName]
}
// 优先级相同时,按照参数排序
var aArgs, bArgs []string
switch a.typ {
case "directive":
if dir, ok := a.item.(*Directive); ok {
aArgs = dir.Args
}
case "virtualhost":
if vhost, ok := a.item.(*VirtualHost); ok {
aArgs = vhost.Args
}
}
switch b.typ {
case "directive":
if dir, ok := b.item.(*Directive); ok {
bArgs = dir.Args
}
case "virtualhost":
if vhost, ok := b.item.(*VirtualHost); ok {
bArgs = vhost.Args
}
}
return slices.Compare(aArgs, bArgs)
})
}