mirror of
https://github.com/dexoron/dcr.git
synced 2026-10-22 11:59:37 +00:00
feat: add native Qt support and dcr lint command; refactor architecture and integration tests
This commit is contained in:
@@ -1,128 +1,6 @@
|
||||
// DCR — Cargo-like C/C++ project manager.
|
||||
//
|
||||
// Copyright (C) 2026 Dexoron (Bezotechestvo Vladimir) <main@dexoron.su>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#[allow(dead_code)]
|
||||
use std::fs;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[allow(dead_code)]
|
||||
pub enum DepSource {
|
||||
Path(String),
|
||||
Git {
|
||||
url: String,
|
||||
branch: Option<String>,
|
||||
tag: Option<String>,
|
||||
rev: Option<String>,
|
||||
},
|
||||
Registry {
|
||||
version: String,
|
||||
features: Option<Vec<String>>,
|
||||
},
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct DepSpec {
|
||||
pub name: String,
|
||||
pub source: DepSource,
|
||||
pub include_raw: Option<Vec<String>>,
|
||||
pub lib_raw: Option<Vec<String>>,
|
||||
pub libs_raw: Option<Vec<String>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct ResolvedDeps {
|
||||
pub include_dirs: Vec<String>,
|
||||
pub lib_dirs: Vec<String>,
|
||||
pub libs: Vec<String>,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn resolve_path(project_root: &Path, raw: &str) -> Result<PathBuf, String> {
|
||||
let p = Path::new(raw);
|
||||
let full = if p.is_absolute() {
|
||||
p.to_path_buf()
|
||||
} else {
|
||||
project_root.join(p)
|
||||
};
|
||||
Ok(full)
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn resolve_paths(
|
||||
base: &Path,
|
||||
raw: Option<&[String]>,
|
||||
defaults: &[&str],
|
||||
profile: &str,
|
||||
) -> Result<Vec<PathBuf>, String> {
|
||||
let mut out = Vec::new();
|
||||
if let Some(raw) = raw {
|
||||
for r in raw {
|
||||
let expanded = expand_profile(r, profile);
|
||||
let p = Path::new(&expanded);
|
||||
let full = if p.is_absolute() {
|
||||
p.to_path_buf()
|
||||
} else {
|
||||
base.join(p)
|
||||
};
|
||||
if !full.exists() {
|
||||
return Err(format!("Path does not exist: {}", full.display()));
|
||||
}
|
||||
out.push(full);
|
||||
}
|
||||
return Ok(out);
|
||||
}
|
||||
|
||||
for d in defaults {
|
||||
let candidate = base.join(d);
|
||||
if candidate.exists() {
|
||||
out.push(candidate);
|
||||
}
|
||||
}
|
||||
Ok(out)
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn expand_profile(raw: &str, profile: &str) -> String {
|
||||
raw.replace("{profile}", profile)
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn sync_dep_dir(src: &Path, dst: &Path) -> std::io::Result<()> {
|
||||
if dst.exists() {
|
||||
fs::remove_dir_all(dst)?;
|
||||
}
|
||||
copy_dir_all(src, dst)
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn copy_dir_all(src: &Path, dst: &Path) -> std::io::Result<()> {
|
||||
fs::create_dir_all(dst)?;
|
||||
for entry in fs::read_dir(src)? {
|
||||
let entry = entry?;
|
||||
let ty = entry.file_type()?;
|
||||
let from = entry.path();
|
||||
let to = dst.join(entry.file_name());
|
||||
if ty.is_dir() {
|
||||
copy_dir_all(&from, &to)?;
|
||||
} else {
|
||||
fs::copy(&from, &to)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
// DCR — Cargo-like C/C++ project manager.
|
||||
//
|
||||
// Copyright (C) 2026 Dexoron (Bezotechestvo Vladimir) <main@dexoron.su>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use std::path::Path;
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn fetch_git_dep(
|
||||
url: &str,
|
||||
target_dir: &Path,
|
||||
branch: Option<&str>,
|
||||
tag: Option<&str>,
|
||||
rev: Option<&str>,
|
||||
) -> Result<(), String> {
|
||||
if target_dir.exists() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
crate::utils::git::git_clone_and_checkout(url, target_dir, branch, tag, rev)
|
||||
}
|
||||
@@ -15,10 +15,8 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use sha2::{Digest, Sha256};
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
use toml::Value;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct DepLock {
|
||||
@@ -73,65 +71,3 @@ fn quote_list(items: &[String]) -> String {
|
||||
fn escape_value(input: &str) -> String {
|
||||
input.replace('\\', "\\\\").replace('"', "\\\"")
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn read_dep_version(dep_path: &Path) -> Option<String> {
|
||||
let path = dep_path.join("dcr.toml");
|
||||
let content = fs::read_to_string(path).ok()?;
|
||||
let value: Value = content.parse().ok()?;
|
||||
value
|
||||
.get("package")
|
||||
.and_then(|v| v.as_table())
|
||||
.and_then(|t| t.get("version"))
|
||||
.and_then(|v| v.as_str())
|
||||
.map(|s| s.to_string())
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn compute_checksum(root: &Path) -> Result<String, String> {
|
||||
let mut files = Vec::new();
|
||||
collect_files(root, root, &mut files)?;
|
||||
files.sort();
|
||||
let mut hasher = Sha256::new();
|
||||
for rel in files {
|
||||
hasher.update(rel.as_bytes());
|
||||
let data =
|
||||
fs::read(root.join(&rel)).map_err(|err| format!("failed to read {}: {err}", rel))?;
|
||||
hasher.update(&data);
|
||||
}
|
||||
let hash = hasher.finalize();
|
||||
Ok(to_hex(&hash))
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn collect_files(root: &Path, dir: &Path, out: &mut Vec<String>) -> Result<(), String> {
|
||||
for entry in fs::read_dir(dir).map_err(|err| format!("read_dir failed: {err}"))? {
|
||||
let entry = entry.map_err(|err| format!("read_dir failed: {err}"))?;
|
||||
let path = entry.path();
|
||||
let name = entry.file_name();
|
||||
let name_str = name.to_string_lossy();
|
||||
if name_str == "target" {
|
||||
continue;
|
||||
}
|
||||
if path.is_dir() {
|
||||
collect_files(root, &path, out)?;
|
||||
} else if path.is_file() {
|
||||
let rel = path
|
||||
.strip_prefix(root)
|
||||
.unwrap_or(&path)
|
||||
.to_string_lossy()
|
||||
.to_string();
|
||||
out.push(rel);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn to_hex(bytes: &[u8]) -> String {
|
||||
let mut out = String::with_capacity(bytes.len() * 2);
|
||||
for b in bytes {
|
||||
out.push_str(&format!("{:02x}", b));
|
||||
}
|
||||
out
|
||||
}
|
||||
|
||||
@@ -16,11 +16,10 @@
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
pub mod common;
|
||||
pub mod git;
|
||||
pub mod lock;
|
||||
pub mod register;
|
||||
|
||||
use crate::core::config::Config;
|
||||
use crate::core::build_config::Config;
|
||||
use crate::core::deps::common::ResolvedDeps;
|
||||
use crate::core::deps::lock::{DepLock, write_lock};
|
||||
use std::path::Path;
|
||||
|
||||
@@ -33,13 +33,7 @@ pub struct DcrConfig {
|
||||
}
|
||||
|
||||
fn home_dir() -> Option<PathBuf> {
|
||||
if let Ok(home) = std::env::var("HOME") {
|
||||
return Some(PathBuf::from(home));
|
||||
}
|
||||
if let Ok(profile) = std::env::var("USERPROFILE") {
|
||||
return Some(PathBuf::from(profile));
|
||||
}
|
||||
None
|
||||
crate::utils::fs::home_dir()
|
||||
}
|
||||
|
||||
fn dcr_config_dir() -> Option<PathBuf> {
|
||||
|
||||
Reference in New Issue
Block a user