// DCR — Cargo-like C/C++ project manager. // // Copyright (C) 2026 Dexoron (Bezotechestvo Vladimir) // // 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 . #[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, tag: Option, rev: Option, }, Registry { version: String, features: Option>, }, } #[allow(dead_code)] #[derive(Debug, Clone)] pub struct DepSpec { pub name: String, pub source: DepSource, pub include_raw: Option>, pub lib_raw: Option>, pub libs_raw: Option>, } #[derive(Debug, Clone, Default)] pub struct ResolvedDeps { pub include_dirs: Vec, pub lib_dirs: Vec, pub libs: Vec, } #[allow(dead_code)] pub fn resolve_path(project_root: &Path, raw: &str) -> Result { 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, 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(()) }