Skip to repository content

tenant.openagents/omega

No repository description is available.

OpenAgents Git authority 2026-07-28T03:59:27.862Z Public web read
NIP-34 coordinate30617:7649603503856e5148d571eac2766b288a8ff1e9e35d380337a1d2b0015b4f92:omega
MaintainersHidden in public view
References2 branches · 1 tag
Read-only clonegit clone https://openagents.com/git/tenant.openagents/omega.git
Browse files

go.rs

248 lines · 8.9 KB · rust
1use anyhow::Result;
2use async_trait::async_trait;
3use collections::HashMap;
4use dap::{DapLocator, DebugRequest, adapters::DebugAdapterName};
5use gpui::{BackgroundExecutor, SharedString};
6use serde::{Deserialize, Serialize};
7use task::{DebugScenario, SpawnInTerminal, TaskTemplate};
8
9pub struct GoLocator;
10
11#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
12#[serde(rename_all = "camelCase")]
13pub struct DelveLaunchRequest {
14    pub request: String,
15    pub mode: String,
16    pub program: String,
17    #[serde(skip_serializing_if = "Option::is_none")]
18    pub cwd: Option<String>,
19    pub args: Vec<String>,
20    pub build_flags: Vec<String>,
21    pub env: HashMap<String, String>,
22}
23
24fn is_debug_flag(arg: &str) -> Option<bool> {
25    let mut part = if let Some(suffix) = arg.strip_prefix("test.") {
26        suffix
27    } else {
28        arg
29    };
30    let mut might_have_arg = true;
31    if let Some(idx) = part.find('=') {
32        might_have_arg = false;
33        part = &part[..idx];
34    }
35    match part {
36        "benchmem" | "failfast" | "fullpath" | "fuzzworker" | "json" | "short" | "v"
37        | "paniconexit0" => Some(false),
38        "bench"
39        | "benchtime"
40        | "blockprofile"
41        | "blockprofilerate"
42        | "count"
43        | "coverprofile"
44        | "cpu"
45        | "cpuprofile"
46        | "fuzz"
47        | "fuzzcachedir"
48        | "fuzzminimizetime"
49        | "fuzztime"
50        | "gocoverdir"
51        | "list"
52        | "memprofile"
53        | "memprofilerate"
54        | "mutexprofile"
55        | "mutexprofilefraction"
56        | "outputdir"
57        | "parallel"
58        | "run"
59        | "shuffle"
60        | "skip"
61        | "testlogfile"
62        | "timeout"
63        | "trace" => Some(might_have_arg),
64        _ if arg.starts_with("test.") => Some(false),
65        _ => None,
66    }
67}
68
69fn is_build_flag(mut arg: &str) -> Option<bool> {
70    let mut might_have_arg = true;
71    if let Some(idx) = arg.find('=') {
72        might_have_arg = false;
73        arg = &arg[..idx];
74    }
75    match arg {
76        "a" | "n" | "race" | "msan" | "asan" | "cover" | "work" | "x" | "v" | "buildvcs"
77        | "json" | "linkshared" | "modcacherw" | "trimpath" => Some(false),
78
79        "p" | "covermode" | "coverpkg" | "asmflags" | "buildmode" | "compiler" | "gccgoflags"
80        | "gcflags" | "installsuffix" | "ldflags" | "mod" | "modfile" | "overlay" | "pgo"
81        | "pkgdir" | "tags" | "toolexec" => Some(might_have_arg),
82        _ => None,
83    }
84}
85
86#[async_trait]
87impl DapLocator for GoLocator {
88    fn name(&self) -> SharedString {
89        SharedString::new_static("go-debug-locator")
90    }
91
92    async fn create_scenario(
93        &self,
94        build_config: &TaskTemplate,
95        resolved_label: &str,
96        adapter: &DebugAdapterName,
97    ) -> Option<DebugScenario> {
98        if build_config.command != "go" {
99            return None;
100        }
101        let go_action = build_config.args.first()?;
102
103        match go_action.as_str() {
104            "test" => {
105                let mut program = ".".to_string();
106                let mut args = Vec::default();
107                let mut build_flags = Vec::default();
108
109                let mut all_args_are_test = false;
110                let mut next_arg_is_test = false;
111                let mut next_arg_is_build = false;
112                let mut seen_pkg = false;
113                let mut seen_v = false;
114
115                for arg in build_config.args.iter().skip(1) {
116                    if all_args_are_test || next_arg_is_test {
117                        // HACK: tasks assume that they are run in a shell context,
118                        // so the -run regex has escaped specials. Delve correctly
119                        // handles escaping, so we undo that here.
120                        if let Some((left, right)) = arg.split_once("/")
121                            && left.starts_with("\\^")
122                            && left.ends_with("\\$")
123                            && right.starts_with("\\^")
124                            && right.ends_with("\\$")
125                        {
126                            let mut left = left[1..left.len() - 2].to_string();
127                            left.push('$');
128
129                            let mut right = right[1..right.len() - 2].to_string();
130                            right.push('$');
131
132                            args.push(format!("{left}/{right}"));
133                        } else if arg.starts_with("\\^") && arg.ends_with("\\$") {
134                            let mut arg = arg[1..arg.len() - 2].to_string();
135                            arg.push('$');
136                            args.push(arg);
137                        } else {
138                            args.push(arg.clone());
139                        }
140                        next_arg_is_test = false;
141                    } else if next_arg_is_build {
142                        build_flags.push(arg.clone());
143                        next_arg_is_build = false;
144                    } else if arg.starts_with('-') {
145                        let flag = arg.trim_start_matches('-');
146                        if flag == "args" {
147                            all_args_are_test = true;
148                        } else if let Some(has_arg) = is_debug_flag(flag) {
149                            if flag == "v" || flag == "test.v" {
150                                seen_v = true;
151                            }
152                            if flag.starts_with("test.") {
153                                args.push(arg.clone());
154                            } else {
155                                args.push(format!("-test.{flag}"))
156                            }
157                            next_arg_is_test = has_arg;
158                        } else if let Some(has_arg) = is_build_flag(flag) {
159                            build_flags.push(arg.clone());
160                            next_arg_is_build = has_arg;
161                        }
162                    } else if !seen_pkg {
163                        program = arg.clone();
164                        seen_pkg = true;
165                    } else {
166                        args.push(arg.clone());
167                    }
168                }
169                if !seen_v {
170                    args.push("-test.v".to_string());
171                }
172
173                let config: serde_json::Value = serde_json::to_value(DelveLaunchRequest {
174                    request: "launch".to_string(),
175                    mode: "test".to_string(),
176                    program,
177                    args,
178                    build_flags,
179                    cwd: build_config.cwd.clone(),
180                    env: build_config.env.clone(),
181                })
182                .unwrap();
183
184                Some(DebugScenario {
185                    label: resolved_label.to_string().into(),
186                    adapter: adapter.0.clone(),
187                    build: None,
188                    config,
189                    tcp_connection: None,
190                })
191            }
192            "run" => {
193                let mut next_arg_is_build = false;
194                let mut seen_pkg = false;
195
196                let mut program = ".".to_string();
197                let mut args = Vec::default();
198                let mut build_flags = Vec::default();
199
200                for arg in build_config.args.iter().skip(1) {
201                    if seen_pkg {
202                        args.push(arg.clone())
203                    } else if next_arg_is_build {
204                        build_flags.push(arg.clone());
205                        next_arg_is_build = false;
206                    } else if arg.starts_with("-") {
207                        if let Some(has_arg) = is_build_flag(arg.trim_start_matches("-")) {
208                            next_arg_is_build = has_arg;
209                        }
210                        build_flags.push(arg.clone())
211                    } else {
212                        program = arg.to_string();
213                        seen_pkg = true;
214                    }
215                }
216
217                let config: serde_json::Value = serde_json::to_value(DelveLaunchRequest {
218                    cwd: build_config.cwd.clone(),
219                    env: build_config.env.clone(),
220                    request: "launch".to_string(),
221                    mode: "debug".to_string(),
222                    program,
223                    args,
224                    build_flags,
225                })
226                .unwrap();
227
228                Some(DebugScenario {
229                    label: resolved_label.to_string().into(),
230                    adapter: adapter.0.clone(),
231                    build: None,
232                    config,
233                    tcp_connection: None,
234                })
235            }
236            _ => None,
237        }
238    }
239
240    async fn run(
241        &self,
242        _build_config: SpawnInTerminal,
243        _executor: BackgroundExecutor,
244    ) -> Result<DebugRequest> {
245        unreachable!()
246    }
247}
248
Served at tenant.openagents/omega Member data and write actions are omitted.