MCPcopy Create free account
hub / github.com/atomicdotdev/atomic / write_settings

Function write_settings

atomic-agent/src/hooks/claude_code/settings.rs:89–153  ·  view source on GitHub ↗
(
    settings_path: &Path,
    raw: &serde_json::Map<String, serde_json::Value>,
)

Source from the content-addressed store, hash-verified

87}
88
89pub(crate) fn write_settings(
90 settings_path: &Path,
91 raw: &serde_json::Map<String, serde_json::Value>,
92) -> AgentResult<()> {
93 if let Some(parent) = settings_path.parent() {
94 std::fs::create_dir_all(parent).map_err(|e| AgentError::ConfigError {
95 operation: "create directory".to_string(),
96 path: parent.to_path_buf(),
97 reason: e.to_string(),
98 })?;
99 }
100
101 let mut output = serde_json::to_string_pretty(raw).map_err(|e| AgentError::ConfigError {
102 operation: "serialize".to_string(),
103 path: settings_path.to_path_buf(),
104 reason: e.to_string(),
105 })?;
106 if !output.ends_with('\n') {
107 output.push('\n');
108 }
109
110 // Atomic write (temp + rename) so a settings watcher never reads a
111 // half-written file (`std::fs::write` truncates the target first).
112 use std::io::Write as _;
113
114 let parent = settings_path.parent().unwrap_or_else(|| Path::new("."));
115 let file_name = settings_path
116 .file_name()
117 .map(|n| n.to_string_lossy().into_owned())
118 .unwrap_or_else(|| "settings.json".to_string());
119 // Same-dir, pid-suffixed temp: rename stays atomic, no clobber between writers.
120 let tmp_path = parent.join(format!(".{}.{}.tmp", file_name, std::process::id()));
121
122 // Preserve existing permissions.
123 let existing_perms = std::fs::metadata(settings_path)
124 .ok()
125 .map(|m| m.permissions());
126
127 if let Err(e) = (|| -> std::io::Result<()> {
128 let mut f = std::fs::File::create(&tmp_path)?;
129 f.write_all(output.as_bytes())?;
130 f.sync_all()?;
131 Ok(())
132 })() {
133 let _ = std::fs::remove_file(&tmp_path);
134 return Err(AgentError::ConfigError {
135 operation: "write temp file".to_string(),
136 path: tmp_path,
137 reason: e.to_string(),
138 });
139 }
140
141 if let Some(perms) = existing_perms {
142 let _ = std::fs::set_permissions(&tmp_path, perms);
143 }
144
145 std::fs::rename(&tmp_path, settings_path).map_err(|e| {
146 let _ = std::fs::remove_file(&tmp_path);

Callers 6

install_toMethod · 0.85
uninstall_fromMethod · 0.85
install_globalMethod · 0.85
uninstall_globalMethod · 0.85
installMethod · 0.85
uninstallMethod · 0.85

Calls 6

set_permissionsFunction · 0.85
parentMethod · 0.80
file_nameMethod · 0.80
pushMethod · 0.45
permissionsMethod · 0.45
as_bytesMethod · 0.45

Tested by

no test coverage detected