MCPcopy Create free account
hub / github.com/ChrisFeldmeier/OpenCodeRust / execute

Method execute

crates/opencode-tool/src/apply_patch.rs:79–278  ·  view source on GitHub ↗
(
        &self,
        args: serde_json::Value,
        ctx: ToolContext,
    )

Source from the content-addressed store, hash-verified

77 }
78
79 async fn execute(
80 &self,
81 args: serde_json::Value,
82 ctx: ToolContext,
83 ) -> Result<ToolResult, ToolError> {
84 let input: ApplyPatchInput =
85 serde_json::from_value(args).map_err(|e| ToolError::InvalidArguments(e.to_string()))?;
86
87 if input.patch_text.trim().is_empty() {
88 return Err(ToolError::InvalidArguments(
89 "patchText is required".to_string(),
90 ));
91 }
92
93 let file_patches = parse_multi_file_patch(&input.patch_text)?;
94
95 if file_patches.is_empty() {
96 return Err(ToolError::ExecutionError(
97 "No valid hunks found in patch".to_string(),
98 ));
99 }
100
101 let base_path = PathBuf::from(&ctx.directory);
102 let mut file_changes: Vec<FileChange> = Vec::new();
103 let mut total_diff = String::new();
104
105 for file_patch in &file_patches {
106 let file_path = base_path.join(&file_patch.path);
107
108 let file_path_str = file_path.to_string_lossy().to_string();
109 if ctx.is_external_path(&file_path_str) {
110 ctx.ask_permission(
111 PermissionRequest::new("external_directory").with_pattern(&file_path_str),
112 )
113 .await?;
114 }
115
116 let change = process_file_patch(&base_path, file_patch).await?;
117 total_diff.push_str(&change.diff);
118 total_diff.push('\n');
119 file_changes.push(change);
120 }
121
122 let relative_paths: Vec<String> = file_changes
123 .iter()
124 .map(|c| c.relative_path.clone())
125 .collect();
126 let files_metadata: Vec<serde_json::Value> = file_changes
127 .iter()
128 .map(|change| {
129 let (change_type, move_path, target_relative_path) = match &change.operation {
130 PatchOperation::Add => ("add", None, change.relative_path.clone()),
131 PatchOperation::Update => ("update", None, change.relative_path.clone()),
132 PatchOperation::Delete => ("delete", None, change.relative_path.clone()),
133 PatchOperation::Move { move_path } => {
134 ("move", Some(move_path.clone()), move_path.clone())
135 }
136 };

Callers

nothing calls this directly

Calls 14

parse_multi_file_patchFunction · 0.85
newFunction · 0.85
process_file_patchFunction · 0.85
is_emptyMethod · 0.80
is_external_pathMethod · 0.80
ask_permissionMethod · 0.80
with_patternMethod · 0.80
always_allowMethod · 0.80
with_metadataMethod · 0.80
with_patternsMethod · 0.80
do_publish_busMethod · 0.80

Tested by

no test coverage detected