From d510efdaef11fe4b4e7f238dd28f7a699810ffee Mon Sep 17 00:00:00 2001 From: Dexoron Date: Thu, 12 Feb 2026 09:17:35 +0800 Subject: [PATCH] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=20README.md=20=D1=81=20=D0=B8=D0=BD=D1=81=D1=82=D1=80?= =?UTF-8?q?=D1=83=D0=BA=D1=86=D0=B8=D1=8F=D0=BC=D0=B8=20=D0=BF=D0=BE=20?= =?UTF-8?q?=D1=83=D1=81=D1=82=D0=B0=D0=BD=D0=BE=D0=B2=D0=BA=D0=B5=20=D0=B8?= =?UTF-8?q?=20=D1=83=D0=BB=D1=83=D1=87=D1=88=D0=B8=D1=82=D1=8C=20=D1=81?= =?UTF-8?q?=D0=BA=D1=80=D0=B8=D0=BF=D1=82=20=D1=83=D1=81=D1=82=D0=B0=D0=BD?= =?UTF-8?q?=D0=BE=D0=B2=D0=BA=D0=B8.=20=D0=98=D1=81=D0=BF=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D1=8B=20=D0=B8=D0=BC=D0=BF=D0=BE=D1=80?= =?UTF-8?q?=D1=82=D1=8B=20=D0=B2=20=D0=BC=D0=BE=D0=B4=D1=83=D0=BB=D1=8F?= =?UTF-8?q?=D1=85=20=D0=B8=20=D1=83=D0=BB=D1=83=D1=87=D1=88=D0=B8=D1=82?= =?UTF-8?q?=D1=8C=20=D0=BE=D0=B1=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BA=D1=83?= =?UTF-8?q?=20=D1=81=D0=B1=D0=BE=D1=80=D0=BA=D0=B8=20=D0=B2=20run.py/build?= =?UTF-8?q?.py.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 17 +++++- install.sh | 120 +++++++++++++++++++++++++------------------ pyproject.toml | 16 ++---- src/dcr/cli/build.py | 36 +++++++------ src/dcr/cli/clean.py | 3 +- src/dcr/cli/init.py | 7 +-- src/dcr/cli/new.py | 4 +- src/dcr/cli/run.py | 17 ++++-- src/dcr/main.py | 3 +- uv.lock | 8 --- 10 files changed, 133 insertions(+), 98 deletions(-) delete mode 100644 uv.lock diff --git a/README.md b/README.md index b14a445..4dfd905 100644 --- a/README.md +++ b/README.md @@ -18,10 +18,21 @@ DCR — это утилита для управления проектами н ## Установка -``` +### Автоматическая установка(Рекомендуется) + +**GNU/Linux** +```sh curl -L dcr.zov.tatar | bash ``` +### Самостоятельная установка + +```sh +git clone https://github.com/dexoron/dcr.git "~/.local/share/dcr" +chmod +x "~/.local/share/dcr/dcr" +ln -sf ~/.local/share/dcr/dcr ~/.local/bin +``` + ## Быстрый старт Создать новый проект: `dcr new hello` @@ -37,6 +48,10 @@ hello/ - dcr.toml ``` +Сборка и запуск проекта: +`dcr run` или `dcr run --release` - для сбрки с оптимизацией + + ## Команды ### `dcr new ` diff --git a/install.sh b/install.sh index c075e83..c07b4f9 100755 --- a/install.sh +++ b/install.sh @@ -1,12 +1,12 @@ #!/usr/bin/env bash - set -Eeuo pipefail +# ===== CONFIG ===== TMPDIR="/tmp/dcr-temp" INSTALL_PATH="$HOME/.local/share/dcr" PYTHON_DIR="$INSTALL_PATH/Python" BINPATH="$HOME/.local/bin" -LOGFILE="$PWD/dcr-install.log" +LOGFILE="$HOME/.cache/dcr-install.log" PYTHON_DOWNLOAD_URL="https://github.com/astral-sh/python-build-standalone/releases/download/20260203/cpython-3.10.19+20260203-x86_64-unknown-linux-gnu-install_only.tar.gz" GITHUB_API="https://api.github.com/repos/dexoron/dcr/releases/latest" @@ -17,68 +17,49 @@ YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' +mkdir -p "$(dirname "$LOGFILE")" exec > >(tee -a "$LOGFILE") 2>&1 -log() { - echo -e "${BLUE}[$(date '+%Y-%m-%d %H:%M:%S')]${NC} $1" -} - -success() { - echo -e "${GREEN}✔ $1${NC}" -} - -warn() { - echo -e "${YELLOW}⚠ $1${NC}" -} - -error() { - echo -e "${RED}✖ $1${NC}" -} +log() { echo -e "${BLUE}[$(date '+%Y-%m-%d %H:%M:%S')]${NC} $1"; } +success() { echo -e "${GREEN}✔ $1${NC}"; } +warn() { echo -e "${YELLOW}⚠ $1${NC}"; } +error() { echo -e "${RED}✖ $1${NC}"; } trap 'error "Ошибка на строке $LINENO"; exit 1' ERR check_dependencies() { log "Проверка зависимостей..." - command -v curl >/dev/null 2>&1 || { - error "curl не установлен" - exit 1 - } - - command -v tar >/dev/null 2>&1 || { - error "tar не установлен" - exit 1 - } + command -v curl >/dev/null 2>&1 || { error "curl не установлен"; exit 1; } + command -v tar >/dev/null 2>&1 || { error "tar не установлен"; exit 1; } success "Зависимости в порядке" } +check_os() { + if [[ "$(uname -s)" != "Linux" ]]; then + error "Поддерживается только Linux" + exit 1 + fi +} + install_python() { - log "Установка встроенного Python..." + log "Python не найден, установка встроенного Python..." mkdir -p "$PYTHON_DIR" + mkdir -p "$TMPDIR" - curl -L "$PYTHON_DOWNLOAD_URL" -o "$TMPDIR/python.tar.gz" + curl -fsSL "$PYTHON_DOWNLOAD_URL" -o "$TMPDIR/python.tar.gz" tar -xf "$TMPDIR/python.tar.gz" -C "$PYTHON_DIR" --strip-components=1 rm -f "$TMPDIR/python.tar.gz" - cat > "$INSTALL_PATH/dcr" <<'EOF' -#!/usr/bin/env bash -BASE_DIR="$(dirname "$(readlink -f "$0")")" -SRC_DIR="$BASE_DIR/src" -PYTHON_BIN="$BASE_DIR/Python/bin/python3" -PYTHONPATH="$SRC_DIR" exec "$PYTHON_BIN" -m dcr.main "$@" -EOF - - chmod +x "$INSTALL_PATH/dcr" - - success "Python установлен" + success "Встроенный Python установлен" } install_app() { log "Получение последнего релиза..." - TAG=$(curl -s "$GITHUB_API" | grep '"tag_name":' | cut -d'"' -f4) + TAG=$(curl -fsSL "$GITHUB_API" | sed -n 's/.*"tag_name": "\(.*\)".*/\1/p') if [[ -z "$TAG" ]]; then error "Не удалось определить версию релиза" @@ -87,7 +68,8 @@ install_app() { log "Найдена версия: $TAG" - curl -L -o "$TMPDIR/sources.tar.gz" \ + mkdir -p "$TMPDIR" + curl -fsSL -o "$TMPDIR/sources.tar.gz" \ "https://github.com/dexoron/dcr/archive/refs/tags/$TAG.tar.gz" mkdir -p "$INSTALL_PATH" @@ -97,6 +79,29 @@ install_app() { success "Приложение установлено" } +install_wrapper() { + log "Создание launcher..." + + mkdir -p "$INSTALL_PATH" + + cat > "$INSTALL_PATH/dcr" <<'EOF' +#!/usr/bin/env bash +BASE_DIR="$(cd "$(dirname "$0")" && pwd)" + +if command -v python3 >/dev/null 2>&1; then + PYTHON_BIN="python3" +else + PYTHON_BIN="$BASE_DIR/Python/bin/python3" +fi + +PYTHONPATH="$BASE_DIR/src" exec "$PYTHON_BIN" -m dcr.main "$@" +EOF + + chmod +x "$INSTALL_PATH/dcr" + + success "Launcher создан" +} + install_link() { log "Создание симлинка..." @@ -106,23 +111,38 @@ install_link() { success "Команда 'dcr' добавлена в $BINPATH" } +check_path() { + if ! echo "$PATH" | grep -q "$BINPATH"; then + warn "Каталог $BINPATH не найден в PATH" + echo "Добавь в ~/.bashrc или ~/.zshrc:" + echo "export PATH=\"$BINPATH:\$PATH\"" + fi +} + +cleanup() { + rm -rf "$TMPDIR" 2>/dev/null || true +} + main() { log "Запуск установки DCR" + check_os check_dependencies - mkdir -p "$TMPDIR" - rm -rf "$TMPDIR"/* + cleanup install_app - log "проверка наличия Python" - command -v curl >/dev/null 2>&1 || { - error "Python не установлен" - install_python - } - install_link - rm -rf "$TMPDIR" + if ! command -v python3 >/dev/null 2>&1; then + install_python + else + success "Найден системный Python" + fi + + install_wrapper + install_link + check_path + cleanup success "Установка завершена успешно" log "Лог сохранён в $LOGFILE" diff --git a/pyproject.toml b/pyproject.toml index 486cb84..4dcb171 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,17 +1,11 @@ [project] name = "dcr" version = "0.1.0" -description = "Add your description here" +description = "Утилита для управления проектами для C/C++" readme = "README.md" +license = "LICENSE" authors = [ - { name = "Dexoron", email = "probrovova1@gmail.com" } + { name = "Dexoron" }, + { name = "F1F1FISHKA" } ] -requires-python = ">=3.14.2" -dependencies = [] - -[project.scripts] -run = "dcr.main:main" - -[build-system] -requires = ["uv_build>=0.10.0,<0.11.0"] -build-backend = "uv_build" +requires-python = ">=3.10" \ No newline at end of file diff --git a/src/dcr/cli/build.py b/src/dcr/cli/build.py index fb98260..cc08495 100644 --- a/src/dcr/cli/build.py +++ b/src/dcr/cli/build.py @@ -2,7 +2,7 @@ import time import os import subprocess from ..config import flags, profile, c_comp -from dcr.utils.fs import check_dir +from ..utils.fs import check_dir def build(args: list[str] | None = None) -> int: @@ -31,18 +31,24 @@ def build(args: list[str] | None = None) -> int: print(f"Запуск сборки с профилем {active_profile}") compile_flags = flags[active_profile] start_time: float = time.time() - subprocess.run( - [ - c_comp, - "./src/main.c", - *compile_flags, - "-o", - f"./target/{active_profile}/main", - ], - check=True, - ) - end_time: float = time.time() - times: float = end_time - start_time - times: float = int(times * 100) / 100 - print(f"Сборка завершена, за {times} секунд") + try: + subprocess.run( + [ + c_comp, + "./src/main.c", + *compile_flags, + "-o", + f"./target/{active_profile}/main", + ], + check=True, + ) + end_time: float = time.time() + times: float = end_time - start_time + times: float = int(times * 100) / 100 + print(f"Сборка завершена, за {times} секунд") + return 0 + except: + print("Ошибка сборки") + return 1 + return 0 diff --git a/src/dcr/cli/clean.py b/src/dcr/cli/clean.py index 5c29f48..3e3192e 100644 --- a/src/dcr/cli/clean.py +++ b/src/dcr/cli/clean.py @@ -1,5 +1,4 @@ -from dcr.utils.fs import check_dir -import os +from ..utils.fs import check_dir import shutil diff --git a/src/dcr/cli/init.py b/src/dcr/cli/init.py index 49e2127..358d3ad 100644 --- a/src/dcr/cli/init.py +++ b/src/dcr/cli/init.py @@ -1,4 +1,4 @@ -from dcr.config import ( +from ..config import ( file_dcr_toml, file_main_c, project_version, @@ -6,13 +6,14 @@ from dcr.config import ( project_compiler, ) import os -from dcr.utils.fs import check_dir +from ..utils.fs import check_dir + def init(args: list[str] | None = None) -> int: if args: print("Ошибка: команда init не поддерживает аргументы") return 1 - items = check_dir() + items: list[str] = check_dir() project_name = os.path.basename(os.getcwd()) if items: diff --git a/src/dcr/cli/new.py b/src/dcr/cli/new.py index 2bc0ad0..cf5fe21 100644 --- a/src/dcr/cli/new.py +++ b/src/dcr/cli/new.py @@ -1,4 +1,4 @@ -from dcr.config import ( +from ..config import ( file_dcr_toml, file_main_c, project_version, @@ -6,7 +6,7 @@ from dcr.config import ( project_compiler, ) import os -from dcr.utils.fs import check_dir +from ..utils.fs import check_dir def new(args: list[str]) -> int: diff --git a/src/dcr/cli/run.py b/src/dcr/cli/run.py index 7d822ca..c8d51b3 100644 --- a/src/dcr/cli/run.py +++ b/src/dcr/cli/run.py @@ -1,7 +1,6 @@ -import os import subprocess -from dcr.utils.fs import check_dir +from ..utils.fs import check_dir from ..config import flags, profile from .build import build @@ -24,6 +23,14 @@ def run(args: list[str] | None = None) -> int: print("Ошибка: флаг сборки не найден") return 1 - build(args) - print("Запуск проекта") - return subprocess.run([f"./target/{active_profile}/main"]).returncode + build_status: int = build(args) + if build_status == 0: + print("Запуск проекта") + return subprocess.run([f"./target/{active_profile}/main"]).returncode + else: + if active_profile in check_dir("target/" + active_profile): + print("Запуск последнего релиза") + return subprocess.run([f"./target/{active_profile}/main"]).returncode + else: + print("Исправьте ошибки в коде для запуска проекта") + return 0 diff --git a/src/dcr/main.py b/src/dcr/main.py index abbd700..9e308c0 100644 --- a/src/dcr/main.py +++ b/src/dcr/main.py @@ -26,5 +26,6 @@ def main() -> int: return 0 + if __name__ == "__main__": - raise SystemExit(main()) \ No newline at end of file + raise SystemExit(main()) diff --git a/uv.lock b/uv.lock deleted file mode 100644 index 716c93f..0000000 --- a/uv.lock +++ /dev/null @@ -1,8 +0,0 @@ -version = 1 -revision = 3 -requires-python = ">=3.14.2" - -[[package]] -name = "dcr" -version = "0.1.0" -source = { editable = "." }