Skip to content

Commit 25b89f7

Browse files
Merge pull request #48 from reddevilmidzy/location
유효하지 않은 파일 위치 정보도 같이 로그에 포함
2 parents 3964395 + ec63923 commit 25b89f7

File tree

2 files changed

+52
-12
lines changed

2 files changed

+52
-12
lines changed

src/git/mod.rs

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,58 @@
11
use git2::Repository;
22
use regex::Regex;
3+
use serde::{Deserialize, Serialize};
34
use std::env;
45
use std::fs;
56

6-
pub fn extract_links_from_repo_url(repo_url: &str) -> Result<Vec<String>, git2::Error> {
7+
#[derive(Debug, Clone, Serialize, Deserialize)]
8+
/// Represents a hyperlink found in a repository, along with its location.
9+
pub struct LinkInfo {
10+
/// The URL string. This should be a valid HTTP or HTTPS URL.
11+
pub url: String,
12+
/// The relative file path where the URL was found.
13+
pub file_path: String,
14+
/// The 1-based line number in the file where the URL was found.
15+
pub line_number: usize,
16+
}
17+
18+
pub fn extract_links_from_repo_url(repo_url: &str) -> Result<Vec<LinkInfo>, git2::Error> {
719
let temp_dir = env::temp_dir().join("queensac_temp_repo");
820
let _temp_dir_guard = TempDirGuard::new(temp_dir.clone()).map_err(|e| {
921
git2::Error::from_str(&format!("Failed to create temporary directory: {}", e))
1022
})?;
1123
let repo = Repository::clone(repo_url, &temp_dir)?;
1224

13-
let mut all_links = Vec::new();
25+
let mut all_links = Vec::new(); // TODO: HashSet 사용해서 중복 제거 최적화.
1426
let url_regex = Regex::new(r"https?://(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&/=]*)").unwrap();
1527

1628
if let Ok(head) = repo.head() {
1729
if let Ok(tree) = head.peel_to_tree() {
18-
tree.walk(git2::TreeWalkMode::PreOrder, |_, entry| {
19-
if entry.name().is_some() {
30+
tree.walk(git2::TreeWalkMode::PreOrder, |dir, entry| {
31+
if let Some(name) = entry.name() {
32+
let file_path = if dir.is_empty() {
33+
name.to_string()
34+
} else {
35+
format!("{}/{}", dir, name)
36+
};
37+
2038
if let Ok(blob) = entry.to_object(&repo) {
2139
if let Ok(blob) = blob.peel_to_blob() {
2240
if let Ok(content) = String::from_utf8(blob.content().to_vec()) {
23-
all_links.extend(url_regex.find_iter(&content).map(|mat| {
24-
let url = mat.as_str();
25-
url.trim_end_matches(&[')', '>', '.', ',', ';'][..])
26-
.to_string()
27-
}));
41+
// 각 라인별로 링크를 찾기
42+
for (line_num, line) in content.lines().enumerate() {
43+
for mat in url_regex.find_iter(line) {
44+
let url = mat
45+
.as_str()
46+
.trim_end_matches(&[')', '>', '.', ',', ';'][..])
47+
.to_string();
48+
49+
all_links.push(LinkInfo {
50+
url,
51+
file_path: file_path.clone(),
52+
line_number: line_num + 1, // 1-based line number
53+
});
54+
}
55+
}
2856
}
2957
}
3058
}
@@ -71,7 +99,13 @@ mod tests {
7199

72100
let url_regex = Regex::new(r"https?://(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&/=]*)").unwrap();
73101
for link in &links {
74-
assert!(url_regex.is_match(link), "Invalid URL found: {}", link);
102+
assert!(
103+
url_regex.is_match(&link.url),
104+
"Invalid URL found: {} at {}:{}",
105+
link.url,
106+
link.file_path,
107+
link.line_number
108+
);
75109
}
76110

77111
Ok(())

src/schedule/mod.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,20 @@ pub async fn check_repository_links(repo_url: &str, interval_duration: Duration)
3434
let mut handles = Vec::new();
3535
for link in links {
3636
let handle = tokio::spawn(async move {
37-
let result = check_link(&link).await;
37+
let result = check_link(&link.url).await;
3838
(link, result)
3939
});
4040
handles.push(handle);
4141
}
4242
for handle in handles {
4343
if let Ok((link, LinkCheckResult::Invalid(message))) = handle.await {
44-
warn!("Invalid link found: '{}', reason: {}", link, message);
44+
warn!(
45+
"Invalid link found: '{}' at {}:{}, reason: {}",
46+
link.url,
47+
link.file_path,
48+
link.line_number,
49+
message
50+
);
4551
}
4652
}
4753
}

0 commit comments

Comments
 (0)