1
- #!/usr/bin/env python3
2
- import os
3
- import re
4
- from typing import Dict , List , Tuple
5
- from rich .console import Console
6
- from rich .prompt import Confirm
7
-
8
- class ConfigMerger :
9
- def __init__ (self , local_config : str , example_config : str ):
10
- """初始化配置合并器
11
-
12
- Args:
13
- local_config: 本地配置文件路径
14
- example_config: 示例配置文件路径
15
- """
16
- self .local_config = local_config
17
- self .example_config = example_config
18
- self .console = Console ()
19
-
20
- def _parse_config (self , file_path : str ) -> Dict [str , Tuple [str , List [str ]]]:
21
- """解析配置文件
22
-
23
- Returns:
24
- Dict[配置键: (配置值, 配置注释)]
25
- """
26
- config = {}
27
- current_comments = []
28
-
29
- if not os .path .exists (file_path ):
30
- return config
31
-
32
- with open (file_path , 'r' , encoding = 'utf-8' ) as f :
33
- for line in f :
34
- line = line .strip ()
35
- if not line : # 空行
36
- current_comments = []
37
- continue
38
-
39
- if line .startswith ('#' ): # 注释行
40
- current_comments .append (line )
41
- continue
42
-
43
- if '=' in line : # 配置行
44
- key , value = line .split ('=' , 1 )
45
- key = key .strip ()
46
- value = value .strip ()
47
- config [key ] = (value , current_comments )
48
- current_comments = []
49
-
50
- return config
51
-
52
- def _merge_configs (self ) -> Tuple [List [str ], List [str ]]:
53
- """合并配置
54
-
55
- Returns:
56
- (合并后的配置行列表, 需要人工确认的配置键列表)
57
- """
58
- local_config = self ._parse_config (self .local_config )
59
- example_config = self ._parse_config (self .example_config )
60
-
61
- merged_lines = []
62
- need_confirm = []
63
-
64
- # 处理示例配置中的每一项
65
- for key , (example_value , example_comments ) in example_config .items ():
66
- # 添加注释
67
- merged_lines .extend (example_comments )
68
-
69
- if key in local_config :
70
- local_value , _ = local_config [key ]
71
- if local_value != example_value :
72
- # 值不同,需要确认
73
- need_confirm .append (key )
74
- merged_lines .append (f"# 新版本值: { key } ={ example_value } " )
75
- merged_lines .append (f"{ key } ={ local_value } " )
76
- else :
77
- # 值相同,使用本地值
78
- merged_lines .append (f"{ key } ={ local_value } " )
79
- else :
80
- # 新配置项,使用示例值
81
- merged_lines .append (f"{ key } ={ example_value } " )
82
-
83
- merged_lines .append ('' ) # 添加空行分隔
84
-
85
- # 处理本地配置中的自定义项
86
- for key , (local_value , local_comments ) in local_config .items ():
87
- if key not in example_config :
88
- merged_lines .extend (local_comments )
89
- merged_lines .append (f"{ key } ={ local_value } " )
90
- merged_lines .append ('' )
91
-
92
- return merged_lines , need_confirm
93
-
94
- def update_config (self ) -> bool :
95
- """更新配置文件
96
-
97
- Returns:
98
- bool: 是否更新成功
99
- """
100
- try :
101
- # 如果本地配置不存在,直接复制示例配置
102
- if not os .path .exists (self .local_config ):
103
- with open (self .example_config , 'r' , encoding = 'utf-8' ) as src :
104
- content = src .read ()
105
- with open (self .local_config , 'w' , encoding = 'utf-8' ) as dst :
106
- dst .write (content )
107
- return True
108
-
109
- # 合并配置
110
- merged_lines , need_confirm = self ._merge_configs ()
111
-
112
- # 如果有需要确认的配置
113
- if need_confirm :
114
- self .console .print ("\n [yellow]发现配置差异:[/yellow]" )
115
- for key in need_confirm :
116
- self .console .print (f"配置项 [cyan]{ key } [/cyan] 在新版本中有更新" )
117
-
118
- if not Confirm .ask ("是否继续更新配置?" ):
119
- self .console .print ("[yellow]配置更新已取消,请手动检查配置文件[/yellow]" )
120
- return False
121
-
122
- # 备份原配置
123
- backup_path = f"{ self .local_config } .bak"
124
- if os .path .exists (self .local_config ):
125
- with open (self .local_config , 'r' , encoding = 'utf-8' ) as src :
126
- with open (backup_path , 'w' , encoding = 'utf-8' ) as dst :
127
- dst .write (src .read ())
128
-
129
- # 写入新配置
130
- with open (self .local_config , 'w' , encoding = 'utf-8' ) as f :
131
- f .write ('\n ' .join (merged_lines ))
132
-
133
- return True
134
-
135
- except Exception as e :
136
- self .console .print (f"[red]配置更新失败:{ str (e )} [/red]" )
137
- return False
1
+
0 commit comments