Add a script to collect system information when Blender isn't opening

This commit adds a python script that can collect some of the
information necessary to fill out a bug report.

The primary use case is to help users collect system information for
a bug report in the case that Blender can't open.

CMD and sh files are included to help users use the Python script.

Ref !122191
This commit is contained in:
Alaska
2024-09-03 12:59:59 +10:00
committed by Campbell Barton
parent d19c13eb82
commit 3196ef1636
7 changed files with 189 additions and 1 deletions

View File

@@ -0,0 +1,16 @@
#!/bin/sh
# Directory to this SH file.
BASE_DIR=$(dirname "$0")
PYTHON_BIN="$BASE_DIR/@BLENDER_VERSION@/python/bin/@PYTHON_EXECUTABLE_NAME_ONLY@"
SYSTEM_INFO_STARTUP_PY="$BASE_DIR/@BLENDER_VERSION@/scripts/modules/_bpy_internal/system_info/startup.py"
if test -f "$PYTHON_BIN"; then
exec "$PYTHON_BIN" -I "$SYSTEM_INFO_STARTUP_PY"
fi
echo "ERROR: Failed to find Python executable at: $PYTHON_BIN"
echo "Possible causes include:"
echo "- Your Blender installation is corrupt or missing python."
echo "- The location or name the python executable has changed."
exit 1

View File

@@ -0,0 +1,16 @@
#!/bin/sh
# Directory to this SH file.
BASE_DIR=$(dirname "$0")
PYTHON_BIN="$BASE_DIR/@BLENDER_VERSION@/python/bin/@PYTHON_EXECUTABLE_NAME_ONLY@"
SYSTEM_INFO_STARTUP_PY="$BASE_DIR/@BLENDER_VERSION@/scripts/modules/_bpy_internal/system_info/startup.py"
if test -f "$PYTHON_BIN"; then
exec "$PYTHON_BIN" -I "$SYSTEM_INFO_STARTUP_PY"
fi
echo "ERROR: Failed to find Python executable at: $PYTHON_BIN"
echo "Possible causes include:"
echo "- Your Blender installation is corrupt or missing python."
echo "- The location or name of the python executable has changed."
exit 1

View File

@@ -0,0 +1,16 @@
@echo off
set BLENDER_INSTALL_DIRECTORY=%~dp0
set BLENDER_VERSION_FOLDER=%BLENDER_INSTALL_DIRECTORY%@BLENDER_VERSION@
set PYTHON_BIN=%BLENDER_VERSION_FOLDER%\python\bin\@PYTHON_EXECUTABLE_NAME_ONLY@
if exist "%PYTHON_BIN%" (
"%PYTHON_BIN%" -I "%BLENDER_VERSION_FOLDER%\scripts\modules\_bpy_internal\system_info\startup.py"
exit /b
)
echo ERROR: Failed to find python executable at: %PYTHON_BIN%
echo Possible causes include:
echo - Your Blender installation is corrupt or missing @PYTHON_EXECUTABLE_NAME_ONLY@.
echo - The location or name of @PYTHON_EXECUTABLE_NAME_ONLY@ has changed.
pause

View File

@@ -2,6 +2,7 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
# Keep the information collected in this script synchronized with `startup.py`.
def url_prefill_from_blender(*, addon_info=None):
import bpy

View File

@@ -0,0 +1,87 @@
#!/usr/bin/env python3
# SPDX-FileCopyrightText: 2024 Blender Authors
#
# SPDX-License-Identifier: GPL-2.0-or-later
# Keep the information collected in this script synchronized with `runtime.py`.
def prefill_bug_report_info() -> int:
import re
import struct
import platform
import subprocess
import webbrowser
import urllib.parse
from pathlib import Path
print("Collecting system information...")
query_params = {"type": "bug_report", "project": "blender"}
query_params["os"] = "{:s} {:d} Bits".format(
platform.platform(),
struct.calcsize("P") * 8,
)
# There doesn't appear to be a easy way to collect GPU information in Python
# if Blender isn't opening and we can't import the GPU module.
# So just tell users to follow a written guide.
query_params["gpu"] = (
"Follow our guide to collect this information:\n"
"https://developer.blender.org/docs/handbook/bug_reports/making_good_bug_reports/collect_system_information/"
)
os_type = platform.system()
script_directory = Path(__file__).parent.resolve()
if os_type == "Darwin": # macOS appears as Darwin.
blender_dir = script_directory.joinpath("../../../../../../MacOS/Blender")
elif os_type == "Windows":
blender_dir = script_directory.joinpath("../../../../../Blender.exe")
else: # Linux and other Unix systems.
blender_dir = script_directory.joinpath("../../../../../blender")
try:
blender_output = subprocess.run(
[blender_dir, "--version"],
stdout=subprocess.PIPE,
encoding="utf-8",
errors="surrogateescape",
)
except Exception as ex:
sys.stderr.write("{:s}\n".format(str(ex)))
return 1
text = blender_output.stdout
# Gather Blender version information.
version_match = re.search(r"^Blender (.*)", text, flags=re.MULTILINE)
branch_match = re.search(r"^\s+build branch: (.*)", text, flags=re.MULTILINE)
commit_date_match = re.search(r"^\s+build commit date: (.*)", text, flags=re.MULTILINE)
commit_time_match = re.search(r"^\s+build commit time: (.*)", text, flags=re.MULTILINE)
build_hash_match = re.search(r"^\s+build hash: (.*)", text, flags=re.MULTILINE)
if not (version_match or branch_match or commit_date_match or commit_time_match or build_hash_match):
# No valid Blender info could be found.
print("Blender did not provide any build information. Blender may be corrupt or blocked from running.")
print("Please try reinstalling Blender and double check your anti-virus isn't blocking it from running.")
return 1
missing_string = "<unknown>"
query_params["broken_version"] = "{:s}, branch: {:s}, commit date: {:s} {:s}, hash `{:s}`".format(
version_match.group(1) if version_match else missing_string,
branch_match.group(1) if branch_match else missing_string,
commit_date_match.group(1) if commit_date_match else missing_string,
commit_time_match.group(1) if commit_time_match else missing_string,
build_hash_match.group(1) if build_hash_match else missing_string,
)
query_str = urllib.parse.urlencode(query_params)
webbrowser.open("https://redirect.blender.org/?{:s}".format(query_str))
return 0
if __name__ == "__main__":
import sys
sys.exit(prefill_bug_report_info())

View File

@@ -1086,7 +1086,7 @@ class WM_OT_url_open_preset(Operator):
)
def _url_from_bug(self, _context):
from bl_ui_utils.bug_report_url import url_prefill_from_blender
from _bpy_internal.system_info.runtime import url_prefill_from_blender
return url_prefill_from_blender()
def _url_from_release_notes(self, _context):

View File

@@ -961,6 +961,23 @@ file(REMOVE ${CMAKE_BINARY_DIR}/bin/lib/libglapi.so.0.0.0)\n
endif()
unset(_target_LIB)
endif()
if(WITH_INSTALL_PORTABLE)
# The script uses the version of Python installed with Blender,
# so it must only be inside installed if `WITH_PYTHON AND WITH_PYTHON_INSTALL`
# are active.
get_filename_component(PYTHON_EXECUTABLE_NAME_ONLY ${PYTHON_EXECUTABLE} NAME)
configure_file(
${CMAKE_SOURCE_DIR}/release/freedesktop/scripts/blender-system-info.sh.in
${CMAKE_BINARY_DIR}/release/freedesktop/scripts/blender-system-info.sh
@ONLY
)
unset(PYTHON_EXECUTABLE_NAME_ONLY)
install(
PROGRAMS ${CMAKE_BINARY_DIR}/release/freedesktop/scripts/blender-system-info.sh
DESTINATION "."
)
endif()
endif()
if(WITH_DRACO)
@@ -1471,6 +1488,27 @@ elseif(WIN32)
if(NOT WITH_PYTHON_MODULE)
get_filename_component(PYTHON_EXECUTABLE_NAME_ONLY ${PYTHON_EXECUTABLE} NAME)
# Configure then generate file. Note that this copies the literal generator
# for the Python executable name. So the file needs to be generated afterwards
# to get the correct name.
configure_file(
${CMAKE_SOURCE_DIR}/release/windows/batch/blender_system_info.cmd.in
${CMAKE_BINARY_DIR}/release/windows/batch/blender_system_info.with_vars.cmd.in
@ONLY
)
unset(PYTHON_EXECUTABLE_NAME_ONLY)
# Replace Python executable generator with actual executable name.
file(GENERATE
OUTPUT ${CMAKE_BINARY_DIR}/release/windows/batch/blender_system_info_$<CONFIG>.cmd
INPUT ${CMAKE_BINARY_DIR}/release/windows/batch/blender_system_info.with_vars.cmd.in
)
install(
FILES
${CMAKE_BINARY_DIR}/release/windows/batch/blender_system_info_$<CONFIG>.cmd
DESTINATION ${TARGETDIR_EXE}
RENAME blender_system_info.cmd
)
install(
FILES
${CMAKE_SOURCE_DIR}/release/windows/batch/blender_debug_gpu.cmd
@@ -1613,6 +1651,20 @@ elseif(APPLE)
)
endif()
if(NOT WITH_PYTHON_MODULE AND WITH_PYTHON AND WITH_PYTHON_INSTALL)
get_filename_component(PYTHON_EXECUTABLE_NAME_ONLY ${PYTHON_EXECUTABLE} NAME)
configure_file(
${CMAKE_SOURCE_DIR}/release/darwin/scripts/blender-system-info.sh.in
${CMAKE_BINARY_DIR}/release/darwin/scripts/blender-system-info.sh
@ONLY
)
unset(PYTHON_EXECUTABLE_NAME_ONLY)
install(
PROGRAMS ${CMAKE_BINARY_DIR}/release/darwin/scripts/blender-system-info.sh
DESTINATION "./Blender.app/Contents/Resources"
)
endif()
if(WITH_DRACO)
install(
PROGRAMS $<TARGET_FILE:extern_draco>