From bcf1a928d390c8bc1a518d348c641e638f873cd1 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 14 Feb 2024 14:38:29 +0100 Subject: [PATCH 01/11] mention ubuntu in docker build variants --- Dockerfile | 2 +- tools/manage.ps1 | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index 91f9342c2..d730e24aa 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -# Build Pype docker image +# Build AYON docker image FROM ubuntu:focal AS builder ARG PYTHON_VERSION=3.9.12 ARG BUILD_DATE diff --git a/tools/manage.ps1 b/tools/manage.ps1 index bd159a537..6fa3eb86b 100755 --- a/tools/manage.ps1 +++ b/tools/manage.ps1 @@ -189,7 +189,11 @@ function New-DockerBuild { $startTime = [int][double]::Parse((Get-Date -UFormat %s)) Write-Color -Text ">>> ", "Building AYON using Docker ..." -Color Green, Gray, White $variant = $args[0] - $dockerfile = "$($repo_root)\Dockerfile.$variant" + if (($variant -eq $null) -or ($variant -eq "ubuntu")) { + $dockerfile = "$($repo_root)\Dockerfile" + } else { + $dockerfile = "$($repo_root)\Dockerfile.$variant" + } if (-not (Test-Path -PathType Leaf -Path $dockerfile)) { Write-Color -Text "!!! ", "Dockerfile for specifed platform ", "[", $variant, "]", "doesn't exist." -Color Red, Yellow, Cyan, White, Cyan, Yellow Restore-Cwd @@ -251,7 +255,7 @@ function Default-Func { Write-Color -text " build-make-installer ", "Build desktop application and make installer" -Color White, Cyan Write-Color -text " upload ", "Upload installer to server" -Color White, Cyan Write-Color -text " run ", "Run desktop application from code" -Color White, Cyan - Write-Color -text " docker-build ","[variant] ", "Build AYON using Docker. Variant can be '", "centos7", "', '", "debian", "' or '", "rocky9", "'" -Color White, Yellow, Cyan, Yellow, Cyan, Yellow, Cyan, Yellow, Cyan + Write-Color -text " docker-build ","[variant] ", "Build AYON using Docker. Variant can be '", "centos7", "', '", "ubuntu","', '", "debian", "' or '", "rocky9", "'" -Color White, Yellow, Cyan, Yellow, Cyan, Yellow, Cyan, Yellow, Cyan, Yellow, Cyan Write-Host "" } From 0777a76e57d81cc99107e11162cec04f992aad29 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 15 Feb 2024 11:04:26 +0100 Subject: [PATCH 02/11] auto-fix codesign bug --- tools/make.sh | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/tools/make.sh b/tools/make.sh index e61494791..a697f195d 100755 --- a/tools/make.sh +++ b/tools/make.sh @@ -265,13 +265,21 @@ build_ayon () { if [[ "$OSTYPE" == "darwin"* ]]; then macoscontents="$repo_root/build/AYON $ayon_version.app/Contents" macosdir="$macoscontents/MacOS" - + ayonexe="$macosdir/ayon" + tmp_ayonexe="$macosdir/ayon_tmp" # force hide icon from Dock defaults write "$macoscontents/Info" LSUIElement 1 + # Fix codesign bug by creating copy of executable, removing source + # executable and replacing by the copy + # - this will clear cache of codesign + cp $ayonexe $tmp_ayonexe + rm $ayonexe + mv $tmp_ayonexe $ayonexe + # fix code signing issue echo -e "${BIGreen}>>>${RST} Fixing code signatures ...\c" - codesign --remove-signature "$macosdir/ayon" || { echo -e "${BIRed}FAILED${RST}"; return 1; } + codesign --remove-signature $ayonexe || { echo -e "${BIRed}FAILED${RST}"; return 1; } fi if [[ "$should_make_installer" == 1 ]]; then From 4f7cb41e2720ee633f6be335401f8a1da5ab9117 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 15 Feb 2024 11:51:44 +0100 Subject: [PATCH 03/11] add quotes --- tools/make.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/make.sh b/tools/make.sh index a697f195d..c13ac942e 100755 --- a/tools/make.sh +++ b/tools/make.sh @@ -273,13 +273,13 @@ build_ayon () { # Fix codesign bug by creating copy of executable, removing source # executable and replacing by the copy # - this will clear cache of codesign - cp $ayonexe $tmp_ayonexe - rm $ayonexe - mv $tmp_ayonexe $ayonexe + cp "$ayonexe" "$tmp_ayonexe" + rm "$ayonexe" + mv "$tmp_ayonexe" "$ayonexe" # fix code signing issue echo -e "${BIGreen}>>>${RST} Fixing code signatures ...\c" - codesign --remove-signature $ayonexe || { echo -e "${BIRed}FAILED${RST}"; return 1; } + codesign --remove-signature "$ayonexe" || { echo -e "${BIRed}FAILED${RST}"; return 1; } fi if [[ "$should_make_installer" == 1 ]]; then From 385cbd9ef83ab1ad93a1ee7eb396b9b0e1efe89c Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 26 Feb 2024 10:46:59 +0100 Subject: [PATCH 04/11] password button can keep password text visible --- .../ayon_common/connection/ui/login_window.py | 46 +++++++++++++++--- common/ayon_common/resources/eye.png | Bin 2152 -> 1751 bytes common/ayon_common/resources/eye_closed.png | Bin 0 -> 1915 bytes 3 files changed, 38 insertions(+), 8 deletions(-) create mode 100644 common/ayon_common/resources/eye_closed.png diff --git a/common/ayon_common/connection/ui/login_window.py b/common/ayon_common/connection/ui/login_window.py index 94c239852..6d77296e4 100644 --- a/common/ayon_common/connection/ui/login_window.py +++ b/common/ayon_common/connection/ui/login_window.py @@ -18,6 +18,41 @@ ) +class ShowPasswordButton(QtWidgets.QPushButton): + state_changed = QtCore.Signal(bool) + + def __init__(self, parent): + super().__init__(parent) + + show_password_icon = QtGui.QIcon(get_resource_path("eye.png")) + hide_password_icon = QtGui.QIcon(get_resource_path("eye_closed.png")) + + self.setObjectName("PasswordBtn") + self.setIcon(show_password_icon) + self.setToolTip("Show") + + self.clicked.connect(self._on_click) + + self._password_visible = False + self._show_password_icon = show_password_icon + self._hide_password_icon = hide_password_icon + + def _on_click(self): + self._password_visible = not self._password_visible + if self._password_visible: + new_icon = self._hide_password_icon + new_hint = "Show" + else: + new_icon = self._show_password_icon + new_hint = "Hide" + self.setIcon(new_icon) + self.setToolTip(new_hint) + self.state_changed.emit(self._password_visible) + + def is_password_visible(self): + return self._password_visible + + class LogoutConfirmDialog(QtWidgets.QDialog): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @@ -178,12 +213,7 @@ def __init__(self, *args, **kwargs): api_preview.setReadOnly(True) api_preview.setObjectName("LikeDisabledInput") - show_password_icon_path = get_resource_path("eye.png") - show_password_icon = QtGui.QIcon(show_password_icon_path) - show_password_btn = PressHoverButton(user_cred_widget) - show_password_btn.setObjectName("PasswordBtn") - show_password_btn.setIcon(show_password_icon) - show_password_btn.setFocusPolicy(QtCore.Qt.ClickFocus) + show_password_btn = ShowPasswordButton(user_cred_widget) cred_msg_sep = QtWidgets.QFrame(self) cred_msg_sep.setObjectName("Separator") @@ -258,7 +288,7 @@ def __init__(self, *args, **kwargs): username_input.textChanged.connect(self._on_user_change) username_input.returnPressed.connect(self._on_username_enter_press) password_input.returnPressed.connect(self._on_password_enter_press) - show_password_btn.change_state.connect(self._on_show_password) + show_password_btn.state_changed.connect(self._on_password_state_change) url_edit_btn.clicked.connect(self._on_url_edit_click) username_edit_btn.clicked.connect(self._on_username_edit_click) logout_btn.clicked.connect(self._on_logout_click) @@ -452,7 +482,7 @@ def _on_username_enter_press(self): def _on_password_enter_press(self): self._login() - def _on_show_password(self, show_password): + def _on_password_state_change(self, show_password): if show_password: placeholder_text = "< MySecret124 >" echo_mode = QtWidgets.QLineEdit.Normal diff --git a/common/ayon_common/resources/eye.png b/common/ayon_common/resources/eye.png index 5a683e29748b35b3b64a200cb9723e82df45f4b9..dce911949426e01734b3c647c4b4ec22e078cb16 100644 GIT binary patch literal 1751 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 diff --git a/common/ayon_common/resources/eye_closed.png b/common/ayon_common/resources/eye_closed.png new file mode 100644 index 0000000000000000000000000000000000000000..dbfa4fa22141841d6202ae7180c6c7fa465991bf GIT binary patch literal 1915 zcmV->2ZZ>EP)JFJP;zl_FBIwk9^{Id4XdWbW;r^SR%9>HB!5dAfX{$U4 z>5OegM#IYN+`Qs@#!CxTVw+;BWlTQN*IN4h8d!d9tOnr(M5=E*-;`tn9rYLMRHZK202WY zNsz>*Q`D?f*Tn0hYcf;h-2VUVtEKmb3e{`FQ1RqAukGO5g0D@-`8af(uOldXgo{iu zf8_xB-$dUmYJq+5ufy48QH$@u`35vU7%?-Jm&#;$bsb(#pl%KtuAzFN(6gU&j_)D5 zCSP?0yL-?f@&3hc9@1yUfh}E+00009a7bBm001r{001r{0eGc9b^rhcp-DtRRCt{2 znqP<)RTRfR{<0{mO*1Q5m#nprj$)A^WuaNisx0;o#KK;-d%|cAE0x2mUR`fiSt&6!?VXV4ETCHvm_x^N#zn$6N+zI1 zee8vhS^!m@4D5+C{SHj4B!a5m1Uv!E07heOdT317Uf>AOff3{ouvtVp)B5OxivZUH zUBFe5=2#I_^+wE1&jzLd1yBF_fL*|9V5^Ay<7p=m*D3I*Rp6COJiNeh zU>&eVM840;sFMJYP6SmQ1iS_;$->DP)&h$}q&w7*vjA|(h;STu5%@qv`h1Oe2>_Rj z2mm{Q=S8H$=VEUG;F1#I4Db@L%Jpe*eF+W$#)-(ckv3luP5=jh)4)i~@;J=JpBPpH zFSx80uFK%3z}>(s5!o3zmsW(?z$wg)AB+B4_WWJIqd+r85Ffq-o=p3KOeKJ-jskW7 zciN^ic!-b|RjmP*1M^(2i|`}RlxDfCD1fSt1wN<$FH%(zti49elIN3uoB|#Zk$nSo z8c+aLodkRa3{U8CF+>;&tOuH0uf;5tlSSlEQintVRP|oq3*hPsgIp{T4&wJDbOQH_ z$ggoHV+Byvdf*#iM9M+DM6fTu`9LGE4`>sS9};|;4s1{9PdV+t6cOnuKhaMBRUH9* z4UBOdBt(Sb5_tw#46GE9b1}ZH2A*^DtH^F(rilC^i><_nQZ}5?B>&5RtW* zH+eKTxdGU%s^e{+KHz0wskN~J*ruv+8RSCXsE2O=(}4HN?Vdldzr+S$lIH*bo68$K zL;#oxw8Yrz0p1PpZ#M9jy;q?030MF;7GNBpEw0g1gx6K|ju>-W0)1=&78MT)0IGTq zuq@E&$P9yp4yBf;jeaCf-{Xf5DhuPY}h4ebR!@f4vo!RC-~ zcL6w8zyu;kGB7qWp?x1_KKqJLf_;OJ&%oafV17YFP6Bg*eu0N0b+qT^kVikdJ5K&J%m?mh5-{|+S@P@9%Lgz7Qg-y5%~^E=l>hP+kuAr#Su2PUmR%) z6`>~3$B%(GiwEZgu=8yJuqnWJvn^(nvy#$8CPah}xezS5vKN>e%`-|?01-J0JcCIb ze5k`za!RlRHet%xLDL~7Vob|nOtN-5+L)9M*8pE(YIHtK7m?UC+=jPvFhR~lU@*`i zBKsqKvaU9F1NX(H+5;6tZpNg=x271NoS!k(`JV7;y6c#+X`I1W6Nbn{Rl3beJfnV15jD^0*bTgmYvP=qevK@n*mXpFRF@v-<9 zO29nI3q|A)pNl=FLkIA%h*XSlT{cFB10MlXQ+r;@QA{yo3(#I3=0-x?r!nzFi)VSQ z1=u7azoc=>b!+SjOt9p;VNv7+<`F%HnTB=1DBzk%pQ=}z!DDkYqVh7#T3$`6E<(um z_!vyO+EA%)AXOD1bbEXdX3nl4{T_l3E+UK*k>Ao94l0I-NS}yo0LB7qLTpvQC2VeX zF`P*?NJP3tWFAI{<@g0pmG~E!rK*=j#*Gu_Fds|~F6-Kd$ss!J-+o}Dh-6U!O{D4q z#G$H#F>8Ol^`R5$j(?^YNykY Date: Mon, 26 Feb 2024 10:58:16 +0100 Subject: [PATCH 05/11] handle when ayon launcher is relaunched from older version --- start.py | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/start.py b/start.py index 83e20ba42..afa639b11 100644 --- a/start.py +++ b/start.py @@ -94,6 +94,8 @@ ORIGINAL_ARGS = list(sys.argv) +PREVIOUS_AYON_VERSION = os.getenv("AYON_VERSION") + os.environ["AYON_VERSION"] = __version__ # Define which bundle is used @@ -176,6 +178,36 @@ sys.argv.remove("--ayon-login") SHOW_LOGIN_UI = True + +def _is_in_login_mode(): + # Handle cases when source AYON launcher has version before '1.0.1' + # - When user launcher an executable of AYON launcher it will run correct + # version of AYON launcher by bundle, but older launcher versions + # will not set 'AYON_IN_LOGIN_MODE' environment variable. Therefore + # we need to check 'PREVIOUS_AYON_VERSION' and set 'AYON_IN_LOGIN_MODE' + # to 'True' when version is before '1.0.1'. + # - this would be `return "AYON_API_KEY" not in os.environ` otherwise + if "AYON_API_KEY" not in os.environ: + return True + + # Handle cases when source AYON launcher has version before '1.0.1' + version_parts = PREVIOUS_AYON_VERSION.split(".") + if len(version_parts) < 3: + return False + + try: + # Keep only first 3 version parts which should be integers + new_version_parts = [ + int(value) + for idx, value in enumerate(version_parts) + if idx < 3 + ] + except ValueError: + return False + milestone = (1, 0, 1) + return tuple(new_version_parts) < milestone + + # Login mode is helper to detect if user is using AYON server credentials # from login UI (and keyring), or from environment variables. # - Variable is set in first AYON launcher process for possible subprocesses @@ -184,9 +216,7 @@ os.environ["AYON_IN_LOGIN_MODE"] = "1" elif "AYON_IN_LOGIN_MODE" not in os.environ: - os.environ["AYON_IN_LOGIN_MODE"] = ( - "0" if "AYON_API_KEY" in os.environ else "1" - ) + os.environ["AYON_IN_LOGIN_MODE"] = str(int(_is_in_login_mode())) if "--headless" in sys.argv: os.environ["AYON_HEADLESS_MODE"] = "1" From 520bb3130a47a6ffa5af0e100f23ec8168cc579f Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 6 Mar 2024 11:47:40 +0100 Subject: [PATCH 06/11] startup error can show detail --- common/ayon_common/startup/__init__.py | 11 +++++-- .../ayon_common/startup/ui/startup_error.py | 31 +++++++++++++++++-- 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/common/ayon_common/startup/__init__.py b/common/ayon_common/startup/__init__.py index 720655c7b..86aa3803d 100644 --- a/common/ayon_common/startup/__init__.py +++ b/common/ayon_common/startup/__init__.py @@ -7,7 +7,7 @@ from ayon_common.utils import get_ayon_launch_args -def show_startup_error(title, message): +def show_startup_error(title, message, detail=None): """Show startup error message. This will trigger a subprocess with UI message dialog. @@ -26,7 +26,14 @@ def show_startup_error(title, message): filepath = tmp.name with open(filepath, "w") as stream: - json.dump({"title": title, "message": message}, stream) + json.dump( + { + "title": title, + "message": message, + "detail": detail, + }, + stream + ) args = get_ayon_launch_args( script_path, "--skip-bootstrap", filepath diff --git a/common/ayon_common/startup/ui/startup_error.py b/common/ayon_common/startup/ui/startup_error.py index 8b9dee585..83dfcf9a3 100644 --- a/common/ayon_common/startup/ui/startup_error.py +++ b/common/ayon_common/startup/ui/startup_error.py @@ -1,7 +1,7 @@ import sys import json -from qtpy import QtWidgets, QtGui +from qtpy import QtWidgets, QtGui, QtCore from ayon_common.resources import ( get_icon_path, @@ -14,7 +14,7 @@ class MessageWindow(QtWidgets.QDialog): default_width = 410 default_height = 170 - def __init__(self, title, message, parent=None): + def __init__(self, title, message, detail, parent=None): super().__init__(parent) icon_path = get_icon_path() @@ -37,9 +37,28 @@ def __init__(self, title, message, parent=None): info_label = QtWidgets.QLabel(message, info_widget) info_label.setWordWrap(True) + details_wrapper = QtWidgets.QWidget(info_widget) + + details_separator = QtWidgets.QFrame(details_wrapper) + details_separator.setObjectName("Separator") + details_separator.setMinimumHeight(2) + details_separator.setMaximumHeight(2) + + details_widget = QtWidgets.QLabel(details_wrapper) + details_widget.setWordWrap(True) + details_widget.setTextInteractionFlags( + QtCore.Qt.TextBrowserInteraction + ) + + details_wrapper_layout = QtWidgets.QVBoxLayout(details_wrapper) + details_wrapper_layout.setContentsMargins(0, 0, 0, 0) + details_wrapper_layout.addWidget(details_separator, 0) + details_wrapper_layout.addWidget(details_widget, 0) + info_layout = QtWidgets.QVBoxLayout(info_widget) info_layout.setContentsMargins(0, 0, 0, 0) info_layout.addWidget(info_label, 0) + info_layout.addWidget(details_wrapper, 0) info_layout.addStretch(1) body_layout = QtWidgets.QHBoxLayout(body_widget) @@ -61,8 +80,14 @@ def __init__(self, title, message, parent=None): confirm_btn.clicked.connect(self._on_confirm_click) + if detail: + details_widget.setText(detail) + else: + details_wrapper.setVisible(False) + self._icon_label = icon_label self._confirm_btn = confirm_btn + self._details_widget = details_widget def showEvent(self, event): super().showEvent(event) @@ -111,7 +136,7 @@ def main(): data = json.load(stream) app = get_qt_app() - window = MessageWindow(data["title"], data["message"]) + window = MessageWindow(data["title"], data["message"], data["detail"]) window.show() app.exec_() From 868ab510f4aa6d7e6190c6122eb848c81fbb832a Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 6 Mar 2024 11:48:50 +0100 Subject: [PATCH 07/11] print traceback and add error message to detail --- start.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/start.py b/start.py index afa639b11..236ec3376 100644 --- a/start.py +++ b/start.py @@ -739,7 +739,7 @@ def _on_main_addon_missing(): sys.exit(1) -def _on_main_addon_import_error(): +def _on_main_addon_import_error(exception): if HEADLESS_MODE_ENABLED: raise RuntimeError( "Failed to import AYON core addon. Probably because" @@ -752,7 +752,8 @@ def _on_main_addon_import_error(): " addons." "

Please contact your administrator" " to resolve the issue." - ) + ), + str(exception) ) sys.exit(1) @@ -765,8 +766,9 @@ def _main_cli_openpype(): try: from openpype import cli - except ImportError: - _on_main_addon_import_error() + except ImportError as exc: + traceback.print_exception(*sys.exc_info()) + _on_main_addon_import_error(exc) python_path = os.getenv("PYTHONPATH", "") split_paths = python_path.split(os.pathsep) @@ -835,8 +837,9 @@ def main_cli(): try: from ayon_core import cli - except ImportError: - _on_main_addon_import_error() + except ImportError as exc: + traceback.print_exception(*sys.exc_info()) + _on_main_addon_import_error(exc) # print info when not running scripts defined in 'silent commands' if not SKIP_HEADERS: From f0345ad3d245b1f921eb5e0b0fe7c669248e6370 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 6 Mar 2024 15:27:49 +0100 Subject: [PATCH 08/11] export requirements from poetry --- tools/make.sh | 1 + tools/manage.ps1 | 2 ++ 2 files changed, 3 insertions(+) diff --git a/tools/make.sh b/tools/make.sh index c13ac942e..48f43a931 100755 --- a/tools/make.sh +++ b/tools/make.sh @@ -255,6 +255,7 @@ build_ayon () { fi echo -e "${BIGreen}>>>${RST} Building ..." "$POETRY_HOME/bin/poetry" run python -m pip --no-color freeze > "$repo_root/build/requirements.txt" + "$POETRY_HOME/bin/poetry" export --without-urls --without-hashes -f requirements.txt -n --no-ansi > "$repo_root/build/poetry_requirements.txt" if [[ "$OSTYPE" == "linux-gnu"* ]]; then "$POETRY_HOME/bin/poetry" run python "$repo_root/setup.py" build &> "$repo_root/build/build.log" || { echo -e "${BIRed}------------------------------------------${RST}"; cat "$repo_root/build/build.log"; echo -e "${BIRed}------------------------------------------${RST}"; echo -e "${BIRed}!!!${RST} Build failed, see the build log."; return 1; } elif [[ "$OSTYPE" == "darwin"* ]]; then diff --git a/tools/manage.ps1 b/tools/manage.ps1 index 6fa3eb86b..f83353c81 100755 --- a/tools/manage.ps1 +++ b/tools/manage.ps1 @@ -350,9 +350,11 @@ function Build-Ayon($MakeInstaller = $false) { $startTime = [int][double]::Parse((Get-Date -UFormat %s)) $FreezeContent = & "$($env:POETRY_HOME)\bin\poetry" run python -m pip --no-color freeze + $FreezeContentPoetry = & "$($env:POETRY_HOME)\bin\poetry" export --without-urls --without-hashes -f requirements.txt -n --no-ansi # Make sure output is UTF-8 without BOM $Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding $False [System.IO.File]::WriteAllLines("$($repo_root)\build\requirements.txt", $FreezeContent, $Utf8NoBomEncoding) + [System.IO.File]::WriteAllLines("$($repo_root)\build\poetry_requirements.txt", $FreezeContentPoetry, $Utf8NoBomEncoding) $out = & "$($env:POETRY_HOME)\bin\poetry" run python setup.py build 2>&1 Set-Content -Path "$($repo_root)\build\build.log" -Value $out From fec7269b36c795ef73d7894a5acc6b1990813284 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 6 Mar 2024 15:28:04 +0100 Subject: [PATCH 09/11] combine requirements from pip and poetry to calculate the output --- tools/build_post_process.py | 49 +++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/tools/build_post_process.py b/tools/build_post_process.py index f1d47ee1c..2af5a680d 100755 --- a/tools/build_post_process.py +++ b/tools/build_post_process.py @@ -364,20 +364,60 @@ def get_runtime_modules(root): def get_packages_info(build_root): """Read lock file to get packages. - Retruns: + Combine requirements freeze from venv and from poetry export. Requirements + freezed with pip 24 do not contain git urls, instead are pointing to + source folder on a disk. In that case is used poetry export which contains + the git url. + + Notes: + This is not ideal solution. The most ideal would be to get all the + information from poetry. But poetry export is limited only to + requirements.txt and using custom export logic would require + to implement it on our own. + The custom logic would also require to run venv located inside poetry + because poetry does not have mechanism to run internal python + via poetry executable. Parsing poetry lock on our own is also not + ideal because it can change based on poetry version. + We might hit an issue that newer poetry export won't be able to export + the urls either. + + Returns: list[tuple[str, Union[str, None]]]: List of tuples containing package name and version. """ requirements_path = build_root / "requirements.txt" + poetry_requirements_path = build_root / "poetry_requirements.txt" if not requirements_path.exists(): raise RuntimeError( "Failed to get packages info -> couldn't find 'requirements.txt'." ) + if not poetry_requirements_path.exists(): + raise RuntimeError( + "Failed to get packages info" + " -> couldn't find 'poetry_requirements.txt'." + ) + with open(str(requirements_path), "r", encoding="utf-8") as stream: content = stream.read() + with open(str(poetry_requirements_path), "r", encoding="utf-8") as stream: + poetry_content = stream.read() + + poetry_packages = {} + for line in poetry_content.split("\n"): + line = line.strip() + if not line: + continue + + match = re.match(r"^(.+?)(?:==|>=|<=|~=|!=|@)(.+)$", line) + if not match: + raise ValueError(f"Cannot parse package info '{line}'.") + package_name, version = match.groups() + version = version.split(";")[0].strip() + poetry_packages[package_name.rstrip()] = version + packages = {} for line in content.split("\n"): line = line.strip() @@ -388,7 +428,12 @@ def get_packages_info(build_root): if not match: raise ValueError(f"Cannot parse package info '{line}'.") package_name, version = match.groups() - packages[package_name.rstrip()] = version.lstrip() + package_name = package_name.rstrip() + version = version.lstrip() + + if version.startswith("file:"): + version = poetry_packages[package_name] + packages[package_name] = version.lstrip() return packages From 25e1a8873a3e7f5960d78f4c04d8742df5b2ed13 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 6 Mar 2024 16:06:51 +0100 Subject: [PATCH 10/11] bump version to 1.0.2 --- pyproject.toml | 2 +- version.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 4d5513a9e..36df358dd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "AYON" -version = "1.0.2-dev.1" +version = "1.0.2" description = "Open VFX and Animation pipeline with support." authors = ["Ynput s.r.o. "] license = "MIT License" diff --git a/version.py b/version.py index 7d736aef5..7863915fa 100644 --- a/version.py +++ b/version.py @@ -1 +1 @@ -__version__ = "1.0.2-dev.1" +__version__ = "1.0.2" From d1e8132081ffe252b1730ad8cd0a04e35e61c454 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 6 Mar 2024 18:00:05 +0100 Subject: [PATCH 11/11] changes after poetry lock --- poetry.lock | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/poetry.lock b/poetry.lock index 2037f2a4f..27516b0a7 100644 --- a/poetry.lock +++ b/poetry.lock @@ -503,12 +503,11 @@ files = [ {file = "charset_normalizer-3.1.0-py3-none-any.whl", hash = "sha256:3d9098b479e78c85080c98e1e35ff40b4a31d8953102bb0fd7d1b6f8a2111a3d"}, ] - [[package]] name = "colorama" version = "0.4.6" description = "Cross-platform colored terminal text." -category = "main" +category = "dev" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" files = [ @@ -2241,10 +2240,9 @@ files = [ ] [package.extras] -brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] -secure = ["certifi", "cryptography (>=1.9)", "idna (>=2.0.0)", "pyopenssl (>=17.1.0)", "urllib3-secure-extra"] -socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] -zstd = ["zstandard (>=0.18.0)"] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)", "brotlipy (>=0.6.0)"] +secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "pyOpenSSL (>=0.14)", "urllib3-secure-extra"] +socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] [[package]] name = "virtualenv" @@ -2486,4 +2484,4 @@ testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more [metadata] lock-version = "2.0" python-versions = ">=3.9.1,<3.10" -content-hash = "e0f8f1641d6f4ee5c23db9d79c2b7d15c8a456a958e089049415777fdd1378b7" +content-hash = "47673a1ee1ba7e61c506af2b32eb3eb6948b11c44cc7339c9d1b05a278903522"