feat(api): extend commit and diff services with new functionality
- Add FindCommit, ListCommitsByOid, CommitIsAncestor RPCs to CommitService - Add CheckObjectsExist, CommitsByMessage, GetCommitStats RPCs to CommitService - Add LastCommitForPath, CountCommits, CountDivergingCommits RPCs to CommitService - Add RawDiff, RawPatch, FindChangedPaths RPCs to DiffService - Add FindMergeBase, WriteRef, SearchFilesByContent RPCs to RepositoryService - Add SearchFilesByName, ObjectsSize, RepositorySize RPCs to RepositoryService - Add FindLicense, OptimizeRepository, GetRawChanges RPCs to RepositoryService - Add FetchRemote, CreateRepositoryFromURL RPCs to RepositoryService - Implement server handlers for all new RPC methods - Add new modules for commit counting, finding, and querying features - Add new modules for diff changed paths and raw operations - Add new modules for refs and remote operations - Remove unnecessary comments from various source files - Update proto definitions with new message types and service methods
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
use crate::bare::GitBare;
|
||||
use crate::error::GitResult;
|
||||
use crate::pb::*;
|
||||
|
||||
impl GitBare {
|
||||
/// Detect license by reading LICENSE/COPYING files and doing basic matching.
|
||||
pub fn find_license(&self) -> GitResult<FindLicenseResponse> {
|
||||
let possible_paths = [
|
||||
"LICENSE", "LICENSE.md", "LICENSE.txt",
|
||||
"LICENCE", "LICENCE.md", "LICENCE.txt",
|
||||
"COPYING", "COPYING.md", "COPYING.txt",
|
||||
"UNLICENSE",
|
||||
];
|
||||
|
||||
for path in &possible_paths {
|
||||
let output = std::process::Command::new("git")
|
||||
.args([
|
||||
"--git-dir",
|
||||
&self.bare_dir.to_string_lossy(),
|
||||
"show",
|
||||
&format!("HEAD:{path}"),
|
||||
])
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.stderr(std::process::Stdio::null())
|
||||
.output()
|
||||
.map_err(|e| crate::error::GitError::CommandFailed {
|
||||
status_code: None,
|
||||
stderr: e.to_string(),
|
||||
})?;
|
||||
|
||||
if output.status.success() {
|
||||
let content = String::from_utf8_lossy(&output.stdout);
|
||||
let (spdx, name, conf) = detect_license(&content);
|
||||
if conf > 0.0 {
|
||||
return Ok(FindLicenseResponse {
|
||||
license_spdx: spdx.to_string(),
|
||||
license_name: name.to_string(),
|
||||
confidence: conf,
|
||||
license_path: path.to_string(),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(FindLicenseResponse::default())
|
||||
}
|
||||
}
|
||||
|
||||
/// Very basic license detection by keyword matching.
|
||||
/// Returns (SPDX identifier, human-readable name, confidence).
|
||||
fn detect_license(content: &str) -> (&'static str, &'static str, f64) {
|
||||
let lower = content.to_lowercase();
|
||||
|
||||
// MIT
|
||||
if lower.contains("permission is hereby granted, free of charge") && lower.contains("mit") {
|
||||
return ("MIT", "MIT License", 0.95);
|
||||
}
|
||||
|
||||
// Apache 2.0
|
||||
if lower.contains("apache license, version 2.0") || lower.contains("apache-2.0") {
|
||||
return ("Apache-2.0", "Apache License 2.0", 0.95);
|
||||
}
|
||||
|
||||
// GPL 3.0
|
||||
if lower.contains("gnu general public license") && lower.contains("version 3") {
|
||||
return ("GPL-3.0", "GNU General Public License v3.0", 0.90);
|
||||
}
|
||||
// GPL 2.0
|
||||
if lower.contains("gnu general public license") && lower.contains("version 2") {
|
||||
return ("GPL-2.0", "GNU General Public License v2.0", 0.90);
|
||||
}
|
||||
|
||||
// BSD 3
|
||||
if lower.contains("redistribution and use in source and binary forms")
|
||||
&& lower.contains("neither the name of")
|
||||
{
|
||||
return ("BSD-3-Clause", "BSD 3-Clause License", 0.85);
|
||||
}
|
||||
// BSD 2
|
||||
if lower.contains("redistribution and use in source and binary forms") {
|
||||
return ("BSD-2-Clause", "BSD 2-Clause License", 0.80);
|
||||
}
|
||||
|
||||
// AGPL
|
||||
if lower.contains("gnu affero general public license") {
|
||||
return ("AGPL-3.0", "GNU Affero General Public License v3.0", 0.90);
|
||||
}
|
||||
|
||||
// LGPL
|
||||
if lower.contains("gnu lesser general public license") {
|
||||
return ("LGPL-3.0", "GNU Lesser General Public License v3.0", 0.85);
|
||||
}
|
||||
|
||||
// MPL
|
||||
if lower.contains("mozilla public license") {
|
||||
return ("MPL-2.0", "Mozilla Public License 2.0", 0.90);
|
||||
}
|
||||
|
||||
// Unlicense
|
||||
if lower.contains("this is free and unencumbered software released into the public domain") {
|
||||
return ("Unlicense", "The Unlicense", 0.95);
|
||||
}
|
||||
|
||||
// ISC
|
||||
if lower.contains("permission to use, copy, modify, and/or distribute")
|
||||
&& lower.contains("isc")
|
||||
{
|
||||
return ("ISC", "ISC License", 0.80);
|
||||
}
|
||||
|
||||
("", "", 0.0)
|
||||
}
|
||||
Reference in New Issue
Block a user