mirror of
https://github.com/yuaotian/go-cursor-help.git
synced 2025-06-08 12:32:06 +08:00
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
This commit is contained in:
parent
5884f82d66
commit
791156055f
170
main.go
170
main.go
@ -9,6 +9,7 @@ import (
|
|||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
@ -45,21 +46,22 @@ const (
|
|||||||
type (
|
type (
|
||||||
// TextResource stores multilingual text / 存储多语言文本
|
// TextResource stores multilingual text / 存储多语言文本
|
||||||
TextResource struct {
|
TextResource struct {
|
||||||
SuccessMessage string
|
SuccessMessage string
|
||||||
RestartMessage string
|
RestartMessage string
|
||||||
ReadingConfig string
|
ReadingConfig string
|
||||||
GeneratingIds string
|
GeneratingIds string
|
||||||
PressEnterToExit string
|
PressEnterToExit string
|
||||||
ErrorPrefix string
|
ErrorPrefix string
|
||||||
PrivilegeError string
|
PrivilegeError string
|
||||||
RunAsAdmin string
|
RunAsAdmin string
|
||||||
RunWithSudo string
|
RunWithSudo string
|
||||||
SudoExample string
|
SudoExample string
|
||||||
ConfigLocation string
|
ConfigLocation string
|
||||||
CheckingProcesses string
|
CheckingProcesses string
|
||||||
ClosingProcesses string
|
ClosingProcesses string
|
||||||
ProcessesClosed string
|
ProcessesClosed string
|
||||||
PleaseWait string
|
PleaseWait string
|
||||||
|
SetReadOnlyMessage string
|
||||||
}
|
}
|
||||||
|
|
||||||
// StorageConfig optimized storage configuration / 优化的存储配置
|
// StorageConfig optimized storage configuration / 优化的存储配置
|
||||||
@ -117,42 +119,46 @@ var (
|
|||||||
|
|
||||||
texts = map[Language]TextResource{
|
texts = map[Language]TextResource{
|
||||||
CN: {
|
CN: {
|
||||||
SuccessMessage: "[√] 配置文件已成功更新!",
|
SuccessMessage: "[√] 配置文件已成功更新!",
|
||||||
RestartMessage: "[!] 请手动重启 Cursor 以使更新生效",
|
RestartMessage: "[!] 请手动重启 Cursor 以使更新生效",
|
||||||
ReadingConfig: "正在读取配置文件...",
|
ReadingConfig: "正在读取配置文件...",
|
||||||
GeneratingIds: "正在生成新的标识符...",
|
GeneratingIds: "正在生成新的标识符...",
|
||||||
PressEnterToExit: "按回车键退出程序...",
|
PressEnterToExit: "按回车键退出程序...",
|
||||||
ErrorPrefix: "程序发生严重错误: %v",
|
ErrorPrefix: "程序发生严重错误: %v",
|
||||||
PrivilegeError: "\n[!] 错误:需要管理员权限",
|
PrivilegeError: "\n[!] 错误:需要管理员权限",
|
||||||
RunAsAdmin: "请右键点击程序,选择「以管理员身份运行」",
|
RunAsAdmin: "请右键点击程序,选择「以管理员身份运行」",
|
||||||
RunWithSudo: "请使用 sudo 命令运行此程序",
|
RunWithSudo: "请使用 sudo 命令运行此程序",
|
||||||
SudoExample: "示例: sudo %s",
|
SudoExample: "示例: sudo %s",
|
||||||
ConfigLocation: "配置文件位置:",
|
ConfigLocation: "配置文件位置:",
|
||||||
CheckingProcesses: "正在检查运行中的 Cursor 实例...",
|
CheckingProcesses: "正在检查运行中的 Cursor 实例...",
|
||||||
ClosingProcesses: "正在关闭 Cursor 实例...",
|
ClosingProcesses: "正在关闭 Cursor 实例...",
|
||||||
ProcessesClosed: "所有 Cursor 实例已关闭",
|
ProcessesClosed: "所有 Cursor 实例已关闭",
|
||||||
PleaseWait: "请稍候...",
|
PleaseWait: "请稍候...",
|
||||||
|
SetReadOnlyMessage: "设置 storage.json 为只读模式, 这将导致 workspace 记录信息丢失等问题",
|
||||||
},
|
},
|
||||||
EN: {
|
EN: {
|
||||||
SuccessMessage: "[√] Configuration file updated successfully!",
|
SuccessMessage: "[√] Configuration file updated successfully!",
|
||||||
RestartMessage: "[!] Please restart Cursor manually for changes to take effect",
|
RestartMessage: "[!] Please restart Cursor manually for changes to take effect",
|
||||||
ReadingConfig: "Reading configuration file...",
|
ReadingConfig: "Reading configuration file...",
|
||||||
GeneratingIds: "Generating new identifiers...",
|
GeneratingIds: "Generating new identifiers...",
|
||||||
PressEnterToExit: "Press Enter to exit...",
|
PressEnterToExit: "Press Enter to exit...",
|
||||||
ErrorPrefix: "Program encountered a serious error: %v",
|
ErrorPrefix: "Program encountered a serious error: %v",
|
||||||
PrivilegeError: "\n[!] Error: Administrator privileges required",
|
PrivilegeError: "\n[!] Error: Administrator privileges required",
|
||||||
RunAsAdmin: "Please right-click and select 'Run as Administrator'",
|
RunAsAdmin: "Please right-click and select 'Run as Administrator'",
|
||||||
RunWithSudo: "Please run this program with sudo",
|
RunWithSudo: "Please run this program with sudo",
|
||||||
SudoExample: "Example: sudo %s",
|
SudoExample: "Example: sudo %s",
|
||||||
ConfigLocation: "Config file location:",
|
ConfigLocation: "Config file location:",
|
||||||
CheckingProcesses: "Checking for running Cursor instances...",
|
CheckingProcesses: "Checking for running Cursor instances...",
|
||||||
ClosingProcesses: "Closing Cursor instances...",
|
ClosingProcesses: "Closing Cursor instances...",
|
||||||
ProcessesClosed: "All Cursor instances have been closed",
|
ProcessesClosed: "All Cursor instances have been closed",
|
||||||
PleaseWait: "Please wait...",
|
PleaseWait: "Please wait...",
|
||||||
|
SetReadOnlyMessage: "Set storage.json to read-only mode, which will cause issues such as lost workspace records",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var setReadOnly *bool = flag.Bool("r", false, "set storage.json to read-only mode")
|
||||||
|
|
||||||
// Error Implementation / 错误实现
|
// Error Implementation / 错误实现
|
||||||
func (e *AppError) Error() string {
|
func (e *AppError) Error() string {
|
||||||
if e.Context != nil {
|
if e.Context != nil {
|
||||||
@ -225,16 +231,6 @@ func saveConfig(config *StorageConfig, username string) error { // Modified to t
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
content, err := json.MarshalIndent(config, "", " ")
|
|
||||||
if err != nil {
|
|
||||||
return &AppError{
|
|
||||||
Type: ErrSystem,
|
|
||||||
Op: "generate JSON",
|
|
||||||
Path: "",
|
|
||||||
Err: err,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create parent directories with proper permissions
|
// Create parent directories with proper permissions
|
||||||
dir := filepath.Dir(configPath)
|
dir := filepath.Dir(configPath)
|
||||||
if err := os.MkdirAll(dir, 0755); err != nil {
|
if err := os.MkdirAll(dir, 0755); err != nil {
|
||||||
@ -256,9 +252,53 @@ func saveConfig(config *StorageConfig, username string) error { // Modified to t
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
originalFileStat, err := os.Stat(configPath)
|
||||||
|
if err != nil {
|
||||||
|
return &AppError{
|
||||||
|
Type: ErrSystem,
|
||||||
|
Op: "get file mode",
|
||||||
|
Path: configPath,
|
||||||
|
Err: err,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
originalFileMode := originalFileStat.Mode()
|
||||||
|
|
||||||
|
originalFileContent, err := os.ReadFile(configPath)
|
||||||
|
if err != nil {
|
||||||
|
return &AppError{
|
||||||
|
Type: ErrSystem,
|
||||||
|
Op: "read original file",
|
||||||
|
Path: configPath,
|
||||||
|
Err: err,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var originalFile map[string]any
|
||||||
|
if err := json.Unmarshal(originalFileContent, &originalFile); err != nil {
|
||||||
|
return &AppError{
|
||||||
|
Type: ErrSystem,
|
||||||
|
Op: "unmarshal original file",
|
||||||
|
Path: configPath,
|
||||||
|
Err: err,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
originalFile["telemetry.sqmId"] = config.TelemetrySqmId
|
||||||
|
originalFile["telemetry.macMachineId"] = config.TelemetryMacMachineId
|
||||||
|
originalFile["telemetry.machineId"] = config.TelemetryMachineId
|
||||||
|
originalFile["telemetry.devDeviceId"] = config.TelemetryDevDeviceId
|
||||||
|
newFileContent, err := json.MarshalIndent(originalFile, "", " ")
|
||||||
|
if err != nil {
|
||||||
|
return &AppError{
|
||||||
|
Type: ErrSystem,
|
||||||
|
Op: "marshal new file",
|
||||||
|
Path: configPath,
|
||||||
|
Err: err,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Write to temporary file first
|
// Write to temporary file first
|
||||||
tmpPath := configPath + ".tmp"
|
tmpPath := configPath + ".tmp"
|
||||||
if err := os.WriteFile(tmpPath, content, 0666); err != nil {
|
if err := os.WriteFile(tmpPath, newFileContent, 0666); err != nil {
|
||||||
return &AppError{
|
return &AppError{
|
||||||
Type: ErrSystem,
|
Type: ErrSystem,
|
||||||
Op: "write temporary file",
|
Op: "write temporary file",
|
||||||
@ -267,8 +307,12 @@ func saveConfig(config *StorageConfig, username string) error { // Modified to t
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if *setReadOnly {
|
||||||
|
originalFileMode = 0444
|
||||||
|
}
|
||||||
|
|
||||||
// Ensure proper permissions on temporary file
|
// Ensure proper permissions on temporary file
|
||||||
if err := os.Chmod(tmpPath, 0444); err != nil {
|
if err := os.Chmod(tmpPath, originalFileMode); err != nil {
|
||||||
os.Remove(tmpPath)
|
os.Remove(tmpPath)
|
||||||
return &AppError{
|
return &AppError{
|
||||||
Type: ErrSystem,
|
Type: ErrSystem,
|
||||||
@ -495,6 +539,15 @@ func showSuccess() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func showReadOnlyMessage() {
|
||||||
|
if *setReadOnly {
|
||||||
|
warningColor := color.New(color.FgYellow, color.Bold)
|
||||||
|
warningColor.Printf("%s\n", texts[currentLanguage].SetReadOnlyMessage)
|
||||||
|
fmt.Println("Press Enter to continue...")
|
||||||
|
bufio.NewReader(os.Stdin).ReadString('\n')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func showPrivilegeError() {
|
func showPrivilegeError() {
|
||||||
text := texts[currentLanguage]
|
text := texts[currentLanguage]
|
||||||
red := color.New(color.FgRed, color.Bold)
|
red := color.New(color.FgRed, color.Bold)
|
||||||
@ -691,6 +744,9 @@ func main() {
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
flag.Parse()
|
||||||
|
showReadOnlyMessage()
|
||||||
|
|
||||||
var username string
|
var username string
|
||||||
if username = os.Getenv("SUDO_USER"); username == "" {
|
if username = os.Getenv("SUDO_USER"); username == "" {
|
||||||
user, err := user.Current()
|
user, err := user.Current()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user