feat: Initial commit

This commit is contained in:
2025-02-26 10:57:59 +08:00
commit 606ec2106e
11 changed files with 2995 additions and 0 deletions
+2
View File
@@ -0,0 +1,2 @@
/target
.secret.toml
Generated
+2794
View File
File diff suppressed because it is too large Load Diff
+17
View File
@@ -0,0 +1,17 @@
[package]
name = "workshop"
version = "0.1.0"
edition = "2024"
[dependencies]
bollard = "0.18.1"
config = "0.14.1"
lazy_static = "1.5.0"
url = "2.5.4"
gitea-sdk = "0.5.0"
octocrab = "0.43.0"
tokio = { version = "1.43.0", features = ["full"] }
serde_json = "1.0.139"
serde = "1.0.218"
log = "*"
env_logger = "*"
View File
View File
View File
+64
View File
@@ -0,0 +1,64 @@
use gitea_sdk::Client;
use log::warn;
use url::Url;
pub async fn language_analyze(repo: String, gitea_token: String) -> Result<(), String> {
let repo_url = Url::parse(repo.as_str());
if repo_url.is_err() {
warn!("Invalid gitea repository URL");
return Err("Invalid gitea repository URL".to_string());
}
let repo_url = repo_url.unwrap();
let repo_proto = repo_url.scheme();
let repo_host = repo_url.host_str().unwrap();
let mut repo_path = repo_url.path();
if repo_path.ends_with(".git") {
// 处理.git后缀
repo_path = repo_path.strip_suffix(".git").unwrap();
}
let gitea_instance = Client::new(
format!("{}://{}", repo_proto, repo_host),
gitea_sdk::Auth::Token(gitea_token),
);
let repo_lang: serde_json::Value = gitea_instance
.get(format!("repos{}/languages", repo_path))
.send()
.await
.unwrap()
.json()
.await
.unwrap();
// dbg!(&repo_lang);
if repo_lang["message"].is_string() {
warn!(
"Gitea API returned errors: {}",
repo_lang["message"].as_str().unwrap()
);
return Err(format!(
"Gitea API returned errors: {}",
repo_lang["message"].as_str().unwrap()
));
}
Ok(())
}
mod tests {
use super::language_analyze;
#[tokio::test]
async fn test_gitea_language_analyze() {
// let repo = "https://gitea.cattysteve.top/pig2014/GalaxyMusicHall_CTP_Backend";
let repo = "https://gitea.cattysteve.top/pig2014/buildcat_renpy";
language_analyze(repo.to_string(), "".to_string())
.await
.unwrap();
}
#[tokio::test]
#[should_panic(expected = "Gitea API returned errors: The target couldn't be found.")]
async fn test_gitea_language_analyze_nonexistent() {
let repo = "https://gitea.cattysteve.top/pig2014/GalaxyMusicHall_CTP_Backend";
language_analyze(repo.to_string(), "".to_string())
.await
.unwrap();
}
}
+85
View File
@@ -0,0 +1,85 @@
use log::warn;
use octocrab::GitHubError;
use serde::Deserialize;
use std::{error::Error, sync::Arc};
use url::Url;
#[derive(Deserialize, Debug)]
struct RepoLanguage {
#[serde(flatten)]
name: String,
size: u64,
}
pub async fn language_analyze(repo: String, github_token: Option<String>) -> Result<(), String> {
let repo_url = Url::parse(repo.as_str());
if repo_url.is_err() {
warn!("Invalid github repository URL");
return Err("Invalid github repository URL".to_string());
}
let repo_url = repo_url.unwrap();
let repo_host = repo_url.host_str().unwrap();
if repo_host != "github.com" {
warn!("Not a GitHub repository");
return Err(format!("Unsupported host: {}", repo_host));
}
let mut repo_path = repo_url.path();
if repo_path.ends_with(".git") {
// 处理.git后缀
repo_path = repo_path.strip_suffix(".git").unwrap();
};
let github_instance = octocrab::instance();
let github_instance = if github_token.is_some() {
Arc::new(
github_instance
.user_access_token(github_token.unwrap())
.unwrap(),
)
} else {
github_instance
};
let repo_lang = github_instance
.get::<serde_json::Value, String, ()>(format!("/repos{}/languages", repo_path), None::<&()>)
.await;
if repo_lang.is_err() {
match repo_lang.unwrap_err() {
octocrab::Error::GitHub {
source: error,
backtrace: _,
} => {
// dbg!(error.message);
warn!("Failed to fetch language information: {}", error.message);
return Err(format!(
"Failed to fetch language information: {}",
error.message
));
}
_ => {
warn!("Failed to fetch language information");
return Err("Failed to fetch language information".to_string());
}
}
}
let repo_lang = repo_lang.unwrap();
dbg!(repo_lang);
Ok(())
}
mod tests {
use super::language_analyze;
#[tokio::test]
async fn test_github_language_analyze_success() {
let repo = "https://github.com/mono/SkiaSharp";
language_analyze(repo.to_string(), None).await.unwrap();
}
#[tokio::test]
#[should_panic]
async fn test_github_language_analyze_nonexistent() {
let repo = "https://github.com/nonexistant/bass";
language_analyze(repo.to_string(), None).await.unwrap();
}
}
View File
+33
View File
@@ -0,0 +1,33 @@
mod ingredient {
pub mod gitea;
pub mod github;
}
use bollard::{API_DEFAULT_VERSION, Docker};
use config::Config;
use env_logger;
use lazy_static::lazy_static;
lazy_static! {
static ref CONFIG: Config = Config::builder()
.add_source(config::File::with_name("settings.toml"))
.add_source(config::File::with_name(".secret.toml"))
.build()
.unwrap();
}
fn main() {
env_logger::init();
let docker_host = CONFIG.get_string("DOCKER_HOST").unwrap_or(String::new());
let docker_connection_timeout = CONFIG.get_int("DOCKER_CONNECTION_TIMEOUT").unwrap_or(10);
if docker_host.is_empty() {
Docker::connect_with_local_defaults().unwrap();
} else {
Docker::connect_with_http(
&docker_host,
docker_connection_timeout as u64,
API_DEFAULT_VERSION,
)
.unwrap();
}
println!("Good!");
}
View File