Skip to content

Commit 7911560

Browse files
committed
feat: add option to set storage.json as read-only.
1. Default does not set storage.json file to read-only mode 2. Default retains other configuration information in storage.json
1 parent 5884f82 commit 7911560

1 file changed

Lines changed: 113 additions & 57 deletions

File tree

main.go

Lines changed: 113 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"encoding/hex"
1010
"encoding/json"
1111
"errors"
12+
"flag"
1213
"fmt"
1314
"log"
1415
"os"
@@ -45,21 +46,22 @@ const (
4546
type (
4647
// TextResource stores multilingual text / 存储多语言文本
4748
TextResource struct {
48-
SuccessMessage string
49-
RestartMessage string
50-
ReadingConfig string
51-
GeneratingIds string
52-
PressEnterToExit string
53-
ErrorPrefix string
54-
PrivilegeError string
55-
RunAsAdmin string
56-
RunWithSudo string
57-
SudoExample string
58-
ConfigLocation string
59-
CheckingProcesses string
60-
ClosingProcesses string
61-
ProcessesClosed string
62-
PleaseWait string
49+
SuccessMessage string
50+
RestartMessage string
51+
ReadingConfig string
52+
GeneratingIds string
53+
PressEnterToExit string
54+
ErrorPrefix string
55+
PrivilegeError string
56+
RunAsAdmin string
57+
RunWithSudo string
58+
SudoExample string
59+
ConfigLocation string
60+
CheckingProcesses string
61+
ClosingProcesses string
62+
ProcessesClosed string
63+
PleaseWait string
64+
SetReadOnlyMessage string
6365
}
6466

6567
// StorageConfig optimized storage configuration / 优化的存储配置
@@ -117,42 +119,46 @@ var (
117119

118120
texts = map[Language]TextResource{
119121
CN: {
120-
SuccessMessage: "[√] 配置文件已成功更新!",
121-
RestartMessage: "[!] 请手动重启 Cursor 以使更新生效",
122-
ReadingConfig: "正在读取配置文件...",
123-
GeneratingIds: "正在生成新的标识符...",
124-
PressEnterToExit: "按回车键退出程序...",
125-
ErrorPrefix: "程序发生严重错误: %v",
126-
PrivilegeError: "\n[!] 错误:需要管理员权限",
127-
RunAsAdmin: "请右键点击程序,选择「以管理员身份运行」",
128-
RunWithSudo: "请使用 sudo 命令运行此程序",
129-
SudoExample: "示例: sudo %s",
130-
ConfigLocation: "配置文件位置:",
131-
CheckingProcesses: "正在检查运行中的 Cursor 实例...",
132-
ClosingProcesses: "正在关闭 Cursor 实例...",
133-
ProcessesClosed: "所有 Cursor 实例已关闭",
134-
PleaseWait: "请稍候...",
122+
SuccessMessage: "[√] 配置文件已成功更新!",
123+
RestartMessage: "[!] 请手动重启 Cursor 以使更新生效",
124+
ReadingConfig: "正在读取配置文件...",
125+
GeneratingIds: "正在生成新的标识符...",
126+
PressEnterToExit: "按回车键退出程序...",
127+
ErrorPrefix: "程序发生严重错误: %v",
128+
PrivilegeError: "\n[!] 错误:需要管理员权限",
129+
RunAsAdmin: "请右键点击程序,选择「以管理员身份运行」",
130+
RunWithSudo: "请使用 sudo 命令运行此程序",
131+
SudoExample: "示例: sudo %s",
132+
ConfigLocation: "配置文件位置:",
133+
CheckingProcesses: "正在检查运行中的 Cursor 实例...",
134+
ClosingProcesses: "正在关闭 Cursor 实例...",
135+
ProcessesClosed: "所有 Cursor 实例已关闭",
136+
PleaseWait: "请稍候...",
137+
SetReadOnlyMessage: "设置 storage.json 为只读模式, 这将导致 workspace 记录信息丢失等问题",
135138
},
136139
EN: {
137-
SuccessMessage: "[√] Configuration file updated successfully!",
138-
RestartMessage: "[!] Please restart Cursor manually for changes to take effect",
139-
ReadingConfig: "Reading configuration file...",
140-
GeneratingIds: "Generating new identifiers...",
141-
PressEnterToExit: "Press Enter to exit...",
142-
ErrorPrefix: "Program encountered a serious error: %v",
143-
PrivilegeError: "\n[!] Error: Administrator privileges required",
144-
RunAsAdmin: "Please right-click and select 'Run as Administrator'",
145-
RunWithSudo: "Please run this program with sudo",
146-
SudoExample: "Example: sudo %s",
147-
ConfigLocation: "Config file location:",
148-
CheckingProcesses: "Checking for running Cursor instances...",
149-
ClosingProcesses: "Closing Cursor instances...",
150-
ProcessesClosed: "All Cursor instances have been closed",
151-
PleaseWait: "Please wait...",
140+
SuccessMessage: "[√] Configuration file updated successfully!",
141+
RestartMessage: "[!] Please restart Cursor manually for changes to take effect",
142+
ReadingConfig: "Reading configuration file...",
143+
GeneratingIds: "Generating new identifiers...",
144+
PressEnterToExit: "Press Enter to exit...",
145+
ErrorPrefix: "Program encountered a serious error: %v",
146+
PrivilegeError: "\n[!] Error: Administrator privileges required",
147+
RunAsAdmin: "Please right-click and select 'Run as Administrator'",
148+
RunWithSudo: "Please run this program with sudo",
149+
SudoExample: "Example: sudo %s",
150+
ConfigLocation: "Config file location:",
151+
CheckingProcesses: "Checking for running Cursor instances...",
152+
ClosingProcesses: "Closing Cursor instances...",
153+
ProcessesClosed: "All Cursor instances have been closed",
154+
PleaseWait: "Please wait...",
155+
SetReadOnlyMessage: "Set storage.json to read-only mode, which will cause issues such as lost workspace records",
152156
},
153157
}
154158
)
155159

160+
var setReadOnly *bool = flag.Bool("r", false, "set storage.json to read-only mode")
161+
156162
// Error Implementation / 错误实现
157163
func (e *AppError) Error() string {
158164
if e.Context != nil {
@@ -225,16 +231,6 @@ func saveConfig(config *StorageConfig, username string) error { // Modified to t
225231
return err
226232
}
227233

228-
content, err := json.MarshalIndent(config, "", " ")
229-
if err != nil {
230-
return &AppError{
231-
Type: ErrSystem,
232-
Op: "generate JSON",
233-
Path: "",
234-
Err: err,
235-
}
236-
}
237-
238234
// Create parent directories with proper permissions
239235
dir := filepath.Dir(configPath)
240236
if err := os.MkdirAll(dir, 0755); err != nil {
@@ -256,9 +252,53 @@ func saveConfig(config *StorageConfig, username string) error { // Modified to t
256252
}
257253
}
258254

255+
originalFileStat, err := os.Stat(configPath)
256+
if err != nil {
257+
return &AppError{
258+
Type: ErrSystem,
259+
Op: "get file mode",
260+
Path: configPath,
261+
Err: err,
262+
}
263+
}
264+
originalFileMode := originalFileStat.Mode()
265+
266+
originalFileContent, err := os.ReadFile(configPath)
267+
if err != nil {
268+
return &AppError{
269+
Type: ErrSystem,
270+
Op: "read original file",
271+
Path: configPath,
272+
Err: err,
273+
}
274+
}
275+
276+
var originalFile map[string]any
277+
if err := json.Unmarshal(originalFileContent, &originalFile); err != nil {
278+
return &AppError{
279+
Type: ErrSystem,
280+
Op: "unmarshal original file",
281+
Path: configPath,
282+
Err: err,
283+
}
284+
}
285+
originalFile["telemetry.sqmId"] = config.TelemetrySqmId
286+
originalFile["telemetry.macMachineId"] = config.TelemetryMacMachineId
287+
originalFile["telemetry.machineId"] = config.TelemetryMachineId
288+
originalFile["telemetry.devDeviceId"] = config.TelemetryDevDeviceId
289+
newFileContent, err := json.MarshalIndent(originalFile, "", " ")
290+
if err != nil {
291+
return &AppError{
292+
Type: ErrSystem,
293+
Op: "marshal new file",
294+
Path: configPath,
295+
Err: err,
296+
}
297+
}
298+
259299
// Write to temporary file first
260300
tmpPath := configPath + ".tmp"
261-
if err := os.WriteFile(tmpPath, content, 0666); err != nil {
301+
if err := os.WriteFile(tmpPath, newFileContent, 0666); err != nil {
262302
return &AppError{
263303
Type: ErrSystem,
264304
Op: "write temporary file",
@@ -267,8 +307,12 @@ func saveConfig(config *StorageConfig, username string) error { // Modified to t
267307
}
268308
}
269309

310+
if *setReadOnly {
311+
originalFileMode = 0444
312+
}
313+
270314
// Ensure proper permissions on temporary file
271-
if err := os.Chmod(tmpPath, 0444); err != nil {
315+
if err := os.Chmod(tmpPath, originalFileMode); err != nil {
272316
os.Remove(tmpPath)
273317
return &AppError{
274318
Type: ErrSystem,
@@ -495,6 +539,15 @@ func showSuccess() {
495539
}
496540
}
497541

542+
func showReadOnlyMessage() {
543+
if *setReadOnly {
544+
warningColor := color.New(color.FgYellow, color.Bold)
545+
warningColor.Printf("%s\n", texts[currentLanguage].SetReadOnlyMessage)
546+
fmt.Println("Press Enter to continue...")
547+
bufio.NewReader(os.Stdin).ReadString('\n')
548+
}
549+
}
550+
498551
func showPrivilegeError() {
499552
text := texts[currentLanguage]
500553
red := color.New(color.FgRed, color.Bold)
@@ -691,6 +744,9 @@ func main() {
691744
}
692745
}()
693746

747+
flag.Parse()
748+
showReadOnlyMessage()
749+
694750
var username string
695751
if username = os.Getenv("SUDO_USER"); username == "" {
696752
user, err := user.Current()

0 commit comments

Comments
 (0)