mirror of
https://github.com/dexoron/dcr.git
synced 2026-10-21 19:19:41 +00:00
Compare commits
7 Commits
552f6c8e4f
...
dev
| Author | SHA1 | Date | |
|---|---|---|---|
| 6f47e81610 | |||
| d49b271e6a | |||
| f17e4c6642 | |||
| a890f7e6eb | |||
|
|
3b6251ec33 | ||
|
|
e9d09eacaf | ||
|
|
2f4cde9177 |
13
dcrup.cmd
13
dcrup.cmd
@@ -1,13 +0,0 @@
|
|||||||
@echo off
|
|
||||||
setlocal
|
|
||||||
set "SCRIPT_DIR=%~dp0"
|
|
||||||
if exist "%SCRIPT_DIR%dcrup.ps1" (
|
|
||||||
powershell -NoProfile -ExecutionPolicy Bypass -File "%SCRIPT_DIR%dcrup.ps1" %*
|
|
||||||
exit /b %ERRORLEVEL%
|
|
||||||
)
|
|
||||||
if exist "%USERPROFILE%\.dcr\bin\dcrup.ps1" (
|
|
||||||
powershell -NoProfile -ExecutionPolicy Bypass -File "%USERPROFILE%\.dcr\bin\dcrup.ps1" %*
|
|
||||||
exit /b %ERRORLEVEL%
|
|
||||||
)
|
|
||||||
echo [error] dcrup.ps1 not found near dcrup.cmd >&2
|
|
||||||
exit /b 1
|
|
||||||
43
dcrup.ps1
43
dcrup.ps1
@@ -1,4 +1,4 @@
|
|||||||
#Requires -Version 5.1
|
#Requires -Version 5.1
|
||||||
$ErrorActionPreference = 'Stop'
|
$ErrorActionPreference = 'Stop'
|
||||||
|
|
||||||
$DcrupHome = if ($env:DCRUP_HOME) { $env:DCRUP_HOME } else { Join-Path $env:USERPROFILE '.dcr' }
|
$DcrupHome = if ($env:DCRUP_HOME) { $env:DCRUP_HOME } else { Join-Path $env:USERPROFILE '.dcr' }
|
||||||
@@ -6,6 +6,7 @@ $DcrupBin = if ($env:DCRUP_BIN) { $env:DCRUP_BIN } else { Join-Path $DcrupHom
|
|||||||
$DcrupTc = Join-Path $DcrupHome 'toolchains'
|
$DcrupTc = Join-Path $DcrupHome 'toolchains'
|
||||||
$DcrupMeta = Join-Path $DcrupHome 'meta'
|
$DcrupMeta = Join-Path $DcrupHome 'meta'
|
||||||
$RepoUrl = if ($env:DCRUP_REPO) { $env:DCRUP_REPO } else { 'https://github.com/dexoron/dcr' }
|
$RepoUrl = if ($env:DCRUP_REPO) { $env:DCRUP_REPO } else { 'https://github.com/dexoron/dcr' }
|
||||||
|
$InstallUrl = if ($env:DCRUP_INSTALL_URL) { $env:DCRUP_INSTALL_URL } else { 'https://ps1.dcr-tool.ru' }
|
||||||
$DcrupMirror = if ($env:DCRUP_MIRROR) { $env:DCRUP_MIRROR } else { 'auto' }
|
$DcrupMirror = if ($env:DCRUP_MIRROR) { $env:DCRUP_MIRROR } else { 'auto' }
|
||||||
$ApiLatest = 'https://api.github.com/repos/dexoron/dcr/releases/latest'
|
$ApiLatest = 'https://api.github.com/repos/dexoron/dcr/releases/latest'
|
||||||
$ApiAll = 'https://api.github.com/repos/dexoron/dcr/releases'
|
$ApiAll = 'https://api.github.com/repos/dexoron/dcr/releases'
|
||||||
@@ -133,6 +134,18 @@ function Link-Default([string]$id) {
|
|||||||
Ok "default → $id ($dst)"
|
Ok "default → $id ($dst)"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Resolve-InstalledId([string]$spec) {
|
||||||
|
Parse-Spec $spec
|
||||||
|
if ($script:SpecChannel -eq 'night' -or $script:SpecFloating) {
|
||||||
|
$item = Get-ChildItem $DcrupTc -Directory -ErrorAction SilentlyContinue |
|
||||||
|
Where-Object { $_.Name -like "$($script:SpecChannel)-*" } |
|
||||||
|
Sort-Object Name | Select-Object -Last 1
|
||||||
|
if ($item) { return $item.Name }
|
||||||
|
return $null
|
||||||
|
}
|
||||||
|
return (Toolchain-Id)
|
||||||
|
}
|
||||||
|
|
||||||
function Set-Mirror([string]$value) {
|
function Set-Mirror([string]$value) {
|
||||||
if ($value -notin @('auto', 'cf', 'gh', 'sf', 'ya')) {
|
if ($value -notin @('auto', 'cf', 'gh', 'sf', 'ya')) {
|
||||||
Die "invalid --mirror: $value (use auto|cf|gh|sf|ya)"
|
Die "invalid --mirror: $value (use auto|cf|gh|sf|ya)"
|
||||||
@@ -379,7 +392,19 @@ function Cmd-Show {
|
|||||||
|
|
||||||
function Cmd-SelfInstall {
|
function Cmd-SelfInstall {
|
||||||
Ensure-Dirs
|
Ensure-Dirs
|
||||||
|
if ([string]::IsNullOrWhiteSpace($PSCommandPath) -or -not (Test-Path $PSCommandPath)) {
|
||||||
|
# With `irm URL | iex`, PowerShell evaluates text and there is no
|
||||||
|
# source path. Download the canonical installer for self-install.
|
||||||
|
$tmp = Join-Path $env:TEMP ("dcrup-" + [guid]::NewGuid().ToString('N') + '.ps1')
|
||||||
|
try {
|
||||||
|
Invoke-WebRequest -Uri $InstallUrl -OutFile $tmp -UseBasicParsing -UserAgent 'dcrup'
|
||||||
|
Copy-Item $tmp (Join-Path $DcrupBin 'dcrup.ps1') -Force
|
||||||
|
} finally {
|
||||||
|
Remove-Item $tmp -Force -ErrorAction SilentlyContinue
|
||||||
|
}
|
||||||
|
} else {
|
||||||
Copy-Item $PSCommandPath (Join-Path $DcrupBin 'dcrup.ps1') -Force
|
Copy-Item $PSCommandPath (Join-Path $DcrupBin 'dcrup.ps1') -Force
|
||||||
|
}
|
||||||
Install-CmdShim
|
Install-CmdShim
|
||||||
Ensure-UserPath
|
Ensure-UserPath
|
||||||
Ok "dcrup installed to $DcrupBin (use: dcrup …)"
|
Ok "dcrup installed to $DcrupBin (use: dcrup …)"
|
||||||
@@ -417,7 +442,7 @@ switch ($cmd) {
|
|||||||
if ($a -like 'night-*') { Cmd-Install @('night', '--build', '--force') }
|
if ($a -like 'night-*') { Cmd-Install @('night', '--build', '--force') }
|
||||||
elseif ($a -like 'stable-*') { Cmd-Install @('stable', '--force') }
|
elseif ($a -like 'stable-*') { Cmd-Install @('stable', '--force') }
|
||||||
elseif ($a -like 'dev-*') { Cmd-Install @('dev', '--force') }
|
elseif ($a -like 'dev-*') { Cmd-Install @('dev', '--force') }
|
||||||
else { Ok "pinned $a — install a newer version explicitly" }
|
else { Ok "pinned $a - install a newer version explicitly" }
|
||||||
}
|
}
|
||||||
'uninstall' {
|
'uninstall' {
|
||||||
if ($rest -contains '--all') {
|
if ($rest -contains '--all') {
|
||||||
@@ -426,9 +451,21 @@ switch ($cmd) {
|
|||||||
Remove-Item (Active-Path) -ErrorAction SilentlyContinue
|
Remove-Item (Active-Path) -ErrorAction SilentlyContinue
|
||||||
Ok 'removed all'
|
Ok 'removed all'
|
||||||
} else {
|
} else {
|
||||||
Die 'use: dcrup uninstall --all (or install a replacement first)'
|
if ($rest.Count -ne 1) { Die 'usage: dcrup uninstall <spec>|--all' }
|
||||||
|
$id = Resolve-InstalledId $rest[0]
|
||||||
|
if (-not $id) { Die "not installed: $($rest[0])" }
|
||||||
|
$dir = Join-Path $DcrupTc $id
|
||||||
|
if (-not (Test-Path $dir)) { Die "not installed: $($rest[0])" }
|
||||||
|
Remove-Item -Recurse -Force $dir
|
||||||
|
if ((Read-Active) -eq $id) {
|
||||||
|
Remove-Item (Join-Path $DcrupBin 'dcr.exe') -ErrorAction SilentlyContinue
|
||||||
|
Remove-Item (Active-Path) -ErrorAction SilentlyContinue
|
||||||
|
Warn 'removed active toolchain; install or select another default'
|
||||||
|
}
|
||||||
|
Ok "removed $id"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
'self-install' { Cmd-SelfInstall }
|
'self-install' { Cmd-SelfInstall }
|
||||||
default { Die "unknown command: $cmd" }
|
default { Die "unknown command: $cmd" }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
104
dcrup.sh
Executable file → Normal file
104
dcrup.sh
Executable file → Normal file
@@ -6,6 +6,7 @@ DCRUP_BIN="${DCRUP_BIN:-$DCRUP_HOME/bin}"
|
|||||||
DCRUP_TC="${DCRUP_HOME}/toolchains"
|
DCRUP_TC="${DCRUP_HOME}/toolchains"
|
||||||
DCRUP_META="${DCRUP_HOME}/meta"
|
DCRUP_META="${DCRUP_HOME}/meta"
|
||||||
REPO_URL="${DCRUP_REPO:-https://github.com/dexoron/dcr}"
|
REPO_URL="${DCRUP_REPO:-https://github.com/dexoron/dcr}"
|
||||||
|
DCRUP_INSTALL_URL="${DCRUP_INSTALL_URL:-https://sh.dcr-tool.ru}"
|
||||||
DCRUP_MIRROR="${DCRUP_MIRROR:-auto}"
|
DCRUP_MIRROR="${DCRUP_MIRROR:-auto}"
|
||||||
API_LATEST="https://api.github.com/repos/dexoron/dcr/releases/latest"
|
API_LATEST="https://api.github.com/repos/dexoron/dcr/releases/latest"
|
||||||
API_ALL="https://api.github.com/repos/dexoron/dcr/releases"
|
API_ALL="https://api.github.com/repos/dexoron/dcr/releases"
|
||||||
@@ -20,7 +21,10 @@ NC='\033[0m'
|
|||||||
log() { printf "${CYAN}[dcrup]${NC} %s\n" "$*"; }
|
log() { printf "${CYAN}[dcrup]${NC} %s\n" "$*"; }
|
||||||
ok() { printf "${GREEN}[ok]${NC} %s\n" "$*"; }
|
ok() { printf "${GREEN}[ok]${NC} %s\n" "$*"; }
|
||||||
warn() { printf "${YELLOW}[warn]${NC} %s\n" "$*"; }
|
warn() { printf "${YELLOW}[warn]${NC} %s\n" "$*"; }
|
||||||
die() { printf "${RED}[error]${NC} %s\n" "$*" >&2; exit 1; }
|
die() {
|
||||||
|
printf "${RED}[error]${NC} %s\n" "$*" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
cat <<'EOF'
|
cat <<'EOF'
|
||||||
@@ -79,7 +83,7 @@ need_cmd() {
|
|||||||
detect_linux_libc() {
|
detect_linux_libc() {
|
||||||
local pref="${DCRUP_LIBC:-gnu}"
|
local pref="${DCRUP_LIBC:-gnu}"
|
||||||
case "$pref" in
|
case "$pref" in
|
||||||
gnu|glibc) echo "gnu" ;;
|
gnu | glibc) echo "gnu" ;;
|
||||||
musl) echo "musl" ;;
|
musl) echo "musl" ;;
|
||||||
auto)
|
auto)
|
||||||
if command -v ldd >/dev/null 2>&1; then
|
if command -v ldd >/dev/null 2>&1; then
|
||||||
@@ -115,7 +119,7 @@ detect_triple() {
|
|||||||
echo "x86_64-unknown-linux-gnu"
|
echo "x86_64-unknown-linux-gnu"
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
Linux:aarch64|Linux:arm64)
|
Linux:aarch64 | Linux:arm64)
|
||||||
libc="$(detect_linux_libc)"
|
libc="$(detect_linux_libc)"
|
||||||
if [[ "$libc" == "musl" ]]; then
|
if [[ "$libc" == "musl" ]]; then
|
||||||
echo "aarch64-unknown-linux-musl"
|
echo "aarch64-unknown-linux-musl"
|
||||||
@@ -123,7 +127,7 @@ detect_triple() {
|
|||||||
echo "aarch64-unknown-linux-gnu"
|
echo "aarch64-unknown-linux-gnu"
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
Linux:i686|Linux:i386)
|
Linux:i686 | Linux:i386)
|
||||||
libc="$(detect_linux_libc)"
|
libc="$(detect_linux_libc)"
|
||||||
if [[ "$libc" == "musl" ]]; then
|
if [[ "$libc" == "musl" ]]; then
|
||||||
echo "i686-unknown-linux-musl"
|
echo "i686-unknown-linux-musl"
|
||||||
@@ -131,7 +135,7 @@ detect_triple() {
|
|||||||
echo "i686-unknown-linux-gnu"
|
echo "i686-unknown-linux-gnu"
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
Linux:armv7l|Linux:armv7)
|
Linux:armv7l | Linux:armv7)
|
||||||
libc="$(detect_linux_libc)"
|
libc="$(detect_linux_libc)"
|
||||||
if [[ "$libc" == "musl" ]]; then
|
if [[ "$libc" == "musl" ]]; then
|
||||||
echo "armv7-unknown-linux-musleabihf"
|
echo "armv7-unknown-linux-musleabihf"
|
||||||
@@ -148,16 +152,16 @@ detect_triple() {
|
|||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
Darwin:x86_64) echo "x86_64-apple-darwin" ;;
|
Darwin:x86_64) echo "x86_64-apple-darwin" ;;
|
||||||
Darwin:arm64|Darwin:aarch64) echo "aarch64-apple-darwin" ;;
|
Darwin:arm64 | Darwin:aarch64) echo "aarch64-apple-darwin" ;;
|
||||||
FreeBSD:x86_64|FreeBSD:amd64) echo "x86_64-unknown-freebsd" ;;
|
FreeBSD:x86_64 | FreeBSD:amd64) echo "x86_64-unknown-freebsd" ;;
|
||||||
FreeBSD:aarch64|FreeBSD:arm64) echo "aarch64-unknown-freebsd" ;;
|
FreeBSD:aarch64 | FreeBSD:arm64) echo "aarch64-unknown-freebsd" ;;
|
||||||
OpenBSD:x86_64|OpenBSD:amd64) echo "x86_64-unknown-openbsd" ;;
|
OpenBSD:x86_64 | OpenBSD:amd64) echo "x86_64-unknown-openbsd" ;;
|
||||||
NetBSD:x86_64|NetBSD:amd64) echo "x86_64-unknown-netbsd" ;;
|
NetBSD:x86_64 | NetBSD:amd64) echo "x86_64-unknown-netbsd" ;;
|
||||||
MINGW*|MSYS*|CYGWIN*)
|
MINGW* | MSYS* | CYGWIN*)
|
||||||
case "$arch" in
|
case "$arch" in
|
||||||
x86_64|amd64) echo "x86_64-pc-windows-gnu" ;;
|
x86_64 | amd64) echo "x86_64-pc-windows-gnu" ;;
|
||||||
aarch64|arm64) echo "aarch64-pc-windows-gnullvm" ;;
|
aarch64 | arm64) echo "aarch64-pc-windows-gnullvm" ;;
|
||||||
i686|i386) echo "i686-pc-windows-gnu" ;;
|
i686 | i386) echo "i686-pc-windows-gnu" ;;
|
||||||
*) die "unsupported Windows arch under MSYS: $arch" ;;
|
*) die "unsupported Windows arch under MSYS: $arch" ;;
|
||||||
esac
|
esac
|
||||||
;;
|
;;
|
||||||
@@ -180,7 +184,7 @@ parse_spec() {
|
|||||||
|
|
||||||
case "$raw" in
|
case "$raw" in
|
||||||
"") die "missing version/channel spec" ;;
|
"") die "missing version/channel spec" ;;
|
||||||
stable|dev|night)
|
stable | dev | night)
|
||||||
SPEC_CHANNEL="$raw"
|
SPEC_CHANNEL="$raw"
|
||||||
SPEC_VERSION=""
|
SPEC_VERSION=""
|
||||||
SPEC_FLOATING=1
|
SPEC_FLOATING=1
|
||||||
@@ -189,7 +193,7 @@ parse_spec() {
|
|||||||
SPEC_VERSION="$(normalize_version "${raw%@*}")"
|
SPEC_VERSION="$(normalize_version "${raw%@*}")"
|
||||||
SPEC_CHANNEL="${raw#*@}"
|
SPEC_CHANNEL="${raw#*@}"
|
||||||
case "$SPEC_CHANNEL" in
|
case "$SPEC_CHANNEL" in
|
||||||
stable|dev) ;;
|
stable | dev) ;;
|
||||||
night) die "cannot pin a version on night (use: dcrup install night)" ;;
|
night) die "cannot pin a version on night (use: dcrup install night)" ;;
|
||||||
*) die "unknown channel in spec: $SPEC_CHANNEL (use stable|dev)" ;;
|
*) die "unknown channel in spec: $SPEC_CHANNEL (use stable|dev)" ;;
|
||||||
esac
|
esac
|
||||||
@@ -235,6 +239,8 @@ link_default() {
|
|||||||
local id="$1"
|
local id="$1"
|
||||||
local src="$DCRUP_TC/$id/dcr"
|
local src="$DCRUP_TC/$id/dcr"
|
||||||
[[ -x "$src" ]] || die "toolchain not installed: $id"
|
[[ -x "$src" ]] || die "toolchain not installed: $id"
|
||||||
|
# Resolve the source so a relative DCRUP_HOME cannot create a broken link.
|
||||||
|
src="$(cd "$(dirname "$src")" && pwd)/$(basename "$src")"
|
||||||
ln -sfn "$src" "$DCRUP_BIN/dcr"
|
ln -sfn "$src" "$DCRUP_BIN/dcr"
|
||||||
write_active "$id"
|
write_active "$id"
|
||||||
ok "default → $id ($DCRUP_BIN/dcr)"
|
ok "default → $id ($DCRUP_BIN/dcr)"
|
||||||
@@ -251,7 +257,7 @@ json_tag() {
|
|||||||
|
|
||||||
set_mirror() {
|
set_mirror() {
|
||||||
case "$1" in
|
case "$1" in
|
||||||
auto|cf|gh|sf|ya) DCRUP_MIRROR="$1" ;;
|
auto | cf | gh | sf | ya) DCRUP_MIRROR="$1" ;;
|
||||||
*) die "invalid --mirror: $1 (use auto|cf|gh|sf|ya)" ;;
|
*) die "invalid --mirror: $1 (use auto|cf|gh|sf|ya)" ;;
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
@@ -272,7 +278,7 @@ mirror_chain() { echo "cf gh sf ya"; }
|
|||||||
mirrors_to_try() {
|
mirrors_to_try() {
|
||||||
case "$DCRUP_MIRROR" in
|
case "$DCRUP_MIRROR" in
|
||||||
auto) mirror_chain ;;
|
auto) mirror_chain ;;
|
||||||
cf|gh|sf|ya) echo "$DCRUP_MIRROR" ;;
|
cf | gh | sf | ya) echo "$DCRUP_MIRROR" ;;
|
||||||
*) die "invalid mirror: $DCRUP_MIRROR (use auto|cf|gh|sf|ya)" ;;
|
*) die "invalid mirror: $DCRUP_MIRROR (use auto|cf|gh|sf|ya)" ;;
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
@@ -361,8 +367,8 @@ install_prebuilt() {
|
|||||||
|
|
||||||
mkdir -p "$dest"
|
mkdir -p "$dest"
|
||||||
log "downloading $asset (mirror=$DCRUP_MIRROR) …"
|
log "downloading $asset (mirror=$DCRUP_MIRROR) …"
|
||||||
download_from_mirrors "$tag" "$asset" "$dest" \
|
download_from_mirrors "$tag" "$asset" "$dest" ||
|
||||||
|| die "no mirror reachable for $asset (try: --mirror cf|gh|sf|ya)"
|
die "no mirror reachable for $asset (try: --mirror cf|gh|sf|ya)"
|
||||||
mirror="$USED_MIRROR"
|
mirror="$USED_MIRROR"
|
||||||
log "mirror → $mirror"
|
log "mirror → $mirror"
|
||||||
chmod +x "$dest/dcr"
|
chmod +x "$dest/dcr"
|
||||||
@@ -390,8 +396,8 @@ install_build() {
|
|||||||
|
|
||||||
if [[ "$SPEC_CHANNEL" == "night" ]]; then
|
if [[ "$SPEC_CHANNEL" == "night" ]]; then
|
||||||
log "cloning $REPO_URL (branch dev) for night …"
|
log "cloning $REPO_URL (branch dev) for night …"
|
||||||
git clone --depth 1 --branch dev "$REPO_URL" "$tmp/src" 2>/dev/null \
|
git clone --depth 1 --branch dev "$REPO_URL" "$tmp/src" 2>/dev/null ||
|
||||||
|| git clone --depth 1 "$REPO_URL" "$tmp/src"
|
git clone --depth 1 "$REPO_URL" "$tmp/src"
|
||||||
sha="$(git -C "$tmp/src" rev-parse --short HEAD)"
|
sha="$(git -C "$tmp/src" rev-parse --short HEAD)"
|
||||||
version="night"
|
version="night"
|
||||||
id="$(toolchain_id "$sha")"
|
id="$(toolchain_id "$sha")"
|
||||||
@@ -403,8 +409,8 @@ install_build() {
|
|||||||
version="$(normalize_version "$tag")"
|
version="$(normalize_version "$tag")"
|
||||||
id="$(toolchain_id "$version")"
|
id="$(toolchain_id "$version")"
|
||||||
log "cloning $REPO_URL @ $tag …"
|
log "cloning $REPO_URL @ $tag …"
|
||||||
git clone --depth 1 --branch "$tag" "$REPO_URL" "$tmp/src" 2>/dev/null \
|
git clone --depth 1 --branch "$tag" "$REPO_URL" "$tmp/src" 2>/dev/null ||
|
||||||
|| {
|
{
|
||||||
git clone --depth 1 "$REPO_URL" "$tmp/src"
|
git clone --depth 1 "$REPO_URL" "$tmp/src"
|
||||||
git -C "$tmp/src" fetch --depth 1 origin "refs/tags/${tag}:refs/tags/${tag}"
|
git -C "$tmp/src" fetch --depth 1 origin "refs/tags/${tag}:refs/tags/${tag}"
|
||||||
git -C "$tmp/src" checkout "$tag"
|
git -C "$tmp/src" checkout "$tag"
|
||||||
@@ -415,8 +421,8 @@ install_build() {
|
|||||||
id="$(toolchain_id)"
|
id="$(toolchain_id)"
|
||||||
local tag="v${SPEC_VERSION}"
|
local tag="v${SPEC_VERSION}"
|
||||||
log "cloning $REPO_URL @ $tag …"
|
log "cloning $REPO_URL @ $tag …"
|
||||||
git clone --depth 1 --branch "$tag" "$REPO_URL" "$tmp/src" 2>/dev/null \
|
git clone --depth 1 --branch "$tag" "$REPO_URL" "$tmp/src" 2>/dev/null ||
|
||||||
|| {
|
{
|
||||||
git clone --depth 1 "$REPO_URL" "$tmp/src"
|
git clone --depth 1 "$REPO_URL" "$tmp/src"
|
||||||
git -C "$tmp/src" fetch --depth 1 origin "refs/tags/${tag}:refs/tags/${tag}"
|
git -C "$tmp/src" fetch --depth 1 origin "refs/tags/${tag}:refs/tags/${tag}"
|
||||||
git -C "$tmp/src" checkout "$tag"
|
git -C "$tmp/src" checkout "$tag"
|
||||||
@@ -453,9 +459,18 @@ cmd_install() {
|
|||||||
local libc_cli=""
|
local libc_cli=""
|
||||||
while [[ $# -gt 0 ]]; do
|
while [[ $# -gt 0 ]]; do
|
||||||
case "$1" in
|
case "$1" in
|
||||||
--build) mode="build"; shift ;;
|
--build)
|
||||||
--release) mode="release"; shift ;;
|
mode="build"
|
||||||
--force) FORCE=1; shift ;;
|
shift
|
||||||
|
;;
|
||||||
|
--release)
|
||||||
|
mode="release"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--force)
|
||||||
|
FORCE=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
--libc)
|
--libc)
|
||||||
[[ $# -ge 2 ]] || die "--libc needs gnu|musl|auto"
|
[[ $# -ge 2 ]] || die "--libc needs gnu|musl|auto"
|
||||||
libc_cli="$2"
|
libc_cli="$2"
|
||||||
@@ -474,7 +489,10 @@ cmd_install() {
|
|||||||
set_mirror "${1#--mirror=}"
|
set_mirror "${1#--mirror=}"
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
-h|--help) usage; exit 0 ;;
|
-h | --help)
|
||||||
|
usage
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
-*) die "unknown flag: $1" ;;
|
-*) die "unknown flag: $1" ;;
|
||||||
*)
|
*)
|
||||||
[[ -z "$spec" ]] || die "unexpected argument: $1"
|
[[ -z "$spec" ]] || die "unexpected argument: $1"
|
||||||
@@ -489,7 +507,7 @@ cmd_install() {
|
|||||||
|
|
||||||
if [[ -n "$libc_cli" ]]; then
|
if [[ -n "$libc_cli" ]]; then
|
||||||
case "$libc_cli" in
|
case "$libc_cli" in
|
||||||
gnu|glibc|musl|auto) DCRUP_LIBC="$libc_cli" ;;
|
gnu | glibc | musl | auto) DCRUP_LIBC="$libc_cli" ;;
|
||||||
*) die "invalid --libc: $libc_cli (use gnu|musl|auto)" ;;
|
*) die "invalid --libc: $libc_cli (use gnu|musl|auto)" ;;
|
||||||
esac
|
esac
|
||||||
fi
|
fi
|
||||||
@@ -534,12 +552,12 @@ cmd_update() {
|
|||||||
log "updating night (rebuild HEAD) …"
|
log "updating night (rebuild HEAD) …"
|
||||||
FORCE=1 cmd_install night --build --force
|
FORCE=1 cmd_install night --build --force
|
||||||
;;
|
;;
|
||||||
stable-*|dev-*)
|
stable-* | dev-*)
|
||||||
local ch="${active%%-*}"
|
local ch="${active%%-*}"
|
||||||
log "updating floating channel $ch …"
|
log "updating floating channel $ch …"
|
||||||
FORCE=1 cmd_install "$ch" --force
|
FORCE=1 cmd_install "$ch" --force
|
||||||
;;
|
;;
|
||||||
*-stable|*-dev)
|
*-stable | *-dev)
|
||||||
ok "pinned toolchain $active — not floating; install a newer version explicitly"
|
ok "pinned toolchain $active — not floating; install a newer version explicitly"
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
@@ -633,14 +651,28 @@ cmd_self_install() {
|
|||||||
local dest="$DCRUP_BIN"
|
local dest="$DCRUP_BIN"
|
||||||
while [[ $# -gt 0 ]]; do
|
while [[ $# -gt 0 ]]; do
|
||||||
case "$1" in
|
case "$1" in
|
||||||
--to) dest="$2"; shift 2 ;;
|
--to)
|
||||||
|
dest="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
*) die "usage: dcrup self-install [--to DIR]" ;;
|
*) die "usage: dcrup self-install [--to DIR]" ;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
ensure_dirs
|
ensure_dirs
|
||||||
mkdir -p "$dest"
|
mkdir -p "$dest"
|
||||||
local self
|
local self
|
||||||
self="$(readlink -f "$0" 2>/dev/null || realpath "$0" 2>/dev/null || echo "$0")"
|
self="$(readlink -f "$0" 2>/dev/null || realpath "$0" 2>/dev/null || true)"
|
||||||
|
if [[ -z "$self" || ! -f "$self" ]]; then
|
||||||
|
# When invoked as `curl ... | sh`, the shell has no script file to copy.
|
||||||
|
# Fetch the same trusted installer URL and install that exact script.
|
||||||
|
need_cmd curl
|
||||||
|
self="$(mktemp "${TMPDIR:-/tmp}/dcrup.XXXXXX")"
|
||||||
|
curl -fsSL --proto '=https' --tlsv1.2 "$DCRUP_INSTALL_URL" -o "$self" || {
|
||||||
|
rm -f "$self"
|
||||||
|
die "unable to download installer for self-install"
|
||||||
|
}
|
||||||
|
trap 'rm -f "$self"' EXIT
|
||||||
|
fi
|
||||||
cp "$self" "$dest/dcrup"
|
cp "$self" "$dest/dcrup"
|
||||||
chmod +x "$dest/dcrup"
|
chmod +x "$dest/dcrup"
|
||||||
ok "dcrup installed to $dest/dcrup"
|
ok "dcrup installed to $dest/dcrup"
|
||||||
@@ -652,7 +684,7 @@ main() {
|
|||||||
local cmd="${1:-}"
|
local cmd="${1:-}"
|
||||||
shift || true
|
shift || true
|
||||||
case "$cmd" in
|
case "$cmd" in
|
||||||
""|-h|--help|help) usage ;;
|
"" | -h | --help | help) usage ;;
|
||||||
install) cmd_install "$@" ;;
|
install) cmd_install "$@" ;;
|
||||||
default) cmd_default "$@" ;;
|
default) cmd_default "$@" ;;
|
||||||
update) cmd_update "$@" ;;
|
update) cmd_update "$@" ;;
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ Install and switch DCR versions (stable / dev / night, pin `0.8.2`, optional bui
|
|||||||
### Linux / macOS / BSD / Windows (bash)
|
### Linux / macOS / BSD / Windows (bash)
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
curl -fsSL https://sh.dcr-tool.ru | sh -s -- self-install
|
curl --proto '=https' --tlsv1.2 -sSf https://sh.dcr-tool.ru | sh -s -- self-install
|
||||||
export PATH="$HOME/.dcr/bin:$PATH"
|
export PATH="$HOME/.dcr/bin:$PATH"
|
||||||
dcrup install stable
|
dcrup install stable
|
||||||
```
|
```
|
||||||
@@ -19,28 +19,19 @@ dcrup install stable
|
|||||||
Non-interactive install of DCR in one shot:
|
Non-interactive install of DCR in one shot:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
curl -fsSL https://sh.dcr-tool.ru | sh -s -- install stable
|
curl --proto '=https' --tlsv1.2 -sSf https://sh.dcr-tool.ru | sh -s -- install stable
|
||||||
export PATH="$HOME/.dcr/bin:$PATH"
|
export PATH="$HOME/.dcr/bin:$PATH"
|
||||||
```
|
```
|
||||||
|
|
||||||
### Windows (PowerShell)
|
### Windows (PowerShell)
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
irm https://ps1.dcr-tool.ru | iex
|
& ([scriptblock]::Create((irm https://ps1.dcr-tool.ru))) self-install
|
||||||
# or download then run:
|
|
||||||
# irm https://ps1.dcr-tool.ru -OutFile dcrup.ps1
|
|
||||||
# powershell -File .\dcrup.ps1 self-install
|
|
||||||
# $env:Path += ";$env:USERPROFILE\.dcr\bin"
|
# $env:Path += ";$env:USERPROFILE\.dcr\bin"
|
||||||
dcrup install stable
|
dcrup install stable
|
||||||
```
|
```
|
||||||
|
|
||||||
Optional cmd bootstrap (if you prefer `curl` of the cmd shim):
|
After `self-install`, the command is **`dcrup`** (no `.sh` / `.ps1`) and is installed in `~/.dcr/bin` (Unix) or `%USERPROFILE%\.dcr\bin` (Windows).
|
||||||
|
|
||||||
```bat
|
|
||||||
curl -fsSL -o dcrup.cmd https://cmd.dcr-tool.ru
|
|
||||||
```
|
|
||||||
|
|
||||||
After `self-install`, the command is **`dcrup`** (no `.sh` / `.ps1`): shims live in `~/.dcr/bin` (Unix) or `%USERPROFILE%\.dcr\bin` (Windows `dcrup.cmd`).
|
|
||||||
|
|
||||||
### Common dcrup commands
|
### Common dcrup commands
|
||||||
|
|
||||||
@@ -58,6 +49,8 @@ dcrup update
|
|||||||
dcrup list
|
dcrup list
|
||||||
dcrup show
|
dcrup show
|
||||||
dcrup which
|
dcrup which
|
||||||
|
dcrup uninstall 0.8.2 # remove one installed version
|
||||||
|
dcrup uninstall --all # remove all installed versions
|
||||||
```
|
```
|
||||||
|
|
||||||
Layout: `~/.dcr/toolchains/<id>/dcr` and `~/.dcr/bin/dcr` → active version.
|
Layout: `~/.dcr/toolchains/<id>/dcr` and `~/.dcr/bin/dcr` → active version.
|
||||||
|
|||||||
@@ -18,8 +18,9 @@
|
|||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
use crate::core::{build_config::Config, deps::register};
|
use crate::core::{build_config::Config, deps::register};
|
||||||
|
use crate::utils::cli_styles::{Colorize, HELP_EXAMPLES_ST, HELP_SECTION_TITLE_ST, SUCCESS_ST};
|
||||||
use crate::utils::fs::find_project_root;
|
use crate::utils::fs::find_project_root;
|
||||||
use crate::utils::text::{BOLD_CYAN, BOLD_GREEN, colored, printc};
|
use crate::utils::log::sprintln;
|
||||||
use toml::{Value, map::Map};
|
use toml::{Value, map::Map};
|
||||||
|
|
||||||
/// Parsed arguments for the `dcr add` command.
|
/// Parsed arguments for the `dcr add` command.
|
||||||
@@ -58,16 +59,16 @@ pub struct AddArgs {
|
|||||||
/// Process exit code: `0` on success, non-zero on usage or I/O errors.
|
/// Process exit code: `0` on success, non-zero on usage or I/O errors.
|
||||||
pub fn add(args: &[String]) -> i32 {
|
pub fn add(args: &[String]) -> i32 {
|
||||||
if args.first().is_some_and(|a| a == "--help") {
|
if args.first().is_some_and(|a| a == "--help") {
|
||||||
printc("USAGE:", BOLD_GREEN);
|
sprintln!(HELP_SECTION_TITLE_ST, "USAGE:");
|
||||||
printc(
|
sprintln!(
|
||||||
" dcr add <name> <source> [--branch <b>] [--tag <t>] [--rev <r>]",
|
HELP_EXAMPLES_ST,
|
||||||
BOLD_CYAN,
|
" dcr add <name> <source> [--branch <b>] [--tag <t>] [--rev <r>]"
|
||||||
);
|
);
|
||||||
println!();
|
println!();
|
||||||
printc("DESCRIPTION:", BOLD_GREEN);
|
sprintln!(HELP_SECTION_TITLE_ST, "DESCRIPTION:");
|
||||||
println!(" Adds a dependency to the project.");
|
println!(" Adds a dependency to the project.");
|
||||||
println!();
|
println!();
|
||||||
printc("SOURCES:", BOLD_GREEN);
|
sprintln!(HELP_SECTION_TITLE_ST, "SOURCES:");
|
||||||
println!(" github:user/repo GitHub repository");
|
println!(" github:user/repo GitHub repository");
|
||||||
println!(" gitlab:user/repo GitLab repository");
|
println!(" gitlab:user/repo GitLab repository");
|
||||||
println!(" git:host.com/user/repo Generic git repository");
|
println!(" git:host.com/user/repo Generic git repository");
|
||||||
@@ -75,7 +76,7 @@ pub fn add(args: &[String]) -> i32 {
|
|||||||
println!(" pkg-config:fmt System pkg-config dependency");
|
println!(" pkg-config:fmt System pkg-config dependency");
|
||||||
println!(" <version> Version from registry");
|
println!(" <version> Version from registry");
|
||||||
println!();
|
println!();
|
||||||
printc("OPTIONS:", BOLD_GREEN);
|
sprintln!(HELP_SECTION_TITLE_ST, "OPTIONS:");
|
||||||
println!(" --branch <b> Use a specific branch");
|
println!(" --branch <b> Use a specific branch");
|
||||||
println!(" --tag <t> Use a specific tag");
|
println!(" --tag <t> Use a specific tag");
|
||||||
println!(" --rev <r> Use a specific commit hash");
|
println!(" --rev <r> Use a specific commit hash");
|
||||||
@@ -165,7 +166,7 @@ pub fn add(args: &[String]) -> i32 {
|
|||||||
|
|
||||||
println!(
|
println!(
|
||||||
" {} dependency `{}` to dcr.toml",
|
" {} dependency `{}` to dcr.toml",
|
||||||
colored("Added", BOLD_GREEN),
|
"Added".style(SUCCESS_ST),
|
||||||
add_args.name
|
add_args.name
|
||||||
);
|
);
|
||||||
0
|
0
|
||||||
|
|||||||
@@ -28,8 +28,11 @@ use crate::utils::build::{
|
|||||||
get_config_opt, get_config_str, get_language_with_profile_or_default, get_string_with_profile,
|
get_config_opt, get_config_str, get_language_with_profile_or_default, get_string_with_profile,
|
||||||
normalize_kind, resolve_artifact_target_dir, resolve_compiler,
|
normalize_kind, resolve_artifact_target_dir, resolve_compiler,
|
||||||
};
|
};
|
||||||
|
use crate::utils::cli_styles::{
|
||||||
|
BOLD_CYAN, BOLD_YELLOW, Colorize, HELP_EXAMPLES_ST, HELP_SECTION_TITLE_ST, SUCCESS_ST, Style,
|
||||||
|
};
|
||||||
use crate::utils::fs::{canonicalize_path, find_project_root};
|
use crate::utils::fs::{canonicalize_path, find_project_root};
|
||||||
use crate::utils::text::{BOLD_CYAN, BOLD_GREEN, BOLD_YELLOW, colored, printc};
|
use crate::utils::log::sprintln;
|
||||||
use std::io::IsTerminal;
|
use std::io::IsTerminal;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::sync::{Arc, atomic::AtomicBool};
|
use std::sync::{Arc, atomic::AtomicBool};
|
||||||
@@ -37,8 +40,8 @@ use std::sync::{Arc, atomic::AtomicBool};
|
|||||||
pub use crate::core::build::get_build_string_with_profile;
|
pub use crate::core::build::get_build_string_with_profile;
|
||||||
|
|
||||||
/// Formats a left-aligned status verb with the given style for CLI output.
|
/// Formats a left-aligned status verb with the given style for CLI output.
|
||||||
fn status(verb: &str, style: &str) -> String {
|
fn status(verb: &str, style: Style) -> String {
|
||||||
colored(&format!("{verb:<9}"), style)
|
format!("{verb:<9}").style(style).to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// CLI build reporter that prints human-readable progress to stderr/stdout.
|
/// CLI build reporter that prints human-readable progress to stderr/stdout.
|
||||||
@@ -51,7 +54,7 @@ impl CliReporter {
|
|||||||
/// - `verb`: Short status label (e.g. `"target"`, `"dep"`).
|
/// - `verb`: Short status label (e.g. `"target"`, `"dep"`).
|
||||||
/// - `style`: Color/style constant for the verb.
|
/// - `style`: Color/style constant for the verb.
|
||||||
/// - `rest`: Remaining message text after the verb.
|
/// - `rest`: Remaining message text after the verb.
|
||||||
fn line(&self, verb: &str, style: &str, rest: &str) {
|
fn line(&self, verb: &str, style: Style, rest: &str) {
|
||||||
eprintln!(" {} {}", status(verb, style), rest);
|
eprintln!(" {} {}", status(verb, style), rest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -95,12 +98,12 @@ impl BuildReporter for CliReporter {
|
|||||||
common::finish_progress_line();
|
common::finish_progress_line();
|
||||||
// Only announce deps that were actually rebuilt this run.
|
// Only announce deps that were actually rebuilt this run.
|
||||||
if rebuilt {
|
if rebuilt {
|
||||||
self.line("ready", BOLD_GREEN, &format!("{name} v{version}"));
|
self.line("ready", SUCCESS_ST, &format!("{name} v{version}"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BuildEvent::Compiling { name, version } => {
|
BuildEvent::Compiling { name, version } => {
|
||||||
common::finish_progress_line();
|
common::finish_progress_line();
|
||||||
let label = format!(" {} {} v{}", status("compile", BOLD_GREEN), name, version);
|
let label = format!(" {} {} v{}", status("compile", SUCCESS_ST), name, version);
|
||||||
// Terminals use an in-place progress line; non-TTY gets a plain log line.
|
// Terminals use an in-place progress line; non-TTY gets a plain log line.
|
||||||
common::set_progress_label(Some(label.clone()));
|
common::set_progress_label(Some(label.clone()));
|
||||||
if !std::io::stderr().is_terminal() {
|
if !std::io::stderr().is_terminal() {
|
||||||
@@ -113,7 +116,7 @@ impl BuildReporter for CliReporter {
|
|||||||
}
|
}
|
||||||
BuildEvent::Finished { secs } => {
|
BuildEvent::Finished { secs } => {
|
||||||
common::finish_progress_line();
|
common::finish_progress_line();
|
||||||
self.line("done", BOLD_GREEN, &format!("in {secs}s"));
|
self.line("done", SUCCESS_ST, &format!("in {secs}s"));
|
||||||
}
|
}
|
||||||
BuildEvent::CompilerOutput { stream, text } => {
|
BuildEvent::CompilerOutput { stream, text } => {
|
||||||
// Pause the progress spinner so compiler text is not overwritten.
|
// Pause the progress spinner so compiler text is not overwritten.
|
||||||
@@ -141,16 +144,16 @@ impl BuildReporter for CliReporter {
|
|||||||
/// Process exit code: `0` on success or help, non-zero on failure.
|
/// Process exit code: `0` on success or help, non-zero on failure.
|
||||||
pub fn build(args: &[String]) -> i32 {
|
pub fn build(args: &[String]) -> i32 {
|
||||||
if args.first().is_some_and(|a| a == "--help") {
|
if args.first().is_some_and(|a| a == "--help") {
|
||||||
printc("USAGE:", BOLD_GREEN);
|
sprintln!(HELP_SECTION_TITLE_ST, "USAGE:");
|
||||||
printc(
|
sprintln!(
|
||||||
" dcr build [--debug | --release] [--target <triple>] [--force] [--clean] [--verbose] [--print-artifact-path]",
|
HELP_EXAMPLES_ST,
|
||||||
BOLD_CYAN,
|
" dcr build [--debug | --release] [--target <triple>] [--force] [--clean] [--verbose] [--print-artifact-path]"
|
||||||
);
|
);
|
||||||
println!();
|
println!();
|
||||||
printc("DESCRIPTION:", BOLD_GREEN);
|
sprintln!(HELP_SECTION_TITLE_ST, "DESCRIPTION:");
|
||||||
println!(" Compiles the project. Default profile is --debug.");
|
println!(" Compiles the project. Default profile is --debug.");
|
||||||
println!();
|
println!();
|
||||||
printc("OPTIONS:", BOLD_GREEN);
|
sprintln!(HELP_SECTION_TITLE_ST, "OPTIONS:");
|
||||||
println!(" --debug Build with debug profile (default)");
|
println!(" --debug Build with debug profile (default)");
|
||||||
println!(" --release Build with release profile");
|
println!(" --release Build with release profile");
|
||||||
println!(" --target <triple> Cross-compile for the given target");
|
println!(" --target <triple> Cross-compile for the given target");
|
||||||
|
|||||||
@@ -20,8 +20,11 @@ use crate::prelude::*;
|
|||||||
use crate::core::build_config::Config;
|
use crate::core::build_config::Config;
|
||||||
use crate::core::workspace::parse_workspace;
|
use crate::core::workspace::parse_workspace;
|
||||||
use crate::utils::build::{default_profile_flags, default_target_triple, parse_version_info};
|
use crate::utils::build::{default_profile_flags, default_target_triple, parse_version_info};
|
||||||
|
use crate::utils::cli_styles::{
|
||||||
|
BOLD_GREEN, Colorize, HELP_EXAMPLES_ST, HELP_SECTION_TITLE_ST, SUCCESS_ST,
|
||||||
|
};
|
||||||
use crate::utils::fs::{check_dir, find_project_root, with_dir};
|
use crate::utils::fs::{check_dir, find_project_root, with_dir};
|
||||||
use crate::utils::text::{BOLD_CYAN, BOLD_GREEN, colored, printc};
|
use crate::utils::log::sprintln;
|
||||||
use glob::glob;
|
use glob::glob;
|
||||||
use std::{fs, path::Path};
|
use std::{fs, path::Path};
|
||||||
|
|
||||||
@@ -36,16 +39,16 @@ use std::{fs, path::Path};
|
|||||||
/// Process exit code: `0` on success, `1` on failure.
|
/// Process exit code: `0` on success, `1` on failure.
|
||||||
pub fn clean(args: &[String]) -> i32 {
|
pub fn clean(args: &[String]) -> i32 {
|
||||||
if args.first().is_some_and(|a| a == "--help") {
|
if args.first().is_some_and(|a| a == "--help") {
|
||||||
printc("USAGE:", BOLD_GREEN);
|
sprintln!(HELP_SECTION_TITLE_ST, "USAGE:");
|
||||||
printc(
|
sprintln!(
|
||||||
" dcr clean [--debug | --release] [--target <triple>] [--all]",
|
HELP_EXAMPLES_ST,
|
||||||
BOLD_CYAN,
|
" dcr clean [--debug | --release] [--target <triple>] [--all]"
|
||||||
);
|
);
|
||||||
println!();
|
println!();
|
||||||
printc("DESCRIPTION:", BOLD_GREEN);
|
sprintln!(HELP_SECTION_TITLE_ST, "DESCRIPTION:");
|
||||||
println!(" Removes build artifacts from the target directory.");
|
println!(" Removes build artifacts from the target directory.");
|
||||||
println!();
|
println!();
|
||||||
printc("OPTIONS:", BOLD_GREEN);
|
sprintln!(HELP_SECTION_TITLE_ST, "OPTIONS:");
|
||||||
println!(" --debug Clean debug artifacts (default)");
|
println!(" --debug Clean debug artifacts (default)");
|
||||||
println!(" --release Clean release artifacts");
|
println!(" --release Clean release artifacts");
|
||||||
println!(" --target <triple> Clean artifacts for a specific target");
|
println!(" --target <triple> Clean artifacts for a specific target");
|
||||||
@@ -210,10 +213,7 @@ fn clean_project_at(
|
|||||||
if !items.contains(&"dcr.toml".to_string()) {
|
if !items.contains(&"dcr.toml".to_string()) {
|
||||||
return Err("dcr.toml file not found".to_string());
|
return Err("dcr.toml file not found".to_string());
|
||||||
}
|
}
|
||||||
println!(
|
println!(" Cleaning project `{}`", project_name.style(BOLD_GREEN));
|
||||||
" Cleaning project `{}`",
|
|
||||||
colored(&project_name, BOLD_GREEN)
|
|
||||||
);
|
|
||||||
if let Some(profile) = profile {
|
if let Some(profile) = profile {
|
||||||
let target_dir = if let Some(t) = target {
|
let target_dir = if let Some(t) = target {
|
||||||
format!("target/{t}/{profile}")
|
format!("target/{t}/{profile}")
|
||||||
@@ -231,14 +231,14 @@ fn clean_project_at(
|
|||||||
if !dir_exists {
|
if !dir_exists {
|
||||||
warn!("Directory target/{target_dir} not found");
|
warn!("Directory target/{target_dir} not found");
|
||||||
} else {
|
} else {
|
||||||
println!(" Profile: {}", colored(profile, BOLD_GREEN));
|
println!(" Profile: {}", profile.style(BOLD_GREEN));
|
||||||
if let Some(t) = target {
|
if let Some(t) = target {
|
||||||
println!(" Target: {}", colored(t, BOLD_GREEN));
|
println!(" Target: {}", t.style(BOLD_GREEN));
|
||||||
}
|
}
|
||||||
let _ = fs::remove_dir_all(&target_dir);
|
let _ = fs::remove_dir_all(&target_dir);
|
||||||
println!(
|
println!(
|
||||||
"{} Removed directory {}",
|
"{} Removed directory {}",
|
||||||
colored("\n ✔", BOLD_GREEN),
|
"\n ✔".style(SUCCESS_ST),
|
||||||
target_dir
|
target_dir
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -248,10 +248,7 @@ fn clean_project_at(
|
|||||||
|
|
||||||
if items.contains(&"target".to_string()) {
|
if items.contains(&"target".to_string()) {
|
||||||
let _ = fs::remove_dir_all("target");
|
let _ = fs::remove_dir_all("target");
|
||||||
println!(
|
println!("{} Removed directory target", "\n ✔".style(SUCCESS_ST));
|
||||||
"{} Removed directory target",
|
|
||||||
colored("\n ✔", BOLD_GREEN)
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
warn!("Directory target not found");
|
warn!("Directory target not found");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,8 @@
|
|||||||
|
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
use crate::utils::text::{BOLD_CYAN, BOLD_GREEN, printc};
|
use crate::utils::cli_styles::{HELP_EXAMPLES_ST, HELP_SECTION_TITLE_ST};
|
||||||
|
use crate::utils::log::sprintln;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
@@ -56,10 +57,10 @@ struct ReleaseAsset {
|
|||||||
/// `0` on success / already up to date / pacman-managed refuse; `1` on error.
|
/// `0` on success / already up to date / pacman-managed refuse; `1` on error.
|
||||||
pub fn flag_update(args: &[String]) -> i32 {
|
pub fn flag_update(args: &[String]) -> i32 {
|
||||||
if args.first().is_some_and(|a| a == "--help") {
|
if args.first().is_some_and(|a| a == "--help") {
|
||||||
printc("USAGE:", BOLD_GREEN);
|
sprintln!(HELP_SECTION_TITLE_ST, "USAGE:");
|
||||||
printc(" dcr --update", BOLD_CYAN);
|
sprintln!(HELP_EXAMPLES_ST, " dcr --update");
|
||||||
println!();
|
println!();
|
||||||
printc("DESCRIPTION:", BOLD_GREEN);
|
sprintln!(HELP_SECTION_TITLE_ST, "DESCRIPTION:");
|
||||||
println!(" Updates DCR to the latest version from GitHub Releases.");
|
println!(" Updates DCR to the latest version from GitHub Releases.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,10 @@
|
|||||||
|
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
use crate::utils::text::{BOLD_CYAN, BOLD_GREEN, colored, printc};
|
use crate::utils::cli_styles::{
|
||||||
|
BOLD_GREEN, Colorize, HELP_EXAMPLES_ST, HELP_SECTION_TITLE_ST, SUCCESS_ST,
|
||||||
|
};
|
||||||
|
use crate::utils::log::sprintln;
|
||||||
use glob::glob;
|
use glob::glob;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
|
||||||
@@ -29,10 +32,10 @@ use std::process::Command;
|
|||||||
/// If the first argument is `--help`, prints usage information and returns 0.
|
/// If the first argument is `--help`, prints usage information and returns 0.
|
||||||
pub fn fmt(args: &[String]) -> i32 {
|
pub fn fmt(args: &[String]) -> i32 {
|
||||||
if args.first().is_some_and(|a| a == "--help") {
|
if args.first().is_some_and(|a| a == "--help") {
|
||||||
printc("USAGE:", BOLD_GREEN);
|
sprintln!(HELP_SECTION_TITLE_ST, "USAGE:");
|
||||||
printc(" dcr fmt", BOLD_CYAN);
|
sprintln!(HELP_EXAMPLES_ST, " dcr fmt");
|
||||||
println!();
|
println!();
|
||||||
printc("DESCRIPTION:", BOLD_GREEN);
|
sprintln!(HELP_SECTION_TITLE_ST, "DESCRIPTION:");
|
||||||
println!(" Formats all C/C++ source files using clang-format.");
|
println!(" Formats all C/C++ source files using clang-format.");
|
||||||
println!(" Scans src/ and tests/ directories recursively.");
|
println!(" Scans src/ and tests/ directories recursively.");
|
||||||
return 0;
|
return 0;
|
||||||
@@ -70,14 +73,14 @@ pub fn fmt(args: &[String]) -> i32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if files.is_empty() {
|
if files.is_empty() {
|
||||||
println!(" {} No files to format", colored("Format", BOLD_GREEN));
|
println!(" {} No files to format", "Format".style(BOLD_GREEN));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Format the collected files
|
// Format the collected files
|
||||||
println!(
|
println!(
|
||||||
" {} {} files",
|
" {} {} files",
|
||||||
colored("Formatting", BOLD_GREEN),
|
"Formatting".style(BOLD_GREEN),
|
||||||
files.len()
|
files.len()
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -85,7 +88,7 @@ pub fn fmt(args: &[String]) -> i32 {
|
|||||||
|
|
||||||
match status {
|
match status {
|
||||||
Ok(s) if s.success() => {
|
Ok(s) if s.success() => {
|
||||||
println!(" {} successful", colored("Format", BOLD_GREEN));
|
println!(" {} successful", "Format".style(SUCCESS_ST));
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
Ok(s) => {
|
Ok(s) => {
|
||||||
|
|||||||
@@ -28,10 +28,11 @@ use crate::utils::build::{
|
|||||||
get_list_with_profile, get_string_with_profile, normalize_kind, normalize_platform,
|
get_list_with_profile, get_string_with_profile, normalize_kind, normalize_platform,
|
||||||
resolve_artifact_target_dir, resolve_compiler, resolve_pkg_config_flags_lossy,
|
resolve_artifact_target_dir, resolve_compiler, resolve_pkg_config_flags_lossy,
|
||||||
};
|
};
|
||||||
|
use crate::utils::cli_styles::{HELP_EXAMPLES_ST, HELP_SECTION_TITLE_ST};
|
||||||
use crate::utils::fs::{
|
use crate::utils::fs::{
|
||||||
absolute_join, atomic_write, canonicalize_path, ensure_dcr_dir, find_project_root,
|
absolute_join, atomic_write, canonicalize_path, ensure_dcr_dir, find_project_root,
|
||||||
};
|
};
|
||||||
use crate::utils::text::{BOLD_CYAN, BOLD_GREEN, printc};
|
use crate::utils::log::sprintln;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::time::{SystemTime, UNIX_EPOCH};
|
use std::time::{SystemTime, UNIX_EPOCH};
|
||||||
|
|
||||||
@@ -252,29 +253,29 @@ pub struct ProjectInfo {
|
|||||||
pub fn r#gen(args: &[String]) -> i32 {
|
pub fn r#gen(args: &[String]) -> i32 {
|
||||||
let subcommand = match args.first() {
|
let subcommand = match args.first() {
|
||||||
Some(s) if s == "--help" => {
|
Some(s) if s == "--help" => {
|
||||||
printc("USAGE:", BOLD_GREEN);
|
sprintln!(HELP_SECTION_TITLE_ST, "USAGE:");
|
||||||
printc(" dcr gen <subcommand>", BOLD_CYAN);
|
sprintln!(HELP_EXAMPLES_ST, " dcr gen <subcommand>");
|
||||||
println!();
|
println!();
|
||||||
printc("DESCRIPTION:", BOLD_GREEN);
|
sprintln!(HELP_SECTION_TITLE_ST, "DESCRIPTION:");
|
||||||
println!(" Generates IDE and tooling integration files.");
|
println!(" Generates IDE and tooling integration files.");
|
||||||
println!();
|
println!();
|
||||||
printc("SUBCOMMANDS:", BOLD_GREEN);
|
sprintln!(HELP_SECTION_TITLE_ST, "SUBCOMMANDS:");
|
||||||
println!(" project-info Print project metadata as JSON");
|
println!(" project-info Print project metadata as JSON");
|
||||||
println!(" compile-commands Generate .dcr/compile_commands.json");
|
println!(" compile-commands Generate .dcr/compile_commands.json");
|
||||||
println!(" vscode Generate .vscode/ integration files");
|
println!(" vscode Generate .vscode/ integration files");
|
||||||
println!(" clion Generate .idea/ integration files");
|
println!(" clion Generate .idea/ integration files");
|
||||||
println!();
|
println!();
|
||||||
printc("OPTIONS:", BOLD_GREEN);
|
sprintln!(HELP_SECTION_TITLE_ST, "OPTIONS:");
|
||||||
println!(" --debug | --release Profile (default: debug)");
|
println!(" --debug | --release Profile (default: debug)");
|
||||||
println!(" --quiet | -q Suppress success messages on stdout");
|
println!(" --quiet | -q Suppress success messages on stdout");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
Some(s) => s.as_str(),
|
Some(s) => s.as_str(),
|
||||||
None => {
|
None => {
|
||||||
printc("USAGE:", BOLD_GREEN);
|
sprintln!(HELP_SECTION_TITLE_ST, "USAGE:");
|
||||||
printc(" dcr gen <subcommand>", BOLD_CYAN);
|
sprintln!(HELP_EXAMPLES_ST, " dcr gen <subcommand>");
|
||||||
println!();
|
println!();
|
||||||
printc("SUBCOMMANDS:", BOLD_GREEN);
|
sprintln!(HELP_SECTION_TITLE_ST, "SUBCOMMANDS:");
|
||||||
println!(" project-info Print project metadata as JSON");
|
println!(" project-info Print project metadata as JSON");
|
||||||
println!(" compile-commands Generate .dcr/compile_commands.json");
|
println!(" compile-commands Generate .dcr/compile_commands.json");
|
||||||
println!(" vscode Generate .vscode/ integration files");
|
println!(" vscode Generate .vscode/ integration files");
|
||||||
|
|||||||
@@ -15,7 +15,8 @@
|
|||||||
// 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::text::{BOLD_CYAN, BOLD_GREEN, printc};
|
use crate::utils::cli_styles::{HELP_EXAMPLES_ST, HELP_SECTION_TITLE_ST};
|
||||||
|
use crate::utils::log::sprintln;
|
||||||
|
|
||||||
/// Displays the help information for the DCR CLI tool.
|
/// Displays the help information for the DCR CLI tool.
|
||||||
///
|
///
|
||||||
@@ -27,10 +28,10 @@ pub fn help() -> i32 {
|
|||||||
println!("DCR (Dexoron Cargo Realization)");
|
println!("DCR (Dexoron Cargo Realization)");
|
||||||
println!("C project manager inspired by Cargo.");
|
println!("C project manager inspired by Cargo.");
|
||||||
println!();
|
println!();
|
||||||
printc("USAGE:", BOLD_GREEN);
|
sprintln!(HELP_SECTION_TITLE_ST, "USAGE:");
|
||||||
printc(" dcr <command> [options]", BOLD_CYAN);
|
sprintln!(HELP_EXAMPLES_ST, " dcr <command> [options]");
|
||||||
println!();
|
println!();
|
||||||
printc("COMMANDS:", BOLD_GREEN);
|
sprintln!(HELP_SECTION_TITLE_ST, "COMMANDS:");
|
||||||
println!(" new <name> Create a new project");
|
println!(" new <name> Create a new project");
|
||||||
println!(" init Initialize the current directory as a project");
|
println!(" init Initialize the current directory as a project");
|
||||||
println!(" build [--profile] Build the project (default: --debug)");
|
println!(" build [--profile] Build the project (default: --debug)");
|
||||||
@@ -43,24 +44,24 @@ pub fn help() -> i32 {
|
|||||||
println!(" setup Show configured package registries");
|
println!(" setup Show configured package registries");
|
||||||
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);
|
sprintln!(HELP_SECTION_TITLE_ST, "FLAGS:");
|
||||||
println!(" --help Show command help");
|
println!(" --help Show command help");
|
||||||
println!(" --update Update dcr to the latest version");
|
println!(" --update Update dcr to the latest version");
|
||||||
println!(" --version Show dcr version");
|
println!(" --version Show dcr version");
|
||||||
println!();
|
println!();
|
||||||
printc("OPTIONS:", BOLD_GREEN);
|
sprintln!(HELP_SECTION_TITLE_ST, "OPTIONS:");
|
||||||
println!(" --debug Use debug profile");
|
println!(" --debug Use debug profile");
|
||||||
println!(" --release Use release profile");
|
println!(" --release Use release profile");
|
||||||
println!(" --force Force rebuild (build/run)");
|
println!(" --force Force rebuild (build/run)");
|
||||||
println!(" --clean Clean before build (build/run)");
|
println!(" --clean Clean before build (build/run)");
|
||||||
println!(" --all Clean all workspace members (clean)");
|
println!(" --all Clean all workspace members (clean)");
|
||||||
println!();
|
println!();
|
||||||
printc("EXAMPLES:", BOLD_GREEN);
|
sprintln!(HELP_SECTION_TITLE_ST, "EXAMPLES:");
|
||||||
printc(" dcr new hello", BOLD_CYAN);
|
sprintln!(HELP_EXAMPLES_ST, " dcr new hello");
|
||||||
printc(" dcr build --release", BOLD_CYAN);
|
sprintln!(HELP_EXAMPLES_ST, " dcr build --release");
|
||||||
printc(" dcr run --debug", BOLD_CYAN);
|
sprintln!(HELP_EXAMPLES_ST, " dcr run --debug");
|
||||||
println!();
|
println!();
|
||||||
printc("TIP:", BOLD_GREEN);
|
sprintln!(HELP_SECTION_TITLE_ST, "TIP:");
|
||||||
println!(" Run 'dcr <command> --help' for command-specific help.");
|
println!(" Run 'dcr <command> --help' for command-specific help.");
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,8 +20,11 @@ use crate::prelude::*;
|
|||||||
use crate::config::FILE_MAIN_C;
|
use crate::config::FILE_MAIN_C;
|
||||||
use crate::core::build_config::{Config, validate_package_name};
|
use crate::core::build_config::{Config, validate_package_name};
|
||||||
use crate::core::vcs::VcsKind;
|
use crate::core::vcs::VcsKind;
|
||||||
|
use crate::utils::cli_styles::{
|
||||||
|
BOLD_CYAN, BOLD_GREEN, Colorize, HELP_EXAMPLES_ST, HELP_SECTION_TITLE_ST, SUCCESS_ST,
|
||||||
|
};
|
||||||
use crate::utils::fs::check_dir;
|
use crate::utils::fs::check_dir;
|
||||||
use crate::utils::text::{BOLD_CYAN, BOLD_GREEN, colored, printc};
|
use crate::utils::log::sprintln;
|
||||||
use std::{fs, io::Write};
|
use std::{fs, io::Write};
|
||||||
|
|
||||||
/// Initializes the current working directory as a new DCR project.
|
/// Initializes the current working directory as a new DCR project.
|
||||||
@@ -30,10 +33,10 @@ use std::{fs, io::Write};
|
|||||||
/// `dcr.toml` and `src/main.c`, and configures version control (Git) integration if applicable.
|
/// `dcr.toml` and `src/main.c`, and configures version control (Git) integration if applicable.
|
||||||
pub fn init(args: &[String]) -> i32 {
|
pub fn init(args: &[String]) -> i32 {
|
||||||
if args.first().is_some_and(|a| a == "--help") {
|
if args.first().is_some_and(|a| a == "--help") {
|
||||||
printc("USAGE:", BOLD_GREEN);
|
sprintln!(HELP_SECTION_TITLE_ST, "USAGE:");
|
||||||
printc(" dcr init [--vcs <git|none>]", BOLD_CYAN);
|
sprintln!(HELP_EXAMPLES_ST, " dcr init [--vcs <git|none>]");
|
||||||
println!();
|
println!();
|
||||||
printc("DESCRIPTION:", BOLD_GREEN);
|
sprintln!(HELP_SECTION_TITLE_ST, "DESCRIPTION:");
|
||||||
println!(" Initializes the current directory as a DCR project.");
|
println!(" Initializes the current directory as a DCR project.");
|
||||||
println!(" The directory must be empty.");
|
println!(" The directory must be empty.");
|
||||||
return 0;
|
return 0;
|
||||||
@@ -78,7 +81,7 @@ pub fn init(args: &[String]) -> i32 {
|
|||||||
if let Err(e) = validate_package_name(&project_name) {
|
if let Err(e) = validate_package_name(&project_name) {
|
||||||
error!(
|
error!(
|
||||||
"Invalid project name `{}`: {e}",
|
"Invalid project name `{}`: {e}",
|
||||||
colored(&project_name, BOLD_CYAN),
|
project_name.style(BOLD_CYAN),
|
||||||
);
|
);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -95,8 +98,8 @@ pub fn init(args: &[String]) -> i32 {
|
|||||||
}
|
}
|
||||||
println!(
|
println!(
|
||||||
" {} Created file {}",
|
" {} Created file {}",
|
||||||
colored("✔", BOLD_GREEN),
|
"✔".style(SUCCESS_ST),
|
||||||
colored("dcr.toml", BOLD_CYAN)
|
"dcr.toml".style(BOLD_CYAN)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Create src directory and write template main.c file.
|
// Create src directory and write template main.c file.
|
||||||
@@ -117,8 +120,8 @@ pub fn init(args: &[String]) -> i32 {
|
|||||||
}
|
}
|
||||||
println!(
|
println!(
|
||||||
" {} Created file {}",
|
" {} Created file {}",
|
||||||
colored("✔", BOLD_GREEN),
|
"✔".style(SUCCESS_ST),
|
||||||
colored("src/main.c", BOLD_CYAN)
|
"src/main.c".style(BOLD_CYAN)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Resolve target VCS provider or detect existing repositories.
|
// Resolve target VCS provider or detect existing repositories.
|
||||||
@@ -143,10 +146,7 @@ pub fn init(args: &[String]) -> i32 {
|
|||||||
if let Err(e) = crate::core::vcs::init_vcs(vcs_kind, project_path) {
|
if let Err(e) = crate::core::vcs::init_vcs(vcs_kind, project_path) {
|
||||||
warn!("Failed to initialize git repository: {e}");
|
warn!("Failed to initialize git repository: {e}");
|
||||||
} else {
|
} else {
|
||||||
println!(
|
println!(" {} Initialized git repository", "✔".style(SUCCESS_ST));
|
||||||
" {} Initialized git repository",
|
|
||||||
colored("✔", BOLD_GREEN)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
warn!(
|
warn!(
|
||||||
@@ -161,9 +161,9 @@ pub fn init(args: &[String]) -> i32 {
|
|||||||
|
|
||||||
println!(
|
println!(
|
||||||
"Project `{}` successfully created\n",
|
"Project `{}` successfully created\n",
|
||||||
colored(project_name.as_str(), BOLD_GREEN)
|
project_name.style(SUCCESS_ST)
|
||||||
);
|
);
|
||||||
printc("Next step:", BOLD_GREEN);
|
sprintln!(BOLD_GREEN, "Next step:");
|
||||||
printc(" dcr run", BOLD_CYAN);
|
sprintln!(BOLD_CYAN, " dcr run");
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,8 +20,11 @@ use crate::prelude::*;
|
|||||||
use crate::core::build::common;
|
use crate::core::build::common;
|
||||||
use crate::core::build_config::Config;
|
use crate::core::build_config::Config;
|
||||||
use crate::utils::build::{get_bool_with_profile, get_list_with_profile};
|
use crate::utils::build::{get_bool_with_profile, get_list_with_profile};
|
||||||
|
use crate::utils::cli_styles::{
|
||||||
|
ALERT_ST, BOLD_GREEN, Colorize, HELP_EXAMPLES_ST, HELP_SECTION_TITLE_ST, SUCCESS_ST,
|
||||||
|
};
|
||||||
use crate::utils::fs::find_project_root;
|
use crate::utils::fs::find_project_root;
|
||||||
use crate::utils::text::{BOLD_CYAN, BOLD_GREEN, BOLD_YELLOW, colored, printc};
|
use crate::utils::log::sprintln;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
|
||||||
@@ -30,14 +33,14 @@ use std::process::Command;
|
|||||||
/// Scans source roots (configurable via build.roots) and tests/ directory.
|
/// Scans source roots (configurable via build.roots) and tests/ directory.
|
||||||
pub fn lint(args: &[String]) -> i32 {
|
pub fn lint(args: &[String]) -> i32 {
|
||||||
if args.first().is_some_and(|a| a == "--help") {
|
if args.first().is_some_and(|a| a == "--help") {
|
||||||
printc("USAGE:", BOLD_GREEN);
|
sprintln!(HELP_SECTION_TITLE_ST, "USAGE:");
|
||||||
printc(" dcr lint [--fix]", BOLD_CYAN);
|
sprintln!(HELP_EXAMPLES_ST, " dcr lint [--fix]");
|
||||||
println!();
|
println!();
|
||||||
printc("DESCRIPTION:", BOLD_GREEN);
|
sprintln!(HELP_SECTION_TITLE_ST, "DESCRIPTION:");
|
||||||
println!(" Runs clang-tidy on all C/C++ source files.");
|
println!(" Runs clang-tidy on all C/C++ source files.");
|
||||||
println!(" Scans source roots (configurable via build.roots) and tests/ directory.");
|
println!(" Scans source roots (configurable via build.roots) and tests/ directory.");
|
||||||
println!();
|
println!();
|
||||||
printc("OPTIONS:", BOLD_GREEN);
|
sprintln!(HELP_SECTION_TITLE_ST, "OPTIONS:");
|
||||||
println!(" --fix Apply clang-tidy suggestions automatically");
|
println!(" --fix Apply clang-tidy suggestions automatically");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -117,13 +120,13 @@ pub fn lint(args: &[String]) -> i32 {
|
|||||||
files.sort();
|
files.sort();
|
||||||
|
|
||||||
if files.is_empty() {
|
if files.is_empty() {
|
||||||
println!(" {} No files to lint", colored("Lint", BOLD_GREEN));
|
println!(" {} No files to lint", "Lint".style(BOLD_GREEN));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
println!(
|
println!(
|
||||||
" {} {} files {}",
|
" {} {} files {}",
|
||||||
colored("Linting", BOLD_GREEN),
|
"Linting".style(BOLD_GREEN),
|
||||||
files.len(),
|
files.len(),
|
||||||
if do_fix { "(with --fix)" } else { "" }
|
if do_fix { "(with --fix)" } else { "" }
|
||||||
);
|
);
|
||||||
@@ -161,13 +164,13 @@ pub fn lint(args: &[String]) -> i32 {
|
|||||||
if issue_count > 0 {
|
if issue_count > 0 {
|
||||||
total_issues += issue_count as u32;
|
total_issues += issue_count as u32;
|
||||||
failed += 1;
|
failed += 1;
|
||||||
print!(" {} ", colored("×", BOLD_YELLOW));
|
print!(" {} ", "×".style(ALERT_ST));
|
||||||
println!("{} ({} issues)", file, issue_count);
|
println!("{} ({} issues)", file, issue_count);
|
||||||
for issue in &issues {
|
for issue in &issues {
|
||||||
println!(" {}", issue);
|
println!(" {}", issue);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
print!(" {} ", colored("✓", BOLD_GREEN));
|
print!(" {} ", "✓".style(SUCCESS_ST));
|
||||||
println!("{}", file);
|
println!("{}", file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -178,13 +181,13 @@ pub fn lint(args: &[String]) -> i32 {
|
|||||||
if failed == 0 {
|
if failed == 0 {
|
||||||
println!(
|
println!(
|
||||||
" {} {} files, no issues",
|
" {} {} files, no issues",
|
||||||
colored("Lint", BOLD_GREEN),
|
"Lint".style(SUCCESS_ST),
|
||||||
total
|
total
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
println!(
|
println!(
|
||||||
" {} {}/{} files passed, {} issues found",
|
" {} {}/{} files passed, {} issues found",
|
||||||
colored("Lint", BOLD_YELLOW),
|
"Lint".style(ALERT_ST),
|
||||||
passed,
|
passed,
|
||||||
total,
|
total,
|
||||||
total_issues
|
total_issues
|
||||||
|
|||||||
@@ -20,8 +20,11 @@ use crate::prelude::*;
|
|||||||
use crate::config::FILE_MAIN_C;
|
use crate::config::FILE_MAIN_C;
|
||||||
use crate::core::build_config::{Config, validate_package_name};
|
use crate::core::build_config::{Config, validate_package_name};
|
||||||
use crate::core::vcs::VcsKind;
|
use crate::core::vcs::VcsKind;
|
||||||
|
use crate::utils::cli_styles::{
|
||||||
|
BOLD_CYAN, BOLD_GREEN, Colorize, HELP_EXAMPLES_ST, HELP_SECTION_TITLE_ST, SUCCESS_ST,
|
||||||
|
};
|
||||||
use crate::utils::fs::check_dir;
|
use crate::utils::fs::check_dir;
|
||||||
use crate::utils::text::{BOLD_CYAN, BOLD_GREEN, colored, printc};
|
use crate::utils::log::sprintln;
|
||||||
use std::{fs, io::Write};
|
use std::{fs, io::Write};
|
||||||
|
|
||||||
/// Executes the `dcr new` command to scaffold a new C/C++ project directory structure.
|
/// Executes the `dcr new` command to scaffold a new C/C++ project directory structure.
|
||||||
@@ -30,10 +33,10 @@ use std::{fs, io::Write};
|
|||||||
/// template source file generation (`src/main.c`), and initial VCS setup.
|
/// template source file generation (`src/main.c`), and initial VCS setup.
|
||||||
pub fn new(args: &[String]) -> i32 {
|
pub fn new(args: &[String]) -> i32 {
|
||||||
if args.first().is_some_and(|a| a == "--help") {
|
if args.first().is_some_and(|a| a == "--help") {
|
||||||
printc("USAGE:", BOLD_GREEN);
|
sprintln!(HELP_SECTION_TITLE_ST, "USAGE:");
|
||||||
printc(" dcr new <name> [--vcs <git|none>]", BOLD_CYAN);
|
sprintln!(HELP_EXAMPLES_ST, " dcr new <name> [--vcs <git|none>]");
|
||||||
println!();
|
println!();
|
||||||
printc("DESCRIPTION:", BOLD_GREEN);
|
sprintln!(HELP_SECTION_TITLE_ST, "DESCRIPTION:");
|
||||||
println!(" Creates a new C/C++ project with the given name.");
|
println!(" Creates a new C/C++ project with the given name.");
|
||||||
println!(" The name may only contain ASCII letters, digits, '_' and '-'.");
|
println!(" The name may only contain ASCII letters, digits, '_' and '-'.");
|
||||||
return 0;
|
return 0;
|
||||||
@@ -70,15 +73,12 @@ pub fn new(args: &[String]) -> i32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let project_name = &clean_args[0];
|
let project_name = &clean_args[0];
|
||||||
println!(
|
println!("Creating a Project `{}`...", project_name.style(BOLD_CYAN));
|
||||||
"Creating a Project `{}`...",
|
|
||||||
colored(project_name, BOLD_CYAN)
|
|
||||||
);
|
|
||||||
|
|
||||||
if let Err(e) = validate_package_name(project_name) {
|
if let Err(e) = validate_package_name(project_name) {
|
||||||
error!(
|
error!(
|
||||||
"Invalid project name `{}`: {e}",
|
"Invalid project name `{}`: {e}",
|
||||||
colored(project_name, BOLD_CYAN),
|
project_name.style(BOLD_CYAN),
|
||||||
);
|
);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -86,12 +86,12 @@ pub fn new(args: &[String]) -> i32 {
|
|||||||
if items.contains(project_name) {
|
if items.contains(project_name) {
|
||||||
error!(
|
error!(
|
||||||
"Directory `{}` already exists\n",
|
"Directory `{}` already exists\n",
|
||||||
colored(project_name, BOLD_CYAN)
|
project_name.style(BOLD_CYAN)
|
||||||
);
|
);
|
||||||
printc("Hint:", BOLD_CYAN);
|
sprintln!(BOLD_CYAN, "Hint:");
|
||||||
println!(
|
println!(
|
||||||
" Use `{}` to initialize an existing project\n or specify a different project name",
|
" Use `{}` to initialize an existing project\n or specify a different project name",
|
||||||
colored("dcr init", BOLD_CYAN)
|
"dcr init".style(BOLD_CYAN)
|
||||||
);
|
);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -102,7 +102,7 @@ pub fn new(args: &[String]) -> i32 {
|
|||||||
}
|
}
|
||||||
println!(
|
println!(
|
||||||
" {} Directory created {}",
|
" {} Directory created {}",
|
||||||
colored("✔", BOLD_GREEN),
|
"✔".style(SUCCESS_ST),
|
||||||
project_name
|
project_name
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -114,8 +114,8 @@ pub fn new(args: &[String]) -> i32 {
|
|||||||
}
|
}
|
||||||
println!(
|
println!(
|
||||||
" {} Created file {}",
|
" {} Created file {}",
|
||||||
colored("✔", BOLD_GREEN),
|
"✔".style(SUCCESS_ST),
|
||||||
colored("dcr.toml", BOLD_CYAN)
|
"dcr.toml".style(BOLD_CYAN)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Generate src directory and populate initial main.c file.
|
// Generate src directory and populate initial main.c file.
|
||||||
@@ -137,8 +137,8 @@ pub fn new(args: &[String]) -> i32 {
|
|||||||
}
|
}
|
||||||
println!(
|
println!(
|
||||||
" {} Created file {}",
|
" {} Created file {}",
|
||||||
colored("✔", BOLD_GREEN),
|
"✔".style(SUCCESS_ST),
|
||||||
colored("src/main.c", BOLD_CYAN)
|
"src/main.c".style(BOLD_CYAN)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Resolve target VCS mode based on CLI flags or parent directory state.
|
// Resolve target VCS mode based on CLI flags or parent directory state.
|
||||||
@@ -164,10 +164,7 @@ pub fn new(args: &[String]) -> i32 {
|
|||||||
if let Err(e) = crate::core::vcs::init_vcs(vcs_kind, project_path) {
|
if let Err(e) = crate::core::vcs::init_vcs(vcs_kind, project_path) {
|
||||||
warn!("Failed to initialize git repository: {e}");
|
warn!("Failed to initialize git repository: {e}");
|
||||||
} else {
|
} else {
|
||||||
println!(
|
println!(" {} Initialized git repository", "✔".style(SUCCESS_ST));
|
||||||
" {} Initialized git repository",
|
|
||||||
colored("✔", BOLD_GREEN)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
warn!(
|
warn!(
|
||||||
@@ -183,9 +180,9 @@ pub fn new(args: &[String]) -> i32 {
|
|||||||
|
|
||||||
println!(
|
println!(
|
||||||
"Project `{}` successfully created\n",
|
"Project `{}` successfully created\n",
|
||||||
colored(project_name, BOLD_GREEN)
|
project_name.style(SUCCESS_ST)
|
||||||
);
|
);
|
||||||
printc("Next step:", BOLD_GREEN);
|
sprintln!(BOLD_GREEN, "Next step:");
|
||||||
printc(&format!(" cd {}\n dcr run", project_name), BOLD_CYAN);
|
sprintln!(BOLD_CYAN, " cd {}\n dcr run", project_name);
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,8 +22,9 @@ use crate::cli::flags::parse_build_run_flags;
|
|||||||
use crate::core::build_config::Config;
|
use crate::core::build_config::Config;
|
||||||
use crate::core::runner::run_binary;
|
use crate::core::runner::run_binary;
|
||||||
use crate::utils::build::{normalize_target_os, parse_version_info, substitute_vars};
|
use crate::utils::build::{normalize_target_os, parse_version_info, substitute_vars};
|
||||||
|
use crate::utils::cli_styles::{BOLD_GREEN, Colorize, HELP_EXAMPLES_ST, HELP_SECTION_TITLE_ST};
|
||||||
use crate::utils::fs::{find_project_root, with_dir};
|
use crate::utils::fs::{find_project_root, with_dir};
|
||||||
use crate::utils::text::{BOLD_CYAN, BOLD_GREEN, colored, printc};
|
use crate::utils::log::sprintln;
|
||||||
use std::{path::Path, process::Command};
|
use std::{path::Path, process::Command};
|
||||||
|
|
||||||
/// Retrieves the run command from the config, preferring target-specific,
|
/// Retrieves the run command from the config, preferring target-specific,
|
||||||
@@ -66,17 +67,17 @@ fn get_run_cmd(
|
|||||||
/// Process exit code from the built binary / `run.cmd`, or non-zero on build/setup failure.
|
/// Process exit code from the built binary / `run.cmd`, or non-zero on build/setup failure.
|
||||||
pub fn run(args: &[String]) -> i32 {
|
pub fn run(args: &[String]) -> i32 {
|
||||||
if args.first().is_some_and(|a| a == "--help") {
|
if args.first().is_some_and(|a| a == "--help") {
|
||||||
printc("USAGE:", BOLD_GREEN);
|
sprintln!(HELP_SECTION_TITLE_ST, "USAGE:");
|
||||||
printc(
|
sprintln!(
|
||||||
" dcr run [--debug | --release] [--target <triple>] [--force] [--clean] [--verbose] [-- <args>...]",
|
HELP_EXAMPLES_ST,
|
||||||
BOLD_CYAN,
|
" dcr run [--debug | --release] [--target <triple>] [--force] [--clean] [--verbose] [-- <args>...]"
|
||||||
);
|
);
|
||||||
println!();
|
println!();
|
||||||
printc("DESCRIPTION:", BOLD_GREEN);
|
sprintln!(HELP_SECTION_TITLE_ST, "DESCRIPTION:");
|
||||||
println!(" Builds and runs the project. Only available for kind = \"bin\".");
|
println!(" Builds and runs the project. Only available for kind = \"bin\".");
|
||||||
println!(" Arguments after `--` are passed to the built binary (cargo-style).");
|
println!(" Arguments after `--` are passed to the built binary (cargo-style).");
|
||||||
println!();
|
println!();
|
||||||
printc("OPTIONS:", BOLD_GREEN);
|
sprintln!(HELP_SECTION_TITLE_ST, "OPTIONS:");
|
||||||
println!(" --debug Run with debug profile (default)");
|
println!(" --debug Run with debug profile (default)");
|
||||||
println!(" --release Run with release profile");
|
println!(" --release Run with release profile");
|
||||||
println!(" --target <triple> Cross-compile for the given target");
|
println!(" --target <triple> Cross-compile for the given target");
|
||||||
@@ -127,7 +128,7 @@ pub fn run(args: &[String]) -> i32 {
|
|||||||
let display = display_run_cmd(&cmd, &flags.bin_args);
|
let display = display_run_cmd(&cmd, &flags.bin_args);
|
||||||
println!(
|
println!(
|
||||||
" {} {}",
|
" {} {}",
|
||||||
colored(&format!("{:<9}", "run"), BOLD_GREEN),
|
format!("{:<9}", "run").style(BOLD_GREEN),
|
||||||
display
|
display
|
||||||
);
|
);
|
||||||
return run_shell_with_args(&cmd, &flags.bin_args);
|
return run_shell_with_args(&cmd, &flags.bin_args);
|
||||||
@@ -267,7 +268,7 @@ fn run_project(
|
|||||||
let display = display_run_cmd(&cmd, &flags.bin_args);
|
let display = display_run_cmd(&cmd, &flags.bin_args);
|
||||||
println!(
|
println!(
|
||||||
" {} {}",
|
" {} {}",
|
||||||
colored(&format!("{:<9}", "run"), BOLD_GREEN),
|
format!("{:<9}", "run").style(BOLD_GREEN),
|
||||||
display
|
display
|
||||||
);
|
);
|
||||||
return Ok(run_shell_with_args(&cmd, &flags.bin_args));
|
return Ok(run_shell_with_args(&cmd, &flags.bin_args));
|
||||||
@@ -275,7 +276,7 @@ fn run_project(
|
|||||||
let display = display_bin_run(&bin_path, &flags.bin_args);
|
let display = display_bin_run(&bin_path, &flags.bin_args);
|
||||||
println!(
|
println!(
|
||||||
" {} {}",
|
" {} {}",
|
||||||
colored(&format!("{:<9}", "run"), BOLD_GREEN),
|
format!("{:<9}", "run").style(BOLD_GREEN),
|
||||||
display
|
display
|
||||||
);
|
);
|
||||||
return Ok(run_binary(
|
return Ok(run_binary(
|
||||||
|
|||||||
@@ -15,15 +15,16 @@
|
|||||||
// 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::text::{BOLD_CYAN, BOLD_GREEN, printc};
|
use crate::utils::cli_styles::{HELP_EXAMPLES_ST, HELP_SECTION_TITLE_ST};
|
||||||
|
use crate::utils::log::sprintln;
|
||||||
|
|
||||||
/// Sets up DCR registries by loading the registry manager and printing the list of registries.
|
/// Sets up DCR registries by loading the registry manager and printing the list of registries.
|
||||||
pub fn setup(args: &[String]) -> i32 {
|
pub fn setup(args: &[String]) -> i32 {
|
||||||
if args.first().is_some_and(|a| a == "--help") {
|
if args.first().is_some_and(|a| a == "--help") {
|
||||||
printc("USAGE:", BOLD_GREEN);
|
sprintln!(HELP_SECTION_TITLE_ST, "USAGE:");
|
||||||
printc(" dcr setup", BOLD_CYAN);
|
sprintln!(HELP_EXAMPLES_ST, " dcr setup");
|
||||||
println!();
|
println!();
|
||||||
printc("DESCRIPTION:", BOLD_GREEN);
|
sprintln!(HELP_SECTION_TITLE_ST, "DESCRIPTION:");
|
||||||
println!(" Sets up DCR registries. Downloads and indexes");
|
println!(" Sets up DCR registries. Downloads and indexes");
|
||||||
println!(" package registries for dependency resolution.");
|
println!(" package registries for dependency resolution.");
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -24,30 +24,35 @@ use crate::utils::build::{
|
|||||||
get_config_opt, get_config_str, get_language_with_profile, get_list_with_profile,
|
get_config_opt, get_config_str, get_language_with_profile, get_list_with_profile,
|
||||||
get_string_with_profile, resolve_compiler, resolve_pkg_config_flags,
|
get_string_with_profile, resolve_compiler, resolve_pkg_config_flags,
|
||||||
};
|
};
|
||||||
|
use crate::utils::cli_styles::{
|
||||||
|
BOLD_GREEN, Colorize, ERROR_ST, HELP_EXAMPLES_ST, HELP_SECTION_TITLE_ST, SKIP_ST, SUCCESS_ST,
|
||||||
|
Style,
|
||||||
|
};
|
||||||
use crate::utils::fs::{find_project_root, with_dir};
|
use crate::utils::fs::{find_project_root, with_dir};
|
||||||
use crate::utils::text::{BOLD_CYAN, BOLD_GREEN, BOLD_RED, RESET, colored, printc};
|
use crate::utils::log::sprintln;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
|
||||||
const BOLD_BLUE: &str = "\x1b[1m\x1b[94m";
|
|
||||||
|
|
||||||
/// Runs project tests and prints a unified testsuite report.
|
/// Runs project tests and prints a unified testsuite report.
|
||||||
pub fn test(args: &[String]) -> i32 {
|
pub fn test(args: &[String]) -> i32 {
|
||||||
let mut init_header = false;
|
let mut init_header = false;
|
||||||
let mut profile = "debug";
|
let mut profile = "debug";
|
||||||
for arg in args {
|
for arg in args {
|
||||||
if arg == "--help" {
|
if arg == "--help" {
|
||||||
printc("USAGE:", BOLD_GREEN);
|
sprintln!(HELP_SECTION_TITLE_ST, "USAGE:");
|
||||||
printc(" dcr test [--init] [--debug | --release]", BOLD_CYAN);
|
sprintln!(
|
||||||
|
HELP_EXAMPLES_ST,
|
||||||
|
" dcr test [--init] [--debug | --release]"
|
||||||
|
);
|
||||||
println!();
|
println!();
|
||||||
printc("ALIASES:", BOLD_GREEN);
|
sprintln!(HELP_SECTION_TITLE_ST, "ALIASES:");
|
||||||
println!(" dcr tests");
|
println!(" dcr tests");
|
||||||
println!();
|
println!();
|
||||||
printc("DESCRIPTION:", BOLD_GREEN);
|
sprintln!(HELP_SECTION_TITLE_ST, "DESCRIPTION:");
|
||||||
println!(" Runs project tests and prints a unified testsuite report.");
|
println!(" Runs project tests and prints a unified testsuite report.");
|
||||||
println!();
|
println!();
|
||||||
printc("OPTIONS:", BOLD_GREEN);
|
sprintln!(HELP_SECTION_TITLE_ST, "OPTIONS:");
|
||||||
println!(" --init Create tests/dcr_test.h in current project");
|
println!(" --init Create tests/dcr_test.h in current project");
|
||||||
println!(" --debug Build and run tests with debug profile (default)");
|
println!(" --debug Build and run tests with debug profile (default)");
|
||||||
println!(" --release Build and run tests with release profile");
|
println!(" --release Build and run tests with release profile");
|
||||||
@@ -195,19 +200,19 @@ fn run_testsuite(profile: &str) -> Result<i32, String> {
|
|||||||
for line in stdout.lines() {
|
for line in stdout.lines() {
|
||||||
let line = line.trim();
|
let line = line.trim();
|
||||||
if let Some(name) = line.strip_prefix("[PASS] ") {
|
if let Some(name) = line.strip_prefix("[PASS] ") {
|
||||||
println!("{} {}", colored("[PASS]", BOLD_GREEN), name);
|
println!("{} {}", "[PASS]".style(SUCCESS_ST), name);
|
||||||
pass += 1;
|
pass += 1;
|
||||||
parsed_any = true;
|
parsed_any = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if let Some(name) = line.strip_prefix("[SKIP] ") {
|
if let Some(name) = line.strip_prefix("[SKIP] ") {
|
||||||
println!("{} {}", colored("[SKIP]", BOLD_BLUE), name);
|
println!("{} {}", "[SKIP]".style(SKIP_ST), name);
|
||||||
skip += 1;
|
skip += 1;
|
||||||
parsed_any = true;
|
parsed_any = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if let Some(name) = line.strip_prefix("[FAIL] ") {
|
if let Some(name) = line.strip_prefix("[FAIL] ") {
|
||||||
println!("{} {}", colored("[FAIL]", BOLD_RED), name);
|
println!("{} {}", "[FAIL]".style(ERROR_ST), name);
|
||||||
fail += 1;
|
fail += 1;
|
||||||
parsed_any = true;
|
parsed_any = true;
|
||||||
continue;
|
continue;
|
||||||
@@ -215,17 +220,17 @@ fn run_testsuite(profile: &str) -> Result<i32, String> {
|
|||||||
if let Some((status, name)) = line.split_once('\t') {
|
if let Some((status, name)) = line.split_once('\t') {
|
||||||
match status {
|
match status {
|
||||||
"PASS" => {
|
"PASS" => {
|
||||||
println!("{} {}", colored("[PASS]", BOLD_GREEN), name);
|
println!("{} {}", "[PASS]".style(SUCCESS_ST), name);
|
||||||
pass += 1;
|
pass += 1;
|
||||||
parsed_any = true;
|
parsed_any = true;
|
||||||
}
|
}
|
||||||
"SKIP" => {
|
"SKIP" => {
|
||||||
println!("{} {}", colored("[SKIP]", BOLD_BLUE), name);
|
println!("{} {}", "[SKIP]".style(SKIP_ST), name);
|
||||||
skip += 1;
|
skip += 1;
|
||||||
parsed_any = true;
|
parsed_any = true;
|
||||||
}
|
}
|
||||||
"FAIL" => {
|
"FAIL" => {
|
||||||
println!("{} {}", colored("[FAIL]", BOLD_RED), name);
|
println!("{} {}", "[FAIL]".style(ERROR_ST), name);
|
||||||
fail += 1;
|
fail += 1;
|
||||||
parsed_any = true;
|
parsed_any = true;
|
||||||
}
|
}
|
||||||
@@ -237,11 +242,11 @@ fn run_testsuite(profile: &str) -> Result<i32, String> {
|
|||||||
if !parsed_any {
|
if !parsed_any {
|
||||||
if suite_success {
|
if suite_success {
|
||||||
for name in &declared {
|
for name in &declared {
|
||||||
println!("{} {}", colored("[PASS]", BOLD_GREEN), name);
|
println!("{} {}", "[PASS]".style(SUCCESS_ST), name);
|
||||||
}
|
}
|
||||||
pass = declared.len() as i32;
|
pass = declared.len() as i32;
|
||||||
} else {
|
} else {
|
||||||
println!("{} testsuite", colored("[FAIL]", BOLD_RED));
|
println!("{} testsuite", "[FAIL]".style(ERROR_ST));
|
||||||
fail = 1;
|
fail = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -253,14 +258,15 @@ fn run_testsuite(profile: &str) -> Result<i32, String> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
println!();
|
println!();
|
||||||
println!("{}", colored("=====================", BOLD_GREEN));
|
sprintln!(BOLD_GREEN, "=====================");
|
||||||
println!("{}", colored(" Testsuite summary ", BOLD_GREEN));
|
sprintln!(BOLD_GREEN, " Testsuite summary ");
|
||||||
println!("{}", colored("=====================", BOLD_GREEN));
|
sprintln!(BOLD_GREEN, "=====================");
|
||||||
println!("TOTAL: {}", total);
|
println!("TOTAL: {}", total);
|
||||||
print_field("PASS", pass, BOLD_GREEN);
|
print_field("PASS", pass, SUCCESS_ST);
|
||||||
print_field("SKIP", skip, BOLD_BLUE);
|
print_field("SKIP", skip, SKIP_ST);
|
||||||
print_field("FAIL", fail, BOLD_RED);
|
print_field("FAIL", fail, ERROR_ST);
|
||||||
println!("{}", colored("=====================", BOLD_GREEN));
|
sprintln!(BOLD_GREEN, "=====================");
|
||||||
|
sprintln!(BOLD_GREEN, "=====================");
|
||||||
|
|
||||||
if fail > 0 || !suite_success {
|
if fail > 0 || !suite_success {
|
||||||
return Ok(1);
|
return Ok(1);
|
||||||
@@ -395,10 +401,10 @@ fn extract_test_names_path(path: &Path) -> Vec<String> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Prints a test result field with color coding.
|
/// Prints a test result field with color coding.
|
||||||
fn print_field(label: &str, value: i32, color: &str) {
|
fn print_field(label: &str, value: i32, style: Style) {
|
||||||
if value == 0 {
|
if value == 0 {
|
||||||
println!("{}: {}", label, value);
|
println!("{}: {}", label, value);
|
||||||
} else {
|
} else {
|
||||||
println!("{}{}: {}{}", color, label, value, RESET);
|
sprintln!(style, "{}: {}", label, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,8 @@
|
|||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
use crate::core::build_config::Config;
|
use crate::core::build_config::Config;
|
||||||
use crate::utils::text::{BOLD_CYAN, BOLD_GREEN, printc};
|
use crate::utils::cli_styles::{BOLD_CYAN, HELP_EXAMPLES_ST, HELP_SECTION_TITLE_ST};
|
||||||
|
use crate::utils::log::sprintln;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use toml::Value;
|
use toml::Value;
|
||||||
@@ -29,10 +30,10 @@ use toml::Value;
|
|||||||
/// Otherwise, it parses the dcr.toml configuration and prints the dependency tree.
|
/// Otherwise, it parses the dcr.toml configuration and prints the dependency tree.
|
||||||
pub fn tree(args: &[String]) -> i32 {
|
pub fn tree(args: &[String]) -> i32 {
|
||||||
if args.first().is_some_and(|a| a == "--help") {
|
if args.first().is_some_and(|a| a == "--help") {
|
||||||
printc("USAGE:", BOLD_GREEN);
|
sprintln!(HELP_SECTION_TITLE_ST, "USAGE:");
|
||||||
printc(" dcr tree", BOLD_CYAN);
|
sprintln!(HELP_EXAMPLES_ST, " dcr tree");
|
||||||
println!();
|
println!();
|
||||||
printc("DESCRIPTION:", BOLD_GREEN);
|
sprintln!(HELP_SECTION_TITLE_ST, "DESCRIPTION:");
|
||||||
println!(" Displays the dependency tree of the current project.");
|
println!(" Displays the dependency tree of the current project.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -55,7 +56,7 @@ pub fn tree(args: &[String]) -> i32 {
|
|||||||
.and_then(|v| v.as_str())
|
.and_then(|v| v.as_str())
|
||||||
.unwrap_or("0.0.0");
|
.unwrap_or("0.0.0");
|
||||||
|
|
||||||
printc(&format!("{} v{}", name, version), BOLD_CYAN);
|
sprintln!(BOLD_CYAN, "{} v{}", name, version);
|
||||||
|
|
||||||
let mut seen = HashSet::new();
|
let mut seen = HashSet::new();
|
||||||
seen.insert(name.to_string());
|
seen.insert(name.to_string());
|
||||||
|
|||||||
@@ -15,39 +15,33 @@
|
|||||||
// 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/>.
|
||||||
|
|
||||||
#[allow(dead_code)]
|
pub use owo_colors::{OwoColorize as Colorize, Style};
|
||||||
pub const RESET: &str = "\x1b[0m";
|
|
||||||
|
|
||||||
|
// Сli theme styles
|
||||||
|
// Main
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub const BOLD: &str = "\x1b[1m";
|
pub const BOLD_RED: Style = Style::new().bright_red().bold();
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub const BOLD_GREEN: Style = Style::new().bright_green().bold();
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub const BOLD_YELLOW: Style = Style::new().bright_yellow().bold();
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub const BOLD_CYAN: Style = Style::new().bright_cyan().bold();
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub const BOLD_BLUE: Style = Style::new().bright_blue().bold();
|
||||||
|
|
||||||
|
// Help
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub const BRIGHT_RED: &str = "\x1b[91m";
|
pub const HELP_SECTION_TITLE_ST: Style = BOLD_GREEN;
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub const BRIGHT_GREEN: &str = "\x1b[92m";
|
pub const HELP_EXAMPLES_ST: Style = BOLD_CYAN;
|
||||||
#[allow(dead_code)]
|
|
||||||
pub const BRIGHT_YELLOW: &str = "\x1b[93m";
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub const BRIGHT_CYAN: &str = "\x1b[96m";
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub const BOLD_RED: &str = "\x1b[1m\x1b[91m";
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub const BOLD_GREEN: &str = "\x1b[1m\x1b[92m";
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub const BOLD_YELLOW: &str = "\x1b[1m\x1b[93m";
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub const BOLD_CYAN: &str = "\x1b[1m\x1b[96m";
|
|
||||||
|
|
||||||
/// Applies ANSI escape codes to format the message with the given style.
|
// Other
|
||||||
///
|
|
||||||
/// This is a utility for colored output in terminal applications.
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn colored(msg: &str, style: &str) -> String {
|
pub const ERROR_ST: Style = BOLD_RED;
|
||||||
format!("{style}{msg}{RESET}")
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Prints `msg` to stdout with the given ANSI `style`.
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn printc(msg: &str, style: &str) {
|
pub const SUCCESS_ST: Style = BOLD_GREEN;
|
||||||
println!("{style}{msg}{RESET}");
|
#[allow(dead_code)]
|
||||||
}
|
pub const ALERT_ST: Style = BOLD_YELLOW;
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub const SKIP_ST: Style = BOLD_BLUE;
|
||||||
@@ -42,3 +42,28 @@ pub fn init() {
|
|||||||
})
|
})
|
||||||
.init();
|
.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Prints message to stdout with the given `Style`. Copy of println! macro
|
||||||
|
#[allow(unused_macros)]
|
||||||
|
macro_rules! sprintln {
|
||||||
|
($style:expr, $($arg:tt)*) => {
|
||||||
|
{
|
||||||
|
use ::owo_colors::OwoColorize as _;
|
||||||
|
println!("{}", format!($($arg)*).style($style));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Prints message to stdout with the given `Style`. Copy of print! macro
|
||||||
|
#[allow(unused_macros)]
|
||||||
|
macro_rules! sprint {
|
||||||
|
($style:expr, $($arg:tt)*) => {
|
||||||
|
{
|
||||||
|
use ::owo_colors::OwoColorize as _;
|
||||||
|
print!("{}", format!($($arg)*).style($style));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(unused_imports)]
|
||||||
|
pub(crate) use {sprint, sprintln};
|
||||||
|
|||||||
@@ -29,4 +29,4 @@ pub mod git;
|
|||||||
pub mod log;
|
pub mod log;
|
||||||
|
|
||||||
/// Text processing and manipulation helpers.
|
/// Text processing and manipulation helpers.
|
||||||
pub mod text;
|
pub mod cli_styles;
|
||||||
|
|||||||
Reference in New Issue
Block a user