13 Commits

Author SHA1 Message Date
peoplemiau1
800fe38fba Fix GHA release: resolve stable toolchain override and sanitize Arch Linux package version 2026-05-28 23:20:48 +03:00
peoplemiau1
a7f9b79b93 Fix release CI/CD: make git2 target-specific, install zig for cross-compilation, set version to 0.7.0 2026-05-28 23:15:09 +03:00
peoplemiau1
b03660a9d7 Bump version to 0.7.0-dev and update changelog for pre-release 2026-05-28 23:01:15 +03:00
peoplemiau1
2cb02aa102 Add full FreeBSD, OpenBSD, NetBSD, and DragonflyBSD target support 2026-05-28 22:55:53 +03:00
peoplemiau1
06a8458ca7 feat: add fmt command 2026-05-28 22:55:26 +03:00
c2ef5483a0 update: update dexoron packages 2026-05-28 21:11:49 +08:00
eb24d616c5 fix: Fix GPG permissions after Docker 2026-05-28 18:16:18 +08:00
4f76f54b63 fix: update GPG signing process to resolve permission issues and clarify Release generation 2026-05-28 18:11:34 +08:00
37b9b855ec feat: streamline artifact download process and enhance repository indexing with signing 2026-05-28 18:08:06 +08:00
8f0f67ad62 fix: correct paths for RPM package artifacts and update repository indexing 2026-05-28 17:49:29 +08:00
49945aa65d feat: add --clobber flag to Download Packages from Release Assets 2026-05-28 17:44:51 +08:00
83593aa592 feat: enhance Dexoron Packages Index workflow with manual dispatch and improved artifact handling 2026-05-28 17:41:50 +08:00
2835188da9 feat: update Dexoron Packages Index workflow and improve release process for NetBSD 2026-05-28 17:09:36 +08:00
15 changed files with 391 additions and 108 deletions

View File

@@ -2,6 +2,11 @@ name: Dexoron Packages Index
on: on:
workflow_dispatch: workflow_dispatch:
inputs:
tag:
description: "Версия (тег) для ручного импорта пакетов (например, v0.6.9)"
required: true
type: string
workflow_run: workflow_run:
workflows: ["Release"] workflows: ["Release"]
types: types:
@@ -13,7 +18,7 @@ permissions:
jobs: jobs:
update-packages-index: update-packages-index:
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: ${{ github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success' }} if: ${{ github.event_name == 'workflow_dispatch' || github.event_workflow_run.conclusion == 'success' }}
steps: steps:
- name: Checkout Central Packages Repo - name: Checkout Central Packages Repo
@@ -23,105 +28,82 @@ jobs:
token: ${{ secrets.PACKAGES_REPO_TOKEN }} token: ${{ secrets.PACKAGES_REPO_TOKEN }}
path: 'central-packages' path: 'central-packages'
# --- СКАЧИВАНИЕ АРТЕФАКТОВ ИЗ РЕЛИЗА --- - name: Import GPG Key
uses: crazy-max/ghaction-import-gpg@v6
with:
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
- name: Download Arch package artifact # --- Загрузка артефактов (сохранена прежняя логика) ---
- name: Download Artifacts
if: ${{ github.event_name == 'workflow_run' }} if: ${{ github.event_name == 'workflow_run' }}
uses: actions/download-artifact@v4 uses: actions/download-artifact@v4
with: with:
name: arch-package path: central-packages/
path: central-packages/archlinux/x86_64/ github-token: ${{ secrets.GITHUB_TOKEN }}
github-token: ${{ secrets.PACKAGES_REPO_TOKEN }}
run-id: ${{ github.event.workflow_run.id }} run-id: ${{ github.event.workflow_run.id }}
continue-on-error: true
- name: Download Debian package artifact - name: Download Packages from Release Assets
if: ${{ github.event_name == 'workflow_run' }} if: ${{ github.event_name == 'workflow_dispatch' }}
uses: actions/download-artifact@v4 env:
with: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
name: debian-package TAG: ${{ inputs.tag }}
path: central-packages/debian/ run: |
github-token: ${{ secrets.PACKAGES_REPO_TOKEN }} gh release download "$TAG" --repo dexoron/dcr --pattern "*.pkg.tar.zst" --dir central-packages/archlinux/x86_64/ --clobber
run-id: ${{ github.event.workflow_run.id }} gh release download "$TAG" --repo dexoron/dcr --pattern "*.deb" --dir central-packages/debian/ --clobber
continue-on-error: true gh release download "$TAG" --repo dexoron/dcr --pattern "*.rpm" --dir central-packages/fedora/x86_64/ --clobber
- name: Download RPM package artifact # --- ИНДЕКСАЦИЯ И ПОДПИСЬ ---
if: ${{ github.event_name == 'workflow_run' }}
uses: actions/download-artifact@v4
with:
name: rpm-package
path: central-packages/rpm/x86_64/
github-token: ${{ secrets.PACKAGES_REPO_TOKEN }}
run-id: ${{ github.event.workflow_run.id }}
continue-on-error: true
# --- ИНДЕКСАЦИЯ REPO --- - name: Update Pacman Database
- name: Update Pacman Database (Inside Arch Container)
run: | run: |
docker run --rm \ docker run --rm \
-v ${{ github.workspace }}/central-packages:/packages \ -v ${{ github.workspace }}/central-packages:/packages \
-v ~/.gnupg:/root/.gnupg \
archlinux:latest \ archlinux:latest \
bash -c ' bash -c '
cd /packages/archlinux/x86_64 && \ cd /packages/archlinux/x86_64 && \
rm -f dexoron.db dexoron.files && \ packages=(*.pkg.tar.zst) && \
shopt -s nullglob repo-add --sign dexoron.db.tar.gz "${packages[@]}" && \
packages=(*.pkg.tar.zst) ln -sf dexoron.db.tar.gz dexoron.db && \
if [ ${#packages[@]} -gt 0 ]; then ln -sf dexoron.files.tar.gz dexoron.files
echo "Found ${#packages[@]} Arch packages. Updating database..."
repo-add dexoron.db.tar.gz "${packages[@]}" && \
ln -sf dexoron.db.tar.gz dexoron.db && \
ln -sf dexoron.files.tar.gz dexoron.files
else
echo "No .pkg.tar.zst files found. Skipping."
fi
' '
- name: Fix GPG permissions after Docker
run: sudo chown -R runner:runner ~/.gnupg
- name: Update Debian APT Repository Index - name: Update Debian APT Repository Index
run: | run: |
sudo apt-get update && sudo apt-get install -y dpkg-dev sudo apt-get update && sudo apt-get install -y dpkg-dev
cd central-packages/debian cd central-packages/debian
dpkg-scanpackages . /dev/null | gzip -9c > Packages.gz
shopt -s nullglob echo "Origin: Dexoron Packages" > Release
deb_packages=(*.deb) echo "Label: Dexoron Packages" >> Release
echo "Suite: stable" >> Release
echo "Codename: stable" >> Release
echo "Architectures: amd64" >> Release
echo "Components: main" >> Release
echo "Description: Dexoron binary package repository" >> Release
echo "Date: $(date -uR)" >> Release
echo "SHA256:" >> Release
echo " $(sha256sum Packages.gz | awk '{print $1" "$2}')" >> Release
if [ ${#deb_packages[@]} -gt 0 ]; then gpg --batch --yes --pinentry-mode loopback --local-user 74322D39483E9C9E8C86C0AA0770A5C2A2A82DAC --detach-sign --armor --output Release.gpg Release
echo "Found ${#deb_packages[@]} Debian packages. Generating Packages.gz..." gpg --batch --yes --pinentry-mode loopback --local-user 74322D39483E9C9E8C86C0AA0770A5C2A2A82DAC --clearsign --output InRelease Release
# Генерируем индекс для плоского (flat) репозитория
dpkg-scanpackages . /dev/null | gzip -9c > Packages.gz
else
echo "No .deb files found. Skipping Debian index update."
fi
- name: Update Fedora DNF Repository Index - name: Update Fedora DNF Repository Index
run: | run: |
sudo apt-get update && sudo apt-get install -y createrepo-c sudo apt-get update && sudo apt-get install -y createrepo-c
cd central-packages/rpm/x86_64 cd central-packages/fedora/x86_64
createrepo_c .
shopt -s nullglob gpg --batch --yes --detach-sign --armor --output repodata/repomd.xml.asc repodata/repomd.xml
rpm_packages=(*.rpm)
if [ ${#rpm_packages[@]} -gt 0 ]; then
echo "Found ${#rpm_packages[@]} RPM packages. Generating repodata..."
# Пересоздаем метаданные для dnf
createrepo_c .
else
echo "No .rpm files found. Skipping Fedora index update."
fi
# --- ПУШ ИЗМЕНЕНИЙ ---
- name: Push to dexoron/packages - name: Push to dexoron/packages
run: | run: |
cd central-packages cd central-packages
git config user.name "github-actions[bot]" git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com" git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add .
# Проверяем изменения во всех трех целевых папках if ! git diff --cached --quiet; then
if [ -n "$(git status --porcelain)" ]; then git commit -m "chore: update and sign repositories"
git add archlinux/ debian/ rpm/
git commit -m "chore: update repositories index (arch, debian, rpm)"
git push git push
else
echo "No changes detected in repository databases."
fi fi

View File

@@ -129,6 +129,12 @@ jobs:
pip install cargo-zigbuild pip install cargo-zigbuild
echo "$HOME/.local/bin" >> $GITHUB_PATH echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: Setup Zig
if: matrix.target != 'x86_64-unknown-linux-gnu'
uses: mlugg/setup-zig@v1
with:
version: 0.13.0
- name: Setup Rust - name: Setup Rust
uses: dtolnay/rust-toolchain@stable uses: dtolnay/rust-toolchain@stable
with: with:
@@ -222,14 +228,15 @@ jobs:
- name: Build Arch Package inside Container - name: Build Arch Package inside Container
if: matrix.package_type == 'arch' if: matrix.package_type == 'arch'
run: | run: |
PKGVER='${{ needs.setup.outputs.version }}' PKGVER_ORIG='${{ needs.setup.outputs.version }}'
PKGVER_CLEAN="${PKGVER_ORIG//-/.}"
TAG='${{ needs.setup.outputs.tag }}' TAG='${{ needs.setup.outputs.tag }}'
SRC_URL="https://github.com/dexoron/dcr/archive/refs/tags/${TAG}.tar.gz" SRC_URL="https://github.com/dexoron/dcr/archive/refs/tags/${TAG}.tar.gz"
SHA256="$(curl -fsSL "$SRC_URL" | sha256sum | awk '{print $1}')" SHA256="$(curl -fsSL "$SRC_URL" | sha256sum | awk '{print $1}')"
mkdir -p arch-build mkdir -p arch-build
cat > arch-build/PKGBUILD <<PKG cat > arch-build/PKGBUILD <<PKG
pkgname=dcr pkgname=dcr
pkgver=${PKGVER} pkgver=${PKGVER_CLEAN}
pkgrel=1 pkgrel=1
pkgdesc="Cargo-like utility to manage C/C++ projects" pkgdesc="Cargo-like utility to manage C/C++ projects"
arch=('x86_64') arch=('x86_64')
@@ -238,14 +245,14 @@ jobs:
depends=('gcc-libs') depends=('gcc-libs')
makedepends=('cargo') makedepends=('cargo')
options=('!lto') options=('!lto')
source=("\$pkgname-\$pkgver.tar.gz::\$url/archive/refs/tags/v\$pkgver.tar.gz") source=("\$pkgname-\$pkgver.tar.gz::\$url/archive/refs/tags/${TAG}.tar.gz")
sha256sums=('${SHA256}') sha256sums=('${SHA256}')
build() { build() {
cd "\$srcdir/\$pkgname-\$pkgver" cd "\$srcdir/\$pkgname-${PKGVER_ORIG}"
cargo build --release --locked cargo build --release --locked
} }
package() { package() {
cd "\$srcdir/\$pkgname-\$pkgver" cd "\$srcdir/\$pkgname-${PKGVER_ORIG}"
install -Dm755 "target/release/dcr" "\$pkgdir/usr/bin/dcr" install -Dm755 "target/release/dcr" "\$pkgdir/usr/bin/dcr"
install -Dm644 LICENSE "\$pkgdir/usr/share/licenses/\$pkgname/LICENSE" install -Dm644 LICENSE "\$pkgdir/usr/share/licenses/\$pkgname/LICENSE"
} }
@@ -408,9 +415,10 @@ jobs:
with: with:
usesh: true usesh: true
run: | run: |
export PATH="/usr/pkg/bin:/usr/pkg/sbin:$PATH"
pkg_add rust perl gmake pkg_add rust perl gmake
export MAKE=gmake mkdir -p /tmp/bin
ln -sf /usr/pkg/bin/gmake /tmp/bin/make
export PATH="/tmp/bin:/usr/pkg/bin:/usr/pkg/sbin:$PATH"
cargo build --release cargo build --release
- name: Prepare NetBSD Artifact - name: Prepare NetBSD Artifact
@@ -499,14 +507,15 @@ jobs:
shell: bash shell: bash
run: | run: |
set -euo pipefail set -euo pipefail
PKGVER='${{ needs.setup.outputs.version }}' PKGVER_ORIG='${{ needs.setup.outputs.version }}'
PKGVER_CLEAN="${PKGVER_ORIG//-/.}"
SRC_URL='${{ steps.meta.outputs.source_url }}' SRC_URL='${{ steps.meta.outputs.source_url }}'
SHA256='${{ steps.meta.outputs.sha256 }}' SHA256='${{ steps.meta.outputs.sha256 }}'
mkdir -p packages/aur/dcr mkdir -p packages/aur/dcr
cat > packages/aur/dcr/PKGBUILD <<PKG cat > packages/aur/dcr/PKGBUILD <<PKG
pkgname=dcr pkgname=dcr
pkgver=${PKGVER} pkgver=${PKGVER_CLEAN}
pkgrel=1 pkgrel=1
pkgdesc="Cargo-like utility to manage C/C++ projects" pkgdesc="Cargo-like utility to manage C/C++ projects"
arch=('x86_64' 'aarch64') arch=('x86_64' 'aarch64')
@@ -519,11 +528,11 @@ jobs:
'gcc: build C/C++ projects with GCC' 'gcc: build C/C++ projects with GCC'
'clang: build C/C++ projects with Clang' 'clang: build C/C++ projects with Clang'
) )
source=("\$pkgname-\$pkgver.tar.gz::\$url/archive/refs/tags/v\$pkgver.tar.gz") source=("\$pkgname-\$pkgver.tar.gz::\${SRC_URL}")
sha256sums=('${SHA256}') sha256sums=('${SHA256}')
build() { build() {
cd "\$srcdir/\$pkgname-\$pkgver" cd "\$srcdir/\$pkgname-${PKGVER_ORIG}"
export CARGO_PROFILE_RELEASE_LTO=false export CARGO_PROFILE_RELEASE_LTO=false
export RUSTFLAGS="\${RUSTFLAGS:-}" export RUSTFLAGS="\${RUSTFLAGS:-}"
export RUSTFLAGS="\${RUSTFLAGS/-C link-arg=-fuse-ld=lld/}" export RUSTFLAGS="\${RUSTFLAGS/-C link-arg=-fuse-ld=lld/}"
@@ -531,7 +540,7 @@ jobs:
} }
package() { package() {
cd "\$srcdir/\$pkgname-\$pkgver" cd "\$srcdir/\$pkgname-${PKGVER_ORIG}"
install -Dm755 "target/release/dcr" "\$pkgdir/usr/bin/dcr" install -Dm755 "target/release/dcr" "\$pkgdir/usr/bin/dcr"
install -Dm644 LICENSE "\$pkgdir/usr/share/licenses/\$pkgname/LICENSE" install -Dm644 LICENSE "\$pkgdir/usr/share/licenses/\$pkgname/LICENSE"
} }
@@ -540,7 +549,7 @@ jobs:
cat > packages/aur/dcr/.SRCINFO <<SRC cat > packages/aur/dcr/.SRCINFO <<SRC
pkgbase = dcr pkgbase = dcr
pkgdesc = Cargo-like utility to manage C/C++ projects pkgdesc = Cargo-like utility to manage C/C++ projects
pkgver = ${PKGVER} pkgver = ${PKGVER_CLEAN}
pkgrel = 1 pkgrel = 1
url = https://github.com/dexoron/dcr url = https://github.com/dexoron/dcr
arch = x86_64 arch = x86_64
@@ -551,7 +560,7 @@ jobs:
optdepends = gcc: build C/C++ projects with GCC optdepends = gcc: build C/C++ projects with GCC
optdepends = clang: build C/C++ projects with Clang optdepends = clang: build C/C++ projects with Clang
options = !lto options = !lto
source = dcr-${PKGVER}.tar.gz::${SRC_URL} source = dcr-${PKGVER_CLEAN}.tar.gz::${SRC_URL}
sha256sums = ${SHA256} sha256sums = ${SHA256}
pkgname = dcr pkgname = dcr
@@ -611,14 +620,15 @@ jobs:
shell: bash shell: bash
run: | run: |
set -euo pipefail set -euo pipefail
PKGVER='${{ needs.setup.outputs.version }}' PKGVER_ORIG='${{ needs.setup.outputs.version }}'
PKGVER_CLEAN="${PKGVER_ORIG//-/.}"
BIN_URL='${{ steps.meta.outputs.bin_url }}' BIN_URL='${{ steps.meta.outputs.bin_url }}'
SHA256='${{ steps.meta.outputs.sha256 }}' SHA256='${{ steps.meta.outputs.sha256 }}'
mkdir -p packages/aur/dcr-bin mkdir -p packages/aur/dcr-bin
cat > packages/aur/dcr-bin/PKGBUILD <<PKG cat > packages/aur/dcr-bin/PKGBUILD <<PKG
pkgname=dcr-bin pkgname=dcr-bin
pkgver=${PKGVER} pkgver=${PKGVER_CLEAN}
pkgrel=1 pkgrel=1
pkgdesc="Cargo-like utility to manage C/C++ projects (pre-compiled musl binary)" pkgdesc="Cargo-like utility to manage C/C++ projects (pre-compiled musl binary)"
arch=('x86_64') arch=('x86_64')
@@ -641,7 +651,7 @@ jobs:
cat > packages/aur/dcr-bin/.SRCINFO <<SRC cat > packages/aur/dcr-bin/.SRCINFO <<SRC
pkgbase = dcr-bin pkgbase = dcr-bin
pkgdesc = Cargo-like utility to manage C/C++ projects (pre-compiled musl binary) pkgdesc = Cargo-like utility to manage C/C++ projects (pre-compiled musl binary)
pkgver = ${PKGVER} pkgver = ${PKGVER_CLEAN}
pkgrel = 1 pkgrel = 1
url = https://github.com/dexoron/dcr url = https://github.com/dexoron/dcr
arch = x86_64 arch = x86_64
@@ -650,7 +660,7 @@ jobs:
conflicts = dcr conflicts = dcr
optdepends = gcc: build C/C++ projects with GCC optdepends = gcc: build C/C++ projects with GCC
optdepends = clang: build C/C++ projects with Clang optdepends = clang: build C/C++ projects with Clang
source_x86_64 = dcr-${PKGVER}::${BIN_URL} source_x86_64 = dcr-${PKGVER_CLEAN}::${BIN_URL}
sha256sums_x86_64 = ${SHA256} sha256sums_x86_64 = ${SHA256}
pkgname = dcr-bin pkgname = dcr-bin

View File

@@ -1,5 +1,11 @@
# Changelog # Changelog
## [0.7.0] - 2026-05-28
Added:
- **FreeBSD, OpenBSD, NetBSD, DragonflyBSD target support** — full platform routing and dynamically generated target triples.
## [0.6.9] - 2026-05-28 ## [0.6.9] - 2026-05-28
Added: Added:

2
Cargo.lock generated
View File

@@ -112,7 +112,7 @@ dependencies = [
[[package]] [[package]]
name = "dcr" name = "dcr"
version = "0.6.9" version = "0.7.0"
dependencies = [ dependencies = [
"ctrlc", "ctrlc",
"git2", "git2",

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "dcr" name = "dcr"
version = "0.6.9" version = "0.7.0"
edition = "2024" edition = "2024"
build = "build.rs" build = "build.rs"
description = "DCR is a utility for managing C/C++ projects in a Cargo-like style." description = "DCR is a utility for managing C/C++ projects in a Cargo-like style."
@@ -42,7 +42,10 @@ sha2 = "0.10"
toml = "1.0.3" toml = "1.0.3"
serde_json = "1" serde_json = "1"
ctrlc = "3" ctrlc = "3"
git2 = { version = "0.20.4", features = ["vendored-libgit2", "vendored-openssl"] }
[target.'cfg(not(windows))'.dependencies] [target.'cfg(not(windows))'.dependencies]
openssl = { version = "0.10", features = ["vendored"] } git2 = { version = "0.20.4", features = ["vendored-libgit2", "vendored-openssl"] }
openssl = { version = "0.10", features = ["vendored"] }
[target.'cfg(windows)'.dependencies]
git2 = { version = "0.20.4", features = ["vendored-libgit2"] }

2
rust-toolchain.toml Normal file
View File

@@ -0,0 +1,2 @@
[toolchain]
channel = "stable"

View File

@@ -80,15 +80,26 @@ pub fn build(args: &[String]) -> i32 {
} }
if flags.target.is_none() { if flags.target.is_none() {
let default_target = if cfg!(target_os = "linux") { let default_target = if cfg!(target_os = "linux") {
"x86_64-unknown-linux-gnu" format!("{}-unknown-linux-gnu", std::env::consts::ARCH)
} else if cfg!(target_os = "macos") { } else if cfg!(target_os = "macos") {
"x86_64-apple-darwin" "x86_64-apple-darwin".to_string()
} else if cfg!(target_os = "windows") { } else if cfg!(target_os = "windows") {
"x86_64-pc-windows-msvc" "x86_64-pc-windows-msvc".to_string()
} else if cfg!(any(
target_os = "freebsd",
target_os = "openbsd",
target_os = "netbsd",
target_os = "dragonfly"
)) {
format!(
"{}-unknown-{}",
std::env::consts::ARCH,
std::env::consts::OS
)
} else { } else {
"unknown" "unknown".to_string()
}; };
flags.target = Some(default_target.to_string()); flags.target = Some(default_target);
} }
if flags.clean { if flags.clean {
let mut clean_args = Vec::new(); let mut clean_args = Vec::new();
@@ -390,6 +401,15 @@ fn ensure_target_dirs(
let default_dir = if cfg!(target_os = "linux") { let default_dir = if cfg!(target_os = "linux") {
let arch = std::env::consts::ARCH; let arch = std::env::consts::ARCH;
format!("{arch}-unknown-linux-gnu/{profile}") format!("{arch}-unknown-linux-gnu/{profile}")
} else if cfg!(any(
target_os = "freebsd",
target_os = "openbsd",
target_os = "netbsd",
target_os = "dragonfly"
)) {
let arch = std::env::consts::ARCH;
let os = std::env::consts::OS;
format!("{arch}-unknown-{os}/{profile}")
} else { } else {
profile.to_string() profile.to_string()
}; };

View File

@@ -120,11 +120,22 @@ fn clean_from_root(root: &Path, flags: &CleanFlags) -> Result<(), String> {
}) })
.or_else(|| { .or_else(|| {
Some(if cfg!(target_os = "linux") { Some(if cfg!(target_os = "linux") {
"x86_64-unknown-linux-gnu".to_string() format!("{}-unknown-linux-gnu", std::env::consts::ARCH)
} else if cfg!(target_os = "macos") { } else if cfg!(target_os = "macos") {
"x86_64-apple-darwin".to_string() "x86_64-apple-darwin".to_string()
} else if cfg!(target_os = "windows") { } else if cfg!(target_os = "windows") {
"x86_64-pc-windows-msvc".to_string() "x86_64-pc-windows-msvc".to_string()
} else if cfg!(any(
target_os = "freebsd",
target_os = "openbsd",
target_os = "netbsd",
target_os = "dragonfly"
)) {
format!(
"{}-unknown-{}",
std::env::consts::ARCH,
std::env::consts::OS
)
} else { } else {
"unknown".to_string() "unknown".to_string()
}) })

56
src/cli/fmt.rs Normal file
View File

@@ -0,0 +1,56 @@
use crate::utils::log::error;
use crate::utils::text::{BOLD_GREEN, colored};
use glob::glob;
use std::process::Command;
pub fn fmt(_args: &[String]) -> i32 {
let patterns = [
"src/**/*.c",
"src/**/*.cpp",
"src/**/*.h",
"src/**/*.hpp",
"tests/**/*.c",
"tests/**/*.cpp",
"tests/**/*.h",
"tests/**/*.hpp",
];
let mut files = Vec::new();
for pattern in patterns {
if let Ok(paths) = glob(pattern) {
for path in paths.flatten() {
if let Some(s) = path.to_str() {
files.push(s.to_string());
}
}
}
}
if files.is_empty() {
println!(" {} No files to format", colored("Format", BOLD_GREEN));
return 0;
}
println!(
" {} {} files",
colored("Formatting", BOLD_GREEN),
files.len()
);
let status = Command::new("clang-format").arg("-i").args(&files).status();
match status {
Ok(s) if s.success() => {
println!(" {} successful", colored("Format", BOLD_GREEN));
0
}
Ok(s) => {
error(&format!("clang-format failed with status: {}", s));
1
}
Err(e) => {
error(&format!("Failed to execute clang-format: {}", e));
1
}
}
}

View File

@@ -31,6 +31,7 @@ pub fn help() -> i32 {
println!(" run [--profile] Build and run the project (default: --debug)"); println!(" run [--profile] Build and run the project (default: --debug)");
println!(" tree Display the dependency tree"); println!(" tree Display the dependency tree");
println!(" test Run project tests (alias: tests)"); println!(" test Run project tests (alias: tests)");
println!(" fmt Format all C/C++ source files using clang-format");
println!(" clean Remove the target directory"); println!(" clean Remove the target directory");
println!(" gen <subcommand> Generate IDE integration files"); println!(" gen <subcommand> Generate IDE integration files");
printc("FLAGS:", BOLD_GREEN); printc("FLAGS:", BOLD_GREEN);

View File

@@ -20,6 +20,7 @@ pub mod build;
pub mod clean; pub mod clean;
pub mod flag_update; pub mod flag_update;
pub mod flags; pub mod flags;
pub mod fmt;
pub mod r#gen; pub mod r#gen;
pub mod help; pub mod help;
pub mod init; pub mod init;

View File

@@ -160,15 +160,26 @@ fn run_project(
let mut target = flags.target.clone(); let mut target = flags.target.clone();
if target.is_none() { if target.is_none() {
let default_target = if cfg!(target_os = "linux") { let default_target = if cfg!(target_os = "linux") {
"x86_64-unknown-linux-gnu" format!("{}-unknown-linux-gnu", std::env::consts::ARCH)
} else if cfg!(target_os = "macos") { } else if cfg!(target_os = "macos") {
"x86_64-apple-darwin" "x86_64-apple-darwin".to_string()
} else if cfg!(target_os = "windows") { } else if cfg!(target_os = "windows") {
"x86_64-pc-windows-msvc" "x86_64-pc-windows-msvc".to_string()
} else if cfg!(any(
target_os = "freebsd",
target_os = "openbsd",
target_os = "netbsd",
target_os = "dragonfly"
)) {
format!(
"{}-unknown-{}",
std::env::consts::ARCH,
std::env::consts::OS
)
} else { } else {
"unknown" "unknown".to_string()
}; };
target = Some(default_target.to_string()); target = Some(default_target);
} }
let build_kind = config let build_kind = config

View File

@@ -14,7 +14,6 @@
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
use crate::utils::log::error; use crate::utils::log::error;
mod cli; mod cli;
mod config; mod config;
@@ -41,6 +40,7 @@ fn main() {
"run" => cli::run::run(rest), "run" => cli::run::run(rest),
"tree" => cli::tree::tree(rest), "tree" => cli::tree::tree(rest),
"test" | "tests" => cli::test::test(rest), "test" | "tests" => cli::test::test(rest),
"fmt" => cli::fmt::fmt(rest),
"clean" => cli::clean::clean(rest), "clean" => cli::clean::clean(rest),
"gen" => cli::r#gen::r#gen(rest), "gen" => cli::r#gen::r#gen(rest),
"--version" => { "--version" => {

88
src/platform/bsd.rs Normal file
View File

@@ -0,0 +1,88 @@
pub fn bin_path(profile: &str, name: &str, target_dir: Option<&str>) -> String {
match target_dir {
Some(dir) => format!("{}/{}", dir.trim_end_matches('/'), name),
None => {
let arch = std::env::consts::ARCH;
let os = std::env::consts::OS;
let target = format!("{arch}-unknown-{os}");
format!("./target/{target}/{profile}/{name}")
}
}
}
pub fn lib_path(profile: &str, name: &str, target_dir: Option<&str>) -> String {
match target_dir {
Some(dir) => format!("{}/lib{}.a", dir.trim_end_matches('/'), name),
None => {
let arch = std::env::consts::ARCH;
let os = std::env::consts::OS;
let target = format!("{arch}-unknown-{os}");
format!("./target/{target}/{profile}/lib{name}.a")
}
}
}
pub fn elf_path(profile: &str, name: &str, target_dir: Option<&str>) -> String {
match target_dir {
Some(dir) => format!("{}/{}", dir.trim_end_matches('/'), name),
None => {
let arch = std::env::consts::ARCH;
let os = std::env::consts::OS;
let target = format!("{arch}-unknown-{os}");
format!("./target/{target}/{profile}/{name}")
}
}
}
pub fn efi_path(profile: &str, name: &str, target_dir: Option<&str>) -> String {
match target_dir {
Some(dir) => format!("{}/{}.efi", dir.trim_end_matches('/'), name),
None => {
let arch = std::env::consts::ARCH;
let os = std::env::consts::OS;
let target = format!("{arch}-unknown-{os}");
format!("./target/{target}/{profile}/{name}.efi")
}
}
}
pub fn shared_lib_path(profile: &str, name: &str, target_dir: Option<&str>) -> String {
match target_dir {
Some(dir) => format!("{}/lib{}.so", dir.trim_end_matches('/'), name),
None => {
let arch = std::env::consts::ARCH;
let os = std::env::consts::OS;
let target = format!("{arch}-unknown-{os}");
format!("./target/{target}/{profile}/lib{name}.so")
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn bin_path_default() {
let arch = std::env::consts::ARCH;
let os = std::env::consts::OS;
let expected = format!("./target/{arch}-unknown-{os}/debug/hello");
assert_eq!(bin_path("debug", "hello", None), expected);
}
#[test]
fn lib_path_default() {
let arch = std::env::consts::ARCH;
let os = std::env::consts::OS;
let expected = format!("./target/{arch}-unknown-{os}/debug/libmylib.a");
assert_eq!(lib_path("debug", "mylib", None), expected);
}
#[test]
fn shared_lib_path_default() {
let arch = std::env::consts::ARCH;
let os = std::env::consts::OS;
let expected = format!("./target/{arch}-unknown-{os}/debug/libmylib.so");
assert_eq!(shared_lib_path("debug", "mylib", None), expected);
}
}

View File

@@ -15,6 +15,13 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
#[cfg(any(
target_os = "freebsd",
target_os = "openbsd",
target_os = "netbsd",
target_os = "dragonfly"
))]
pub mod bsd;
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
pub mod linux; pub mod linux;
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
@@ -35,7 +42,24 @@ pub fn bin_path(profile: &str, name: &str, target_dir: Option<&str>) -> String {
{ {
return windows::bin_path(profile, name, target_dir); return windows::bin_path(profile, name, target_dir);
} }
#[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "windows")))] #[cfg(any(
target_os = "freebsd",
target_os = "openbsd",
target_os = "netbsd",
target_os = "dragonfly"
))]
{
return bsd::bin_path(profile, name, target_dir);
}
#[cfg(not(any(
target_os = "linux",
target_os = "macos",
target_os = "windows",
target_os = "freebsd",
target_os = "openbsd",
target_os = "netbsd",
target_os = "dragonfly"
)))]
{ {
match target_dir { match target_dir {
Some(dir) => format!("{}/{}", dir.trim_end_matches('/'), name), Some(dir) => format!("{}/{}", dir.trim_end_matches('/'), name),
@@ -57,7 +81,24 @@ pub fn elf_path(profile: &str, name: &str, target_dir: Option<&str>) -> String {
{ {
return windows::elf_path(profile, name, target_dir); return windows::elf_path(profile, name, target_dir);
} }
#[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "windows")))] #[cfg(any(
target_os = "freebsd",
target_os = "openbsd",
target_os = "netbsd",
target_os = "dragonfly"
))]
{
return bsd::elf_path(profile, name, target_dir);
}
#[cfg(not(any(
target_os = "linux",
target_os = "macos",
target_os = "windows",
target_os = "freebsd",
target_os = "openbsd",
target_os = "netbsd",
target_os = "dragonfly"
)))]
{ {
match target_dir { match target_dir {
Some(dir) => format!("{}/{}", dir.trim_end_matches('/'), name), Some(dir) => format!("{}/{}", dir.trim_end_matches('/'), name),
@@ -79,7 +120,24 @@ pub fn efi_path(profile: &str, name: &str, target_dir: Option<&str>) -> String {
{ {
return windows::efi_path(profile, name, target_dir); return windows::efi_path(profile, name, target_dir);
} }
#[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "windows")))] #[cfg(any(
target_os = "freebsd",
target_os = "openbsd",
target_os = "netbsd",
target_os = "dragonfly"
))]
{
return bsd::efi_path(profile, name, target_dir);
}
#[cfg(not(any(
target_os = "linux",
target_os = "macos",
target_os = "windows",
target_os = "freebsd",
target_os = "openbsd",
target_os = "netbsd",
target_os = "dragonfly"
)))]
{ {
match target_dir { match target_dir {
Some(dir) => format!("{}/{}.efi", dir.trim_end_matches('/'), name), Some(dir) => format!("{}/{}.efi", dir.trim_end_matches('/'), name),
@@ -101,7 +159,24 @@ pub fn lib_path(profile: &str, name: &str, target_dir: Option<&str>) -> String {
{ {
return windows::lib_path(profile, name, target_dir); return windows::lib_path(profile, name, target_dir);
} }
#[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "windows")))] #[cfg(any(
target_os = "freebsd",
target_os = "openbsd",
target_os = "netbsd",
target_os = "dragonfly"
))]
{
return bsd::lib_path(profile, name, target_dir);
}
#[cfg(not(any(
target_os = "linux",
target_os = "macos",
target_os = "windows",
target_os = "freebsd",
target_os = "openbsd",
target_os = "netbsd",
target_os = "dragonfly"
)))]
{ {
match target_dir { match target_dir {
Some(dir) => format!("{}/lib{}.a", dir.trim_end_matches('/'), name), Some(dir) => format!("{}/lib{}.a", dir.trim_end_matches('/'), name),
@@ -123,7 +198,24 @@ pub fn shared_lib_path(profile: &str, name: &str, target_dir: Option<&str>) -> S
{ {
return windows::shared_lib_path(profile, name, target_dir); return windows::shared_lib_path(profile, name, target_dir);
} }
#[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "windows")))] #[cfg(any(
target_os = "freebsd",
target_os = "openbsd",
target_os = "netbsd",
target_os = "dragonfly"
))]
{
return bsd::shared_lib_path(profile, name, target_dir);
}
#[cfg(not(any(
target_os = "linux",
target_os = "macos",
target_os = "windows",
target_os = "freebsd",
target_os = "openbsd",
target_os = "netbsd",
target_os = "dragonfly"
)))]
{ {
match target_dir { match target_dir {
Some(dir) => format!("{}/lib{}.so", dir.trim_end_matches('/'), name), Some(dir) => format!("{}/lib{}.so", dir.trim_end_matches('/'), name),