mirror of
https://gitlab.com/kelteseth/ScreenPlay.git
synced 2024-11-06 19:12:30 +01:00
Merge branch 'master' into 172-add-wayland-layer-shell-support
This commit is contained in:
commit
dccc08f2ff
126
.gitlab-ci.yml
126
.gitlab-ci.yml
@ -1,118 +1,22 @@
|
|||||||
|
include:
|
||||||
|
- ".gitlab/ci/base_jobs.yml"
|
||||||
|
- ".gitlab/ci/build_jobs.yml"
|
||||||
|
- ".gitlab/ci/build_release_jobs.yml"
|
||||||
|
- ".gitlab/ci/check_jobs.yml"
|
||||||
|
|
||||||
stages:
|
stages:
|
||||||
|
# None Steam build for every commit
|
||||||
- build
|
- build
|
||||||
|
# Steam build for every commit
|
||||||
|
- build_steam
|
||||||
|
# Git release tag builds
|
||||||
|
- release_build
|
||||||
|
# Gitlab releases at:
|
||||||
|
# https://gitlab.com/kelteseth/ScreenPlay/-/releases
|
||||||
|
- release
|
||||||
|
# Checks for source code formattings
|
||||||
- check
|
- check
|
||||||
|
|
||||||
.base_windows_build:
|
|
||||||
before_script:
|
|
||||||
- python -m pip install -U pip wheel
|
|
||||||
- python -m pip install -r Tools/requirements.txt
|
|
||||||
- python Tools/setup.py
|
|
||||||
|
|
||||||
.base_linux_build:
|
|
||||||
before_script:
|
|
||||||
# Otherwise libglib2 needs interaction
|
|
||||||
- export DEBIAN_FRONTEND=noninteractive
|
|
||||||
- apt update -y
|
|
||||||
- apt install libwayland-dev wayland-protocols curl wget zip unzip tar git pkg-config libxcb-* libfontconfig-dev apt-transport-https ca-certificates gnupg software-properties-common python3 python3-pip build-essential libgl1-mesa-dev mesa-common-dev lld ninja-build libxkbcommon-* libx11-dev xserver-xorg-dev xorg-dev -y
|
|
||||||
- wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | gpg --dearmor - | tee /usr/share/keyrings/kitware-archive-keyring.gpg >/dev/null
|
|
||||||
- echo 'deb [signed-by=/usr/share/keyrings/kitware-archive-keyring.gpg] https://apt.kitware.com/ubuntu/ focal-rc main' | tee -a /etc/apt/sources.list.d/kitware.list >/dev/null
|
|
||||||
- apt update -y
|
|
||||||
- apt install cmake -y
|
|
||||||
- python3 -m pip install -U pip
|
|
||||||
- python3 -m pip install -r Tools/requirements.txt
|
|
||||||
- python3 Tools/setup.py
|
|
||||||
|
|
||||||
.base_osx_build:
|
|
||||||
before_script:
|
|
||||||
- pip3 install -U pip
|
|
||||||
- pip3 install -r Tools/requirements.txt
|
|
||||||
- python3 Tools/setup.py
|
|
||||||
|
|
||||||
standalone_windows:
|
|
||||||
stage: build
|
|
||||||
extends:
|
|
||||||
- .base_windows_build
|
|
||||||
tags:
|
|
||||||
- windows10
|
|
||||||
script:
|
|
||||||
- python Tools/build.py -type release -use-aqt -installer -deploy-version
|
|
||||||
artifacts:
|
|
||||||
expire_in: "2 weeks"
|
|
||||||
paths:
|
|
||||||
- build-x64-windows-release/bin/
|
|
||||||
- build-x64-windows-release/ScreenPlay-Installer.exe
|
|
||||||
|
|
||||||
standalone_osx:
|
|
||||||
stage: build
|
|
||||||
extends:
|
|
||||||
- .base_osx_build
|
|
||||||
tags:
|
|
||||||
- osx
|
|
||||||
script:
|
|
||||||
- python3 Tools/build.py -type release -use-aqt -deploy-version -sign_osx
|
|
||||||
artifacts:
|
|
||||||
expire_in: "2 weeks"
|
|
||||||
paths:
|
|
||||||
- build-64-osx-universal-release/bin/
|
|
||||||
|
|
||||||
standalone_linux:
|
|
||||||
stage: build
|
|
||||||
extends:
|
|
||||||
- .base_linux_build
|
|
||||||
image:
|
|
||||||
name: ubuntu:20.04
|
|
||||||
tags:
|
|
||||||
- gitlab-org-docker
|
|
||||||
script:
|
|
||||||
- python3 Tools/build.py -type release -deploy-version -use-aqt -installer
|
|
||||||
artifacts:
|
|
||||||
expire_in: "4 weeks"
|
|
||||||
paths:
|
|
||||||
- build-x64-linux-release/bin/
|
|
||||||
|
|
||||||
steam_windows:
|
|
||||||
stage: build
|
|
||||||
extends:
|
|
||||||
- .base_windows_build
|
|
||||||
tags:
|
|
||||||
- windows10
|
|
||||||
script:
|
|
||||||
- python Tools/build.py -type release -steam -use-aqt -deploy-version
|
|
||||||
artifacts:
|
|
||||||
expire_in: "2 weeks"
|
|
||||||
paths:
|
|
||||||
- build-x64-windows-release/bin/
|
|
||||||
|
|
||||||
steam_osx:
|
|
||||||
stage: build
|
|
||||||
extends:
|
|
||||||
- .base_osx_build
|
|
||||||
tags:
|
|
||||||
- osx
|
|
||||||
script:
|
|
||||||
- python3 Tools/build.py -type release -steam -use-aqt -deploy-version -sign_osx
|
|
||||||
artifacts:
|
|
||||||
expire_in: "2 weeks"
|
|
||||||
paths:
|
|
||||||
- build-64-osx-universal-release/bin/
|
|
||||||
|
|
||||||
formatting:
|
|
||||||
stage: check
|
|
||||||
allow_failure: true
|
|
||||||
image:
|
|
||||||
name: ubuntu:20.04
|
|
||||||
tags:
|
|
||||||
- gitlab-org-docker
|
|
||||||
before_script:
|
|
||||||
- apt-get update -y
|
|
||||||
- apt-get install python3-pip python-is-python3 clang clang-format -y
|
|
||||||
script:
|
|
||||||
- python -m pip install -U pip wheel
|
|
||||||
- python -m pip install -U cmakelang
|
|
||||||
- cd Tools
|
|
||||||
- python clang_format.py
|
|
||||||
- python cmake_format.py
|
|
||||||
|
|
||||||
documentation:
|
documentation:
|
||||||
stage: .post
|
stage: .post
|
||||||
script:
|
script:
|
||||||
|
49
.gitlab/ci/base_jobs.yml
Normal file
49
.gitlab/ci/base_jobs.yml
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
.base_windows_build:
|
||||||
|
dependencies: []
|
||||||
|
before_script:
|
||||||
|
- python -m pip install -U pip wheel
|
||||||
|
- python -m pip install -r Tools/requirements.txt
|
||||||
|
- python Tools/setup.py
|
||||||
|
tags:
|
||||||
|
- windows10
|
||||||
|
artifacts:
|
||||||
|
expire_in: "2 weeks"
|
||||||
|
paths:
|
||||||
|
- build-x64-windows-release/bin/
|
||||||
|
- build-x64-windows-release/ScreenPlay-Installer.exe
|
||||||
|
|
||||||
|
.base_linux_build:
|
||||||
|
dependencies: []
|
||||||
|
before_script:
|
||||||
|
# Otherwise libglib2 needs interaction
|
||||||
|
- export DEBIAN_FRONTEND=noninteractive
|
||||||
|
- apt update -y
|
||||||
|
- apt install libwayland-dev wayland-protocols curl wget zip unzip tar git pkg-config libxcb-* libfontconfig-dev apt-transport-https ca-certificates gnupg software-properties-common python3 python3-pip build-essential libgl1-mesa-dev mesa-common-dev lld ninja-build libxkbcommon-* libx11-dev xserver-xorg-dev xorg-dev -y
|
||||||
|
- wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | gpg --dearmor - | tee /usr/share/keyrings/kitware-archive-keyring.gpg >/dev/null
|
||||||
|
- echo 'deb [signed-by=/usr/share/keyrings/kitware-archive-keyring.gpg] https://apt.kitware.com/ubuntu/ focal-rc main' | tee -a /etc/apt/sources.list.d/kitware.list >/dev/null
|
||||||
|
- apt update -y
|
||||||
|
- apt install cmake -y
|
||||||
|
- python3 -m pip install -U pip
|
||||||
|
- python3 -m pip install -r Tools/requirements.txt
|
||||||
|
- python3 Tools/setup.py
|
||||||
|
image:
|
||||||
|
name: ubuntu:20.04
|
||||||
|
tags:
|
||||||
|
- gitlab-org-docker
|
||||||
|
artifacts:
|
||||||
|
expire_in: "4 weeks"
|
||||||
|
paths:
|
||||||
|
- build-x64-linux-release/bin/
|
||||||
|
|
||||||
|
.base_osx_build:
|
||||||
|
dependencies: []
|
||||||
|
before_script:
|
||||||
|
- pip3 install -U pip
|
||||||
|
- pip3 install -r Tools/requirements.txt
|
||||||
|
- python3 Tools/setup.py
|
||||||
|
tags:
|
||||||
|
- osx
|
||||||
|
artifacts:
|
||||||
|
expire_in: "2 weeks"
|
||||||
|
paths:
|
||||||
|
- build-64-osx-universal-release/bin/
|
41
.gitlab/ci/build_jobs.yml
Normal file
41
.gitlab/ci/build_jobs.yml
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
standalone_windows:
|
||||||
|
stage: build
|
||||||
|
extends:
|
||||||
|
- .base_windows_build
|
||||||
|
script:
|
||||||
|
- python Tools/build.py --type=release --use-aqt --installer --deploy-version
|
||||||
|
|
||||||
|
standalone_osx:
|
||||||
|
stage: build
|
||||||
|
extends:
|
||||||
|
- .base_osx_build
|
||||||
|
script:
|
||||||
|
- python3 Tools/build.py --type=release --use-aqt --deploy-version --sign_osx
|
||||||
|
|
||||||
|
standalone_linux:
|
||||||
|
stage: build
|
||||||
|
extends:
|
||||||
|
- .base_linux_build
|
||||||
|
script:
|
||||||
|
- python3 Tools/build.py --type=release --use-aqt --installer --deploy-version
|
||||||
|
|
||||||
|
steam_windows:
|
||||||
|
stage: build_steam
|
||||||
|
extends:
|
||||||
|
- .base_windows_build
|
||||||
|
script:
|
||||||
|
- python Tools/build.py --type=release -steam --use-aqt --deploy-version
|
||||||
|
|
||||||
|
steam_osx:
|
||||||
|
stage: build_steam
|
||||||
|
extends:
|
||||||
|
- .base_osx_build
|
||||||
|
script:
|
||||||
|
- python3 Tools/build.py --type=release -steam --use-aqt --deploy-version --sign_osx
|
||||||
|
|
||||||
|
steam_linux:
|
||||||
|
stage: build_steam
|
||||||
|
extends:
|
||||||
|
- .base_linux_build
|
||||||
|
script:
|
||||||
|
- python3 Tools/build.py --type=release -steam --deploy-version --use-aqt --installer
|
78
.gitlab/ci/build_release_jobs.yml
Normal file
78
.gitlab/ci/build_release_jobs.yml
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
steam_linux:
|
||||||
|
stage: release_build
|
||||||
|
extends:
|
||||||
|
- .base_linux_build
|
||||||
|
script:
|
||||||
|
- python3 Tools/build.py --type=release --steam --deploy-version --use-aqt --installer
|
||||||
|
rules:
|
||||||
|
- if: "$CI_COMMIT_TAG"
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- build-x64-linux-release/ScreenPlay-$CI_COMMIT_TAG-x64-linux-release.zip
|
||||||
|
- build-x64-linux-release/ScreenPlay-$CI_COMMIT_TAG-x64-linux-release.zip.sha256.txt
|
||||||
|
|
||||||
|
steam_windows:
|
||||||
|
stage: release_build
|
||||||
|
extends:
|
||||||
|
- .base_windows_build
|
||||||
|
script:
|
||||||
|
- python Tools/build.py --type=release --steam --use-aqt --deploy-version
|
||||||
|
rules:
|
||||||
|
- if: "$CI_COMMIT_TAG"
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- build-x64-windows-release/ScreenPlay-$CI_COMMIT_TAG-x64-windows-release.zip
|
||||||
|
- build-x64-windows-release/ScreenPlay-$CI_COMMIT_TAG-x64-windows-release.zip.sha256.txt
|
||||||
|
|
||||||
|
steam_osx:
|
||||||
|
stage: release_build
|
||||||
|
extends:
|
||||||
|
- .base_osx_build
|
||||||
|
script:
|
||||||
|
- python3 Tools/build.py --type=release --steam --use-aqt --deploy-version --sign_osx
|
||||||
|
rules:
|
||||||
|
- if: "$CI_COMMIT_TAG"
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- build-64-osx-universal-release/ScreenPlay-$CI_COMMIT_TAG-64-osx-universal-release.zip
|
||||||
|
- build-64-osx-universal-release/ScreenPlay-$CI_COMMIT_TAG-64-osx-universal-release.zip.sha256.txt
|
||||||
|
|
||||||
|
release_job:
|
||||||
|
stage: release
|
||||||
|
image: python:3.11
|
||||||
|
dependencies:
|
||||||
|
- steam_linux
|
||||||
|
- steam_windows
|
||||||
|
- steam_osx
|
||||||
|
rules:
|
||||||
|
- if: "$CI_COMMIT_TAG" # Run this job when a tag is created
|
||||||
|
when: on_success # Only when all previous jobs succeed
|
||||||
|
script:
|
||||||
|
# 1. Combining sha256 files into a SHA512-SUMS.txt
|
||||||
|
- python3 Tools/create_sha512.py
|
||||||
|
# 2. Install dependencies and handle the folder
|
||||||
|
- apt update
|
||||||
|
- apt install -y sshpass ssh curl
|
||||||
|
- curl --location --output /usr/local/bin/release-cli "https://gitlab.com/api/v4/projects/gitlab-org%2Frelease-cli/packages/generic/release-cli/latest/release-cli-linux-amd64"
|
||||||
|
- chmod +x /usr/local/bin/release-cli
|
||||||
|
- ssh-keyscan 91.204.46.10 >> ~/.ssh/known_hosts
|
||||||
|
- sshpass -p $GETSP_PASSWORD ssh $GETSP_USERNAME@91.204.46.10 "rm -rf /getsp.de/httpdocs/releases/$CI_COMMIT_TAG; mkdir /getsp.de/httpdocs/releases/$CI_COMMIT_TAG;"
|
||||||
|
# 3. Upload files to the remote folder
|
||||||
|
- sshpass -p $GETSP_PASSWORD scp build-x64-linux-release/ScreenPlay-$CI_COMMIT_TAG-x64-linux-release.zip $GETSP_USERNAME@91.204.46.10:/getsp.de/httpdocs/releases/$CI_COMMIT_TAG/
|
||||||
|
- sshpass -p $GETSP_PASSWORD scp build-x64-windows-release/ScreenPlay-$CI_COMMIT_TAG-x64-windows-release.zip $GETSP_USERNAME@91.204.46.10:/getsp.de/httpdocs/releases/$CI_COMMIT_TAG/
|
||||||
|
- sshpass -p $GETSP_PASSWORD scp build-64-osx-universal-release/ScreenPlay-$CI_COMMIT_TAG-64-osx-universal-release.zip $GETSP_USERNAME@91.204.46.10:/getsp.de/httpdocs/releases/$CI_COMMIT_TAG/
|
||||||
|
- sshpass -p $GETSP_PASSWORD scp SHA512-SUMS.txt $GETSP_USERNAME@91.204.46.10:/getsp.de/httpdocs/releases/$CI_COMMIT_TAG/
|
||||||
|
release:
|
||||||
|
tag_name: $CI_COMMIT_TAG
|
||||||
|
name: "ScreenPlay $CI_COMMIT_TAG Released!"
|
||||||
|
description: "🎉 A Wild ScreenPlay Release Appeared!"
|
||||||
|
assets:
|
||||||
|
links:
|
||||||
|
- name: 🐧 Linux x64 build
|
||||||
|
url: "https://getsp.de/releases/$CI_COMMIT_TAG/ScreenPlay-$CI_COMMIT_TAG-x64-linux-release.zip"
|
||||||
|
- name: 🪟 Windows x64 build
|
||||||
|
url: "https://getsp.de/releases/$CI_COMMIT_TAG/ScreenPlay-$CI_COMMIT_TAG-x64-windows-release.zip"
|
||||||
|
- name: 🍏 OSX universal build
|
||||||
|
url: "https://getsp.de/releases/$CI_COMMIT_TAG/ScreenPlay-$CI_COMMIT_TAG-64-osx-universal-release.zip"
|
||||||
|
- name: ℹ️ SHA512-SUMS.txt
|
||||||
|
url: "https://getsp.de/releases/$CI_COMMIT_TAG/SHA512-SUMS.txt"
|
18
.gitlab/ci/check_jobs.yml
Normal file
18
.gitlab/ci/check_jobs.yml
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
formatting:
|
||||||
|
dependencies: []
|
||||||
|
stage: check
|
||||||
|
allow_failure: true
|
||||||
|
image:
|
||||||
|
name: ubuntu:23.10
|
||||||
|
tags:
|
||||||
|
- gitlab-org-docker
|
||||||
|
before_script:
|
||||||
|
- apt-get update -y
|
||||||
|
- apt-get install python3-pip python-is-python3 clang clang-format -y
|
||||||
|
script:
|
||||||
|
- python -m pip install -U pip wheel --break-system-packages
|
||||||
|
- python -m pip install -U cmakelang --break-system-packages
|
||||||
|
- cd Tools
|
||||||
|
- python check_format_cmake.py --check
|
||||||
|
- python check_format_cpp.py --check
|
||||||
|
#- python check_format_qml.py --check
|
20
.vscode/tasks.json
vendored
20
.vscode/tasks.json
vendored
@ -28,7 +28,7 @@
|
|||||||
"cwd": "${workspaceFolder}/Tools"
|
"cwd": "${workspaceFolder}/Tools"
|
||||||
},
|
},
|
||||||
"args": [
|
"args": [
|
||||||
"clang_format.py"
|
"check_format_cpp.py"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -46,7 +46,7 @@
|
|||||||
"cwd": "${workspaceFolder}/Tools"
|
"cwd": "${workspaceFolder}/Tools"
|
||||||
},
|
},
|
||||||
"args": [
|
"args": [
|
||||||
"cmake_format.py"
|
"check_format_cmake.py"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -64,7 +64,7 @@
|
|||||||
"cwd": "${workspaceFolder}/Tools"
|
"cwd": "${workspaceFolder}/Tools"
|
||||||
},
|
},
|
||||||
"args": [
|
"args": [
|
||||||
"qml_format.py"
|
"check_format_qml.py"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -87,7 +87,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "process",
|
"type": "process",
|
||||||
"label": "Export ScreenPlay release, with deploy and steam enabled",
|
"label": "Build ScreenPlay release, with deploy and steam enabled",
|
||||||
"command": "python3",
|
"command": "python3",
|
||||||
"windows": {
|
"windows": {
|
||||||
"command": "python"
|
"command": "python"
|
||||||
@ -102,16 +102,16 @@
|
|||||||
"osx": {
|
"osx": {
|
||||||
"args": [
|
"args": [
|
||||||
"build.py",
|
"build.py",
|
||||||
"-type=release",
|
"--type=release",
|
||||||
"-deploy-version",
|
"--deploy-version",
|
||||||
"-steam"
|
"--steam"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"args": [
|
"args": [
|
||||||
"build.py",
|
"build.py",
|
||||||
"-type=release",
|
"--type=release",
|
||||||
"-deploy-version",
|
"--deploy-version",
|
||||||
"-steam"
|
"--steam"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -2,6 +2,7 @@ project(CMake)
|
|||||||
|
|
||||||
set(FILES
|
set(FILES
|
||||||
CMakeVariables.h.in
|
CMakeVariables.h.in
|
||||||
|
GetProjectVersion.cmake
|
||||||
GenerateCMakeVariableHeader.cmake
|
GenerateCMakeVariableHeader.cmake
|
||||||
CopyRecursive.cmake
|
CopyRecursive.cmake
|
||||||
CreateIFWInstaller.cmake)
|
CreateIFWInstaller.cmake)
|
||||||
|
22
CMake/CreateDmgInstaller.cmake
Normal file
22
CMake/CreateDmgInstaller.cmake
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
message(STATUS "[DMG INSTALLER ENABLED]: Configuring. This can take some time...")
|
||||||
|
|
||||||
|
set(CPACK_GENERATOR "DragNDrop")
|
||||||
|
set(CPACK_DMG_FORMAT "UDBZ")
|
||||||
|
set(CPACK_DMG_VOLUME_NAME "ScreenPlay")
|
||||||
|
set(CPACK_SYSTEM_NAME "OSX")
|
||||||
|
set(CPACK_PACKAGE_ICON "${CMAKE_SOURCE_DIR}/ScreenPlay/assets/icons/app.ico")
|
||||||
|
|
||||||
|
set(CPACK_COMPONENTS_GROUPING IGNORE)
|
||||||
|
set(CPACK_PACKAGE_NAME "ScreenPlay")
|
||||||
|
set(CPACK_PACKAGE_FILE_NAME "ScreenPlay-Installer")
|
||||||
|
set(CPACK_PACKAGE_VENDOR "Elias Steurer")
|
||||||
|
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "${PROJECT_DESCRIPTION}")
|
||||||
|
set(CPACK_PACKAGE_DIRECTORY "${CMAKE_BINARY_DIR}")
|
||||||
|
|
||||||
|
include(CPack)
|
||||||
|
|
||||||
|
# Install all files from /bin
|
||||||
|
install(
|
||||||
|
DIRECTORY "${CMAKE_BINARY_DIR}/bin/"
|
||||||
|
COMPONENT ScreenPlay
|
||||||
|
DESTINATION "./")
|
33
CMake/GetProjectVersion.cmake
Normal file
33
CMake/GetProjectVersion.cmake
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
# Function: get_project_version
|
||||||
|
#
|
||||||
|
# Description:
|
||||||
|
# Fetches the project version from the latest Git tag. If Git is not found or
|
||||||
|
# the current directory is not a Git repository, it defaults to "0.0.0".
|
||||||
|
#
|
||||||
|
# Parameters:
|
||||||
|
# - VERSION_VAR: The name of the variable in which the fetched or default version will be stored.
|
||||||
|
#
|
||||||
|
# Example Usage:
|
||||||
|
# get_project_version(PROJECT_VERSION)
|
||||||
|
# message(STATUS "Version: ${PROJECT_VERSION}")
|
||||||
|
#
|
||||||
|
function(get_project_version VERSION_VAR)
|
||||||
|
find_package(Git)
|
||||||
|
if(GIT_FOUND)
|
||||||
|
execute_process(
|
||||||
|
COMMAND ${GIT_EXECUTABLE} describe --tags --always
|
||||||
|
OUTPUT_VARIABLE GIT_VERSION
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
message(STATUS "Parsing git tag: ${GIT_VERSION}")
|
||||||
|
string(REPLACE "v" "" STRIPPED_VERSION "${GIT_VERSION}") # Remove the 'v' prefix
|
||||||
|
string(REPLACE "-" ";" VERSION_LIST ${STRIPPED_VERSION})
|
||||||
|
list(GET VERSION_LIST 0 VERSION_STRING)
|
||||||
|
|
||||||
|
set(${VERSION_VAR} ${VERSION_STRING} PARENT_SCOPE)
|
||||||
|
else()
|
||||||
|
set(${VERSION_VAR} "0.0.0" PARENT_SCOPE)
|
||||||
|
endif()
|
||||||
|
endfunction()
|
@ -1,8 +1,12 @@
|
|||||||
cmake_minimum_required(VERSION 3.23.0)
|
cmake_minimum_required(VERSION 3.23.0)
|
||||||
|
|
||||||
|
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake" ${CMAKE_MODULE_PATH})
|
||||||
|
include(GetProjectVersion)
|
||||||
|
get_project_version(PROJECT_VERSION)
|
||||||
|
|
||||||
project(
|
project(
|
||||||
ScreenPlay
|
ScreenPlay
|
||||||
VERSION 0.15.0
|
VERSION ${PROJECT_VERSION}
|
||||||
DESCRIPTION "Modern, Cross Plattform, Live Wallpaper, Widgets and AppDrawer!"
|
DESCRIPTION "Modern, Cross Plattform, Live Wallpaper, Widgets and AppDrawer!"
|
||||||
HOMEPAGE_URL "https://screen-play.app/"
|
HOMEPAGE_URL "https://screen-play.app/"
|
||||||
LANGUAGES CXX)
|
LANGUAGES CXX)
|
||||||
@ -146,23 +150,28 @@ if(WIN32)
|
|||||||
add_subdirectory(ScreenPlaySysInfo)
|
add_subdirectory(ScreenPlaySysInfo)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(${SCREENPLAY_INSTALLER} AND NOT APPLE)
|
if(${SCREENPLAY_INSTALLER})
|
||||||
include(${CMAKE_CURRENT_SOURCE_DIR}/CMake/CreateIFWInstaller.cmake)
|
if(APPLE)
|
||||||
|
include(${CMAKE_CURRENT_SOURCE_DIR}/CMake/CreateDmgInstaller.cmake)
|
||||||
|
else()
|
||||||
|
include(${CMAKE_CURRENT_SOURCE_DIR}/CMake/CreateIFWInstaller.cmake)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
message(STATUS "[CPP DEFINE] DEPLOY_VERSION = ${DEPLOY_VERSION}")
|
message(STATUS "[PROJECT] PROJECT_VERSION = ${PROJECT_VERSION}")
|
||||||
message(STATUS "[CPP DEFINE] SOURCE_DIR = ${CMAKE_CURRENT_SOURCE_DIR}")
|
message(STATUS "[PROJECT] CMAKE_VERSION = ${CMAKE_VERSION}")
|
||||||
message(STATUS "[CPP DEFINE] BUILD_DATE = ${BUILD_DATE}")
|
|
||||||
message(STATUS "[DEFINE] BUILD_TYPE = ${CMAKE_BUILD_TYPE}")
|
|
||||||
message(STATUS "[DEFINE] GIT_COMMIT_HASH = ${GIT_COMMIT_HASH}")
|
|
||||||
message(STATUS "[OPTION] SCREENPLAY_DEPLOY = ${SCREENPLAY_DEPLOY}")
|
|
||||||
message(STATUS "[OPTION] SCREENPLAY_INSTALLER = ${SCREENPLAY_INSTALLER}")
|
|
||||||
message(STATUS "[OPTION] SCREENPLAY_STEAM = ${SCREENPLAY_STEAM}")
|
|
||||||
message(STATUS "[OPTION] SCREENPLAY_TESTS = ${SCREENPLAY_TESTS}")
|
|
||||||
message(STATUS "[PROJECT] SCREENPLAY_QML_MODULES_PATH = ${SCREENPLAY_QML_MODULES_PATH}")
|
message(STATUS "[PROJECT] SCREENPLAY_QML_MODULES_PATH = ${SCREENPLAY_QML_MODULES_PATH}")
|
||||||
message(STATUS "[PROJECT] CMAKE_TOOLCHAIN_FILE = ${CMAKE_TOOLCHAIN_FILE}")
|
message(STATUS "[PROJECT] CMAKE_TOOLCHAIN_FILE = ${CMAKE_TOOLCHAIN_FILE}")
|
||||||
message(STATUS "[PROJECT] VCPKG_PATH = ${VCPKG_PATH}")
|
message(STATUS "[PROJECT] VCPKG_PATH = ${VCPKG_PATH}")
|
||||||
message(STATUS "[PROJECT] CMAKE_MODULE_PATH = ${CMAKE_MODULE_PATH}")
|
message(STATUS "[PROJECT] CMAKE_MODULE_PATH = ${CMAKE_MODULE_PATH}")
|
||||||
message(STATUS "[PROJECT] VCPKG_TARGET_TRIPLET = ${VCPKG_TARGET_TRIPLET}")
|
message(STATUS "[PROJECT] VCPKG_TARGET_TRIPLET = ${VCPKG_TARGET_TRIPLET}")
|
||||||
message(STATUS "[PROJECT] CMAKE_PREFIX_PATH = ${CMAKE_PREFIX_PATH}")
|
message(STATUS "[PROJECT] CMAKE_PREFIX_PATH = ${CMAKE_PREFIX_PATH}")
|
||||||
message(STATUS "[PROJECT] CMAKE_VERSION = ${CMAKE_VERSION}")
|
message(STATUS "[OPTION] SCREENPLAY_DEPLOY = ${SCREENPLAY_DEPLOY}")
|
||||||
|
message(STATUS "[OPTION] SCREENPLAY_INSTALLER = ${SCREENPLAY_INSTALLER}")
|
||||||
|
message(STATUS "[OPTION] SCREENPLAY_STEAM = ${SCREENPLAY_STEAM}")
|
||||||
|
message(STATUS "[OPTION] SCREENPLAY_TESTS = ${SCREENPLAY_TESTS}")
|
||||||
|
message(STATUS "[DEFINE] BUILD_TYPE = ${CMAKE_BUILD_TYPE}")
|
||||||
|
message(STATUS "[DEFINE] GIT_COMMIT_HASH = ${GIT_COMMIT_HASH}")
|
||||||
|
message(STATUS "[CPP DEFINE] DEPLOY_VERSION = ${DEPLOY_VERSION}")
|
||||||
|
message(STATUS "[CPP DEFINE] SOURCE_DIR = ${CMAKE_CURRENT_SOURCE_DIR}")
|
||||||
|
message(STATUS "[CPP DEFINE] BUILD_DATE = ${BUILD_DATE}")
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
|
@ -42,19 +42,19 @@ Item {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
attractor.pointX = parent.width * .5
|
attractor.pointX = parent.width * .5;
|
||||||
attractor.pointY = 0
|
attractor.pointY = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
onPressed: {
|
onPressed: {
|
||||||
attractor.enabled = true
|
attractor.enabled = true;
|
||||||
}
|
}
|
||||||
onPositionChanged: {
|
onPositionChanged: {
|
||||||
attractor.pointX = mouseX
|
attractor.pointX = mouseX;
|
||||||
attractor.pointY = mouseY
|
attractor.pointY = mouseY;
|
||||||
}
|
}
|
||||||
onReleased: {
|
onReleased: {
|
||||||
attractor.enabled = false
|
attractor.enabled = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,7 +119,7 @@ Item {
|
|||||||
bottom: parent.bottom
|
bottom: parent.bottom
|
||||||
bottomMargin: -width * .65
|
bottomMargin: -width * .65
|
||||||
}
|
}
|
||||||
SequentialAnimation on opacity {
|
SequentialAnimation on opacity {
|
||||||
loops: Animation.Infinite
|
loops: Animation.Infinite
|
||||||
|
|
||||||
OpacityAnimator {
|
OpacityAnimator {
|
||||||
|
@ -8,32 +8,31 @@ Item {
|
|||||||
implicitHeight: 100
|
implicitHeight: 100
|
||||||
|
|
||||||
function timeChanged() {
|
function timeChanged() {
|
||||||
var date = new Date
|
var date = new Date;
|
||||||
var hours = ""
|
var hours = "";
|
||||||
var minutes = ""
|
var minutes = "";
|
||||||
var seconds = ""
|
var seconds = "";
|
||||||
if (date.getHours() < 10) {
|
if (date.getHours() < 10) {
|
||||||
hours = "0" + date.getHours().toString()
|
hours = "0" + date.getHours().toString();
|
||||||
} else {
|
} else {
|
||||||
hours = date.getHours().toString()
|
hours = date.getHours().toString();
|
||||||
}
|
}
|
||||||
if (date.getMinutes() < 10) {
|
if (date.getMinutes() < 10) {
|
||||||
minutes = "0" + date.getMinutes().toString()
|
minutes = "0" + date.getMinutes().toString();
|
||||||
} else {
|
} else {
|
||||||
minutes = date.getMinutes().toString()
|
minutes = date.getMinutes().toString();
|
||||||
}
|
}
|
||||||
if (date.getSeconds() < 10) {
|
if (date.getSeconds() < 10) {
|
||||||
seconds = "0" + date.getSeconds().toString()
|
seconds = "0" + date.getSeconds().toString();
|
||||||
} else {
|
} else {
|
||||||
seconds = date.getSeconds().toString()
|
seconds = date.getSeconds().toString();
|
||||||
}
|
}
|
||||||
var days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']
|
var days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
|
||||||
var months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
|
var months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
|
||||||
var day = days[date.getDay()]
|
var day = days[date.getDay()];
|
||||||
var month = months[date.getMonth()]
|
var month = months[date.getMonth()];
|
||||||
txtClock.text = hours + ":" + minutes + ":" + seconds
|
txtClock.text = hours + ":" + minutes + ":" + seconds;
|
||||||
txtDate.text = day + ", " + date.getDay(
|
txtDate.text = day + ", " + date.getDay() + " " + month + ", " + date.getFullYear();
|
||||||
) + " " + month + ", " + date.getFullYear()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Timer {
|
Timer {
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
@ -17,16 +16,16 @@ Item {
|
|||||||
property string link
|
property string link
|
||||||
property string mediaContent
|
property string mediaContent
|
||||||
onMediaContentChanged: {
|
onMediaContentChanged: {
|
||||||
print("src")
|
print("src");
|
||||||
const src = parseItem(model.mediaContent, 'url="', '"')
|
const src = parseItem(model.mediaContent, 'url="', '"');
|
||||||
print("src", src)
|
print("src", src);
|
||||||
//img.source = src;
|
//img.source = src;
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseItem(raw, startTag, endTag) {
|
function parseItem(raw, startTag, endTag) {
|
||||||
var startIdx = raw.indexOf(startTag) + startTag.length
|
var startIdx = raw.indexOf(startTag) + startTag.length;
|
||||||
var endIdx = raw.indexOf(endTag, startIdx)
|
var endIdx = raw.indexOf(endTag, startIdx);
|
||||||
return raw.substring(startIdx, endIdx)
|
return raw.substring(startIdx, endIdx);
|
||||||
}
|
}
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
@ -49,8 +48,8 @@ Item {
|
|||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
onClicked: {
|
onClicked: {
|
||||||
print(model.category)
|
print(model.category);
|
||||||
print(model.mediaContent)
|
print(model.mediaContent);
|
||||||
//Qt.openUrlExternally(model.link);
|
//Qt.openUrlExternally(model.link);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
@ -18,7 +17,7 @@ Item {
|
|||||||
query: "/rss/channel/item"
|
query: "/rss/channel/item"
|
||||||
onStatusChanged: {
|
onStatusChanged: {
|
||||||
if (status === XmlListModel.Error) {
|
if (status === XmlListModel.Error) {
|
||||||
console.log("Error: " + errorString)
|
console.log("Error: " + errorString);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,41 +12,38 @@ Item {
|
|||||||
property string pubDate
|
property string pubDate
|
||||||
property string pubDateFormatted
|
property string pubDateFormatted
|
||||||
onPubDateChanged: {
|
onPubDateChanged: {
|
||||||
var date = new Date(pubDate)
|
var date = new Date(pubDate);
|
||||||
root.pubDateFormatted = date.toLocaleDateString(
|
root.pubDateFormatted = date.toLocaleDateString(Qt.locale(), "ddd, dd MMM yyyy") + ' ' + date.toLocaleTimeString(Qt.locale(), "HH:mm:ss");
|
||||||
Qt.locale(),
|
|
||||||
"ddd, dd MMM yyyy") + ' ' + date.toLocaleTimeString(
|
|
||||||
Qt.locale(), "HH:mm:ss")
|
|
||||||
}
|
}
|
||||||
property string description
|
property string description
|
||||||
onDescriptionChanged: {
|
onDescriptionChanged: {
|
||||||
print("description")
|
print("description");
|
||||||
// See https://hnrss.org/frontpage <description> content
|
// See https://hnrss.org/frontpage <description> content
|
||||||
// We need to manually parse it here to get the points and comments
|
// We need to manually parse it here to get the points and comments
|
||||||
points = parsePoints(description)
|
points = parsePoints(description);
|
||||||
commentCount = parseCommentCount(description)
|
commentCount = parseCommentCount(description);
|
||||||
print(points, commentCount)
|
print(points, commentCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseCommentCount(raw) {
|
function parseCommentCount(raw) {
|
||||||
var commentPrefix = "<p># Comments: "
|
var commentPrefix = "<p># Comments: ";
|
||||||
var commentSuffix = "</p>"
|
var commentSuffix = "</p>";
|
||||||
var startIdx = raw.indexOf(commentPrefix)
|
var startIdx = raw.indexOf(commentPrefix);
|
||||||
if (startIdx === -1)
|
if (startIdx === -1)
|
||||||
return "N/A" // return "N/A" if comment count is not found in the description
|
return "N/A"; // return "N/A" if comment count is not found in the description
|
||||||
startIdx += commentPrefix.length
|
startIdx += commentPrefix.length;
|
||||||
var endIdx = raw.indexOf(commentSuffix, startIdx)
|
var endIdx = raw.indexOf(commentSuffix, startIdx);
|
||||||
return raw.substring(startIdx, endIdx)
|
return raw.substring(startIdx, endIdx);
|
||||||
}
|
}
|
||||||
function parsePoints(raw) {
|
function parsePoints(raw) {
|
||||||
var pointsPrefix = "<p>Points: "
|
var pointsPrefix = "<p>Points: ";
|
||||||
var pointsSuffix = "</p>"
|
var pointsSuffix = "</p>";
|
||||||
var startIdx = raw.indexOf(pointsPrefix)
|
var startIdx = raw.indexOf(pointsPrefix);
|
||||||
if (startIdx === -1)
|
if (startIdx === -1)
|
||||||
return "N/A" // return "N/A" if points are not found in the description
|
return "N/A"; // return "N/A" if points are not found in the description
|
||||||
startIdx += pointsPrefix.length
|
startIdx += pointsPrefix.length;
|
||||||
var endIdx = raw.indexOf(pointsSuffix, startIdx)
|
var endIdx = raw.indexOf(pointsSuffix, startIdx);
|
||||||
return raw.substring(startIdx, endIdx)
|
return raw.substring(startIdx, endIdx);
|
||||||
}
|
}
|
||||||
RowLayout {
|
RowLayout {
|
||||||
id: wrapper
|
id: wrapper
|
||||||
@ -68,15 +65,14 @@ Item {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onClicked: {
|
||||||
Qt.openUrlExternally(model.link)
|
Qt.openUrlExternally(model.link);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
id: descriptionText
|
id: descriptionText
|
||||||
text: root.points + " Points • " + root.commentCount
|
text: root.points + " Points • " + root.commentCount + " Comments 🔗 " + "• Published: " + root.pubDateFormatted
|
||||||
+ " Comments 🔗 " + "• Published: " + root.pubDateFormatted
|
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
font.pointSize: 10
|
font.pointSize: 10
|
||||||
opacity: .7
|
opacity: .7
|
||||||
@ -85,7 +81,7 @@ Item {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onClicked: {
|
||||||
Qt.openUrlExternally(model.commentsLink)
|
Qt.openUrlExternally(model.commentsLink);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
@ -44,7 +43,7 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
onActivated: {
|
onActivated: {
|
||||||
rssModel.source = combo.currentValue
|
rssModel.source = combo.currentValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ToolButton {
|
ToolButton {
|
||||||
@ -79,10 +78,10 @@ Item {
|
|||||||
source: combo.currentValue
|
source: combo.currentValue
|
||||||
query: "/rss/channel/item"
|
query: "/rss/channel/item"
|
||||||
function load() {
|
function load() {
|
||||||
print(":load")
|
print(":load");
|
||||||
var tempSource = rssModel.source
|
var tempSource = rssModel.source;
|
||||||
rssModel.source = ""
|
rssModel.source = "";
|
||||||
rssModel.source = tempSource
|
rssModel.source = tempSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
XmlListModelRole {
|
XmlListModelRole {
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
@ -28,11 +27,11 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function stringListToString(list) {
|
function stringListToString(list) {
|
||||||
let out = ""
|
let out = "";
|
||||||
for (var i = 0; i < list.length; i++) {
|
for (var i = 0; i < list.length; i++) {
|
||||||
out += "\n" + list[i]
|
out += "\n" + list[i];
|
||||||
}
|
}
|
||||||
return out
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
@ -57,8 +56,7 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Text {
|
Text {
|
||||||
text: root.stringListToString(
|
text: root.stringListToString(ipAddress.privateIpV4AddressList)
|
||||||
ipAddress.privateIpV4AddressList)
|
|
||||||
color: root.accentColor
|
color: root.accentColor
|
||||||
font {
|
font {
|
||||||
pointSize: 16
|
pointSize: 16
|
||||||
@ -66,8 +64,7 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Text {
|
Text {
|
||||||
text: root.stringListToString(
|
text: root.stringListToString(ipAddress.privateIpV6AddressList)
|
||||||
ipAddress.privateIpV6AddressList)
|
|
||||||
color: root.accentColor
|
color: root.accentColor
|
||||||
font {
|
font {
|
||||||
pointSize: 16
|
pointSize: 16
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
@ -20,56 +19,57 @@ Item {
|
|||||||
id: weather
|
id: weather
|
||||||
city: "Friedrichshafen"
|
city: "Friedrichshafen"
|
||||||
onReady: {
|
onReady: {
|
||||||
rp.model = weather.days
|
rp.model = weather.days;
|
||||||
// Qt bug https://bugreports.qt.io/browse/QTBUG-105137
|
// Qt bug https://bugreports.qt.io/browse/QTBUG-105137
|
||||||
test()
|
test();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function test() {}
|
function test() {
|
||||||
|
}
|
||||||
|
|
||||||
function mapWeatherCode(code) {
|
function mapWeatherCode(code) {
|
||||||
const weather_time = ""
|
const weather_time = "";
|
||||||
// or "-day", "-night"
|
// or "-day", "-night"
|
||||||
const weather_prefix = "wi" + weather_time + "-"
|
const weather_prefix = "wi" + weather_time + "-";
|
||||||
// https://open-meteo.com/en/docs
|
// https://open-meteo.com/en/docs
|
||||||
// WMO Weather interpretation codes (WW)
|
// WMO Weather interpretation codes (WW)
|
||||||
// to https://erikflowers.github.io/weather-icons/
|
// to https://erikflowers.github.io/weather-icons/
|
||||||
switch (code) {
|
switch (code) {
|
||||||
case 0:
|
case 0:
|
||||||
return weather_prefix + "day-sunny"
|
return weather_prefix + "day-sunny";
|
||||||
case 1:
|
case 1:
|
||||||
case 2:
|
case 2:
|
||||||
case 3:
|
case 3:
|
||||||
return weather_prefix + "cloud"
|
return weather_prefix + "cloud";
|
||||||
case 45:
|
case 45:
|
||||||
case 48:
|
case 48:
|
||||||
return weather_prefix + "day-sunny"
|
return weather_prefix + "day-sunny";
|
||||||
case 51:
|
case 51:
|
||||||
case 53:
|
case 53:
|
||||||
case 55:
|
case 55:
|
||||||
return weather_prefix + "rain-mix"
|
return weather_prefix + "rain-mix";
|
||||||
case 61:
|
case 61:
|
||||||
case 63:
|
case 63:
|
||||||
case 65:
|
case 65:
|
||||||
return weather_prefix + "rain-mix"
|
return weather_prefix + "rain-mix";
|
||||||
case 71:
|
case 71:
|
||||||
case 73:
|
case 73:
|
||||||
case 75:
|
case 75:
|
||||||
return weather_prefix + "snow"
|
return weather_prefix + "snow";
|
||||||
case 77:
|
case 77:
|
||||||
return weather_prefix + "snow"
|
return weather_prefix + "snow";
|
||||||
case 80:
|
case 80:
|
||||||
case 81:
|
case 81:
|
||||||
case 82:
|
case 82:
|
||||||
return weather_prefix + "snow"
|
return weather_prefix + "snow";
|
||||||
case 85:
|
case 85:
|
||||||
case 86:
|
case 86:
|
||||||
return weather_prefix + "snow"
|
return weather_prefix + "snow";
|
||||||
case 95:
|
case 95:
|
||||||
return weather_prefix + "thunderstorm"
|
return weather_prefix + "thunderstorm";
|
||||||
case 96:
|
case 96:
|
||||||
case 99:
|
case 99:
|
||||||
return weather_prefix + "storm-showers"
|
return weather_prefix + "storm-showers";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,9 +89,7 @@ Item {
|
|||||||
Layout.alignment: Qt.AlignCenter
|
Layout.alignment: Qt.AlignCenter
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
color: Material.primaryTextColor
|
color: Material.primaryTextColor
|
||||||
text: "longtitude: " + weather.longtitude + " - latitude: "
|
text: "longtitude: " + weather.longtitude + " - latitude: " + weather.latitude + " - elevation: " + weather.elevation + "m - population: " + weather.population
|
||||||
+ weather.latitude + " - elevation: " + weather.elevation
|
|
||||||
+ "m - population: " + weather.population
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
@ -129,8 +127,7 @@ Item {
|
|||||||
}
|
}
|
||||||
Layout.alignment: Qt.AlignCenter
|
Layout.alignment: Qt.AlignCenter
|
||||||
horizontalAlignment: Image.AlignHCenter
|
horizontalAlignment: Image.AlignHCenter
|
||||||
source: "qrc:/qml/ScreenPlayWeather/assets/icons/" + root.mapWeatherCode(
|
source: "qrc:/qml/ScreenPlayWeather/assets/icons/" + root.mapWeatherCode(weatherCode) + ".svg"
|
||||||
weatherCode) + ".svg"
|
|
||||||
}
|
}
|
||||||
TextItem {
|
TextItem {
|
||||||
text: "Weather Code"
|
text: "Weather Code"
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
@ -15,27 +14,27 @@ Item {
|
|||||||
property int defaultHeight: 200
|
property int defaultHeight: 200
|
||||||
|
|
||||||
function request(url, callback) {
|
function request(url, callback) {
|
||||||
var xhr = new XMLHttpRequest()
|
var xhr = new XMLHttpRequest();
|
||||||
xhr.onreadystatechange = (function (myxhr) {
|
xhr.onreadystatechange = (function (myxhr) {
|
||||||
return function () {
|
return function () {
|
||||||
if (myxhr.readyState === 4)
|
if (myxhr.readyState === 4)
|
||||||
callback(myxhr)
|
callback(myxhr);
|
||||||
}
|
};
|
||||||
})(xhr)
|
})(xhr);
|
||||||
xhr.open('GET', url)
|
xhr.open('GET', url);
|
||||||
xhr.send('')
|
xhr.send('');
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
request("http://xkcd.com/info.0.json", function (o) {
|
request("http://xkcd.com/info.0.json", function (o) {
|
||||||
if (o.status === 200) {
|
if (o.status === 200) {
|
||||||
var d = eval('new Object(' + o.responseText + ')')
|
var d = eval('new Object(' + o.responseText + ')');
|
||||||
console.log(o.responseText)
|
console.log(o.responseText);
|
||||||
img.source = d.img
|
img.source = d.img;
|
||||||
} else {
|
} else {
|
||||||
console.log("Some error has occurred")
|
console.log("Some error has occurred");
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
@ -45,22 +44,22 @@ Item {
|
|||||||
property size imgSize: Qt.size(root.defaultWidth, defaultHeight)
|
property size imgSize: Qt.size(root.defaultWidth, defaultHeight)
|
||||||
onStatusChanged: {
|
onStatusChanged: {
|
||||||
if (img.status !== Image.Ready)
|
if (img.status !== Image.Ready)
|
||||||
return
|
return;
|
||||||
if (img.sourceSize.width === 0 || img.sourceSize.height === 0)
|
if (img.sourceSize.width === 0 || img.sourceSize.height === 0)
|
||||||
return
|
return;
|
||||||
root.implicitWidth = img.sourceSize.width
|
root.implicitWidth = img.sourceSize.width;
|
||||||
root.implicitHeight = img.sourceSize.height
|
root.implicitHeight = img.sourceSize.height;
|
||||||
print(img.status, img.sourceSize.width, img.sourceSize.height)
|
print(img.status, img.sourceSize.width, img.sourceSize.height);
|
||||||
img.imgSize = Qt.size(img.sourceSize.width, img.sourceSize.height)
|
img.imgSize = Qt.size(img.sourceSize.width, img.sourceSize.height);
|
||||||
print("img.size", img.imgSize)
|
print("img.size", img.imgSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
onClicked: {
|
onClicked: {
|
||||||
root.state = root.state === "expanded" ? "normal" : "expanded"
|
root.state = root.state === "expanded" ? "normal" : "expanded";
|
||||||
print(root.state, root.implicitHeight, root.implicitWidth)
|
print(root.state, root.implicitHeight, root.implicitWidth);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,17 +11,9 @@ Item {
|
|||||||
implicitWidth: 240
|
implicitWidth: 240
|
||||||
implicitHeight: 120
|
implicitHeight: 120
|
||||||
property int totalHours: 24
|
property int totalHours: 24
|
||||||
property int remainingHours: Math.max(0, Math.floor(
|
property int remainingHours: Math.max(0, Math.floor((new Date().setHours(24, 0, 0, 0) - new Date()) / 3600000))
|
||||||
(new Date().setHours(
|
property int totalDays: new Date(new Date().getFullYear() + 1, 0, 1) - new Date() / (24 * 60 * 60 * 1000)
|
||||||
24, 0, 0,
|
property int remainingDays: Math.max(0, Math.floor((new Date(new Date().getFullYear() + 1, 0, 1) - new Date()) / (24 * 60 * 60 * 1000)))
|
||||||
0) - new Date()) / 3600000))
|
|
||||||
property int totalDays: new Date(new Date().getFullYear() + 1, 0,
|
|
||||||
1) - new Date() / (24 * 60 * 60 * 1000)
|
|
||||||
property int remainingDays: Math.max(
|
|
||||||
0, Math.floor(
|
|
||||||
(new Date(new Date().getFullYear() + 1,
|
|
||||||
0,
|
|
||||||
1) - new Date()) / (24 * 60 * 60 * 1000)))
|
|
||||||
|
|
||||||
Material.theme: Material.Dark
|
Material.theme: Material.Dark
|
||||||
Material.accent: Material.DeepOrange
|
Material.accent: Material.DeepOrange
|
||||||
@ -50,11 +42,7 @@ Item {
|
|||||||
running: true
|
running: true
|
||||||
repeat: true
|
repeat: true
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
remainingHours = Math.max(
|
remainingHours = Math.max(0, Math.floor((new Date().setHours(24, 0, 0, 0) - new Date()) / 3600000));
|
||||||
0,
|
|
||||||
Math.floor((new Date().setHours(
|
|
||||||
24, 0, 0,
|
|
||||||
0) - new Date()) / 3600000))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -81,11 +69,7 @@ Item {
|
|||||||
running: true
|
running: true
|
||||||
repeat: true
|
repeat: true
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
remainingDays = Math.max(0,
|
remainingDays = Math.max(0, Math.floor((new Date(new Date().getFullYear() + 1, 0, 1) - new Date()) / (24 * 60 * 60 * 1000)));
|
||||||
Math.floor((new Date(new Date().getFullYear(
|
|
||||||
) + 1,
|
|
||||||
0, 1)
|
|
||||||
- new Date()) / (24 * 60 * 60 * 1000)))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -138,6 +138,7 @@ set(RESOURCES
|
|||||||
assets/icons/icon_close.svg
|
assets/icons/icon_close.svg
|
||||||
assets/icons/icon_code.svg
|
assets/icons/icon_code.svg
|
||||||
assets/icons/icon_community.svg
|
assets/icons/icon_community.svg
|
||||||
|
assets/icons/icon_contains_audio.svg
|
||||||
assets/icons/icon_delete.svg
|
assets/icons/icon_delete.svg
|
||||||
assets/icons/icon_document.svg
|
assets/icons/icon_document.svg
|
||||||
assets/icons/icon_done.svg
|
assets/icons/icon_done.svg
|
||||||
@ -152,7 +153,6 @@ set(RESOURCES
|
|||||||
assets/icons/icon_installed.svg
|
assets/icons/icon_installed.svg
|
||||||
assets/icons/icon_launch.svg
|
assets/icons/icon_launch.svg
|
||||||
assets/icons/icon_minimize.svg
|
assets/icons/icon_minimize.svg
|
||||||
assets/icons/icon_contains_audio.svg
|
|
||||||
assets/icons/icon_movie.svg
|
assets/icons/icon_movie.svg
|
||||||
assets/icons/icon_new_releases.svg
|
assets/icons/icon_new_releases.svg
|
||||||
assets/icons/icon_open_in_new.svg
|
assets/icons/icon_open_in_new.svg
|
||||||
|
@ -470,7 +470,7 @@ private:
|
|||||||
bool m_checkWallpaperVisible { false };
|
bool m_checkWallpaperVisible { false };
|
||||||
bool m_silentStart { false };
|
bool m_silentStart { false };
|
||||||
bool m_anonymousTelemetry { true };
|
bool m_anonymousTelemetry { true };
|
||||||
bool m_showDefaultContent { true };
|
bool m_showDefaultContent { false };
|
||||||
|
|
||||||
QString m_decoder;
|
QString m_decoder;
|
||||||
ScreenPlay::FillMode::FillMode m_videoFillMode { ScreenPlay::FillMode::FillMode::Cover };
|
ScreenPlay::FillMode::FillMode m_videoFillMode { ScreenPlay::FillMode::FillMode::Cover };
|
||||||
|
@ -65,7 +65,7 @@ ApplicationWindow {
|
|||||||
screenSize: Qt.size(root.width, root.height)
|
screenSize: Qt.size(root.width, root.height)
|
||||||
domain: "app.screen-play.app"
|
domain: "app.screen-play.app"
|
||||||
debug: false
|
debug: false
|
||||||
enabled: App.settings.anonymousTelemetry
|
enabled: false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Partial workaround for
|
// Partial workaround for
|
||||||
|
@ -175,7 +175,6 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
id: icnType
|
id: icnType
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ Item {
|
|||||||
const item = App.installedListModel.get(root.contentFolderName);
|
const item = App.installedListModel.get(root.contentFolderName);
|
||||||
txtHeadline.text = item.m_title;
|
txtHeadline.text = item.m_title;
|
||||||
const previewGiFilePath = Qt.resolvedUrl(item.m_absoluteStoragePath + "/" + item.m_previewGIF);
|
const previewGiFilePath = Qt.resolvedUrl(item.m_absoluteStoragePath + "/" + item.m_previewGIF);
|
||||||
const previewImageFilePath = Qt.resolvedUrl( item.m_absoluteStoragePath + "/" + item.m_preview);
|
const previewImageFilePath = Qt.resolvedUrl(item.m_absoluteStoragePath + "/" + item.m_preview);
|
||||||
root.hasPreviewGif = App.util.fileExists(previewGiFilePath);
|
root.hasPreviewGif = App.util.fileExists(previewGiFilePath);
|
||||||
if (hasPreviewGif) {
|
if (hasPreviewGif) {
|
||||||
animatedImagePreview.source = previewGiFilePath;
|
animatedImagePreview.source = previewGiFilePath;
|
||||||
|
@ -82,7 +82,7 @@ Item {
|
|||||||
isChecked: App.settings.showDefaultContent
|
isChecked: App.settings.showDefaultContent
|
||||||
onCheckboxChanged: function (checked) {
|
onCheckboxChanged: function (checked) {
|
||||||
App.settings.setShowDefaultContent(checked);
|
App.settings.setShowDefaultContent(checked);
|
||||||
App.installedListModel.reset()
|
App.installedListModel.reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,20 +186,19 @@ void ScreenPlaySDK::ScreenPlaySDK::redirectMessageOutputToMainWindow(QtMsgType t
|
|||||||
|
|
||||||
// Also redirect to regular output if we debug
|
// Also redirect to regular output if we debug
|
||||||
// wallpaper or widgets directly
|
// wallpaper or widgets directly
|
||||||
switch (type)
|
switch (type) {
|
||||||
{
|
|
||||||
case QtDebugMsg:
|
case QtDebugMsg:
|
||||||
qDebug() << msg;
|
qDebug() << msg;
|
||||||
break;
|
break;
|
||||||
case QtWarningMsg:
|
case QtWarningMsg:
|
||||||
qWarning() << msg;
|
qWarning() << msg;
|
||||||
break;
|
break;
|
||||||
case QtCriticalMsg:
|
case QtCriticalMsg:
|
||||||
case QtFatalMsg:
|
case QtFatalMsg:
|
||||||
qCritical() << msg;
|
qCritical() << msg;
|
||||||
break;
|
break;
|
||||||
case QtInfoMsg:
|
case QtInfoMsg:
|
||||||
qInfo() << msg;
|
qInfo() << msg;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -27,9 +27,9 @@ bool ProjectFile::init()
|
|||||||
return false;
|
return false;
|
||||||
file = obj.value("file").toString();
|
file = obj.value("file").toString();
|
||||||
|
|
||||||
QFileInfo fileInfo(folder.path() + "/"+ file);
|
QFileInfo fileInfo(folder.path() + "/" + file);
|
||||||
if(!fileInfo.exists()){
|
if (!fileInfo.exists()) {
|
||||||
qCritical() << "Requested file:" << fileInfo.absoluteFilePath() << "does not exist!";
|
qCritical() << "Requested file:" << fileInfo.absoluteFilePath() << "does not exist!";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,7 +107,7 @@ bool ProjectFile::init()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == ScreenPlay::InstalledType::InstalledType::VideoWallpaper){
|
if (type == ScreenPlay::InstalledType::InstalledType::VideoWallpaper) {
|
||||||
QFileInfo audioFile(folder.absolutePath() + "/audio.mp3");
|
QFileInfo audioFile(folder.absolutePath() + "/audio.mp3");
|
||||||
containsAudio = audioFile.exists();
|
containsAudio = audioFile.exists();
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@ Item {
|
|||||||
onPlaybackStateChanged: {
|
onPlaybackStateChanged: {
|
||||||
if (mediaPlayer.playbackState == MediaPlayer.PlayingState && !fadeInDone) {
|
if (mediaPlayer.playbackState == MediaPlayer.PlayingState && !fadeInDone) {
|
||||||
fadeInDone = true;
|
fadeInDone = true;
|
||||||
startTimer.start()
|
startTimer.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
loops: root.loops ? MediaPlayer.Infinite : 1
|
loops: root.loops ? MediaPlayer.Infinite : 1
|
||||||
@ -72,8 +72,7 @@ Item {
|
|||||||
id: pauseTimer
|
id: pauseTimer
|
||||||
interval: 100
|
interval: 100
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
mediaPlayer.pause()
|
mediaPlayer.pause();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Connections {
|
Connections {
|
||||||
@ -96,12 +95,12 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function onVisualsPausedChanged(visualsPaused) {
|
function onVisualsPausedChanged(visualsPaused) {
|
||||||
if(!Wallpaper.isPlaying)
|
if (!Wallpaper.isPlaying)
|
||||||
return
|
return;
|
||||||
if(visualsPaused)
|
if (visualsPaused)
|
||||||
pauseTimer.start()
|
pauseTimer.start();
|
||||||
else
|
else
|
||||||
mediaPlayer.play()
|
mediaPlayer.play();
|
||||||
}
|
}
|
||||||
|
|
||||||
target: Wallpaper
|
target: Wallpaper
|
||||||
|
@ -60,8 +60,8 @@ ScreenPlay::WallpaperExitCode BaseWindow::setup()
|
|||||||
|
|
||||||
// We do not yet have implemented continue playing the audio.mp3 yet
|
// We do not yet have implemented continue playing the audio.mp3 yet
|
||||||
// so disable the checkWallpaperVisible for now
|
// so disable the checkWallpaperVisible for now
|
||||||
if(checkWallpaperVisible()){
|
if (checkWallpaperVisible()) {
|
||||||
if(projectFile.containsAudio){
|
if (projectFile.containsAudio) {
|
||||||
qInfo() << "Disable wallpaper visible check, because it contains audio.";
|
qInfo() << "Disable wallpaper visible check, because it contains audio.";
|
||||||
setCheckWallpaperVisible(false);
|
setCheckWallpaperVisible(false);
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ int main(int argc, char* argv[])
|
|||||||
QtWebEngineQuick::initialize();
|
QtWebEngineQuick::initialize();
|
||||||
|
|
||||||
#if defined(Q_OS_WIN)
|
#if defined(Q_OS_WIN)
|
||||||
// Workaround for Qt 6.5.1 crash https://bugreports.qt.io/browse/QTBUG-113832
|
// Workaround for Qt 6.5.1 crash https://bugreports.qt.io/browse/QTBUG-113832
|
||||||
qputenv("QT_DISABLE_HW_TEXTURES_CONVERSION", "1");
|
qputenv("QT_DISABLE_HW_TEXTURES_CONVERSION", "1");
|
||||||
qputenv("QT_MEDIA_BACKEND", "ffmpeg");
|
qputenv("QT_MEDIA_BACKEND", "ffmpeg");
|
||||||
#endif
|
#endif
|
||||||
@ -55,8 +55,8 @@ int main(int argc, char* argv[])
|
|||||||
|
|
||||||
// Lets center the widget
|
// Lets center the widget
|
||||||
const auto* screen = QGuiApplication::screens().at(0);
|
const auto* screen = QGuiApplication::screens().at(0);
|
||||||
const int offset = - 200;
|
const int offset = -200;
|
||||||
QPoint center((screen->size().width() / 2) + offset, (screen->size().height() / 2)+offset);
|
QPoint center((screen->size().width() / 2) + offset, (screen->size().height() / 2) + offset);
|
||||||
|
|
||||||
WidgetWindow spwmw(projectPath,
|
WidgetWindow spwmw(projectPath,
|
||||||
"appid",
|
"appid",
|
||||||
|
174
Tools/build.py
174
Tools/build.py
@ -8,10 +8,12 @@ import argparse
|
|||||||
import time
|
import time
|
||||||
import zipfile
|
import zipfile
|
||||||
import defines
|
import defines
|
||||||
|
from build_result import BuildResult
|
||||||
|
from build_config import BuildConfig
|
||||||
from typing import Tuple
|
from typing import Tuple
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import macos_sign
|
import macos_sign
|
||||||
from util import sha256, cd_repo_root_path,repo_root_path, zipdir, run, get_vs_env_dict
|
from util import sha256, cd_repo_root_path, repo_root_path, zipdir, run, get_vs_env_dict, get_latest_git_tag, parse_semver, semver_to_string
|
||||||
from sys import stdout
|
from sys import stdout
|
||||||
|
|
||||||
stdout.reconfigure(encoding='utf-8')
|
stdout.reconfigure(encoding='utf-8')
|
||||||
@ -25,54 +27,6 @@ def clean_build_dir(build_dir):
|
|||||||
build_dir.mkdir(parents=True, exist_ok=True)
|
build_dir.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
|
||||||
class BuildResult:
|
|
||||||
# Windows example with absolute paths:
|
|
||||||
# [...]/build-x64-windows-release/
|
|
||||||
build: Path
|
|
||||||
# [...]/build-x64-windows-release/bin
|
|
||||||
bin: Path
|
|
||||||
# [...]/build-x64-windows-release/ScreenPlay-Installer.exe
|
|
||||||
installer: Path
|
|
||||||
# [...]/build-x64-windows-release/ScreenPlay-Installer.zip
|
|
||||||
installer_zip: Path
|
|
||||||
# [...]/build-x64-windows-release/ScreenPlay-0.X.0-RCX-x64-windows-release.zip
|
|
||||||
build_zip: Path
|
|
||||||
# [...]/build-x64-windows-release/ScreenPlay-0.X.0-RCX-x64-windows-release.txt :sha256, needed for scoop
|
|
||||||
build_hash: Path
|
|
||||||
# x64, arm64, universal
|
|
||||||
build_arch: str
|
|
||||||
|
|
||||||
class BuildConfig:
|
|
||||||
root_path: str
|
|
||||||
cmake_osx_architectures: str
|
|
||||||
cmake_target_triplet: str
|
|
||||||
package: bool
|
|
||||||
osx_bundle: str
|
|
||||||
package_command: str
|
|
||||||
executable_file_ending: str
|
|
||||||
# qt_* use either aqt or from the maintenance tool
|
|
||||||
qt_path: str # C:\Qt
|
|
||||||
qt_bin_path: str # C:\Qt\6.3.2\msvc2019_64
|
|
||||||
qt_version: str
|
|
||||||
qt_ifw_version: str
|
|
||||||
ifw_root_path: str
|
|
||||||
cmake_toolchain_file: str
|
|
||||||
aqt_install_qt_packages: str
|
|
||||||
aqt_install_tool_packages: str
|
|
||||||
executable_file_ending: str
|
|
||||||
build_folder: str
|
|
||||||
bin_dir: str
|
|
||||||
screenplay_version: str
|
|
||||||
# CMake variables need str: "ON" or "OFF"
|
|
||||||
build_steam: str
|
|
||||||
build_tests: str
|
|
||||||
build_deploy: str
|
|
||||||
build_type: str
|
|
||||||
build_architecture: str
|
|
||||||
create_installer: str
|
|
||||||
sign_osx: bool
|
|
||||||
|
|
||||||
|
|
||||||
def execute(
|
def execute(
|
||||||
build_config: BuildConfig
|
build_config: BuildConfig
|
||||||
) -> BuildResult:
|
) -> BuildResult:
|
||||||
@ -95,7 +49,7 @@ def execute(
|
|||||||
step_time = time.time()
|
step_time = time.time()
|
||||||
build_result = build(build_config, build_result)
|
build_result = build(build_config, build_result)
|
||||||
build_duration = time.time() - step_time
|
build_duration = time.time() - step_time
|
||||||
#print(f"⏱️ build_duration (for {build_config.build_architecture}): {build_duration}s")
|
print(f"⏱️ build_duration: {build_duration}s")
|
||||||
|
|
||||||
# Copies all needed libraries and assets into the bin folder
|
# Copies all needed libraries and assets into the bin folder
|
||||||
step_time = time.time()
|
step_time = time.time()
|
||||||
@ -103,6 +57,11 @@ def execute(
|
|||||||
package_duration = time.time() - step_time
|
package_duration = time.time() - step_time
|
||||||
print(f"⏱️ package_duration: {package_duration}s")
|
print(f"⏱️ package_duration: {package_duration}s")
|
||||||
|
|
||||||
|
if platform.system() == "Darwin":
|
||||||
|
if (build_config.sign_osx):
|
||||||
|
print(f"Sign binary at: {build_config.bin_dir}")
|
||||||
|
macos_sign.sign(build_config=build_config)
|
||||||
|
|
||||||
# Creates a Qt InstallerFrameWork (IFW) installer
|
# Creates a Qt InstallerFrameWork (IFW) installer
|
||||||
if build_config.create_installer == "ON":
|
if build_config.create_installer == "ON":
|
||||||
step_time = time.time()
|
step_time = time.time()
|
||||||
@ -110,8 +69,14 @@ def execute(
|
|||||||
build_installer_duration = time.time() - step_time
|
build_installer_duration = time.time() - step_time
|
||||||
print(f"⏱️ build_installer_duration: {build_installer_duration}s")
|
print(f"⏱️ build_installer_duration: {build_installer_duration}s")
|
||||||
|
|
||||||
# Create a zip file for scoop & chocolatey
|
if platform.system() == "Darwin":
|
||||||
if platform.system() == "Windows":
|
if (build_config.sign_osx):
|
||||||
|
print(
|
||||||
|
f"Sign ScreenPlay-installer.dmg at: {build_config.bin_dir}")
|
||||||
|
macos_sign.sign_dmg(build_config=build_config)
|
||||||
|
|
||||||
|
# Create a zip file of the build
|
||||||
|
if platform.system() != "Darwin":
|
||||||
step_time = time.time()
|
step_time = time.time()
|
||||||
build_result = zip(build_config, build_result)
|
build_result = zip(build_config, build_result)
|
||||||
zip_duration = time.time() - step_time
|
zip_duration = time.time() - step_time
|
||||||
@ -122,9 +87,11 @@ def execute(
|
|||||||
|
|
||||||
# Print BuildConfig & BuildResult member for easier debugging
|
# Print BuildConfig & BuildResult member for easier debugging
|
||||||
print("\n🆗 BuildResult:")
|
print("\n🆗 BuildResult:")
|
||||||
print(' '.join("\n- %s: \t\t%s" % item for item in vars(build_result).items()))
|
print(' '.join("\n- %s: \t\t%s" %
|
||||||
|
item for item in vars(build_result).items()))
|
||||||
print("\n⚙️ BuildConfig:")
|
print("\n⚙️ BuildConfig:")
|
||||||
print(' '.join("\n- %s: \t\t%s" % item for item in vars(build_config).items()))
|
print(' '.join("\n- %s: \t\t%s" %
|
||||||
|
item for item in vars(build_config).items()))
|
||||||
|
|
||||||
return build_result
|
return build_result
|
||||||
|
|
||||||
@ -134,10 +101,13 @@ def setup(build_config: BuildConfig) -> Tuple[BuildConfig, BuildResult]:
|
|||||||
build_config.qt_path = defines.QT_PATH
|
build_config.qt_path = defines.QT_PATH
|
||||||
|
|
||||||
if not build_config.qt_path.exists():
|
if not build_config.qt_path.exists():
|
||||||
print(f"Qt path does not exist at {build_config.qt_path}. Please make sure to run setup.py!")
|
print(
|
||||||
|
f"Qt path does not exist at {build_config.qt_path}. Please make sure to run setup.py!")
|
||||||
exit(2)
|
exit(2)
|
||||||
build_config.qt_bin_path = Path(build_config.qt_path).joinpath(f"{build_config.qt_version}/{defines.QT_PLATFORM}").resolve()
|
build_config.qt_bin_path = Path(build_config.qt_path).joinpath(
|
||||||
build_config.ifw_root_path = Path(f"{build_config.qt_path}/Tools/QtInstallerFramework/{build_config.qt_ifw_version}").resolve()
|
f"{build_config.qt_version}/{defines.QT_PLATFORM}").resolve()
|
||||||
|
build_config.ifw_root_path = Path(
|
||||||
|
f"{build_config.qt_path}/Tools/QtInstallerFramework/{build_config.qt_ifw_version}").resolve()
|
||||||
|
|
||||||
if platform.system() == "Windows":
|
if platform.system() == "Windows":
|
||||||
build_config.cmake_target_triplet = "x64-windows"
|
build_config.cmake_target_triplet = "x64-windows"
|
||||||
@ -157,7 +127,7 @@ def setup(build_config: BuildConfig) -> Tuple[BuildConfig, BuildResult]:
|
|||||||
build_config.cmake_target_triplet = "64-osx-universal"
|
build_config.cmake_target_triplet = "64-osx-universal"
|
||||||
build_config.executable_file_ending = ".app"
|
build_config.executable_file_ending = ".app"
|
||||||
# NO f string we fill it later!
|
# NO f string we fill it later!
|
||||||
#build_config.package_command = "{prefix_path}/bin/macdeployqt ScreenPlay.app -qmldir=../../{app}/qml -executable=ScreenPlay.app/Contents/MacOS/{app} -appstore-compliant -timestamp -hardened-runtime"
|
# build_config.package_command = "{prefix_path}/bin/macdeployqt ScreenPlay.app -qmldir=../../{app}/qml -executable=ScreenPlay.app/Contents/MacOS/{app} -appstore-compliant -timestamp -hardened-runtime"
|
||||||
build_config.aqt_install_qt_packages = f"mac desktop {build_config.qt_version} clang_64 -m all"
|
build_config.aqt_install_qt_packages = f"mac desktop {build_config.qt_version} clang_64 -m all"
|
||||||
build_config.aqt_install_tool_packages = "mac desktop tools_ifw"
|
build_config.aqt_install_tool_packages = "mac desktop tools_ifw"
|
||||||
|
|
||||||
@ -171,21 +141,27 @@ def setup(build_config: BuildConfig) -> Tuple[BuildConfig, BuildResult]:
|
|||||||
"Unsupported platform, ScreenPlay only supports Windows, macOS and Linux.")
|
"Unsupported platform, ScreenPlay only supports Windows, macOS and Linux.")
|
||||||
|
|
||||||
# Prepare
|
# Prepare
|
||||||
build_config.cmake_toolchain_file = Path(f"{build_config.root_path}/../vcpkg/scripts/buildsystems/vcpkg.cmake").resolve()
|
build_config.cmake_toolchain_file = Path(
|
||||||
|
f"{build_config.root_path}/../vcpkg/scripts/buildsystems/vcpkg.cmake").resolve()
|
||||||
print(f"cmake_toolchain_file: {build_config.cmake_toolchain_file}")
|
print(f"cmake_toolchain_file: {build_config.cmake_toolchain_file}")
|
||||||
print(f"Starting build with type {build_config.build_type}.")
|
print(f"Starting build with type {build_config.build_type}.")
|
||||||
print(f"Qt Version: {build_config.qt_version}. Root path: {build_config.root_path}")
|
print(
|
||||||
|
f"Qt Version: {build_config.qt_version}. Root path: {build_config.root_path}")
|
||||||
|
|
||||||
# Remove old build folder to before configuring to get rid of all cmake chaches
|
# Remove old build folder to before configuring to get rid of all cmake chaches
|
||||||
build_config.build_folder = build_config.root_path.joinpath(f"build-{build_config.cmake_target_triplet}-{build_config.build_type}")
|
build_config.build_folder = build_config.root_path.joinpath(
|
||||||
|
f"build-{build_config.cmake_target_triplet}-{build_config.build_type}")
|
||||||
build_config.bin_dir = build_config.build_folder.joinpath("bin")
|
build_config.bin_dir = build_config.build_folder.joinpath("bin")
|
||||||
|
|
||||||
if platform.system() == "Windows":
|
if platform.system() == "Windows":
|
||||||
build_result.installer = Path(build_config.build_folder).joinpath("ScreenPlay-Installer.exe")
|
build_result.installer = Path(build_config.build_folder).joinpath(
|
||||||
|
"ScreenPlay-Installer.exe")
|
||||||
elif platform.system() == "Darwin":
|
elif platform.system() == "Darwin":
|
||||||
build_result.installer = Path(build_config.build_folder).joinpath("ScreenPlay.dmg")
|
build_result.installer = Path(
|
||||||
|
build_config.build_folder).joinpath("ScreenPlay.dmg")
|
||||||
elif platform.system() == "Linux":
|
elif platform.system() == "Linux":
|
||||||
build_result.installer = Path(build_config.build_folder).joinpath("ScreenPlay-Installer.run")
|
build_result.installer = Path(build_config.build_folder).joinpath(
|
||||||
|
"ScreenPlay-Installer.run")
|
||||||
|
|
||||||
return build_config, build_result
|
return build_config, build_result
|
||||||
|
|
||||||
@ -201,7 +177,7 @@ def build(build_config: BuildConfig, build_result: BuildResult) -> BuildResult:
|
|||||||
-DSCREENPLAY_DEPLOY={build_config.build_deploy} \
|
-DSCREENPLAY_DEPLOY={build_config.build_deploy} \
|
||||||
-DSCREENPLAY_INSTALLER={build_config.create_installer} \
|
-DSCREENPLAY_INSTALLER={build_config.create_installer} \
|
||||||
-DSCREENPLAY_IFW_ROOT:STRING={build_config.ifw_root_path} \
|
-DSCREENPLAY_IFW_ROOT:STRING={build_config.ifw_root_path} \
|
||||||
-G "CodeBlocks - Ninja" \
|
-G "Ninja" \
|
||||||
-B.'
|
-B.'
|
||||||
|
|
||||||
print(f"\n⚙️ CMake configure:\n", cmake_configure_command.replace(
|
print(f"\n⚙️ CMake configure:\n", cmake_configure_command.replace(
|
||||||
@ -220,20 +196,21 @@ def package(build_config: BuildConfig):
|
|||||||
if platform.system() == "Darwin":
|
if platform.system() == "Darwin":
|
||||||
# Make sure to reset to tools path
|
# Make sure to reset to tools path
|
||||||
os.chdir(repo_root_path())
|
os.chdir(repo_root_path())
|
||||||
cmd_raw = "{qt_bin_path}/macdeployqt {build_bin_dir}/ScreenPlay.app -qmldir={repo_root_path}/{app}/qml -executable={build_bin_dir}/ScreenPlay.app/Contents/MacOS/{app} -verbose=1 -appstore-compliant -timestamp -hardened-runtime " # -sign-for-notarization=\"Developer ID Application: Elias Steurer (V887LHYKRH)\"
|
# -sign-for-notarization=\"Developer ID Application: Elias Steurer (V887LHYKRH)\"
|
||||||
build_bin_dir = Path(repo_root_path()).joinpath(f"{build_config.build_folder}/bin/")
|
cmd_raw = "{qt_bin_path}/macdeployqt {build_bin_dir}/ScreenPlay.app -qmldir={repo_root_path}/{app}/qml -executable={build_bin_dir}/ScreenPlay.app/Contents/MacOS/{app} -verbose=1 -appstore-compliant -timestamp -hardened-runtime "
|
||||||
cwd = Path(repo_root_path()).joinpath(f"{build_bin_dir}/ScreenPlay.app/Contents/MacOS/")
|
build_bin_dir = Path(repo_root_path()).joinpath(
|
||||||
|
f"{build_config.build_folder}/bin/")
|
||||||
|
cwd = Path(repo_root_path()).joinpath(
|
||||||
|
f"{build_bin_dir}/ScreenPlay.app/Contents/MacOS/")
|
||||||
qt_bin_path = Path(defines.QT_BIN_PATH).resolve()
|
qt_bin_path = Path(defines.QT_BIN_PATH).resolve()
|
||||||
source_path = Path(repo_root_path()).resolve()
|
source_path = Path(repo_root_path()).resolve()
|
||||||
|
|
||||||
run(cmd=cmd_raw.format(qt_bin_path=qt_bin_path,repo_root_path=source_path, build_bin_dir=build_bin_dir, app="ScreenPlay"), cwd=cwd)
|
run(cmd=cmd_raw.format(qt_bin_path=qt_bin_path, repo_root_path=source_path,
|
||||||
run(cmd=cmd_raw.format(qt_bin_path=qt_bin_path,repo_root_path=source_path, build_bin_dir=build_bin_dir, app="ScreenPlayWallpaper"), cwd=cwd)
|
build_bin_dir=build_bin_dir, app="ScreenPlay"), cwd=cwd)
|
||||||
run(cmd=cmd_raw.format(qt_bin_path=qt_bin_path,repo_root_path=source_path, build_bin_dir=build_bin_dir, app="ScreenPlayWidget"), cwd=cwd)
|
run(cmd=cmd_raw.format(qt_bin_path=qt_bin_path, repo_root_path=source_path,
|
||||||
|
build_bin_dir=build_bin_dir, app="ScreenPlayWallpaper"), cwd=cwd)
|
||||||
if(build_config.sign_osx):
|
run(cmd=cmd_raw.format(qt_bin_path=qt_bin_path, repo_root_path=source_path,
|
||||||
print(f"Sign binary at: {build_config.bin_dir}")
|
build_bin_dir=build_bin_dir, app="ScreenPlayWidget"), cwd=cwd)
|
||||||
macos_sign.sign(build_config=build_config)
|
|
||||||
|
|
||||||
|
|
||||||
if platform.system() == "Windows":
|
if platform.system() == "Windows":
|
||||||
print("Executing deploy commands...")
|
print("Executing deploy commands...")
|
||||||
@ -291,8 +268,6 @@ def package(build_config: BuildConfig):
|
|||||||
shutil.copy(str(file), str(build_config.bin_dir))
|
shutil.copy(str(file), str(build_config.bin_dir))
|
||||||
print("Copied %s" % file)
|
print("Copied %s" % file)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Some dlls like openssl do no longer get copied automatically.
|
# Some dlls like openssl do no longer get copied automatically.
|
||||||
# Lets just copy all of them into bin.
|
# Lets just copy all of them into bin.
|
||||||
if platform.system() == "Windows":
|
if platform.system() == "Windows":
|
||||||
@ -326,6 +301,7 @@ def build_installer(build_config: BuildConfig, build_result: BuildResult):
|
|||||||
print("Running cpack at: ", os.getcwd())
|
print("Running cpack at: ", os.getcwd())
|
||||||
run("cpack", cwd=build_config.build_folder)
|
run("cpack", cwd=build_config.build_folder)
|
||||||
|
|
||||||
|
|
||||||
def zip(build_config: BuildConfig, build_result: BuildResult) -> BuildResult:
|
def zip(build_config: BuildConfig, build_result: BuildResult) -> BuildResult:
|
||||||
zipName = f"ScreenPlay-{build_config.screenplay_version}-{build_config.cmake_target_triplet}-{build_config.build_type}.zip"
|
zipName = f"ScreenPlay-{build_config.screenplay_version}-{build_config.cmake_target_triplet}-{build_config.build_type}.zip"
|
||||||
build_result.build_zip = Path(build_result.build).joinpath(zipName)
|
build_result.build_zip = Path(build_result.build).joinpath(zipName)
|
||||||
@ -346,9 +322,11 @@ def zip(build_config: BuildConfig, build_result: BuildResult) -> BuildResult:
|
|||||||
# Some weird company firewalls do not allow direct .exe downloads
|
# Some weird company firewalls do not allow direct .exe downloads
|
||||||
# lets just zip the installer lol
|
# lets just zip the installer lol
|
||||||
if build_config.create_installer == "ON":
|
if build_config.create_installer == "ON":
|
||||||
build_result.installer_zip = Path(build_result.build).joinpath(build_result.installer.stem + ".zip")
|
build_result.installer_zip = Path(build_result.build).joinpath(
|
||||||
|
build_result.installer.stem + ".zip")
|
||||||
print(f"Create zip from installer: {build_result.installer_zip}")
|
print(f"Create zip from installer: {build_result.installer_zip}")
|
||||||
zipfile.ZipFile(build_result.installer_zip, 'w').write(build_result.installer, build_result.installer.name)
|
zipfile.ZipFile(build_result.installer_zip, 'w').write(
|
||||||
|
build_result.installer, build_result.installer.name)
|
||||||
|
|
||||||
return build_result
|
return build_result
|
||||||
|
|
||||||
@ -357,35 +335,47 @@ if __name__ == "__main__":
|
|||||||
|
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
description='Build and Package ScreenPlay')
|
description='Build and Package ScreenPlay')
|
||||||
|
parser.add_argument('--qt-version', action="store", dest="qt_version_overwrite",
|
||||||
parser.add_argument('-qt-version', action="store", dest="qt_version_overwrite",
|
|
||||||
help="Overwrites the default Qt version")
|
help="Overwrites the default Qt version")
|
||||||
parser.add_argument('-qt-installer-version', action="store", dest="qt_installer_version_overwrite",
|
parser.add_argument('--qt-installer-version', action="store", dest="qt_installer_version_overwrite",
|
||||||
help="Overwrites the default Qt installer framework version")
|
help="Overwrites the default Qt installer framework version")
|
||||||
parser.add_argument('-type', action="store", dest="build_type", default="release",
|
parser.add_argument('--type', action="store", dest="build_type", default="release",
|
||||||
help="Build type. This is either debug or release.")
|
help="Build type. This is either debug or release.")
|
||||||
parser.add_argument('-use-aqt', action="store_true", dest="use_aqt",
|
parser.add_argument('--use-aqt', action="store_true", dest="use_aqt",
|
||||||
help="Absolute qt path. If not set the default path is used\Windows: C:\Qt\nLinux & macOS:~/Qt/.")
|
help="Absolute qt path. If not set the default path is used\Windows: C:\Qt\nLinux & macOS:~/Qt/.")
|
||||||
parser.add_argument('-steam', action="store_true", dest="build_steam",
|
parser.add_argument('--steam', action="store_true", dest="build_steam",
|
||||||
help="Enable if you want to build the Steam workshop plugin.")
|
help="Enable if you want to build the Steam workshop plugin.")
|
||||||
parser.add_argument('-tests', action="store_true", dest="build_tests",
|
parser.add_argument('--tests', action="store_true", dest="build_tests",
|
||||||
help="Build tests.")
|
help="Build tests.")
|
||||||
parser.add_argument('-installer', action="store_true", dest="create_installer",
|
parser.add_argument('--installer', action="store_true", dest="create_installer",
|
||||||
help="Create a installer.")
|
help="Create a installer.")
|
||||||
parser.add_argument('-sign_osx', action="store_true", dest="sign_osx", default=False,
|
parser.add_argument('--sign_osx', action="store_true", dest="sign_osx", default=False,
|
||||||
help="Signs the executable on macOS. This requires a valid Apple Developer ID set up.")
|
help="Signs the executable on macOS. This requires a valid Apple Developer ID set up.")
|
||||||
parser.add_argument('-deploy-version', action="store_true", dest="build_deploy",
|
parser.add_argument('--deploy-version', action="store_true", dest="build_deploy",
|
||||||
help="Create a deploy version of ScreenPlay for sharing with the world. A not deploy version is for local development only!")
|
help="Create a deploy version of ScreenPlay for sharing with the world. A not deploy version is for local development only!")
|
||||||
parser.add_argument('-architecture', action="store", dest="build_architecture", default="",
|
parser.add_argument('--architecture', action="store", dest="build_architecture", default="",
|
||||||
help="Sets the build architecture. Used to build x86 and ARM osx versions. Currently only works with x86_64 and arm64")
|
help="Sets the build architecture. Used to build x86 and ARM osx versions. Currently only works with x86_64 and arm64")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
qt_version = defines.QT_VERSION
|
qt_version = defines.QT_VERSION
|
||||||
screenplay_version = defines.SCREENPLAY_VERSION
|
|
||||||
qt_ifw_version = defines.QT_IFW_VERSION # Not yet used.
|
qt_ifw_version = defines.QT_IFW_VERSION # Not yet used.
|
||||||
qt_version_overwrite: str
|
qt_version_overwrite: str
|
||||||
use_aqt = False
|
use_aqt = False
|
||||||
|
|
||||||
|
tag = get_latest_git_tag()
|
||||||
|
if tag:
|
||||||
|
print(f"Latest Git tag: {tag}")
|
||||||
|
semver = parse_semver(tag)
|
||||||
|
if semver:
|
||||||
|
print(f"Parsed SemVer: {semver}")
|
||||||
|
screenplay_version = semver_to_string(semver)
|
||||||
|
else:
|
||||||
|
print("Failed to parse SemVer.")
|
||||||
|
exit(-1)
|
||||||
|
else:
|
||||||
|
print("No git tags found.")
|
||||||
|
exit(-1)
|
||||||
|
|
||||||
if args.qt_version_overwrite:
|
if args.qt_version_overwrite:
|
||||||
qt_version = args.qt_version_overwrite
|
qt_version = args.qt_version_overwrite
|
||||||
print("Using Qt version {qt_version}")
|
print("Using Qt version {qt_version}")
|
||||||
|
@ -1,107 +0,0 @@
|
|||||||
#!/usr/bin/python3
|
|
||||||
# SPDX-License-Identifier: LicenseRef-EliasSteurerTachiom OR AGPL-3.0-only
|
|
||||||
import steam_publish
|
|
||||||
import shutil
|
|
||||||
import sys
|
|
||||||
import macos_sign
|
|
||||||
import argparse
|
|
||||||
import os
|
|
||||||
import build
|
|
||||||
from pathlib import Path
|
|
||||||
import platform
|
|
||||||
import paramiko
|
|
||||||
import defines
|
|
||||||
from util import sftp_exists, run, repo_root_path
|
|
||||||
from sys import stdout
|
|
||||||
|
|
||||||
stdout.reconfigure(encoding='utf-8')
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
parser = argparse.ArgumentParser(description='Build and Package ScreenPlay')
|
|
||||||
parser.add_argument('-skip_publish', '-skp', action="store_true", dest="skip_publish", default=False, help="skip publish")
|
|
||||||
parser.add_argument('-skip_build', '-skb', action="store_true", dest="skip_build", default=False, help="skip build. If we already have a build and only want to upload it")
|
|
||||||
parser.add_argument('-steam_password', '-sp', action="store", dest="steam_password", help="Steam password")
|
|
||||||
parser.add_argument('-hosting_username','-hu', action="store", dest="hosting_username", help="ssh username")
|
|
||||||
parser.add_argument('-hosting_password', '-hp', action="store", dest="hosting_password", help="ssh password")
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
# Script needs to run in the tools folder
|
|
||||||
tools_path = Path.cwd()
|
|
||||||
os.chdir(tools_path)
|
|
||||||
root_path = tools_path.parent
|
|
||||||
print(f"Set root directory to: {root_path}")
|
|
||||||
|
|
||||||
build_result = build.BuildResult()
|
|
||||||
|
|
||||||
build_config = build.BuildConfig()
|
|
||||||
build_config.screenplay_version = defines.SCREENPLAY_VERSION
|
|
||||||
build_config.qt_version = defines.QT_VERSION
|
|
||||||
build_config.qt_ifw_version = defines.QT_IFW_VERSION
|
|
||||||
build_config.build_steam = "ON"
|
|
||||||
build_config.build_tests = "OFF"
|
|
||||||
build_config.build_deploy = "ON"
|
|
||||||
build_config.create_installer = "ON"
|
|
||||||
build_config.build_type = "release"
|
|
||||||
|
|
||||||
if platform.system() == "Darwin" and not args.skip_build:
|
|
||||||
# We do not yet support a standalone osx installer
|
|
||||||
build_config.create_installer = "OFF"
|
|
||||||
|
|
||||||
# We need to manually package here at the end after
|
|
||||||
build_config.package = True
|
|
||||||
build_config.sign_osx = True
|
|
||||||
|
|
||||||
# This will build both arm64 and x64 and sign the unversal binary
|
|
||||||
build_result = build.execute(build_config)
|
|
||||||
|
|
||||||
|
|
||||||
if platform.system() == "Windows" and not args.skip_build:
|
|
||||||
build_config.build_architecture = "x64"
|
|
||||||
|
|
||||||
if not args.skip_publish:
|
|
||||||
# Steamless version first
|
|
||||||
build_config.build_steam = "OFF"
|
|
||||||
build_result = build.execute(build_config)
|
|
||||||
ssh = paramiko.SSHClient()
|
|
||||||
ssh.load_system_host_keys()
|
|
||||||
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
|
||||||
ssh.connect('kelteseth.com', username=args.hosting_username, password=args.hosting_password)
|
|
||||||
sftp = ssh.open_sftp()
|
|
||||||
release_folder = "/kelteseth_com/public/releases/" + build_config.screenplay_version + "/"
|
|
||||||
if sftp_exists(sftp,release_folder):
|
|
||||||
remoteFiles = sftp.listdir(path=release_folder)
|
|
||||||
for file in remoteFiles:
|
|
||||||
print(f"Delte old: {release_folder+file}")
|
|
||||||
sftp.remove(release_folder+file)
|
|
||||||
else:
|
|
||||||
sftp.mkdir(release_folder)
|
|
||||||
print("Uploading files...")
|
|
||||||
|
|
||||||
sftp.put(build_result.build_zip, release_folder + str(build_result.build_zip.name))
|
|
||||||
sftp.put(build_result.installer, release_folder + str(build_result.installer.name))
|
|
||||||
sftp.put(build_result.installer_zip,release_folder + str(build_result.installer_zip.name))
|
|
||||||
sftp.put(build_result.build_hash, release_folder + str(build_result.build_hash.name))
|
|
||||||
sftp.close()
|
|
||||||
ssh.close()
|
|
||||||
|
|
||||||
# Now build the steam version
|
|
||||||
os.chdir(tools_path)
|
|
||||||
build_config.build_steam = "ON"
|
|
||||||
build_config.create_installer = "OFF"
|
|
||||||
build_result = build.execute(build_config)
|
|
||||||
|
|
||||||
if args.skip_publish:
|
|
||||||
print("Skip publishing.")
|
|
||||||
sys.exit(0)
|
|
||||||
|
|
||||||
if args.steam_password is None:
|
|
||||||
print("Steam password is required.")
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
# Make sure to reset to tools path
|
|
||||||
os.chdir(tools_path)
|
|
||||||
steam_publish.publish(
|
|
||||||
steam_username="tachiom",
|
|
||||||
steam_password=args.steam_password,
|
|
||||||
set_live_branch_name="internal"
|
|
||||||
)
|
|
94
Tools/build_and_publish_steam.py
Normal file
94
Tools/build_and_publish_steam.py
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
# SPDX-License-Identifier: LicenseRef-EliasSteurerTachiom OR AGPL-3.0-only
|
||||||
|
import steam_publish
|
||||||
|
import sys
|
||||||
|
import argparse
|
||||||
|
import os
|
||||||
|
import build
|
||||||
|
from pathlib import Path
|
||||||
|
import platform
|
||||||
|
import defines
|
||||||
|
from build_result import BuildResult
|
||||||
|
from build_config import BuildConfig
|
||||||
|
from util import get_latest_git_tag, parse_semver, semver_to_string
|
||||||
|
from sys import stdout
|
||||||
|
|
||||||
|
stdout.reconfigure(encoding='utf-8')
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
description='Build and Package ScreenPlay')
|
||||||
|
parser.add_argument('--skip_steam_publish', '-skstp', action="store_true",
|
||||||
|
dest="skip_steam_publish", default=False, help="skip publish")
|
||||||
|
parser.add_argument('--skip_build', '-skb', action="store_true", dest="skip_build",
|
||||||
|
default=False, help="skip build. If we already have a build and only want to upload it")
|
||||||
|
parser.add_argument('--steam_password', '-sp', action="store",
|
||||||
|
dest="steam_password", help="Steam password")
|
||||||
|
parser.add_argument('--hosting_username', '-hu', action="store",
|
||||||
|
dest="hosting_username", help="ssh username")
|
||||||
|
parser.add_argument('--hosting_password', '-hp', action="store",
|
||||||
|
dest="hosting_password", help="ssh password")
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
if not args.skip_steam_publish and args.steam_password is None:
|
||||||
|
print("Steam password is required.")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if not steam_publish.check_steam_login("tachiom", args.steam_password):
|
||||||
|
print("Failed to login to Steam!")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
# Script needs to run in the tools folder
|
||||||
|
tools_path = Path.cwd()
|
||||||
|
os.chdir(tools_path)
|
||||||
|
root_path = tools_path.parent
|
||||||
|
print(f"Set root directory to: {root_path}")
|
||||||
|
|
||||||
|
tag = get_latest_git_tag()
|
||||||
|
if tag:
|
||||||
|
print(f"Latest Git tag: {tag}")
|
||||||
|
semver = parse_semver(tag)
|
||||||
|
if semver:
|
||||||
|
print(f"Parsed SemVer: {semver}")
|
||||||
|
screenplay_version = semver_to_string(semver)
|
||||||
|
else:
|
||||||
|
print("Failed to parse SemVer.")
|
||||||
|
exit(-1)
|
||||||
|
else:
|
||||||
|
print("No git tags found.")
|
||||||
|
exit(-1)
|
||||||
|
|
||||||
|
build_result = BuildResult()
|
||||||
|
|
||||||
|
build_config = BuildConfig()
|
||||||
|
build_config.qt_version = defines.QT_VERSION
|
||||||
|
build_config.qt_ifw_version = defines.QT_IFW_VERSION
|
||||||
|
build_config.build_steam = "ON"
|
||||||
|
build_config.build_tests = "OFF"
|
||||||
|
build_config.build_deploy = "ON"
|
||||||
|
build_config.create_installer = "OFF"
|
||||||
|
build_config.build_type = "release"
|
||||||
|
build_config.screenplay_version = screenplay_version
|
||||||
|
|
||||||
|
if platform.system() == "Darwin" and not args.skip_build:
|
||||||
|
# We need to manually package here at the end after
|
||||||
|
build_config.package = True
|
||||||
|
build_config.sign_osx = True
|
||||||
|
|
||||||
|
# This will build both arm64 and x64 and sign the unversal binary
|
||||||
|
build_result = build.execute(build_config)
|
||||||
|
|
||||||
|
if platform.system() == "Windows" and not args.skip_build:
|
||||||
|
build_result = build.execute(build_config)
|
||||||
|
|
||||||
|
if args.skip_steam_publish:
|
||||||
|
print("Skip steam publishing.")
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
# Make sure to reset to tools path
|
||||||
|
os.chdir(tools_path)
|
||||||
|
steam_publish.publish(
|
||||||
|
steam_username="tachiom",
|
||||||
|
steam_password=args.steam_password,
|
||||||
|
set_live_branch_name="internal"
|
||||||
|
)
|
29
Tools/build_config.py
Normal file
29
Tools/build_config.py
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
class BuildConfig:
|
||||||
|
root_path: str
|
||||||
|
cmake_osx_architectures: str
|
||||||
|
cmake_target_triplet: str
|
||||||
|
package: bool
|
||||||
|
osx_bundle: str
|
||||||
|
package_command: str
|
||||||
|
executable_file_ending: str
|
||||||
|
# qt_* use either aqt or from the maintenance tool
|
||||||
|
qt_path: str # C:\Qt
|
||||||
|
qt_bin_path: str # C:\Qt\6.3.2\msvc2019_64
|
||||||
|
qt_version: str
|
||||||
|
qt_ifw_version: str
|
||||||
|
ifw_root_path: str
|
||||||
|
cmake_toolchain_file: str
|
||||||
|
aqt_install_qt_packages: str
|
||||||
|
aqt_install_tool_packages: str
|
||||||
|
executable_file_ending: str
|
||||||
|
build_folder: str
|
||||||
|
bin_dir: str
|
||||||
|
screenplay_version: str
|
||||||
|
# CMake variables need str: "ON" or "OFF"
|
||||||
|
build_steam: str
|
||||||
|
build_tests: str
|
||||||
|
build_deploy: str
|
||||||
|
build_type: str
|
||||||
|
build_architecture: str
|
||||||
|
create_installer: str
|
||||||
|
sign_osx: bool
|
20
Tools/build_result.py
Normal file
20
Tools/build_result.py
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
class BuildResult:
|
||||||
|
# Windows example with absolute paths:
|
||||||
|
# [...]/build-x64-windows-release/
|
||||||
|
build: Path
|
||||||
|
# [...]/build-x64-windows-release/bin
|
||||||
|
bin: Path
|
||||||
|
# [...]/build-x64-windows-release/ScreenPlay-Installer.exe
|
||||||
|
installer: Path
|
||||||
|
# [...]/build-x64-windows-release/ScreenPlay-Installer.zip
|
||||||
|
installer_zip: Path
|
||||||
|
# [...]/build-x64-windows-release/ScreenPlay-0.X.0-RCX-x64-windows-release.zip
|
||||||
|
build_zip: Path
|
||||||
|
# [...]/build-x64-windows-release/ScreenPlay-0.X.0-RCX-x64-windows-release.txt :sha256, needed for scoop
|
||||||
|
build_hash: Path
|
||||||
|
# x64, arm64, universal
|
||||||
|
build_arch: str
|
56
Tools/check_format_cmake.py
Normal file
56
Tools/check_format_cmake.py
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
# SPDX-License-Identifier: LicenseRef-EliasSteurerTachiom OR AGPL-3.0-only
|
||||||
|
import os
|
||||||
|
import argparse
|
||||||
|
import util
|
||||||
|
from format_util import find_files
|
||||||
|
from format_util import execute_threaded
|
||||||
|
from sys import stdout
|
||||||
|
|
||||||
|
stdout.reconfigure(encoding='utf-8')
|
||||||
|
|
||||||
|
|
||||||
|
def format_file_function(file):
|
||||||
|
executable = "cmake-format"
|
||||||
|
if os.name == 'nt':
|
||||||
|
executable += ".exe"
|
||||||
|
os.system(" %s -c ../.cmake-format.py -i %s" % (executable, file))
|
||||||
|
print("Format: ", file)
|
||||||
|
|
||||||
|
|
||||||
|
def check_format_file_function(file):
|
||||||
|
executable = "cmake-format"
|
||||||
|
if os.name == 'nt':
|
||||||
|
executable += ".exe"
|
||||||
|
result = os.system(" %s -c ../.cmake-format.py --check %s" %
|
||||||
|
(executable, file))
|
||||||
|
|
||||||
|
# If the return code is non-zero, the file isn't formatted correctly
|
||||||
|
if result != 0:
|
||||||
|
print(f"{file} is not correctly formatted.")
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def main(git_staged_only=False, check_only=False):
|
||||||
|
file_list = find_files(
|
||||||
|
('CMakeLists.txt', '*.cmake'), util.repo_root_path(), git_staged_only)
|
||||||
|
|
||||||
|
if check_only:
|
||||||
|
result = execute_threaded(file_list, check_format_file_function)
|
||||||
|
if not result: # Since result is a single boolean, you can directly check its value
|
||||||
|
print("Some files are not correctly formatted!")
|
||||||
|
exit(1)
|
||||||
|
else:
|
||||||
|
execute_threaded(file_list, format_file_function)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument('-s', '--stage-only', action="store_true", dest="stage_only", default=False,
|
||||||
|
help="Check/format only staged files")
|
||||||
|
parser.add_argument('-c', '--check', action="store_true", dest="check_only", default=False,
|
||||||
|
help="Only check if files are correctly formatted without actually formatting them")
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
main(args.stage_only, args.check_only)
|
61
Tools/check_format_cpp.py
Normal file
61
Tools/check_format_cpp.py
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
# SPDX-License-Identifier: LicenseRef-EliasSteurerTachiom OR AGPL-3.0-only
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
import argparse
|
||||||
|
import util
|
||||||
|
from format_util import find_files
|
||||||
|
from format_util import execute_threaded
|
||||||
|
from sys import stdout
|
||||||
|
|
||||||
|
stdout.reconfigure(encoding='utf-8')
|
||||||
|
|
||||||
|
|
||||||
|
def format_file_function(file):
|
||||||
|
executable = "clang-format"
|
||||||
|
if os.name == 'nt':
|
||||||
|
executable = "clang-format.exe"
|
||||||
|
process = subprocess.run(" %s -style=file -i %s" %
|
||||||
|
(executable, file), capture_output=True, shell=True)
|
||||||
|
print("Format: %s \t return: %s" % (file, process.returncode))
|
||||||
|
|
||||||
|
|
||||||
|
def check_format_file_function(file):
|
||||||
|
executable = "clang-format"
|
||||||
|
if os.name == 'nt':
|
||||||
|
executable += ".exe"
|
||||||
|
result = subprocess.run(" %s -style=file --output-replacements-xml %s" %
|
||||||
|
(executable, file), capture_output=True, shell=True, text=True)
|
||||||
|
|
||||||
|
# Check for opening replacement tag with attributes (a space after it indicates attributes)
|
||||||
|
if "<replacement " in result.stdout:
|
||||||
|
print(f"{file} is not correctly formatted.")
|
||||||
|
print(f"{result.stdout} ")
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def main(git_staged_only=False, check_only=False):
|
||||||
|
exclude_folders = ("ScreenPlayWorkshop/SteamSDK",
|
||||||
|
"ThirdParty", "build-x64-windows-release")
|
||||||
|
file_list = find_files(
|
||||||
|
('.cpp', '.h'), util.repo_root_path(), git_staged_only, exclude_folders)
|
||||||
|
|
||||||
|
if check_only:
|
||||||
|
result = execute_threaded(file_list, check_format_file_function)
|
||||||
|
if not result: # Since result is a single boolean, you can directly check its value
|
||||||
|
print("Some files are not correctly formatted!")
|
||||||
|
exit(1)
|
||||||
|
else:
|
||||||
|
execute_threaded(file_list, format_file_function)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument('--s', '--stage-only', action="store_true", dest="stage_only", default=False,
|
||||||
|
help="Check/format only staged files")
|
||||||
|
parser.add_argument('--c', '--check', action="store_true", dest="check_only", default=False,
|
||||||
|
help="Only check if files are correctly formatted without actually formatting them")
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
main(args.stage_only, args.check_only)
|
88
Tools/check_format_qml.py
Normal file
88
Tools/check_format_qml.py
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
import argparse
|
||||||
|
import util
|
||||||
|
import defines
|
||||||
|
import hashlib
|
||||||
|
from format_util import find_files
|
||||||
|
from format_util import execute_threaded
|
||||||
|
from sys import stdout, exit
|
||||||
|
import hashlib
|
||||||
|
import shutil
|
||||||
|
|
||||||
|
stdout.reconfigure(encoding='utf-8')
|
||||||
|
|
||||||
|
|
||||||
|
def format_qml_file(file):
|
||||||
|
executable = "qmlformat"
|
||||||
|
if os.name == 'nt':
|
||||||
|
executable = "qmlformat.exe"
|
||||||
|
qt_bin_path = defines.QT_BIN_PATH
|
||||||
|
executable = qt_bin_path.joinpath(executable)
|
||||||
|
|
||||||
|
# Add -i for formatting in place
|
||||||
|
process = subprocess.run(
|
||||||
|
[executable, "-i", file], capture_output=True, shell=True)
|
||||||
|
print("Format: %s \t return: %s" % (file, process.returncode))
|
||||||
|
|
||||||
|
|
||||||
|
def compute_md5(file_path):
|
||||||
|
"""Compute MD5 hash of the content of the given file."""
|
||||||
|
with open(file_path, 'rb') as f:
|
||||||
|
return hashlib.md5(f.read()).hexdigest()
|
||||||
|
|
||||||
|
|
||||||
|
# Instead of comparing the direct outputs (which was leading to ambiguous results),
|
||||||
|
# this function uses a workaround that checks the file's MD5 hash before and after formatting.
|
||||||
|
def check_format_qml_file(file):
|
||||||
|
executable = "qmlformat"
|
||||||
|
if os.name == 'nt':
|
||||||
|
executable = "qmlformat.exe"
|
||||||
|
qt_bin_path = defines.QT_BIN_PATH
|
||||||
|
executable = qt_bin_path.joinpath(executable)
|
||||||
|
|
||||||
|
# Step 1: Copy the original file
|
||||||
|
backup_file = file + ".backup"
|
||||||
|
shutil.copy(file, backup_file)
|
||||||
|
|
||||||
|
# Step 2: Run qmlformat with in-place editing
|
||||||
|
subprocess.run([executable, "-i", file], check=True)
|
||||||
|
|
||||||
|
# Step 3: Compare MD5 hash of the original (backup) and the formatted file
|
||||||
|
original_hash = compute_md5(backup_file)
|
||||||
|
formatted_hash = compute_md5(file)
|
||||||
|
|
||||||
|
# Step 4: Remove the backup copy
|
||||||
|
os.remove(backup_file)
|
||||||
|
|
||||||
|
# Step 5: Return the comparison result
|
||||||
|
if original_hash != formatted_hash:
|
||||||
|
print(f"{file} is not correctly formatted.")
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def main(git_staged_only=False, check_only=False):
|
||||||
|
exclude_folders = ("ThirdParty", "build-x64-windows-release")
|
||||||
|
file_list = find_files(('.qml'), util.repo_root_path(),
|
||||||
|
git_staged_only, exclude_folders)
|
||||||
|
|
||||||
|
if check_only:
|
||||||
|
result = execute_threaded(file_list, check_format_qml_file)
|
||||||
|
if not result:
|
||||||
|
print("Some files are not correctly formatted!")
|
||||||
|
exit(1)
|
||||||
|
else:
|
||||||
|
execute_threaded(file_list, format_qml_file)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument('--s', '--stage-only', action="store_true", dest="stage_only", default=False,
|
||||||
|
help="Check/format only staged files")
|
||||||
|
parser.add_argument('--c', '--check', action="store_true", dest="check_only", default=False,
|
||||||
|
help="Only check if files are correctly formatted without actually formatting them")
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
main(args.stage_only, args.check_only)
|
61
Tools/check_license_header.py
Normal file
61
Tools/check_license_header.py
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
# SPDX-License-Identifier: LicenseRef-EliasSteurerTachiom OR AGPL-3.0-only
|
||||||
|
import argparse
|
||||||
|
from format_util import find_files
|
||||||
|
from format_util import execute_threaded
|
||||||
|
from sys import stdout
|
||||||
|
import util
|
||||||
|
|
||||||
|
stdout.reconfigure(encoding='utf-8')
|
||||||
|
|
||||||
|
|
||||||
|
def check_license_header_file_function(file_path):
|
||||||
|
"""
|
||||||
|
Check if the given file has a license header in its first or second line.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
- file_path (str): Path to the file to be checked.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
- bool: True if the license header is present, otherwise False.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
with open(file_path, 'r') as f:
|
||||||
|
# Read the first two lines of the file
|
||||||
|
first_line = f.readline().strip()
|
||||||
|
second_line = f.readline().strip()
|
||||||
|
|
||||||
|
# Check if either of the two lines has the required header
|
||||||
|
if "SPDX-License-Identifier:" in first_line or "SPDX-License-Identifier:" in second_line:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
print(f"INVALID: {file_path}")
|
||||||
|
return False
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error reading the file: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def main(git_staged_only=False):
|
||||||
|
|
||||||
|
# Setting exclude_folders before calling the function
|
||||||
|
exclude_folders = (
|
||||||
|
"ThirdParty", "ScreenPlayWorkshop/SteamSDK", "build-x64-windows-release")
|
||||||
|
file_endings = ('.cpp', '.h', '.qml')
|
||||||
|
file_list = find_files(file_endings_tuple=file_endings,
|
||||||
|
path=util.repo_root_path(),
|
||||||
|
git_staged_only=git_staged_only,
|
||||||
|
exclude_folders=exclude_folders)
|
||||||
|
result = execute_threaded(file_list, check_license_header_file_function)
|
||||||
|
if result is False:
|
||||||
|
print("At least one file is missing the license header!")
|
||||||
|
# Depending on your requirement, you can exit the script here
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument("--s", '--stage-only', action="store_true", dest="stage_only",
|
||||||
|
default=False)
|
||||||
|
args = parser.parse_args()
|
||||||
|
main(args.stage_only)
|
@ -1,36 +0,0 @@
|
|||||||
#!/usr/bin/python3
|
|
||||||
# SPDX-License-Identifier: LicenseRef-EliasSteurerTachiom OR AGPL-3.0-only
|
|
||||||
import os
|
|
||||||
import subprocess
|
|
||||||
import argparse
|
|
||||||
from format_util import find_files
|
|
||||||
from format_util import check_git_exit
|
|
||||||
from format_util import execute_threaded
|
|
||||||
from sys import stdout
|
|
||||||
|
|
||||||
stdout.reconfigure(encoding='utf-8')
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def format_file_function(file):
|
|
||||||
executable = "clang-format"
|
|
||||||
if os.name == 'nt':
|
|
||||||
executable = "clang-format.exe"
|
|
||||||
process = subprocess.run(" %s -style=file -i %s" %
|
|
||||||
(executable, file), capture_output=True, shell=True)
|
|
||||||
print("Format: %s \t return: %s" % (file, process.returncode))
|
|
||||||
|
|
||||||
|
|
||||||
def main(git_staged_only=False):
|
|
||||||
file_list = find_files(('.cpp', '.h'), "", git_staged_only)
|
|
||||||
execute_threaded(file_list, format_file_function)
|
|
||||||
if not git_staged_only:
|
|
||||||
check_git_exit("Clang Format")
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
parser = argparse.ArgumentParser()
|
|
||||||
parser.add_argument('-s', action="store_true", dest="stage_only",
|
|
||||||
default=False)
|
|
||||||
args = parser.parse_args()
|
|
||||||
main(args.stage_only)
|
|
@ -1,31 +0,0 @@
|
|||||||
#!/usr/bin/python3
|
|
||||||
# SPDX-License-Identifier: LicenseRef-EliasSteurerTachiom OR AGPL-3.0-only
|
|
||||||
import os
|
|
||||||
import argparse
|
|
||||||
from format_util import find_files
|
|
||||||
from format_util import check_git_exit
|
|
||||||
from format_util import execute_threaded
|
|
||||||
from sys import stdout
|
|
||||||
|
|
||||||
stdout.reconfigure(encoding='utf-8')
|
|
||||||
|
|
||||||
|
|
||||||
def format_file_function(file):
|
|
||||||
executable = "cmake-format"
|
|
||||||
if os.name == 'nt':
|
|
||||||
executable = "cmake-format.exe"
|
|
||||||
os.system(" %s -c ../.cmake-format.py -i %s" % (executable, file))
|
|
||||||
print("Format: ", file)
|
|
||||||
|
|
||||||
def main(git_staged_only=False):
|
|
||||||
file_list = find_files(('CMakeLists.txt'), "", git_staged_only)
|
|
||||||
execute_threaded(file_list, format_file_function)
|
|
||||||
if not git_staged_only:
|
|
||||||
check_git_exit("CMake Format")
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
parser = argparse.ArgumentParser()
|
|
||||||
parser.add_argument('-s', action="store_true", dest="stage_only",
|
|
||||||
default=False)
|
|
||||||
args = parser.parse_args()
|
|
||||||
main(args.stage_only)
|
|
30
Tools/create_sha512.py
Normal file
30
Tools/create_sha512.py
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import hashlib
|
||||||
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
import util
|
||||||
|
|
||||||
|
|
||||||
|
def combine_sha256():
|
||||||
|
tag = os.environ['CI_COMMIT_TAG']
|
||||||
|
|
||||||
|
# Get the repo root path as a Path object
|
||||||
|
root_path = Path(util.repo_root_path())
|
||||||
|
|
||||||
|
files = [
|
||||||
|
Path(
|
||||||
|
f"{root_path}/build-x64-windows-release/ScreenPlay-{tag}-x64-windows-release.zip"),
|
||||||
|
Path(
|
||||||
|
f"{root_path}/build-x64-linux-release/ScreenPlay-{tag}-x64-linux-release.zip"),
|
||||||
|
Path(f"{root_path}/build-64-osx-universal-release/ScreenPlay-{tag}-64-osx-universal-release.zip")
|
||||||
|
]
|
||||||
|
|
||||||
|
with open('SHA512-SUMS.txt', 'w') as f_out:
|
||||||
|
for file in files:
|
||||||
|
with open(file.with_name(f"{file.name}.sha256.txt"), 'r') as f_in:
|
||||||
|
sha256_hash = f_in.read().strip()
|
||||||
|
sha512_hash = hashlib.sha512(sha256_hash.encode()).hexdigest()
|
||||||
|
f_out.write(f"{sha512_hash} {file.name}\n")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
combine_sha256()
|
@ -18,7 +18,6 @@ elif sys.platform == "linux":
|
|||||||
OS = "linux"
|
OS = "linux"
|
||||||
QT_PLATFORM = "gcc_64"
|
QT_PLATFORM = "gcc_64"
|
||||||
|
|
||||||
SCREENPLAY_VERSION = "0.15.1"
|
|
||||||
QT_PATH = path = Path(os.path.join(
|
QT_PATH = path = Path(os.path.join(
|
||||||
os.path.realpath(__file__), "../../../aqt")).resolve()
|
os.path.realpath(__file__), "../../../aqt")).resolve()
|
||||||
QT_VERSION = "6.5.2"
|
QT_VERSION = "6.5.2"
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
|
import util
|
||||||
from multiprocessing import cpu_count
|
from multiprocessing import cpu_count
|
||||||
from multiprocessing import Pool
|
from multiprocessing import Pool
|
||||||
from multiprocessing import dummy
|
from multiprocessing import dummy
|
||||||
@ -28,33 +29,38 @@ def find_all_git_staged_files():
|
|||||||
return out
|
return out
|
||||||
|
|
||||||
|
|
||||||
def find_files(file_endings_tuple, path="", git_staged_only=False):
|
def find_files(file_endings_tuple, path="", git_staged_only=False, exclude_folders=()):
|
||||||
file_list = []
|
file_list = []
|
||||||
# Get the root folder by moving one up
|
|
||||||
root = Path(__file__).parent.absolute()
|
|
||||||
root = os.path.abspath(os.path.join(root, "../"))
|
|
||||||
|
|
||||||
root = os.path.join(root, path)
|
|
||||||
print(root)
|
|
||||||
|
|
||||||
if git_staged_only:
|
if git_staged_only:
|
||||||
file_list = find_all_git_staged_files()
|
file_list = find_all_git_staged_files() # Assuming you've defined this
|
||||||
else:
|
else:
|
||||||
file_list = find_all_files(root)
|
for dirpath, dirnames, filenames in os.walk(path):
|
||||||
|
# Normalize the current directory path
|
||||||
|
norm_dirpath = os.path.normpath(dirpath)
|
||||||
|
|
||||||
filtered_file_list = []
|
# Check if the current directory is to be excluded
|
||||||
for filename in file_list:
|
if exclude_folders and any(os.path.normpath(excl_folder) in norm_dirpath for excl_folder in exclude_folders):
|
||||||
if filename.endswith(file_endings_tuple):
|
continue
|
||||||
filtered_file_list.append(os.path.join(root, filename))
|
|
||||||
|
|
||||||
return filtered_file_list
|
for filename in filenames:
|
||||||
|
if filename.endswith(file_endings_tuple):
|
||||||
|
file_list.append(os.path.join(dirpath, filename))
|
||||||
|
|
||||||
|
return file_list
|
||||||
|
|
||||||
|
|
||||||
def execute_threaded(file_list, format_file_function):
|
def execute_threaded(file_list, format_file_function):
|
||||||
p = Pool(cpu_count())
|
if not file_list:
|
||||||
p.map(format_file_function, file_list)
|
return True # or False, depending on how you want to handle an empty list
|
||||||
p.close()
|
|
||||||
p.join()
|
with Pool(cpu_count()) as p:
|
||||||
|
results = p.map(format_file_function, file_list)
|
||||||
|
|
||||||
|
# Check if any result is False and return accordingly
|
||||||
|
if any(result is False for result in results):
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
def check_git_exit(caller_name):
|
def check_git_exit(caller_name):
|
||||||
@ -70,4 +76,3 @@ def check_git_exit(caller_name):
|
|||||||
out.replace("\\n", "\n")
|
out.replace("\\n", "\n")
|
||||||
# print(out)
|
# print(out)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
@ -1,15 +1,14 @@
|
|||||||
#!/usr/bin/python3
|
#!/usr/bin/python3
|
||||||
# SPDX-License-Identifier: LicenseRef-EliasSteurerTachiom OR AGPL-3.0-only
|
# SPDX-License-Identifier: LicenseRef-EliasSteurerTachiom OR AGPL-3.0-only
|
||||||
from build import BuildConfig
|
from build_config import BuildConfig
|
||||||
from util import run
|
from util import run
|
||||||
from sys import stdout
|
from sys import stdout
|
||||||
import time
|
|
||||||
|
|
||||||
stdout.reconfigure(encoding='utf-8')
|
stdout.reconfigure(encoding='utf-8')
|
||||||
|
|
||||||
|
|
||||||
def sign(build_config: BuildConfig):
|
def sign(build_config: BuildConfig):
|
||||||
print("Run codedesign")
|
print("Run codedesign")
|
||||||
#run("codesign -f -s 'Developer ID Application: Elias Steurer (V887LHYKRH)' --verbose --force --timestamp --options 'runtime' -f --entitlements '../../ScreenPlay/entitlements.plist' 'ScreenPlay.app/' ",
|
# run("codesign -f -s 'Developer ID Application: Elias Steurer (V887LHYKRH)' --verbose --force --timestamp --options 'runtime' -f --entitlements '../../ScreenPlay/entitlements.plist' 'ScreenPlay.app/' ",
|
||||||
# cwd=build_config.bin_dir)
|
# cwd=build_config.bin_dir)
|
||||||
# Do not use --deep https://developer.apple.com/forums/thread/129980
|
# Do not use --deep https://developer.apple.com/forums/thread/129980
|
||||||
# base_sign_command = "codesign -s \"Developer ID Application: Elias Steurer (V887LHYKRH)\" --verbose --force --timestamp --options \"runtime\" \"ScreenPlay.app/Contents/MacOS/{app}\""
|
# base_sign_command = "codesign -s \"Developer ID Application: Elias Steurer (V887LHYKRH)\" --verbose --force --timestamp --options \"runtime\" \"ScreenPlay.app/Contents/MacOS/{app}\""
|
||||||
@ -26,7 +25,8 @@ def sign(build_config: BuildConfig):
|
|||||||
# xcrun notarytool submit "ScreenPlay.app.zip" --keychain-profile "ScreenPlay" --wait
|
# xcrun notarytool submit "ScreenPlay.app.zip" --keychain-profile "ScreenPlay" --wait
|
||||||
# xcrun stapler staple "ScreenPlay.app"
|
# xcrun stapler staple "ScreenPlay.app"
|
||||||
print("Packing .apps for upload")
|
print("Packing .apps for upload")
|
||||||
run("ditto -c -k --keepParent 'ScreenPlay.app' 'ScreenPlay.app.zip'", cwd=build_config.bin_dir)
|
run("ditto -c -k --keepParent 'ScreenPlay.app' 'ScreenPlay.app.zip'",
|
||||||
|
cwd=build_config.bin_dir)
|
||||||
|
|
||||||
# run this if you get an error:
|
# run this if you get an error:
|
||||||
# `xcrun notarytool log --apple-id "xxxxx@xxxx.com" --password "xxxx-xxxx-xxxx-xxxx" --team-id "xxxxxxxxxxx" <ID>`
|
# `xcrun notarytool log --apple-id "xxxxx@xxxx.com" --password "xxxx-xxxx-xxxx-xxxx" --team-id "xxxxxxxxxxx" <ID>`
|
||||||
@ -34,32 +34,41 @@ def sign(build_config: BuildConfig):
|
|||||||
# id: xxxxxx-xxxxxx-xxxx-xxxxx-xxxxx
|
# id: xxxxxx-xxxxxx-xxxx-xxxxx-xxxxx
|
||||||
# status: Invalid
|
# status: Invalid
|
||||||
print("Run xcnotary submit")
|
print("Run xcnotary submit")
|
||||||
run("xcrun notarytool submit --keychain-profile 'ScreenPlay' ScreenPlay.app.zip --wait", cwd=build_config.bin_dir)
|
run("xcrun notarytool submit --keychain-profile 'ScreenPlay' ScreenPlay.app.zip --wait",
|
||||||
|
cwd=build_config.bin_dir)
|
||||||
|
|
||||||
print("Run stapler staple")
|
print("Run stapler staple")
|
||||||
run("xcrun stapler staple ScreenPlay.app", cwd=build_config.bin_dir)
|
run("xcrun stapler staple ScreenPlay.app", cwd=build_config.bin_dir)
|
||||||
print("Run spctl assess")
|
print("Run spctl assess")
|
||||||
run("spctl --assess --verbose 'ScreenPlay.app/'", cwd=build_config.bin_dir)
|
run("spctl --assess --verbose 'ScreenPlay.app/'", cwd=build_config.bin_dir)
|
||||||
|
|
||||||
print("Remove *.app.zip files.")
|
print("Remove ScreenPlay.app.zip.")
|
||||||
run("rm ScreenPlay.app.zip", cwd=build_config.bin_dir)
|
run("rm ScreenPlay.app.zip", cwd=build_config.bin_dir)
|
||||||
|
|
||||||
|
|
||||||
# We also need to sign the installer in osx:
|
def sign_dmg(build_config: BuildConfig):
|
||||||
if build_config.create_installer == "ON":
|
# Sign the DMG
|
||||||
run("codesign --deep -f -s \"Developer ID Application: Elias Steurer (V887LHYKRH)\" --timestamp --options \"runtime\" -f --deep \"ScreenPlay-Installer.dmg/ScreenPlay-Installer.app/Contents/MacOS/ScreenPlay-Installer\"", cwd=build_config.build_folder)
|
run("codesign -f -s \"Developer ID Application: Elias Steurer (V887LHYKRH)\" --timestamp --options \"runtime\" -f --deep \"ScreenPlay-Installer.dmg\"", cwd=build_config.build_folder)
|
||||||
run("codesign --verify --verbose=4 \"ScreenPlay-Installer.dmg/ScreenPlay-Installer.app/Contents/MacOS/ScreenPlay-Installer\"",
|
|
||||||
cwd=build_config.build_folder)
|
|
||||||
run("xcnotary notarize ScreenPlay-Installer.dmg/ScreenPlay-Installer.app -d kelteseth@gmail.com -k ScreenPlay",
|
|
||||||
cwd=build_config.build_folder)
|
|
||||||
run("spctl --assess --verbose \"ScreenPlay-Installer.dmg/ScreenPlay-Installer.app/\"",
|
|
||||||
cwd=build_config.build_folder)
|
|
||||||
|
|
||||||
run("codesign --deep -f -s \"Developer ID Application: Elias Steurer (V887LHYKRH)\" --timestamp --options \"runtime\" -f --deep \"ScreenPlay-Installer.dmg/\"", cwd=build_config.build_folder)
|
# Verify the DMG's signature
|
||||||
run("codesign --verify --verbose=4 \"ScreenPlay-Installer.dmg/\"",
|
run("codesign --verify --verbose=4 \"ScreenPlay-Installer.dmg\"",
|
||||||
cwd=build_config.build_folder)
|
cwd=build_config.build_folder)
|
||||||
run("xcnotary notarize ScreenPlay-Installer.dmg -d kelteseth@gmail.com -k ScreenPlay",
|
|
||||||
cwd=build_config.build_folder)
|
|
||||||
run("spctl --assess --verbose \"ScreenPlay-Installer.dmg/\"",
|
|
||||||
cwd=build_config.build_folder)
|
|
||||||
|
|
||||||
|
# Pack the DMG for notarization
|
||||||
|
run("ditto -c -k --keepParent ScreenPlay-Installer.dmg ScreenPlay-Installer.dmg.zip",
|
||||||
|
cwd=build_config.build_folder)
|
||||||
|
|
||||||
|
# Notarize the DMG using notarytool
|
||||||
|
run("xcrun notarytool submit ScreenPlay-Installer.dmg.zip --keychain-profile 'ScreenPlay' --wait",
|
||||||
|
cwd=build_config.build_folder)
|
||||||
|
|
||||||
|
# Staple the notarization ticket to the DMG
|
||||||
|
run("xcrun stapler staple ScreenPlay-Installer.dmg",
|
||||||
|
cwd=build_config.build_folder)
|
||||||
|
|
||||||
|
# Check the notarization status for the DMG
|
||||||
|
run("spctl --assess --verbose \"ScreenPlay-Installer.dmg\"",
|
||||||
|
cwd=build_config.build_folder)
|
||||||
|
|
||||||
|
# Clean up the zip file
|
||||||
|
run("rm ScreenPlay-Installer.dmg.zip", cwd=build_config.build_folder)
|
||||||
|
@ -1,40 +0,0 @@
|
|||||||
#!/usr/bin/python3
|
|
||||||
# SPDX-License-Identifier: LicenseRef-EliasSteurerTachiom OR AGPL-3.0-only
|
|
||||||
import os
|
|
||||||
import subprocess
|
|
||||||
import argparse
|
|
||||||
import sys
|
|
||||||
import defines
|
|
||||||
from format_util import find_files
|
|
||||||
from format_util import check_git_exit
|
|
||||||
from format_util import execute_threaded
|
|
||||||
from sys import stdout
|
|
||||||
|
|
||||||
stdout.reconfigure(encoding='utf-8')
|
|
||||||
|
|
||||||
|
|
||||||
def format_file_function(file):
|
|
||||||
executable = "qmlformat"
|
|
||||||
if os.name == 'nt':
|
|
||||||
executable = "qmlformat.exe"
|
|
||||||
qt_bin_path = defines.QT_BIN_PATH
|
|
||||||
executable = qt_bin_path.joinpath(executable)
|
|
||||||
|
|
||||||
process = subprocess.run(
|
|
||||||
"%s -i %s" % (executable, file), capture_output=True, shell=True)
|
|
||||||
print("Format: %s \t return: %s" % (file, process.returncode))
|
|
||||||
|
|
||||||
|
|
||||||
def main(git_staged_only=False):
|
|
||||||
file_list = find_files(('.qml'), os.path.abspath(os.path.join(os.getcwd(), "../")), git_staged_only)
|
|
||||||
execute_threaded(file_list, format_file_function)
|
|
||||||
if not git_staged_only:
|
|
||||||
check_git_exit("QML Format")
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
parser = argparse.ArgumentParser()
|
|
||||||
parser.add_argument('-s', action="store_true", dest="stage_only",
|
|
||||||
default=False)
|
|
||||||
args = parser.parse_args()
|
|
||||||
main(args.stage_only)
|
|
@ -1,3 +1,2 @@
|
|||||||
cmake-format
|
cmake-format
|
||||||
paramiko
|
|
||||||
aqtinstall
|
aqtinstall
|
@ -5,6 +5,7 @@ import sys
|
|||||||
import subprocess
|
import subprocess
|
||||||
import shutil
|
import shutil
|
||||||
import argparse
|
import argparse
|
||||||
|
from pathlib import Path
|
||||||
from sys import platform
|
from sys import platform
|
||||||
from execute_util import execute
|
from execute_util import execute
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
@ -16,6 +17,67 @@ from sys import stdout
|
|||||||
|
|
||||||
stdout.reconfigure(encoding='utf-8')
|
stdout.reconfigure(encoding='utf-8')
|
||||||
|
|
||||||
|
|
||||||
|
class PublishConfig:
|
||||||
|
vdf_config_name: str
|
||||||
|
depot_config_name: str
|
||||||
|
steamcmd_path: Path
|
||||||
|
|
||||||
|
|
||||||
|
def init_publish_config():
|
||||||
|
config = PublishConfig()
|
||||||
|
|
||||||
|
root_path = cd_repo_root_path()
|
||||||
|
tools_path = os.path.join(root_path, "Tools")
|
||||||
|
contentBuiler_path = os.path.join(tools_path, "Steam/ContentBuilder/")
|
||||||
|
|
||||||
|
if platform.system() == "Windows":
|
||||||
|
config.vdf_config_name = "app_build_windows.vdf"
|
||||||
|
config.depot_config_name = "depot_build_windows.vdf"
|
||||||
|
config.steamcmd_path = os.path.join(
|
||||||
|
contentBuiler_path, "builder/steamcmd.exe")
|
||||||
|
elif platform.system() == "Darwin":
|
||||||
|
config.vdf_config_name = "app_build_mac.vdf"
|
||||||
|
config.depot_config_name = "depot_build_mac.vdf"
|
||||||
|
config.steamcmd_path = os.path.join(
|
||||||
|
contentBuiler_path, "builder_osx/steamcmd")
|
||||||
|
execute(f"chmod +x {config.steamcmd_path}")
|
||||||
|
elif platform.system() == "Linux":
|
||||||
|
config.vdf_config_name = "app_build_linux.vdf"
|
||||||
|
config.depot_config_name = "depot_build_linux.vdf"
|
||||||
|
config.steamcmd_path = os.path.join(
|
||||||
|
contentBuiler_path, "builder_linux/steamcmd.sh")
|
||||||
|
execute(f"chmod +x {config.steamcmd_path}")
|
||||||
|
|
||||||
|
return config
|
||||||
|
|
||||||
|
|
||||||
|
def check_steam_login(username: str, password: str):
|
||||||
|
config = init_publish_config()
|
||||||
|
cmd = [config.steamcmd_path, "+login", username, password, "+quit"]
|
||||||
|
|
||||||
|
try:
|
||||||
|
with subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) as process:
|
||||||
|
try:
|
||||||
|
stdout, stderr = process.communicate(
|
||||||
|
timeout=60) # 1 minute timeout
|
||||||
|
for line in stdout.splitlines():
|
||||||
|
print(line) # Print the line for debugging purposes
|
||||||
|
|
||||||
|
if "Logging in user" in line:
|
||||||
|
return True
|
||||||
|
elif "Steam Guard code" in line:
|
||||||
|
process.terminate()
|
||||||
|
return False
|
||||||
|
except subprocess.TimeoutExpired:
|
||||||
|
process.kill()
|
||||||
|
print("Steam login check timed out after 1 minute.")
|
||||||
|
return False
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error during Steam login check: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
# Executes steamcmd with username and password. Changes the content of the config
|
# Executes steamcmd with username and password. Changes the content of the config
|
||||||
# for better readability in the steam builds tab
|
# for better readability in the steam builds tab
|
||||||
# https://partner.steamgames.com/apps/builds/672870
|
# https://partner.steamgames.com/apps/builds/672870
|
||||||
@ -27,6 +89,7 @@ def get_git_revision_short_hash():
|
|||||||
def get_git_commit_text():
|
def get_git_commit_text():
|
||||||
return subprocess.check_output(['git', 'log', '-1', '--pretty=%B'])
|
return subprocess.check_output(['git', 'log', '-1', '--pretty=%B'])
|
||||||
|
|
||||||
|
|
||||||
def publish(
|
def publish(
|
||||||
steam_username,
|
steam_username,
|
||||||
steam_password,
|
steam_password,
|
||||||
@ -36,30 +99,13 @@ def publish(
|
|||||||
# Make sure the script is always started from the same folder
|
# Make sure the script is always started from the same folder
|
||||||
root_path = cd_repo_root_path()
|
root_path = cd_repo_root_path()
|
||||||
tools_path = os.path.join(root_path, "Tools")
|
tools_path = os.path.join(root_path, "Tools")
|
||||||
contentBuiler_path = os.path.join(tools_path, "Steam/ContentBuilder/")
|
|
||||||
|
|
||||||
vdf_config_name = ""
|
config = init_publish_config()
|
||||||
depot_config_name = ""
|
|
||||||
steamcmd_path = ""
|
|
||||||
if platform.system() == "Windows":
|
|
||||||
vdf_config_name = "app_build_windows.vdf"
|
|
||||||
depot_config_name = "depot_build_windows.vdf"
|
|
||||||
steamcmd_path = os.path.join(contentBuiler_path, "builder/steamcmd.exe")
|
|
||||||
steamcmd_path = steamcmd_path.replace("/","\\")
|
|
||||||
elif platform.system() == "Darwin":
|
|
||||||
vdf_config_name = "app_build_mac.vdf"
|
|
||||||
depot_config_name = "depot_build_mac.vdf"
|
|
||||||
steamcmd_path = os.path.join(contentBuiler_path, "builder_osx/steamcmd")
|
|
||||||
execute(f"chmod +x {steamcmd_path}")
|
|
||||||
elif platform.system() == "Linux":
|
|
||||||
vdf_config_name = "app_build_linux.vdf"
|
|
||||||
depot_config_name = "depot_build_linux.vdf"
|
|
||||||
steamcmd_path = os.path.join(contentBuiler_path, "builder_linux/steamcmd.sh")
|
|
||||||
execute(f"chmod +x {steamcmd_path}")
|
|
||||||
|
|
||||||
print(f"Set steamCmd path: {steamcmd_path}")
|
print(f"Set steamCmd path: {config.steamcmd_path}")
|
||||||
|
|
||||||
abs_vdf_path = os.path.join(tools_path,"Steam/steamcmd/" + vdf_config_name)
|
abs_vdf_path = os.path.join(
|
||||||
|
tools_path, "Steam/steamcmd/" + config.vdf_config_name)
|
||||||
|
|
||||||
if not os.path.isfile(abs_vdf_path):
|
if not os.path.isfile(abs_vdf_path):
|
||||||
print("Incorrect vdf name")
|
print("Incorrect vdf name")
|
||||||
@ -71,15 +117,19 @@ def publish(
|
|||||||
git_hash = get_git_revision_short_hash().decode("utf-8").replace("\n", "")
|
git_hash = get_git_revision_short_hash().decode("utf-8").replace("\n", "")
|
||||||
git_commit_text = get_git_commit_text().decode("utf-8").replace("\n", "")
|
git_commit_text = get_git_commit_text().decode("utf-8").replace("\n", "")
|
||||||
# Remove ' and " that can occour it is a merge commit
|
# Remove ' and " that can occour it is a merge commit
|
||||||
git_commit_text = git_commit_text.replace('\"','')
|
git_commit_text = git_commit_text.replace('\"', '')
|
||||||
git_commit_text = git_commit_text.replace('\'','')
|
git_commit_text = git_commit_text.replace('\'', '')
|
||||||
current_date_time = datetime.now().strftime("%d/%m/%Y, %H:%M:%S")
|
current_date_time = datetime.now().strftime("%d/%m/%Y, %H:%M:%S")
|
||||||
|
|
||||||
build_description = "- git hash: " + git_hash + ", commit: " + git_commit_text + " - upload datetime: " + current_date_time
|
build_description = "- git hash: " + git_hash + ", commit: " + \
|
||||||
config_content = config_content.replace("{{BUILD_DESCRIPTION}}", build_description)
|
git_commit_text + " - upload datetime: " + current_date_time
|
||||||
config_content = config_content.replace("{{SET_LIVE_ON_BRANCH}}", set_live_branch_name)
|
config_content = config_content.replace(
|
||||||
|
"{{BUILD_DESCRIPTION}}", build_description)
|
||||||
|
config_content = config_content.replace(
|
||||||
|
"{{SET_LIVE_ON_BRANCH}}", set_live_branch_name)
|
||||||
tmp_steam_config_foldername = "tmp_steam_config/"
|
tmp_steam_config_foldername = "tmp_steam_config/"
|
||||||
tmp_steam_config_dir = os.path.abspath(os.path.join(tools_path,tmp_steam_config_foldername))
|
tmp_steam_config_dir = os.path.abspath(
|
||||||
|
os.path.join(tools_path, tmp_steam_config_foldername))
|
||||||
|
|
||||||
if os.path.isdir(tmp_steam_config_dir):
|
if os.path.isdir(tmp_steam_config_dir):
|
||||||
print(f"Deleting tmp config {tmp_steam_config_dir}")
|
print(f"Deleting tmp config {tmp_steam_config_dir}")
|
||||||
@ -87,24 +137,30 @@ def publish(
|
|||||||
|
|
||||||
os.mkdir(tmp_steam_config_dir)
|
os.mkdir(tmp_steam_config_dir)
|
||||||
|
|
||||||
f = open(os.path.abspath(tmp_steam_config_dir + "/" + vdf_config_name), "w")
|
f = open(os.path.abspath(tmp_steam_config_dir +
|
||||||
|
"/" + config.vdf_config_name), "w")
|
||||||
f.write(config_content)
|
f.write(config_content)
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
print(f"Using config:\n {config_content}\n")
|
print(f"Using config:\n {config_content}\n")
|
||||||
|
|
||||||
# We also must copy the depot file
|
# We also must copy the depot file
|
||||||
abs_depot_path = os.path.join(tools_path, "Steam/steamcmd/" + depot_config_name)
|
abs_depot_path = os.path.join(
|
||||||
copyfile(abs_depot_path, tmp_steam_config_dir + "/" + depot_config_name)
|
tools_path, "Steam/steamcmd/" + config.depot_config_name)
|
||||||
|
copyfile(abs_depot_path, tmp_steam_config_dir +
|
||||||
|
"/" + config.depot_config_name)
|
||||||
|
|
||||||
tmp_steam_config_path = "\"" + os.path.abspath(os.path.join(tmp_steam_config_dir,vdf_config_name) ) + "\""
|
tmp_steam_config_path = "\"" + \
|
||||||
|
os.path.abspath(os.path.join(
|
||||||
|
tmp_steam_config_dir, config.vdf_config_name)) + "\""
|
||||||
|
|
||||||
print("Execute steamcmd on: " + tmp_steam_config_path)
|
print("Execute steamcmd on: " + tmp_steam_config_path)
|
||||||
execute(f"{steamcmd_path} +login {steam_username} {steam_password} +run_app_build {tmp_steam_config_path} +quit")
|
execute(f"{config.steamcmd_path} +login {steam_username} {steam_password} +run_app_build {tmp_steam_config_path} +quit")
|
||||||
|
|
||||||
print("Deleting tmp config")
|
print("Deleting tmp config")
|
||||||
shutil.rmtree(tmp_steam_config_dir)
|
shutil.rmtree(tmp_steam_config_dir)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
parser = argparse.ArgumentParser(description='Publish ScreenPlay to Steam')
|
parser = argparse.ArgumentParser(description='Publish ScreenPlay to Steam')
|
||||||
parser.add_argument('-steam_username', action="store", dest="steam_username", required=True,
|
parser.add_argument('-steam_username', action="store", dest="steam_username", required=True,
|
||||||
|
@ -6,11 +6,13 @@ from pathlib import Path
|
|||||||
from os import chdir
|
from os import chdir
|
||||||
from concurrent.futures import ThreadPoolExecutor
|
from concurrent.futures import ThreadPoolExecutor
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
import subprocess
|
import subprocess
|
||||||
from sys import stdout
|
from sys import stdout
|
||||||
|
|
||||||
stdout.reconfigure(encoding='utf-8')
|
stdout.reconfigure(encoding='utf-8')
|
||||||
|
|
||||||
|
|
||||||
def sftp_exists(sftp, path) -> bool:
|
def sftp_exists(sftp, path) -> bool:
|
||||||
try:
|
try:
|
||||||
sftp.stat(path)
|
sftp.stat(path)
|
||||||
@ -24,6 +26,7 @@ def run(cmd, cwd=Path.cwd()):
|
|||||||
if result.returncode != 0:
|
if result.returncode != 0:
|
||||||
raise RuntimeError(f"Failed to execute {cmd}")
|
raise RuntimeError(f"Failed to execute {cmd}")
|
||||||
|
|
||||||
|
|
||||||
def run_and_capture_output(cmd, cwd=Path.cwd()) -> str:
|
def run_and_capture_output(cmd, cwd=Path.cwd()) -> str:
|
||||||
result = subprocess.run(cmd, shell=True, cwd=cwd, stdout=subprocess.PIPE)
|
result = subprocess.run(cmd, shell=True, cwd=cwd, stdout=subprocess.PIPE)
|
||||||
if result.returncode != 0:
|
if result.returncode != 0:
|
||||||
@ -32,11 +35,13 @@ def run_and_capture_output(cmd, cwd=Path.cwd()) -> str:
|
|||||||
return str(result.stdout.decode('utf-8'))
|
return str(result.stdout.decode('utf-8'))
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
|
||||||
def repo_root_path() -> str:
|
def repo_root_path() -> str:
|
||||||
# Root dir of the repository
|
# Root dir of the repository
|
||||||
path = os.path.join(os.path.realpath(__file__), "../../")
|
path = os.path.join(os.path.realpath(__file__), "../../")
|
||||||
return os.path.realpath(path)
|
return os.path.realpath(path)
|
||||||
|
|
||||||
|
|
||||||
def cd_repo_root_path() -> str:
|
def cd_repo_root_path() -> str:
|
||||||
# Make sure the script is always started from the same
|
# Make sure the script is always started from the same
|
||||||
# ScreenPlay root folder
|
# ScreenPlay root folder
|
||||||
@ -47,6 +52,7 @@ def cd_repo_root_path() -> str:
|
|||||||
chdir(root_path)
|
chdir(root_path)
|
||||||
return root_path
|
return root_path
|
||||||
|
|
||||||
|
|
||||||
def sha256(fname) -> str:
|
def sha256(fname) -> str:
|
||||||
hash_sha256 = hashlib.sha256()
|
hash_sha256 = hashlib.sha256()
|
||||||
with open(fname, "rb") as f:
|
with open(fname, "rb") as f:
|
||||||
@ -55,7 +61,6 @@ def sha256(fname) -> str:
|
|||||||
return hash_sha256.hexdigest()
|
return hash_sha256.hexdigest()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def zipdir(path, ziph):
|
def zipdir(path, ziph):
|
||||||
# ziph is zipfile handle
|
# ziph is zipfile handle
|
||||||
for root, dirs, files in os.walk(path):
|
for root, dirs, files in os.walk(path):
|
||||||
@ -102,3 +107,40 @@ def get_vs_env_dict():
|
|||||||
raise ValueError(stderr.decode("mbcs"))
|
raise ValueError(stderr.decode("mbcs"))
|
||||||
output = stdout.decode("mbcs").split("\r\n")
|
output = stdout.decode("mbcs").split("\r\n")
|
||||||
return dict((e[0].upper(), e[1]) for e in [p.rstrip().split("=", 1) for p in output] if len(e) == 2)
|
return dict((e[0].upper(), e[1]) for e in [p.rstrip().split("=", 1) for p in output] if len(e) == 2)
|
||||||
|
|
||||||
|
|
||||||
|
def get_latest_git_tag():
|
||||||
|
try:
|
||||||
|
tag = subprocess.check_output(
|
||||||
|
["git", "describe", "--tags"]).decode("utf-8").strip()
|
||||||
|
return tag
|
||||||
|
except subprocess.CalledProcessError:
|
||||||
|
print("Error fetching the Git tag.")
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def parse_semver(tag):
|
||||||
|
# Regular expression to match semver
|
||||||
|
# Like v0.15.1-RC1-305-g18b8c402
|
||||||
|
# Do NOT add a - between RC and the version number (1 in this example)
|
||||||
|
pattern = r'(?i)^v?(\d+)\.(\d+)\.(\d+)(?:-([a-zA-Z0-9]+))?(?:-(\d+)-g([a-f0-9]+))?$'
|
||||||
|
match = re.match(pattern, tag)
|
||||||
|
if match:
|
||||||
|
major, minor, patch, pre_release, commits_since, commit_hash = match.groups()
|
||||||
|
return {
|
||||||
|
'major': major,
|
||||||
|
'minor': minor,
|
||||||
|
'patch': patch,
|
||||||
|
'pre_release': pre_release,
|
||||||
|
'commits_since': commits_since,
|
||||||
|
'commit_hash': commit_hash
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def semver_to_string(semver_dict):
|
||||||
|
version_str = f"v{semver_dict['major']}.{semver_dict['minor']}.{semver_dict['patch']}"
|
||||||
|
if semver_dict['pre_release']:
|
||||||
|
version_str += f"-{semver_dict['pre_release']}"
|
||||||
|
return version_str
|
||||||
|
Loading…
Reference in New Issue
Block a user