• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

galaxy-sec / orion-variate / 16833159723

08 Aug 2025 02:38PM UTC coverage: 70.216% (+0.03%) from 70.183%
16833159723

push

github

sec-wukong
clippy

9 of 20 new or added lines in 4 files covered. (45.0%)

2 existing lines in 2 files now uncovered.

3027 of 4311 relevant lines covered (70.22%)

4.54 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

20.55
/src/addr/git.rs
1
use crate::vars::EnvEvalable;
2
use crate::{predule::*, vars::EnvDict};
3
use getset::{Getters, Setters, WithSetters};
4
use home::home_dir;
5

6
///
7
/// 支持通过SSH和HTTPS协议访问Git仓库
8
///
9
/// # Token认证示例
10
///
11

12
#[derive(Clone, Debug, Serialize, Deserialize, Default, Getters, Setters, WithSetters)]
13
#[getset(get = "pub", set = "pub")]
14
#[serde(rename = "git")]
15
pub struct GitRepository {
16
    repo: String,
17
    #[serde(skip_serializing_if = "Option::is_none")]
18
    res: Option<String>,
19
    #[serde(skip_serializing_if = "Option::is_none")]
20
    tag: Option<String>,
21
    #[serde(skip_serializing_if = "Option::is_none")]
22
    branch: Option<String>,
23
    #[serde(skip_serializing_if = "Option::is_none")]
24
    rev: Option<String>,
25
    #[serde(skip_serializing_if = "Option::is_none")]
26
    path: Option<String>,
27
    // 新增:SSH私钥路径
28
    #[serde(skip_serializing_if = "Option::is_none")]
29
    ssh_key: Option<String>,
30
    // 新增:SSH密钥密码
31
    #[serde(skip_serializing_if = "Option::is_none")]
32
    ssh_passphrase: Option<String>,
33
    // 新增:Token认证(用于HTTPS协议)
34
    #[serde(skip_serializing_if = "Option::is_none")]
35
    token: Option<String>,
36
    // 新增:用户名(用于Token认证)
37
    #[serde(skip_serializing_if = "Option::is_none")]
38
    username: Option<String>,
39
}
40

41
impl PartialEq for GitRepository {
42
    fn eq(&self, other: &Self) -> bool {
×
43
        self.repo == other.repo
×
44
    }
×
45
}
46
impl EnvEvalable<GitRepository> for GitRepository {
47
    fn env_eval(self, dict: &EnvDict) -> GitRepository {
×
48
        Self {
×
49
            repo: self.repo.env_eval(dict),
×
50
            res: self.res.env_eval(dict),
×
51
            tag: self.tag.env_eval(dict),
×
52
            branch: self.branch.env_eval(dict),
×
53
            rev: self.rev.env_eval(dict),
×
54
            path: self.path.env_eval(dict),
×
55
            ssh_key: self.ssh_key.env_eval(dict),
×
56
            ssh_passphrase: self.ssh_passphrase.env_eval(dict),
×
57
            token: self.token.env_eval(dict),
×
58
            username: self.username.env_eval(dict),
×
59
        }
×
60
    }
×
61
}
62

63
impl GitRepository {
64
    pub fn from<S: Into<String>>(repo: S) -> Self {
15✔
65
        Self {
15✔
66
            repo: repo.into(),
15✔
67
            ..Default::default()
15✔
68
        }
15✔
69
    }
15✔
70
    pub fn with_tag<S: Into<String>>(mut self, tag: S) -> Self {
×
71
        self.tag = Some(tag.into());
×
72
        self
×
73
    }
×
74
    pub fn with_opt_tag(mut self, tag: Option<String>) -> Self {
×
75
        self.tag = tag;
×
76
        self
×
77
    }
×
78
    pub fn with_branch<S: Into<String>>(mut self, branch: S) -> Self {
4✔
79
        self.branch = Some(branch.into());
4✔
80
        self
4✔
81
    }
4✔
82
    pub fn with_opt_branch(mut self, branch: Option<String>) -> Self {
×
83
        self.branch = branch;
×
84
        self
×
85
    }
×
86
    pub fn with_rev<S: Into<String>>(mut self, rev: S) -> Self {
×
87
        self.rev = Some(rev.into());
×
88
        self
×
89
    }
×
90
    pub fn with_path<S: Into<String>>(mut self, path: S) -> Self {
1✔
91
        self.path = Some(path.into());
1✔
92
        self
1✔
93
    }
1✔
94
    // 新增:设置SSH私钥
95
    pub fn with_ssh_key<S: Into<String>>(mut self, ssh_key: S) -> Self {
×
96
        self.ssh_key = Some(ssh_key.into());
×
97
        self
×
98
    }
×
99
    // 新增:设置SSH密钥密码
100
    pub fn with_ssh_passphrase<S: Into<String>>(mut self, ssh_passphrase: S) -> Self {
×
101
        self.ssh_passphrase = Some(ssh_passphrase.into());
×
102
        self
×
103
    }
×
104
    // 新增:设置Token认证
105
    pub fn with_token<S: Into<String>>(mut self, token: S) -> Self {
×
106
        self.token = Some(token.into());
×
107
        self
×
108
    }
×
109
    // 新增:设置用户名(用于Token认证)
110
    pub fn with_username<S: Into<String>>(mut self, username: S) -> Self {
×
111
        self.username = Some(username.into());
×
112
        self
×
113
    }
×
114
    // 新增:设置Token认证(可选)
115
    pub fn with_opt_token(mut self, token: Option<String>) -> Self {
×
116
        self.token = token;
×
117
        self
×
118
    }
×
119
    // 新增:设置用户名(可选)
120
    pub fn with_opt_username(mut self, username: Option<String>) -> Self {
×
121
        self.username = username;
×
122
        self
×
123
    }
×
124

125
    /// 为GitHub设置Token认证(便捷方法)
126
    /// GitHub使用用户名+Token作为密码的方式
127
    pub fn with_github_token<S: Into<String>>(mut self, token: S) -> Self {
×
128
        self.username = Some("git".to_string());
×
129
        self.token = Some(token.into());
×
130
        self
×
131
    }
×
132

133
    /// 为GitLab设置Token认证(便捷方法)
134
    /// GitLab可以使用"oauth2"作为用户名,Token作为密码
135
    pub fn with_gitlab_token<S: Into<String>>(mut self, token: S) -> Self {
×
136
        self.username = Some("oauth2".to_string());
×
137
        self.token = Some(token.into());
×
138
        self
×
139
    }
×
140

141
    /// 为Gitea设置Token认证(便捷方法)
142
    /// Gitea可以使用Token作为密码
143
    pub fn with_gitea_token<S: Into<String>>(mut self, token: S) -> Self {
×
144
        self.username = Some("git".to_string());
×
145
        self.token = Some(token.into());
×
146
        self
×
147
    }
×
148

149
    /// 从环境变量读取Token认证
150
    ///
151
    /// # Arguments
152
    /// * `env_var` - 环境变量名,例如 "GITHUB_TOKEN"
153
    pub fn with_env_token(mut self, env_var: &str) -> Self {
1✔
154
        if let Ok(token) = std::env::var(env_var) {
1✔
155
            self.token = Some(token);
×
156
        }
1✔
157
        self
1✔
158
    }
1✔
159

160
    /// 从环境变量读取GitHub Token认证
161
    pub fn with_github_env_token(self) -> Self {
×
162
        self.with_env_token("GITHUB_TOKEN")
×
163
    }
×
164

165
    /// 从环境变量读取GitLab Token认证
166
    pub fn with_gitlab_env_token(mut self) -> Self {
×
167
        if let Ok(token) = std::env::var("GITLAB_TOKEN") {
×
168
            self.username = Some("oauth2".to_string());
×
169
            self.token = Some(token);
×
170
        }
×
171
        self
×
172
    }
×
173

174
    /// 从环境变量读取Gitea Token认证
175
    pub fn with_gitea_env_token(self) -> Self {
×
176
        self.with_env_token("GITEA_TOKEN")
×
177
    }
×
178

179
    /// 从~/.git-credentials文件读取token
180
    pub fn with_git_credentials(mut self) -> Self {
1✔
181
        if let Some(credentials) = Self::read_git_credentials() {
1✔
182
            for (url, username, token) in credentials {
×
183
                if self.repo.starts_with(&url) {
×
184
                    self.username = Some(username);
×
185
                    self.token = Some(token);
×
186
                    break;
×
187
                }
×
188
            }
189
        }
1✔
190
        self
1✔
191
    }
1✔
192
    /// 读取~/.git-credentials文件
193
    pub fn read_git_credentials() -> Option<Vec<(String, String, String)>> {
2✔
194
        use std::fs;
195
        use std::io::{BufRead, BufReader};
196

197
        let home = home_dir()?;
2✔
198
        let credentials_path = home.join(".git-credentials");
2✔
199

200
        if !credentials_path.exists() {
2✔
201
            return None;
2✔
202
        }
×
203

204
        let file = fs::File::open(credentials_path).ok()?;
×
205
        let reader = BufReader::new(file);
×
206
        let mut credentials = Vec::new();
×
207

208
        for line in reader.lines().map_while(Result::ok) {
×
209
            //if let Ok(line) = line {
210
            let line = line.trim();
×
211
            if line.is_empty() || line.starts_with('#') {
×
212
                continue;
×
213
            }
×
214

215
            // 使用URL解析来正确提取各个部分
216
            if let Ok(url) = url::Url::parse(line) {
×
217
                let host = url.host_str()?;
×
218
                let scheme = url.scheme();
×
219
                let path = url.path();
×
220

221
                // 构建基础URL用于匹配
222
                let base_url = format!("{scheme}://{host}{path}");
×
223

224
                // 提取用户名和密码
225
                let username = url.username();
×
NEW
226
                if !username.is_empty()
×
NEW
227
                    && let Some(password) = url.password()
×
NEW
228
                {
×
NEW
229
                    credentials.push((base_url, username.to_string(), password.to_string()));
×
UNCOV
230
                }
×
231
                //}
232
            }
×
233
        }
234

235
        if credentials.is_empty() {
×
236
            None
×
237
        } else {
238
            Some(credentials)
×
239
        }
240
    }
2✔
241
}
242

243
#[cfg(test)]
244
mod tests {}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc