GUI Bootstrap Manager — это desktop-приложение на PySide6 для автоматизации старта новых проектов под разные технологические стеки.
Программа решает 4 задачи:
- Проверка доступности инструментов разработки в системе (git, python, node, dotnet и т.д.).
- Provisioning (подготовка среды) через PowerShell-скрипт с
winget. - Генерация структуры нового проекта из Jinja2-шаблонов.
- Запуск стек-специфичной инициализации фреймворка (например,
wails init,create-next-app,dotnet new, создание Python venv).
Итог: пользователь через GUI получает готовую директорию проекта с базовой структурой, скриптами запуска/сборки, метаданными и (опционально) инициализированным Git-репозиторием.
Корневые элементы:
main.py— точка входа.app/— GUI и бизнес-логика.templates/— шаблоны файлов для каждого стека.provisioning/setup_env.ps1— сценарий установки инструментов.requirements.txt— зависимости текущего GUI-приложения (PySide6,Jinja2).
Ключевые модули app/:
app/main.py— созданиеQApplicationи запуск окна.app/window.py— главное окно и обработчики действий пользователя.app/models.py— описание поддерживаемых стеков (конфигурация).app/services/tooling.py— проверка инструментов и версий.app/services/provisioning.py— запуск provisioning-скрипта.app/services/generator.py— генерация проекта и пост-обработка.app/utils.py— утилиты путей, нормализация имени проекта.app/widgets/log_view.py— виджет лога.
Стек определяется в app/models.py (словарь STACKS).
Поддерживаются:
go— Wails + React + TypeScript + Tailwind.cs— .NET + WinUI 3 + Windows App SDK + XAML.python— PySide6 + Qt Quick + QML + PyInstaller + Nuitka.astro— Astro + TypeScript + Tailwind.next— Next.js + TypeScript + React + Tailwind.docs— Docusaurus + TypeScript + MDX.
Для каждого стека задано:
required_tools— список инструментов, проверяемых в GUI.provision_profile— профиль для PowerShell provisioning (go,cs,python,web,docs).template_dir— каталог шаблонов вtemplates/.
DEFAULT_PROJECT_ROOT = Path.home() / "Projects" — базовый путь для новых проектов в UI.
- Выполняется корневой
main.py. - Он вызывает
app.main.run(). - В
run():- создается
QApplication; - задаются имя приложения и организация;
- создается
MainWindow; - окно показывается;
- запускается event loop через
app.exec().
- создается
В MainWindow.__init__():
- Устанавливаются заголовок и размер окна.
- Создается
ProjectGenerator. - Строится UI (
_build_ui). - Заполняется список стеков (
_fill_stacks). - В поле целевой папки подставляется
DEFAULT_PROJECT_ROOT.
_fill_stacks() вызывает on_stack_changed(), а тот вызывает on_check_tools().
То есть сразу после запуска идет проверка инструментов для текущего выбранного стека + powershell + winget.
Экран состоит из 3 блоков:
-
Создание проекта:
- имя проекта;
- папка назначения;
- стек;
- чекбокс
git init; - чекбокс
Upgrade при provisioning; - кнопки: выбрать папку, подготовить среду, создать проект.
-
Проверка инструментов:
- кнопка обновления;
- таблица с колонками:
Tool,Found,Path,Version.
-
Лог:
- текстовый лог;
- кнопка очистки.
Отдельно есть кнопка Открыть папку проекта.
on_stack_changed():
- обновляет описание стека в
description_view; - запускает повторную проверку инструментов.
on_check_tools():
- Берет
required_toolsвыбранного стека. - Добавляет
powershellиwinget. - Вызывает
check_many(...). - Заполняет таблицу статусами.
- Пишет запись в лог.
Механика check_many/check_tool (app/services/tooling.py):
- путь ищется через
shutil.which; - если команда найдена, версия определяется через
subprocess.runс соответствующей командой (git --version,node --version, и т.п.); - timeout получения версии: 10 секунд;
- исключения при получении версии не роняют процесс, версия просто остается пустой.
on_provision():
- Берет
provision_profileтекущего стека. - Вызывает
start_provisioning(profile, upgrade). - Если процесс запущен, читает
stdoutцеликом черезread()и пишет вывод в лог. - Ошибки показываются через
QMessageBox.criticalи пишутся в лог.
start_provisioning (app/services/provisioning.py):
- находит
provisioning/setup_env.ps1черезapp_root(); - проверяет, что файл существует;
- разрешает запуск только на Windows (
os.name == "nt"); - запускает
powershell -NoProfile -ExecutionPolicy Bypass -File ... -Profile ... [-Upgrade]; - возвращает
subprocess.Popenс объединенным stdout/stderr.
Важно: чтение stdout.read() синхронное, UI может ждать завершения provisioning.
on_create_project():
- Читает
project_name,target_root,stack_key,git_init. - Валидирует непустое имя.
- Вызывает
ProjectGenerator.generate(...). - При успехе:
- логирует путь проекта;
- логирует число созданных файлов;
- добавляет вывод framework-init, если он есть;
- показывает
QMessageBox.information.
- При ошибке: лог +
QMessageBox.critical.
on_open_project_dir():
- требует заполненное имя проекта;
- формирует путь как
root_edit / project_name(в этом месте имя не нормализуется, используется сырой ввод); - если папки нет, показывает ошибку;
- если Windows:
os.startfile(path); - иначе:
xdg-open.
Основной поток в ProjectGenerator.generate(...):
- Проверка, что
stack_keyсуществует вSTACKS. - Нормализация имени проекта (
normalize_project_name):- допустимы только
[A-Za-z0-9-_]; - остальные символы заменяются на
_; - повторяющиеся
__схлопываются; - подчеркивания по краям убираются.
- допустимы только
- Если после нормализации имя пустое — ошибка.
- Формируется
project_dir = target_root / safe_name. - Если папка уже существует —
FileExistsError. - Создается
project_dir. - Создаются базовые подпапки:
src,assets,assets/locales,docs,tests,build,scripts,tools.
- Рендерятся шаблоны выбранного стека (
_render_stack_templates). - Выполняется framework-init (
_run_framework_init). - Дописываются общие служебные файлы:
CHANGELOG.md;assets/locales/en.json,ru.json,uk.json;.cursorrules,.windsurfrules,AGENTS.md,.editorconfig,.gitignore,.env.example;bootstrap.meta.json.
- Если включен
git_init— выполняетсяgit init. - Возвращается
GenerationResult:- путь проекта;
- список созданных из шаблонов файлов;
- вывод framework-init команд.
_render_stack_templates(...):
- берет каталог
templates/<template_dir>; - рекурсивно проходит все файлы;
- для
.j2:- удаляет суффикс
.j2у целевого файла; - рендерит Jinja2-контекстом:
project_name,stack; - пишет UTF-8 текст;
- удаляет суффикс
- для не-
.j2файлов копирует как есть (shutil.copy2); - возвращает список созданных путей.
_run_framework_init(...):
-
python:python -m venv venv;venv\Scripts\python.exe -m pip install -U pip;venv\Scripts\python.exe -m pip install -r requirements.txt.
-
go:cmd /c "cd /d src && wails init -n src -t react-ts".
-
cs:dotnet new winui -n <project_name> -o src.
-
astro:cmd /c "npm create astro@latest src -- --template basics --typescript --install --no-git".
-
next:cmd /c "npx create-next-app@latest src --ts --tailwind --eslint --app --src-dir --import-alias @/* --use-npm".
-
docs:cmd /c "npx create-docusaurus@latest src classic --typescript".
Все команды запускаются через _run_optional_command:
- используется
subprocess.run(..., capture_output=True, text=True, shell=False); - возвращается строка вида
[Label] exit=<code> + stdout/stderr; - если команда не найдена, возвращается
skipped: command not found; - при любой другой ошибке возвращается
failed: <error>; - это не прерывает генерацию автоматически (ошибка конвертируется в текстовый результат).
Генератор всегда добавляет:
CHANGELOG.mdс записью про initial scaffold;- локали с
greetingнаen/ru/uk; - правила для IDE/агентов (
.cursorrules,.windsurfrules,AGENTS.md); .editorconfig,.gitignore,.env.example;bootstrap.meta.jsonс метаданными проекта.
git init выполняется «best effort»: исключения подавляются (except Exception: pass).
Для каждого стека есть минимум:
README.mddocs/STACK.mdscripts/build.batscripts/run.batscripts/clean.batscripts/check_env.bat
Дополнительно:
go:package.jsonpython:requirements.txtsrc/main.pysrc/main.qmlscripts/AppxManifest.xml
Скрипты ориентированы на Windows (.bat) и запускают типичные команды для dev/build/clean/check окружения.
Параметры:
-Profile: один изgo,cs,python,web,docs,all.-Upgrade: при наличии пытается выполнитьwinget upgradeпередwinget install.
Порядок выполнения:
- Включается
ErrorActionPreference = "Stop". - Проверяется запуск PowerShell от администратора (
Require-Admin). - Проверяется наличие
winget(Require-Winget). - Ставятся базовые инструменты:
Git.GitMicrosoft.VisualStudioCode
- По профилю ставятся стековые зависимости:
go: Go + Node LTS +go install ... wails;cs: .NET SDK 8 + Windows SDK;python: Python 3.12 + Node LTS + pip-пакеты (PySide6/PyInstaller/Nuitka/Jinja2);web: Node LTS;docs: Node LTS;all: объединение всех выше.
- Пишется сообщение о завершении.
Если после установки Go команда go еще не в PATH, скрипт выводит предупреждение и просит перезапустить PowerShell.
Что сделано:
- Ошибки UI-операций (provision/create/open) перехватываются и показываются пользователю через модальные окна.
- Проверка инструментов не падает на ошибках получения версии.
- Отсутствие внешних команд в framework-init не приводит к крэшу генератора: возвращается текст
skipped. - Проверка существования папки проекта предотвращает перезапись.
Наблюдаемые ограничения:
- Provisioning выполняется синхронным чтением
stdout.read(), что может блокировать UI до завершения процесса. - В
on_open_project_dirиспользуется сырое имя проекта, а генерация использует нормализованное: при спецсимволах возможен «путь не найден» после успешной генерации. git initвыполняется без проверки кода возврата и без лога причин ошибки.- Команды framework-init выполняются даже если
required_toolsфактически не найдены; проверка в таблице носит информативный характер, а не блокирующий.
Программа нужна как GUI-оркестратор старта проекта:
- снижает ручную рутину по созданию структуры и базовых файлов;
- стандартизирует bootstrap для нескольких стеков;
- позволяет non-CLI пользователям запускать provisioning и генерацию из одного окна;
- ускоряет выход к рабочему «нулевому» состоянию проекта (
src,scripts, базовые конфиги, локали, метаданные, опционально git).
Иными словами, это внутренний инструмент стандартизированного проектного старта, а не runtime-приложение конечного пользователя.
Start app
-> create QApplication
-> show MainWindow
-> load stacks
-> auto-check tools for selected stack
User chooses stack/root/name
-> optional: run provisioning (PowerShell profile)
-> click "Create project"
-> validate and normalize name
-> create project directory and base folders
-> render stack templates
-> run stack framework init commands
-> write common files/locales/metadata
-> optional git init
-> show success + logs
User may open created folder from UI
main.py— делегирует запуск вapp.main.run.app/main.py— точка запуска Qt event loop.app/window.py— весь GUI + handlers.app/models.py— конфигурация стеков.app/utils.py— путь приложения, нормализация имени, mkdir helper.app/services/tooling.py— which + version probing.app/services/provisioning.py— запуск PowerShell provisioning.app/services/generator.py— генератор проекта + framework init + общие файлы.app/widgets/log_view.py— текстовый лог-виджет.provisioning/setup_env.ps1— установка SDK/инструментов через winget.templates/**— шаблоны генерируемых файлов для стеков.