From ca1356b4f58f32475f374804203ef05afc48bf78 Mon Sep 17 00:00:00 2001 From: jrmartin Date: Thu, 27 Jun 2024 21:52:03 -0700 Subject: [PATCH 01/33] #PSYNEU-134 - POC packacking application as a python package installable with 'pip install'. --- package/LICENSE | 19 +++++++++ package/README.md | 3 ++ package/pyproject.toml | 18 +++++++++ package/src/__init__.py | 0 package/src/setup.py | 89 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 129 insertions(+) create mode 100644 package/LICENSE create mode 100644 package/README.md create mode 100644 package/pyproject.toml create mode 100644 package/src/__init__.py create mode 100644 package/src/setup.py diff --git a/package/LICENSE b/package/LICENSE new file mode 100644 index 00000000..335ea9d0 --- /dev/null +++ b/package/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2018 The Python Packaging Authority + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/package/README.md b/package/README.md new file mode 100644 index 00000000..bd4c0a5a --- /dev/null +++ b/package/README.md @@ -0,0 +1,3 @@ +# PsyNeuLinkView Package + +PsyNeuLinkView package release 0.0.5 \ No newline at end of file diff --git a/package/pyproject.toml b/package/pyproject.toml new file mode 100644 index 00000000..2cca7790 --- /dev/null +++ b/package/pyproject.toml @@ -0,0 +1,18 @@ +[project] +name = "PsyNeuLinkView" +version = "0.0.5" +authors = [ + { name="Metacell", email="metacell@metacell.com" }, +] +description = "Metacell Package" +readme = "README.md" +requires-python = "==3.11" +classifiers = [ + "Programming Language :: Python :: 3", + "License :: OSI Approved :: MIT License", + "Operating System :: OS Independent", +] + +[project.urls] +Homepage = "https://github.com/Metacell/PsyNeuLinkView" +Issues = "https://github.com/Metacell/PsyNeuLinkView/issues" \ No newline at end of file diff --git a/package/src/__init__.py b/package/src/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/package/src/setup.py b/package/src/setup.py new file mode 100644 index 00000000..ececef4a --- /dev/null +++ b/package/src/setup.py @@ -0,0 +1,89 @@ +import requests +import re +import json +import platform +import os +import logging +import tarfile +from setuptools import setup, find_packages +from setuptools.command.install import install + +logger = logging.getLogger(__name__) +logging.basicConfig(level=logging.INFO) + +def get_filename_from_cd(cd): + """ + Get filename from content-disposition + """ + if not cd: + return None + fname = re.findall('filename=(.+)', cd) + if len(fname) == 0: + return None + return fname[0] + +def get_latest_release(installation_path): + url = 'https://api.github.com/repos/MetaCell/PsyNeuLinkView/releases' + headers = {'Accept': 'application/vnd.github+json','Authorization': 'Bearer JWT', 'X-GitHub-Api-Version' : '2022-11-28'} + r = requests.get(url, allow_redirects=True) + releases = json.loads(r.text) + assets = releases[0]["assets"] + + target_release = None + for asset in assets : + if platform.system().lower() in asset['name'] : + target_release = asset["browser_download_url"] + + logging.info("System detected %s :", platform.system()) + logging.info("Target release url found %s :", target_release) + logging.info("Downloading release to %s...", installation_path) + release_download = requests.get(target_release, allow_redirects=True) + + filename = get_filename_from_cd(release_download.headers.get('content-disposition')) + location = os.path.join(installation_path, filename) + logging.info("Writing release to %s...", location) + open(location, 'wb').write(release_download.content) + + logging.info("Opening compressed file %s", filename) + tar = tarfile.open(location) + tar.extractall(path=installation_path) + tar.close() + logging.info("Release file uncompressed at : %s", location) + + application = os.path.join(installation_path, "psyneulinkviewer-linux-x64/psyneulinkviewer") + logging.info("***") + logging.info("***") + logging.info("***") + logging.info("***") + logging.info("*** To launch the application run : **** ") + logging.info(" %s " , application) + +class InstallCommand(install): + user_options = install.user_options + [ + ('path=', None, 'an option that takes a value') + ] + + def initialize_options(self): + install.initialize_options(self) + self.path = None + + def finalize_options(self): + # Validate options + if self.path is None: + self.path = os.path.dirname(os.path.realpath(__file__)) + super().finalize_options() + + + def run(self): + global path + path = self.path # will be 1 or None + install.run(self) + get_latest_release(self.path) + +setup( + name="PsyNeuLinkView", + version="0.0.5", + cmdclass={ + 'install': InstallCommand + } +) \ No newline at end of file From dc11b75f7c0c4885b315168ab3a2b7841d4694a0 Mon Sep 17 00:00:00 2001 From: jrmartin Date: Thu, 27 Jun 2024 22:07:08 -0700 Subject: [PATCH 02/33] #PSYNEU-134 -Better logging and symlink creation --- package/src/setup.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/package/src/setup.py b/package/src/setup.py index ececef4a..6ec9cb5a 100644 --- a/package/src/setup.py +++ b/package/src/setup.py @@ -51,6 +51,10 @@ def get_latest_release(installation_path): logging.info("Release file uncompressed at : %s", location) application = os.path.join(installation_path, "psyneulinkviewer-linux-x64/psyneulinkviewer") + symlink = "/usr/local/bin/psyneulinkviewer" + logging.info("Creating symlink at : %s", symlink) + os.symlink(application, symlink) + logging.info("Symlink created") logging.info("***") logging.info("***") logging.info("***") From f0e970c12b5a584800efc2ac91554baf41696b9d Mon Sep 17 00:00:00 2001 From: jrmartin Date: Sun, 30 Jun 2024 09:25:15 -0700 Subject: [PATCH 03/33] #134 - Fix symlink path --- package/pyproject.toml | 18 ------------------ package/{src => }/setup.py | 30 +++++++++++++++++++----------- 2 files changed, 19 insertions(+), 29 deletions(-) delete mode 100644 package/pyproject.toml rename package/{src => }/setup.py (74%) diff --git a/package/pyproject.toml b/package/pyproject.toml deleted file mode 100644 index 2cca7790..00000000 --- a/package/pyproject.toml +++ /dev/null @@ -1,18 +0,0 @@ -[project] -name = "PsyNeuLinkView" -version = "0.0.5" -authors = [ - { name="Metacell", email="metacell@metacell.com" }, -] -description = "Metacell Package" -readme = "README.md" -requires-python = "==3.11" -classifiers = [ - "Programming Language :: Python :: 3", - "License :: OSI Approved :: MIT License", - "Operating System :: OS Independent", -] - -[project.urls] -Homepage = "https://github.com/Metacell/PsyNeuLinkView" -Issues = "https://github.com/Metacell/PsyNeuLinkView/issues" \ No newline at end of file diff --git a/package/src/setup.py b/package/setup.py similarity index 74% rename from package/src/setup.py rename to package/setup.py index 6ec9cb5a..8e110b97 100644 --- a/package/src/setup.py +++ b/package/setup.py @@ -1,4 +1,4 @@ -import requests +from pip._vendor import requests import re import json import platform @@ -40,27 +40,35 @@ def get_latest_release(installation_path): release_download = requests.get(target_release, allow_redirects=True) filename = get_filename_from_cd(release_download.headers.get('content-disposition')) - location = os.path.join(installation_path, filename) - logging.info("Writing release to %s...", location) - open(location, 'wb').write(release_download.content) + tar_location = os.path.join(installation_path, filename) + logging.info("Writing release to %s...", tar_location) + open(tar_location, 'wb').write(release_download.content) logging.info("Opening compressed file %s", filename) - tar = tarfile.open(location) - tar.extractall(path=installation_path) + tar = tarfile.open(tar_location) + extract_location = "/usr/local/bin" + tar.extractall(path=extract_location) tar.close() - logging.info("Release file uncompressed at : %s", location) + logging.info("Release file uncompressed at : %s", extract_location) - application = os.path.join(installation_path, "psyneulinkviewer-linux-x64/psyneulinkviewer") + application = os.path.join(extract_location, "psyneulinkviewer-linux-x64/psyneulinkviewer") symlink = "/usr/local/bin/psyneulinkviewer" logging.info("Creating symlink at : %s", symlink) - os.symlink(application, symlink) + logging.info("Application at : %s", application) + try: + if os.path.islink(symlink): + os.remove(symlink) + os.symlink(application, symlink) + except OSError as e: + logging.error("Error applying symlin %f ", e) + logging.info("Symlink created") logging.info("***") logging.info("***") logging.info("***") logging.info("***") logging.info("*** To launch the application run : **** ") - logging.info(" %s " , application) + logging.info(" %s " ,symlink) class InstallCommand(install): user_options = install.user_options + [ @@ -85,7 +93,7 @@ def run(self): get_latest_release(self.path) setup( - name="PsyNeuLinkView", + name="psyneulinkview", version="0.0.5", cmdclass={ 'install': InstallCommand From e0622fef220e2693b8c1bb46a4b1d8e39dc67d20 Mon Sep 17 00:00:00 2001 From: jrmartin Date: Sun, 30 Jun 2024 09:29:00 -0700 Subject: [PATCH 04/33] #134- Add read me instructions --- package/README.md | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/package/README.md b/package/README.md index bd4c0a5a..ca51137e 100644 --- a/package/README.md +++ b/package/README.md @@ -1,3 +1,23 @@ # PsyNeuLinkView Package -PsyNeuLinkView package release 0.0.5 \ No newline at end of file +To build pip package +``` +cd package +python3 -m build +``` + +To pip install package created in previous step +``` +python3 -m pip install --no-index --find-links={package_directory_path + "/dist"} psyneulinkview +``` + +To run psyneulinkviewer +``` +/usr/local/bin/psyneulinkviewer +``` + +or + +``` +psyneulinkviewer +``` \ No newline at end of file From 1baba8e096abf31457776b64ea40067595523589 Mon Sep 17 00:00:00 2001 From: jrmartin Date: Wed, 3 Jul 2024 16:17:40 -0700 Subject: [PATCH 05/33] #134 - Add checks for OS, python version, conda version, graphviz and psyneulink --- package/README.md | 2 +- package/setup.py | 81 +++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 75 insertions(+), 8 deletions(-) diff --git a/package/README.md b/package/README.md index ca51137e..bfd7db8b 100644 --- a/package/README.md +++ b/package/README.md @@ -8,7 +8,7 @@ python3 -m build To pip install package created in previous step ``` -python3 -m pip install --no-index --find-links={package_directory_path + "/dist"} psyneulinkview +python3 -m pip install --no-index --find-links=package_directory_path + "/dist" psyneulinkview ``` To run psyneulinkviewer diff --git a/package/setup.py b/package/setup.py index 8e110b97..b495a3fe 100644 --- a/package/setup.py +++ b/package/setup.py @@ -1,9 +1,11 @@ -from pip._vendor import requests import re import json import platform import os +import sys +import subprocess import logging +import importlib.util import tarfile from setuptools import setup, find_packages from setuptools.command.install import install @@ -11,6 +13,62 @@ logger = logging.getLogger(__name__) logging.basicConfig(level=logging.INFO) +graphviz = "graphviz" +psyneulink = "psyneulink" + +def check_os(self): + if os.name == 'nt': + sys.exit('Windows is not supported') + else: + logging.info("OS version supported") + +def check_python(self): + if not sys.version_info.major == 3 and not sys.version_info.minor == 6 : + logging.error('Python version not supported, 3.11 is required. %f' , sys.version_info) + sys.exit('Python version not supported, 3.11 is required.') + else: + logging.info("Python version is supported") + +def check_conda(self): + result = subprocess.run( + ["conda", "--version"], + capture_output = True, + text = True + ) + logging.info("conda version %s", result.stdout) + +def check_rosetta(self): + if sys.platform == "darwin": + result = subprocess.run( + ["rosseta", "--version"], + capture_output = True, + text = True + ) + logging.info("rosseta version %s", result.stdout) + +def check_graphviz(self): + if importlib.util.find_spec(graphviz) is None: + logging.error(graphviz +" is not installed, installing") + result = subprocess.run( + ["pip", "install", "graphviz"], + capture_output = True, + text = True + ) + else: + logging.info(graphviz +" is installed") + +def check_psyneulink(self): + if importlib.util.find_spec(psyneulink) is None: + logging.error(psyneulink +" is not installed, installing") + result = subprocess.run( + ["pip", "install", "psyneulink"], + capture_output = True, + text = True + ) + else: + logging.info(psyneulink +" is installed") + + def get_filename_from_cd(cd): """ Get filename from content-disposition @@ -23,6 +81,8 @@ def get_filename_from_cd(cd): return fname[0] def get_latest_release(installation_path): + import requests + url = 'https://api.github.com/repos/MetaCell/PsyNeuLinkView/releases' headers = {'Accept': 'application/vnd.github+json','Authorization': 'Bearer JWT', 'X-GitHub-Api-Version' : '2022-11-28'} r = requests.get(url, allow_redirects=True) @@ -63,13 +123,19 @@ def get_latest_release(installation_path): logging.error("Error applying symlin %f ", e) logging.info("Symlink created") - logging.info("***") - logging.info("***") - logging.info("***") - logging.info("***") + logging.info("*** To launch the application run : **** ") logging.info(" %s " ,symlink) +def prerequisites(self): + check_os(self) + check_python(self) + check_conda(self) + check_rosetta(self) + check_graphviz(self) + check_psyneulink(self) + get_latest_release(self.path) + class InstallCommand(install): user_options = install.user_options + [ ('path=', None, 'an option that takes a value') @@ -90,12 +156,13 @@ def run(self): global path path = self.path # will be 1 or None install.run(self) - get_latest_release(self.path) + prerequisites(self) setup( name="psyneulinkview", version="0.0.5", cmdclass={ 'install': InstallCommand - } + }, + setup_requires=['requests'] ) \ No newline at end of file From 73f87b70eb62d6871f8356cb04839f8ea5105dba Mon Sep 17 00:00:00 2001 From: jrmartin Date: Thu, 4 Jul 2024 08:10:19 -0700 Subject: [PATCH 06/33] #134 - Add entry point to launch psyneulink. Adds dist packages --- .../psyneulinkview-0.0.5-py3-none-any.whl | Bin 0 -> 3963 bytes package/dist/psyneulinkview-0.0.5.tar.gz | Bin 0 -> 3530 bytes package/{src => psyneulinkviewer}/__init__.py | 0 package/psyneulinkviewer/start.py | 155 ++++++++++++++++++ package/setup.py | 40 ++--- 5 files changed, 176 insertions(+), 19 deletions(-) create mode 100644 package/dist/psyneulinkview-0.0.5-py3-none-any.whl create mode 100644 package/dist/psyneulinkview-0.0.5.tar.gz rename package/{src => psyneulinkviewer}/__init__.py (100%) create mode 100644 package/psyneulinkviewer/start.py diff --git a/package/dist/psyneulinkview-0.0.5-py3-none-any.whl b/package/dist/psyneulinkview-0.0.5-py3-none-any.whl new file mode 100644 index 0000000000000000000000000000000000000000..2e21180bf8bbe854c3dae13e78f33ce805bd3ec8 GIT binary patch literal 3963 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 hkt-sYz&pzR(;zU$ER4jZi}UB(e*khldSn0q literal 0 HcmV?d00001 diff --git a/package/dist/psyneulinkview-0.0.5.tar.gz b/package/dist/psyneulinkview-0.0.5.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..bd97d99ce0562032416ab3ef74c4e7dde5a18fee GIT binary patch literal 3530 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 Date: Fri, 5 Jul 2024 07:38:31 -0700 Subject: [PATCH 07/33] #134 - Add entry point to allow installing and running psyneulinkviewer after installation --- package/psyneulinkviewer/start.py | 8 ++------ package/setup.py | 2 +- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/package/psyneulinkviewer/start.py b/package/psyneulinkviewer/start.py index a673c3f7..3818f1d7 100644 --- a/package/psyneulinkviewer/start.py +++ b/package/psyneulinkviewer/start.py @@ -120,9 +120,7 @@ def get_latest_release(installation_path): os.remove(symlink) os.symlink(application, symlink) result = subprocess.run( - [symlink], - capture_output = True, - text = True + [symlink] ) except OSError as e: logging.error("Error applying symlin %f ", e) @@ -141,9 +139,7 @@ def prerequisites(): check_psyneulink() if os.path.islink(symlink): result = subprocess.run( - [symlink], - capture_output = True, - text = True + [symlink] ) else: get_latest_release(os.path.dirname(os.path.realpath(__file__))) diff --git a/package/setup.py b/package/setup.py index f11266a3..4755485b 100644 --- a/package/setup.py +++ b/package/setup.py @@ -160,7 +160,7 @@ def run(self): setup( name="psyneulinkview", - version="0.0.5", + version="0.0.1", setup_requires=['requests'], entry_points={ 'console_scripts': [ From 4e1479140018e9b8e91f9c4e337759d3ea5c72f5 Mon Sep 17 00:00:00 2001 From: Jesus M Date: Fri, 5 Jul 2024 15:16:31 -0700 Subject: [PATCH 08/33] Update README.md --- package/README.md | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/package/README.md b/package/README.md index bfd7db8b..b7528eb7 100644 --- a/package/README.md +++ b/package/README.md @@ -1,4 +1,4 @@ -# PsyNeuLinkView Package +# PsyNeuLinkView Package Building To build pip package ``` @@ -6,18 +6,24 @@ cd package python3 -m build ``` -To pip install package created in previous step +To upload to distribution server ``` -python3 -m pip install --no-index --find-links=package_directory_path + "/dist" psyneulinkview +twine upload dist/* ``` -To run psyneulinkviewer +To pip install local package created in previous steps ``` -/usr/local/bin/psyneulinkviewer +python3 -m pip install --no-index --find-links=package_directory_path + "/dist" psyneulinkview ``` -or +# PsyNeuLinkView Installing from PyPI + +To install from PyPi +``` +pip install psyneulinkview --extra-index-url https://pypi.org/project/psyneulinkview +``` +To run psyneulinkviewer ``` psyneulinkviewer -``` \ No newline at end of file +``` From b481c429403abba3e38789e2ad7d5de9b083fd5c Mon Sep 17 00:00:00 2001 From: Jesus M Date: Fri, 12 Jul 2024 00:52:08 -0700 Subject: [PATCH 09/33] Update README.md --- package/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/README.md b/package/README.md index b7528eb7..b3918df8 100644 --- a/package/README.md +++ b/package/README.md @@ -6,7 +6,7 @@ cd package python3 -m build ``` -To upload to distribution server +To upload to distribution server. You will need token shared privately. ``` twine upload dist/* ``` From 274bd7d620f21a8758af7290b490a941f45c5a2e Mon Sep 17 00:00:00 2001 From: jrmartin Date: Fri, 26 Jul 2024 11:12:51 +0200 Subject: [PATCH 10/33] #PSYNEU-136 - Conda installation as part of pip install process --- .../build/lib/psyneulinkviewer/__init__.py | 0 package/build/lib/psyneulinkviewer/conda.py | 71 ++++++++ package/build/lib/psyneulinkviewer/start.py | 151 ++++++++++++++++++ package/configuration.py | 15 ++ package/psyneulinkviewer/conda.py | 72 +++++++++ package/requirements.txt | 2 + package/setup.py | 43 +++-- 7 files changed, 331 insertions(+), 23 deletions(-) create mode 100644 package/build/lib/psyneulinkviewer/__init__.py create mode 100644 package/build/lib/psyneulinkviewer/conda.py create mode 100644 package/build/lib/psyneulinkviewer/start.py create mode 100644 package/configuration.py create mode 100644 package/psyneulinkviewer/conda.py create mode 100644 package/requirements.txt diff --git a/package/build/lib/psyneulinkviewer/__init__.py b/package/build/lib/psyneulinkviewer/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/package/build/lib/psyneulinkviewer/conda.py b/package/build/lib/psyneulinkviewer/conda.py new file mode 100644 index 00000000..8ba6afe3 --- /dev/null +++ b/package/build/lib/psyneulinkviewer/conda.py @@ -0,0 +1,71 @@ +import re +import json +import platform +import os +import sys +import subprocess +import logging +import importlib.util +import tarfile +import atexit +import configuration +import wget +import platform +from setuptools import setup, find_packages +from setuptools.command.install import install +from packaging.version import Version + +logger = logging.getLogger(__name__) +logging.basicConfig(level=logging.INFO) + +def activate_env(): + logging.info("Creating conda ") + subprocess.run(configuration.create_env, shell=True) + + logging.info("Activating conda ") + subprocess.run(configuration.activate_env, shell=True) + +def install_conda(): + if os.name == 'posix': + bash_file = wget.download(configuration.linux_conda_bash, out="psyneulinkviewer") + elif platform.system() == 'Darwin': + bash_file = wget.download(configuration.mac_conda_bashf) + + logging.info("Installing conda %s", bash_file) + logging.info(bash_file) + subprocess.run("chmod +x " + bash_file, shell=True) + subprocess.run(bash_file + " -b -u -p ~/miniconda3", shell=True) + + activate_env() + logging.info("Clean up ") + subprocess.run("rm -rf " + bash_file, shell=True) + + +def check_conda_installation(): + conda_version = subprocess.run( + ["conda", "--version"], + capture_output = True, + text = True + ).stdout + if conda_version: + conda_version = conda_version.split(" ")[1] + logging.info("conda version %s", conda_version) + + if conda_version is not None: + logging.info("Conda not installed") + install_conda() + + if Version(conda_version) > Version(configuration.conda_required_version): + logging.info("Conda version exists and valid, %s", conda_version) + else: + logging.error("Conda version not up to date, update required"); + + envs = subprocess.run( + ["conda", "env","list"], + capture_output = True, + text = True + ).stdout.splitlines() + active_env = list(filter(lambda s: '*' in str(s), envs))[0] + env_name = str(active_env).split()[0] + if env_name is not None: + logging.info("Conda environment foudn and activated%s", env_name) \ No newline at end of file diff --git a/package/build/lib/psyneulinkviewer/start.py b/package/build/lib/psyneulinkviewer/start.py new file mode 100644 index 00000000..3818f1d7 --- /dev/null +++ b/package/build/lib/psyneulinkviewer/start.py @@ -0,0 +1,151 @@ +import re +import json +import platform +import os +import sys +import subprocess +import logging +import importlib.util +import tarfile +from setuptools import setup, find_packages +from setuptools.command.install import install + +logger = logging.getLogger(__name__) +logging.basicConfig(level=logging.INFO) + +graphviz = "graphviz" +psyneulink = "psyneulink" +symlink = "/usr/local/bin/psyneulinkviewer" + +def check_os(): + if os.name == 'nt': + sys.exit('Windows is not supported') + else: + logging.info("OS version supported") + +def check_python(): + if not sys.version_info.major == 3 and not sys.version_info.minor == 6 : + logging.error('Python version not supported, 3.11 is required. %f' , sys.version_info) + sys.exit('Python version not supported, 3.11 is required.') + else: + logging.info("Python version is supported") + +def check_conda(): + result = subprocess.run( + ["conda", "--version"], + capture_output = True, + text = True + ) + logging.info("conda version %s", result.stdout) + +def check_rosetta(): + if sys.platform == "darwin": + result = subprocess.run( + ["rosseta", "--version"], + capture_output = True, + text = True + ) + logging.info("rosseta version %s", result.stdout) + +def check_graphviz(): + if importlib.util.find_spec(graphviz) is None: + logging.error(graphviz +" is not installed, installing") + result = subprocess.run( + ["pip", "install", "graphviz"], + capture_output = True, + text = True + ) + else: + logging.info(graphviz +" is installed") + +def check_psyneulink(): + if importlib.util.find_spec(psyneulink) is None: + logging.error(psyneulink +" is not installed, installing") + result = subprocess.run( + ["pip", "install", "psyneulink"], + capture_output = True, + text = True + ) + else: + logging.info(psyneulink +" is installed") + + +def get_filename_from_cd(cd): + """ + Get filename from content-disposition + """ + if not cd: + return None + fname = re.findall('filename=(.+)', cd) + if len(fname) == 0: + return None + return fname[0] + +def get_latest_release(installation_path): + import requests + + url = 'https://api.github.com/repos/MetaCell/PsyNeuLinkView/releases' + headers = {'Accept': 'application/vnd.github+json','Authorization': 'Bearer JWT', 'X-GitHub-Api-Version' : '2022-11-28'} + r = requests.get(url, allow_redirects=True) + releases = json.loads(r.text) + assets = releases[0]["assets"] + + target_release = None + for asset in assets : + if platform.system().lower() in asset['name'] : + target_release = asset["browser_download_url"] + + logging.info("System detected %s :", platform.system()) + logging.info("Target release url found %s :", target_release) + logging.info("Downloading release to %s...", installation_path) + release_download = requests.get(target_release, allow_redirects=True) + + filename = get_filename_from_cd(release_download.headers.get('content-disposition')) + tar_location = os.path.join(installation_path, filename) + logging.info("Writing release to %s...", tar_location) + open(tar_location, 'wb').write(release_download.content) + + logging.info("Opening compressed file %s", filename) + tar = tarfile.open(tar_location) + extract_location = "/usr/local/bin" + tar.extractall(path=extract_location) + tar.close() + logging.info("Release file uncompressed at : %s", extract_location) + + application = os.path.join(extract_location, "psyneulinkviewer-linux-x64/psyneulinkviewer") + logging.info("Creating symlink at : %s", symlink) + logging.info("Application at : %s", application) + try: + if os.path.islink(symlink): + os.remove(symlink) + os.symlink(application, symlink) + result = subprocess.run( + [symlink] + ) + except OSError as e: + logging.error("Error applying symlin %f ", e) + + logging.info("Symlink created") + + logging.info("*** To launch the application run : **** ") + logging.info(" %s " ,symlink) + +def prerequisites(): + check_os() + check_python() + check_conda() + check_rosetta() + check_graphviz() + check_psyneulink() + if os.path.islink(symlink): + result = subprocess.run( + [symlink] + ) + else: + get_latest_release(os.path.dirname(os.path.realpath(__file__))) + +def main(): + prerequisites() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/package/configuration.py b/package/configuration.py new file mode 100644 index 00000000..24a48df7 --- /dev/null +++ b/package/configuration.py @@ -0,0 +1,15 @@ +graphviz = "graphviz" +psyneulink = "psyneulink" +conda_required_version = "4.9.1" + +releases_url = 'https://api.github.com/repos/MetaCell/PsyNeuLinkView/releases' +application_url = "psyneulinkviewer-linux-x64/psyneulinkviewer" +symlink = "/usr/local/bin/psyneulinkviewer" +extract_location = "/usr/local/bin" + +linux_conda_bash = "https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh" +mac_conda_bash = "https://repo.anaconda.com/miniconda/Miniconda3-latest-MacOSX-arm64.sh" + +env_name = "psyneulinkviewer" +create_env = "conda create --name " + env_name +activate_env = "conda activate " + env_name diff --git a/package/psyneulinkviewer/conda.py b/package/psyneulinkviewer/conda.py new file mode 100644 index 00000000..db0e7390 --- /dev/null +++ b/package/psyneulinkviewer/conda.py @@ -0,0 +1,72 @@ +import re +import json +import platform +import os +import sys +import subprocess +import logging +import importlib.util +import tarfile +import atexit +import configuration +import wget +import platform +import requests +from setuptools import setup, find_packages +from setuptools.command.install import install +from packaging.version import Version + +logger = logging.getLogger(__name__) +logging.basicConfig(level=logging.INFO) + +def activate_env(): + logging.info("Creating conda ") + subprocess.run(configuration.create_env, shell=True) + + logging.info("Activating conda ") + subprocess.run(configuration.activate_env, shell=True) + +def install_conda(): + if os.name == 'posix': + bash_file = requests.get(configuration.linux_conda_bash) + elif platform.system() == 'Darwin': + bash_file = wget.download(configuration.mac_conda_bashf) + + logging.info("Installing conda %s", bash_file) + logging.info(bash_file) + subprocess.run("chmod +x " + bash_file, shell=True) + subprocess.run(bash_file + " -b -u -p ~/miniconda3", shell=True) + + activate_env() + logging.info("Clean up ") + subprocess.run("rm -rf " + bash_file, shell=True) + + +def check_conda_installation(): + conda_version = subprocess.run( + ["conda", "--version"], + capture_output = True, + text = True + ).stdout + if conda_version: + conda_version = conda_version.split(" ")[1] + logging.info("conda version %s", conda_version) + + if conda_version is not None: + logging.info("Conda not installed") + install_conda() + + if Version(conda_version) > Version(configuration.conda_required_version): + logging.info("Conda version exists and valid, %s", conda_version) + else: + logging.error("Conda version not up to date, update required"); + + envs = subprocess.run( + ["conda", "env","list"], + capture_output = True, + text = True + ).stdout.splitlines() + active_env = list(filter(lambda s: '*' in str(s), envs))[0] + env_name = str(active_env).split()[0] + if env_name is not None: + logging.info("Conda environment foudn and activated%s", env_name) \ No newline at end of file diff --git a/package/requirements.txt b/package/requirements.txt new file mode 100644 index 00000000..a379fde6 --- /dev/null +++ b/package/requirements.txt @@ -0,0 +1,2 @@ +wget==3.2 +packaging \ No newline at end of file diff --git a/package/setup.py b/package/setup.py index 4755485b..0fe38785 100644 --- a/package/setup.py +++ b/package/setup.py @@ -10,13 +10,13 @@ import atexit from setuptools import setup, find_packages from setuptools.command.install import install +from packaging.version import Version +from psyneulinkviewer.conda import check_conda_installation +import configuration logger = logging.getLogger(__name__) logging.basicConfig(level=logging.INFO) -graphviz = "graphviz" -psyneulink = "psyneulink" - def check_os(): if os.name == 'nt': sys.exit('Windows is not supported') @@ -30,14 +30,6 @@ def check_python(): else: logging.info("Python version is supported") -def check_conda(): - result = subprocess.run( - ["conda", "--version"], - capture_output = True, - text = True - ) - logging.info("conda version %s", result.stdout) - def check_rosetta(): if sys.platform == "darwin": result = subprocess.run( @@ -48,26 +40,26 @@ def check_rosetta(): logging.info("rosseta version %s", result.stdout) def check_graphviz(): - if importlib.util.find_spec(graphviz) is None: - logging.error(graphviz +" is not installed, installing") + if importlib.util.find_spec(configuration.graphviz) is None: + logging.error(configuration.graphviz +" is not installed, installing") result = subprocess.run( ["pip", "install", "graphviz"], capture_output = True, text = True ) else: - logging.info(graphviz +" is installed") + logging.info(configuration.graphviz +" is installed") def check_psyneulink(): - if importlib.util.find_spec(psyneulink) is None: - logging.error(psyneulink +" is not installed, installing") + if importlib.util.find_spec(configuration.psyneulink) is None: + logging.error(configuration.psyneulink +" is not installed, installing") result = subprocess.run( ["pip", "install", "psyneulink"], capture_output = True, text = True ) else: - logging.info(psyneulink +" is installed") + logging.info(configuration.psyneulink +" is installed") def get_filename_from_cd(cd): @@ -84,9 +76,8 @@ def get_filename_from_cd(cd): def get_latest_release(installation_path): import requests - url = 'https://api.github.com/repos/MetaCell/PsyNeuLinkView/releases' headers = {'Accept': 'application/vnd.github+json','Authorization': 'Bearer JWT', 'X-GitHub-Api-Version' : '2022-11-28'} - r = requests.get(url, allow_redirects=True) + r = requests.get(configuration.releases_url, allow_redirects=True) releases = json.loads(r.text) assets = releases[0]["assets"] @@ -107,13 +98,13 @@ def get_latest_release(installation_path): logging.info("Opening compressed file %s", filename) tar = tarfile.open(tar_location) - extract_location = "/usr/local/bin" + extract_location = configuration.extract_location tar.extractall(path=extract_location) tar.close() logging.info("Release file uncompressed at : %s", extract_location) - application = os.path.join(extract_location, "psyneulinkviewer-linux-x64/psyneulinkviewer") - symlink = "/usr/local/bin/psyneulinkviewer" + application = os.path.join(extract_location, configuration.application_url) + symlink = configuration.symlink logging.info("Creating symlink at : %s", symlink) logging.info("Application at : %s", application) try: @@ -131,7 +122,8 @@ def get_latest_release(installation_path): def prerequisites(): check_os() check_python() - check_conda() + check_conda_installation() + #Install package requirements here check_rosetta() check_graphviz() check_psyneulink() @@ -155,6 +147,8 @@ def finalize_options(self): def run(self): global path + prerequisites() + print("pre") path = self.path # will be 1 or None install.run(self) @@ -166,5 +160,8 @@ def run(self): 'console_scripts': [ 'psyneulinkviewer = psyneulinkviewer.start:main', ] + }, + cmdclass={ + 'install': InstallCommand } ) \ No newline at end of file From 0cc490b9b90d8b775b9f5d304043e3ba3b78ab69 Mon Sep 17 00:00:00 2001 From: jrmartin Date: Fri, 26 Jul 2024 11:16:56 +0200 Subject: [PATCH 11/33] #PSYNEU-136 - Clean up logs --- package/psyneulinkviewer/conda.py | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/package/psyneulinkviewer/conda.py b/package/psyneulinkviewer/conda.py index db0e7390..10fe748b 100644 --- a/package/psyneulinkviewer/conda.py +++ b/package/psyneulinkviewer/conda.py @@ -1,13 +1,7 @@ -import re -import json import platform import os -import sys import subprocess import logging -import importlib.util -import tarfile -import atexit import configuration import wget import platform @@ -50,16 +44,17 @@ def check_conda_installation(): ).stdout if conda_version: conda_version = conda_version.split(" ")[1] - logging.info("conda version %s", conda_version) + logging.info("Conda version detected : %s", conda_version) if conda_version is not None: - logging.info("Conda not installed") + logging.info("Conda ist not installed, downloading conda installation.") install_conda() if Version(conda_version) > Version(configuration.conda_required_version): logging.info("Conda version exists and valid, %s", conda_version) else: - logging.error("Conda version not up to date, update required"); + logging.error("Conda version not up to date, update required") + install_conda() envs = subprocess.run( ["conda", "env","list"], @@ -69,4 +64,4 @@ def check_conda_installation(): active_env = list(filter(lambda s: '*' in str(s), envs))[0] env_name = str(active_env).split()[0] if env_name is not None: - logging.info("Conda environment foudn and activated%s", env_name) \ No newline at end of file + logging.info("Conda environment found and activated %s", env_name) \ No newline at end of file From 2fa6aa9ecf4c6f4786931cd893d9a7acc931fe27 Mon Sep 17 00:00:00 2001 From: jrmartin Date: Fri, 26 Jul 2024 11:35:12 +0200 Subject: [PATCH 12/33] #PSYNEU-136 - Clean up conda installation process --- package/psyneulinkviewer/conda.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/package/psyneulinkviewer/conda.py b/package/psyneulinkviewer/conda.py index 10fe748b..ae75f62c 100644 --- a/package/psyneulinkviewer/conda.py +++ b/package/psyneulinkviewer/conda.py @@ -1,11 +1,11 @@ import platform import os +import sys import subprocess import logging import configuration import wget import platform -import requests from setuptools import setup, find_packages from setuptools.command.install import install from packaging.version import Version @@ -22,7 +22,7 @@ def activate_env(): def install_conda(): if os.name == 'posix': - bash_file = requests.get(configuration.linux_conda_bash) + bash_file = wget.download(configuration.linux_conda_bash, out="psyneulinkviewer") elif platform.system() == 'Darwin': bash_file = wget.download(configuration.mac_conda_bashf) @@ -47,8 +47,14 @@ def check_conda_installation(): logging.info("Conda version detected : %s", conda_version) if conda_version is not None: - logging.info("Conda ist not installed, downloading conda installation.") - install_conda() + logging.info("Conda is not installed") + user_input = input("Do you want to continue with conda installation? (yes/no): ") + if user_input.lower() in ["yes", "y"]: + logging.info("Continuing with conda installation...") + install_conda() + else: + logging.error("Exiting, conda must be installed to continue...") + sys.exit() if Version(conda_version) > Version(configuration.conda_required_version): logging.info("Conda version exists and valid, %s", conda_version) From 6dee38c4caa31b86e17f65081af163505b2bf634 Mon Sep 17 00:00:00 2001 From: jrmartin Date: Fri, 26 Jul 2024 11:38:01 +0200 Subject: [PATCH 13/33] #PSYNEU-137 - Install rosetta as part of pip installation process --- package/configuration.py | 2 ++ package/psyneulinkviewer/rosetta.py | 37 +++++++++++++++++++++++++++++ package/setup.py | 9 ------- 3 files changed, 39 insertions(+), 9 deletions(-) create mode 100644 package/psyneulinkviewer/rosetta.py diff --git a/package/configuration.py b/package/configuration.py index 24a48df7..42ca0154 100644 --- a/package/configuration.py +++ b/package/configuration.py @@ -13,3 +13,5 @@ env_name = "psyneulinkviewer" create_env = "conda create --name " + env_name activate_env = "conda activate " + env_name + +rosetta_installation = "softwareupdate --install-rosetta --agree-to-license" \ No newline at end of file diff --git a/package/psyneulinkviewer/rosetta.py b/package/psyneulinkviewer/rosetta.py new file mode 100644 index 00000000..10c630db --- /dev/null +++ b/package/psyneulinkviewer/rosetta.py @@ -0,0 +1,37 @@ +import platform +import subprocess +import logging +import configuration +import platform +import sys +from setuptools.command.install import install +from packaging.version import Version + +logger = logging.getLogger(__name__) +logging.basicConfig(level=logging.INFO) + +def install_rosetta(): + if platform.system() == 'Darwin': + logging.info("Installing rosetta") + subprocess.run(configuration.rosetta_installation, shell=True) + +def check_conda_installation(): + if platform.system() == 'Darwin': + rosetta_version = subprocess.run( + ["rosseta", "--version"], + capture_output = True, + text = True + ).stdout + if rosetta_version: + rosetta_version = rosetta_version.split(" ")[1] + logging.info("Rosseta version detected : %s", rosetta_version) + + if rosetta_version is None: + logging.info("Rosetta ist not installed") + user_input = input("Do you want to continue with rosetta installation? (yes/no): ") + if user_input.lower() in ["yes", "y"]: + logging.info("Continuing with rosetta installation...") + install_rosetta() + else: + logging.error("Exiting, rosetta must be installed to continue...") + sys.exit() diff --git a/package/setup.py b/package/setup.py index 0fe38785..15e1d302 100644 --- a/package/setup.py +++ b/package/setup.py @@ -30,15 +30,6 @@ def check_python(): else: logging.info("Python version is supported") -def check_rosetta(): - if sys.platform == "darwin": - result = subprocess.run( - ["rosseta", "--version"], - capture_output = True, - text = True - ) - logging.info("rosseta version %s", result.stdout) - def check_graphviz(): if importlib.util.find_spec(configuration.graphviz) is None: logging.error(configuration.graphviz +" is not installed, installing") From b3f5c44168d56ef0364e2fdf9281149b7b81ec92 Mon Sep 17 00:00:00 2001 From: jrmartin Date: Fri, 26 Jul 2024 16:24:56 +0200 Subject: [PATCH 14/33] #PSYNEU-137 - Cleanup check --- package/psyneulinkviewer/conda.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/psyneulinkviewer/conda.py b/package/psyneulinkviewer/conda.py index ae75f62c..540ad748 100644 --- a/package/psyneulinkviewer/conda.py +++ b/package/psyneulinkviewer/conda.py @@ -46,7 +46,7 @@ def check_conda_installation(): conda_version = conda_version.split(" ")[1] logging.info("Conda version detected : %s", conda_version) - if conda_version is not None: + if conda_version is None: logging.info("Conda is not installed") user_input = input("Do you want to continue with conda installation? (yes/no): ") if user_input.lower() in ["yes", "y"]: From 9fb06a8756f3fd56ac39a3d7fff0cb2857bfface Mon Sep 17 00:00:00 2001 From: jrmartin Date: Fri, 26 Jul 2024 16:43:44 +0200 Subject: [PATCH 15/33] #PSYNEU-137 - Fix import --- package/setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/package/setup.py b/package/setup.py index 15e1d302..ec48215d 100644 --- a/package/setup.py +++ b/package/setup.py @@ -12,6 +12,7 @@ from setuptools.command.install import install from packaging.version import Version from psyneulinkviewer.conda import check_conda_installation +from psyneulinkviewer.conda import check_rosetta import configuration logger = logging.getLogger(__name__) From 5d6d8ec7e2b2345e40691ea1f6e1a9da6554ede1 Mon Sep 17 00:00:00 2001 From: jrmartin Date: Fri, 26 Jul 2024 16:50:55 +0200 Subject: [PATCH 16/33] #PSYNEU-137 - Fix rosetta installation --- package/psyneulinkviewer/rosetta.py | 2 +- package/setup.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package/psyneulinkviewer/rosetta.py b/package/psyneulinkviewer/rosetta.py index 10c630db..d710c082 100644 --- a/package/psyneulinkviewer/rosetta.py +++ b/package/psyneulinkviewer/rosetta.py @@ -15,7 +15,7 @@ def install_rosetta(): logging.info("Installing rosetta") subprocess.run(configuration.rosetta_installation, shell=True) -def check_conda_installation(): +def check_rosetta_installation(): if platform.system() == 'Darwin': rosetta_version = subprocess.run( ["rosseta", "--version"], diff --git a/package/setup.py b/package/setup.py index ec48215d..03ed4cb1 100644 --- a/package/setup.py +++ b/package/setup.py @@ -12,7 +12,7 @@ from setuptools.command.install import install from packaging.version import Version from psyneulinkviewer.conda import check_conda_installation -from psyneulinkviewer.conda import check_rosetta +from psyneulinkviewer.rosetta import check_rosetta_installation import configuration logger = logging.getLogger(__name__) @@ -116,7 +116,7 @@ def prerequisites(): check_python() check_conda_installation() #Install package requirements here - check_rosetta() + check_rosetta_installation() check_graphviz() check_psyneulink() get_latest_release(os.path.dirname(os.path.realpath(__file__))) From 300f15a768b80e28fe3ee21d5149cc823b54e91d Mon Sep 17 00:00:00 2001 From: jrmartin Date: Fri, 26 Jul 2024 16:53:55 +0200 Subject: [PATCH 17/33] #PSYNEU-135 - Check node version and install if not present --- package/configuration.py | 6 ++++- package/psyneulinkviewer/node.py | 38 ++++++++++++++++++++++++++++++++ package/setup.py | 4 +++- 3 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 package/psyneulinkviewer/node.py diff --git a/package/configuration.py b/package/configuration.py index 42ca0154..538bb202 100644 --- a/package/configuration.py +++ b/package/configuration.py @@ -14,4 +14,8 @@ create_env = "conda create --name " + env_name activate_env = "conda activate " + env_name -rosetta_installation = "softwareupdate --install-rosetta --agree-to-license" \ No newline at end of file +rosetta_installation = "softwareupdate --install-rosetta --agree-to-license" + +conda_forge = "conda config --add channels conda-forge" +node_installation = "conda install nodejs" +node_required_version = "4.19.0" diff --git a/package/psyneulinkviewer/node.py b/package/psyneulinkviewer/node.py new file mode 100644 index 00000000..93621df7 --- /dev/null +++ b/package/psyneulinkviewer/node.py @@ -0,0 +1,38 @@ +import sys +import subprocess +import logging +import configuration +from setuptools.command.install import install +from packaging.version import Version + +logger = logging.getLogger(__name__) +logging.basicConfig(level=logging.INFO) + +def install_node(): + logging.info("Installing node") + subprocess.run(configuration.conda_forge, shell=True) + subprocess.run(configuration.node_installation, shell=True) + +def check_node_installation(): + node_version = subprocess.run( + ["node", "--version"], + capture_output = True, + text = True + ).stdout + logging.info("Node version detected : %s", node_version) + + if node_version is None: + logging.info("Node is not installed") + user_input = input("Do you want to continue with node installation? (yes/no): ") + if user_input.lower() in ["yes", "y"]: + logging.info("Continuing with node installation...") + install_node() + else: + logging.error("Exiting, node must be installed to continue...") + sys.exit() + + if Version(node_version) > Version(configuration.node_required_version): + logging.info("Node version exists and valid, %s", node_version) + else: + logging.error("Node version not up to date, update required") + install_node() \ No newline at end of file diff --git a/package/setup.py b/package/setup.py index 03ed4cb1..74e1865d 100644 --- a/package/setup.py +++ b/package/setup.py @@ -13,6 +13,7 @@ from packaging.version import Version from psyneulinkviewer.conda import check_conda_installation from psyneulinkviewer.rosetta import check_rosetta_installation +from psyneulinkviewer.node import check_node_installation import configuration logger = logging.getLogger(__name__) @@ -114,9 +115,10 @@ def get_latest_release(installation_path): def prerequisites(): check_os() check_python() - check_conda_installation() + #check_conda_installation() #Install package requirements here check_rosetta_installation() + check_node_installation() check_graphviz() check_psyneulink() get_latest_release(os.path.dirname(os.path.realpath(__file__))) From f7477fbab1c9b1eae2f08281c62c23f6942d6742 Mon Sep 17 00:00:00 2001 From: jrmartin Date: Fri, 26 Jul 2024 16:54:54 +0200 Subject: [PATCH 18/33] #PSYNEU-136 - Create conda with python version 3.11 --- package/configuration.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/configuration.py b/package/configuration.py index 24a48df7..85303b80 100644 --- a/package/configuration.py +++ b/package/configuration.py @@ -11,5 +11,5 @@ mac_conda_bash = "https://repo.anaconda.com/miniconda/Miniconda3-latest-MacOSX-arm64.sh" env_name = "psyneulinkviewer" -create_env = "conda create --name " + env_name +create_env = "conda create --name " + env_name + " python=3.11" activate_env = "conda activate " + env_name From 54ff1563cb8407cdd462b1c4b155d560646d1adb Mon Sep 17 00:00:00 2001 From: jrmartin Date: Fri, 26 Jul 2024 17:02:28 +0200 Subject: [PATCH 19/33] #PSYNEU-135 - Uncoment line for conda installation --- package/setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/setup.py b/package/setup.py index 74e1865d..0cff02d7 100644 --- a/package/setup.py +++ b/package/setup.py @@ -115,7 +115,7 @@ def get_latest_release(installation_path): def prerequisites(): check_os() check_python() - #check_conda_installation() + check_conda_installation() #Install package requirements here check_rosetta_installation() check_node_installation() From 1c2314c5d380cdb77c376fe1b88671867178bf2b Mon Sep 17 00:00:00 2001 From: jrmartin Date: Fri, 26 Jul 2024 18:23:35 +0200 Subject: [PATCH 20/33] #PSYNEU-134 - Use cmdClass to install prerequesites during installation process instead of after --- package/setup.py | 141 ++--------------------------------------------- 1 file changed, 5 insertions(+), 136 deletions(-) diff --git a/package/setup.py b/package/setup.py index 4755485b..ad636475 100644 --- a/package/setup.py +++ b/package/setup.py @@ -1,142 +1,12 @@ -import re -import json -import platform -import os -import sys -import subprocess import logging -import importlib.util -import tarfile -import atexit +import os from setuptools import setup, find_packages from setuptools.command.install import install +from psyneulinkviewer.start import prerequisites logger = logging.getLogger(__name__) logging.basicConfig(level=logging.INFO) -graphviz = "graphviz" -psyneulink = "psyneulink" - -def check_os(): - if os.name == 'nt': - sys.exit('Windows is not supported') - else: - logging.info("OS version supported") - -def check_python(): - if not sys.version_info.major == 3 and not sys.version_info.minor == 6 : - logging.error('Python version not supported, 3.11 is required. %f' , sys.version_info) - sys.exit('Python version not supported, 3.11 is required.') - else: - logging.info("Python version is supported") - -def check_conda(): - result = subprocess.run( - ["conda", "--version"], - capture_output = True, - text = True - ) - logging.info("conda version %s", result.stdout) - -def check_rosetta(): - if sys.platform == "darwin": - result = subprocess.run( - ["rosseta", "--version"], - capture_output = True, - text = True - ) - logging.info("rosseta version %s", result.stdout) - -def check_graphviz(): - if importlib.util.find_spec(graphviz) is None: - logging.error(graphviz +" is not installed, installing") - result = subprocess.run( - ["pip", "install", "graphviz"], - capture_output = True, - text = True - ) - else: - logging.info(graphviz +" is installed") - -def check_psyneulink(): - if importlib.util.find_spec(psyneulink) is None: - logging.error(psyneulink +" is not installed, installing") - result = subprocess.run( - ["pip", "install", "psyneulink"], - capture_output = True, - text = True - ) - else: - logging.info(psyneulink +" is installed") - - -def get_filename_from_cd(cd): - """ - Get filename from content-disposition - """ - if not cd: - return None - fname = re.findall('filename=(.+)', cd) - if len(fname) == 0: - return None - return fname[0] - -def get_latest_release(installation_path): - import requests - - url = 'https://api.github.com/repos/MetaCell/PsyNeuLinkView/releases' - headers = {'Accept': 'application/vnd.github+json','Authorization': 'Bearer JWT', 'X-GitHub-Api-Version' : '2022-11-28'} - r = requests.get(url, allow_redirects=True) - releases = json.loads(r.text) - assets = releases[0]["assets"] - - target_release = None - for asset in assets : - if platform.system().lower() in asset['name'] : - target_release = asset["browser_download_url"] - - logging.info("System detected %s :", platform.system()) - logging.info("Target release url found %s :", target_release) - logging.info("Downloading release to %s...", installation_path) - release_download = requests.get(target_release, allow_redirects=True) - - filename = get_filename_from_cd(release_download.headers.get('content-disposition')) - tar_location = os.path.join(installation_path, filename) - logging.info("Writing release to %s...", tar_location) - open(tar_location, 'wb').write(release_download.content) - - logging.info("Opening compressed file %s", filename) - tar = tarfile.open(tar_location) - extract_location = "/usr/local/bin" - tar.extractall(path=extract_location) - tar.close() - logging.info("Release file uncompressed at : %s", extract_location) - - application = os.path.join(extract_location, "psyneulinkviewer-linux-x64/psyneulinkviewer") - symlink = "/usr/local/bin/psyneulinkviewer" - logging.info("Creating symlink at : %s", symlink) - logging.info("Application at : %s", application) - try: - if os.path.islink(symlink): - os.remove(symlink) - os.symlink(application, symlink) - except OSError as e: - logging.error("Error applying symlin %f ", e) - - logging.info("Symlink created") - - logging.info("*** To launch the application run : **** ") - logging.info(" %s " ,symlink) - -def prerequisites(): - check_os() - check_python() - check_conda() - check_rosetta() - check_graphviz() - check_psyneulink() - get_latest_release(os.path.dirname(os.path.realpath(__file__))) - class InstallCommand(install): user_options = install.user_options + [ ('path=', None, 'an option that takes a value') @@ -157,14 +27,13 @@ def run(self): global path path = self.path # will be 1 or None install.run(self) + prerequisites() setup( name="psyneulinkview", version="0.0.1", setup_requires=['requests'], - entry_points={ - 'console_scripts': [ - 'psyneulinkviewer = psyneulinkviewer.start:main', - ] + cmdclass={ + 'install': InstallCommand, } ) \ No newline at end of file From be43f51a8e6aaee454b92d739abc9a78a18a6881 Mon Sep 17 00:00:00 2001 From: jrmartin Date: Fri, 26 Jul 2024 18:30:42 +0200 Subject: [PATCH 21/33] #PSYNEU-136 - Update prerequesites in start.py file --- package/psyneulinkviewer/start.py | 49 +++++++++++-------------------- 1 file changed, 17 insertions(+), 32 deletions(-) diff --git a/package/psyneulinkviewer/start.py b/package/psyneulinkviewer/start.py index 3818f1d7..ee8fab25 100644 --- a/package/psyneulinkviewer/start.py +++ b/package/psyneulinkviewer/start.py @@ -7,16 +7,16 @@ import logging import importlib.util import tarfile +import atexit from setuptools import setup, find_packages from setuptools.command.install import install +from packaging.version import Version +from psyneulinkviewer.conda import check_conda_installation +import configuration logger = logging.getLogger(__name__) logging.basicConfig(level=logging.INFO) -graphviz = "graphviz" -psyneulink = "psyneulink" -symlink = "/usr/local/bin/psyneulinkviewer" - def check_os(): if os.name == 'nt': sys.exit('Windows is not supported') @@ -30,14 +30,6 @@ def check_python(): else: logging.info("Python version is supported") -def check_conda(): - result = subprocess.run( - ["conda", "--version"], - capture_output = True, - text = True - ) - logging.info("conda version %s", result.stdout) - def check_rosetta(): if sys.platform == "darwin": result = subprocess.run( @@ -48,26 +40,26 @@ def check_rosetta(): logging.info("rosseta version %s", result.stdout) def check_graphviz(): - if importlib.util.find_spec(graphviz) is None: - logging.error(graphviz +" is not installed, installing") + if importlib.util.find_spec(configuration.graphviz) is None: + logging.error(configuration.graphviz +" is not installed, installing") result = subprocess.run( ["pip", "install", "graphviz"], capture_output = True, text = True ) else: - logging.info(graphviz +" is installed") + logging.info(configuration.graphviz +" is installed") def check_psyneulink(): - if importlib.util.find_spec(psyneulink) is None: - logging.error(psyneulink +" is not installed, installing") + if importlib.util.find_spec(configuration.psyneulink) is None: + logging.error(configuration.psyneulink +" is not installed, installing") result = subprocess.run( ["pip", "install", "psyneulink"], capture_output = True, text = True ) else: - logging.info(psyneulink +" is installed") + logging.info(configuration.psyneulink +" is installed") def get_filename_from_cd(cd): @@ -84,9 +76,8 @@ def get_filename_from_cd(cd): def get_latest_release(installation_path): import requests - url = 'https://api.github.com/repos/MetaCell/PsyNeuLinkView/releases' headers = {'Accept': 'application/vnd.github+json','Authorization': 'Bearer JWT', 'X-GitHub-Api-Version' : '2022-11-28'} - r = requests.get(url, allow_redirects=True) + r = requests.get(configuration.releases_url, allow_redirects=True) releases = json.loads(r.text) assets = releases[0]["assets"] @@ -107,21 +98,19 @@ def get_latest_release(installation_path): logging.info("Opening compressed file %s", filename) tar = tarfile.open(tar_location) - extract_location = "/usr/local/bin" + extract_location = configuration.extract_location tar.extractall(path=extract_location) tar.close() logging.info("Release file uncompressed at : %s", extract_location) - application = os.path.join(extract_location, "psyneulinkviewer-linux-x64/psyneulinkviewer") + application = os.path.join(extract_location, configuration.application_url) + symlink = configuration.symlink logging.info("Creating symlink at : %s", symlink) logging.info("Application at : %s", application) try: if os.path.islink(symlink): os.remove(symlink) os.symlink(application, symlink) - result = subprocess.run( - [symlink] - ) except OSError as e: logging.error("Error applying symlin %f ", e) @@ -133,16 +122,12 @@ def get_latest_release(installation_path): def prerequisites(): check_os() check_python() - check_conda() + check_conda_installation() + #Install package requirements here check_rosetta() check_graphviz() check_psyneulink() - if os.path.islink(symlink): - result = subprocess.run( - [symlink] - ) - else: - get_latest_release(os.path.dirname(os.path.realpath(__file__))) + get_latest_release(os.path.dirname(os.path.realpath(__file__))) def main(): prerequisites() From fc52ef64370646c7110fd5e51b35edafb1788ee8 Mon Sep 17 00:00:00 2001 From: jrmartin Date: Fri, 26 Jul 2024 18:34:32 +0200 Subject: [PATCH 22/33] #PSYNEU-136 - Remove build folder --- .../build/lib/psyneulinkviewer/__init__.py | 0 package/build/lib/psyneulinkviewer/conda.py | 71 -------- package/build/lib/psyneulinkviewer/start.py | 151 ------------------ 3 files changed, 222 deletions(-) delete mode 100644 package/build/lib/psyneulinkviewer/__init__.py delete mode 100644 package/build/lib/psyneulinkviewer/conda.py delete mode 100644 package/build/lib/psyneulinkviewer/start.py diff --git a/package/build/lib/psyneulinkviewer/__init__.py b/package/build/lib/psyneulinkviewer/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/package/build/lib/psyneulinkviewer/conda.py b/package/build/lib/psyneulinkviewer/conda.py deleted file mode 100644 index 8ba6afe3..00000000 --- a/package/build/lib/psyneulinkviewer/conda.py +++ /dev/null @@ -1,71 +0,0 @@ -import re -import json -import platform -import os -import sys -import subprocess -import logging -import importlib.util -import tarfile -import atexit -import configuration -import wget -import platform -from setuptools import setup, find_packages -from setuptools.command.install import install -from packaging.version import Version - -logger = logging.getLogger(__name__) -logging.basicConfig(level=logging.INFO) - -def activate_env(): - logging.info("Creating conda ") - subprocess.run(configuration.create_env, shell=True) - - logging.info("Activating conda ") - subprocess.run(configuration.activate_env, shell=True) - -def install_conda(): - if os.name == 'posix': - bash_file = wget.download(configuration.linux_conda_bash, out="psyneulinkviewer") - elif platform.system() == 'Darwin': - bash_file = wget.download(configuration.mac_conda_bashf) - - logging.info("Installing conda %s", bash_file) - logging.info(bash_file) - subprocess.run("chmod +x " + bash_file, shell=True) - subprocess.run(bash_file + " -b -u -p ~/miniconda3", shell=True) - - activate_env() - logging.info("Clean up ") - subprocess.run("rm -rf " + bash_file, shell=True) - - -def check_conda_installation(): - conda_version = subprocess.run( - ["conda", "--version"], - capture_output = True, - text = True - ).stdout - if conda_version: - conda_version = conda_version.split(" ")[1] - logging.info("conda version %s", conda_version) - - if conda_version is not None: - logging.info("Conda not installed") - install_conda() - - if Version(conda_version) > Version(configuration.conda_required_version): - logging.info("Conda version exists and valid, %s", conda_version) - else: - logging.error("Conda version not up to date, update required"); - - envs = subprocess.run( - ["conda", "env","list"], - capture_output = True, - text = True - ).stdout.splitlines() - active_env = list(filter(lambda s: '*' in str(s), envs))[0] - env_name = str(active_env).split()[0] - if env_name is not None: - logging.info("Conda environment foudn and activated%s", env_name) \ No newline at end of file diff --git a/package/build/lib/psyneulinkviewer/start.py b/package/build/lib/psyneulinkviewer/start.py deleted file mode 100644 index 3818f1d7..00000000 --- a/package/build/lib/psyneulinkviewer/start.py +++ /dev/null @@ -1,151 +0,0 @@ -import re -import json -import platform -import os -import sys -import subprocess -import logging -import importlib.util -import tarfile -from setuptools import setup, find_packages -from setuptools.command.install import install - -logger = logging.getLogger(__name__) -logging.basicConfig(level=logging.INFO) - -graphviz = "graphviz" -psyneulink = "psyneulink" -symlink = "/usr/local/bin/psyneulinkviewer" - -def check_os(): - if os.name == 'nt': - sys.exit('Windows is not supported') - else: - logging.info("OS version supported") - -def check_python(): - if not sys.version_info.major == 3 and not sys.version_info.minor == 6 : - logging.error('Python version not supported, 3.11 is required. %f' , sys.version_info) - sys.exit('Python version not supported, 3.11 is required.') - else: - logging.info("Python version is supported") - -def check_conda(): - result = subprocess.run( - ["conda", "--version"], - capture_output = True, - text = True - ) - logging.info("conda version %s", result.stdout) - -def check_rosetta(): - if sys.platform == "darwin": - result = subprocess.run( - ["rosseta", "--version"], - capture_output = True, - text = True - ) - logging.info("rosseta version %s", result.stdout) - -def check_graphviz(): - if importlib.util.find_spec(graphviz) is None: - logging.error(graphviz +" is not installed, installing") - result = subprocess.run( - ["pip", "install", "graphviz"], - capture_output = True, - text = True - ) - else: - logging.info(graphviz +" is installed") - -def check_psyneulink(): - if importlib.util.find_spec(psyneulink) is None: - logging.error(psyneulink +" is not installed, installing") - result = subprocess.run( - ["pip", "install", "psyneulink"], - capture_output = True, - text = True - ) - else: - logging.info(psyneulink +" is installed") - - -def get_filename_from_cd(cd): - """ - Get filename from content-disposition - """ - if not cd: - return None - fname = re.findall('filename=(.+)', cd) - if len(fname) == 0: - return None - return fname[0] - -def get_latest_release(installation_path): - import requests - - url = 'https://api.github.com/repos/MetaCell/PsyNeuLinkView/releases' - headers = {'Accept': 'application/vnd.github+json','Authorization': 'Bearer JWT', 'X-GitHub-Api-Version' : '2022-11-28'} - r = requests.get(url, allow_redirects=True) - releases = json.loads(r.text) - assets = releases[0]["assets"] - - target_release = None - for asset in assets : - if platform.system().lower() in asset['name'] : - target_release = asset["browser_download_url"] - - logging.info("System detected %s :", platform.system()) - logging.info("Target release url found %s :", target_release) - logging.info("Downloading release to %s...", installation_path) - release_download = requests.get(target_release, allow_redirects=True) - - filename = get_filename_from_cd(release_download.headers.get('content-disposition')) - tar_location = os.path.join(installation_path, filename) - logging.info("Writing release to %s...", tar_location) - open(tar_location, 'wb').write(release_download.content) - - logging.info("Opening compressed file %s", filename) - tar = tarfile.open(tar_location) - extract_location = "/usr/local/bin" - tar.extractall(path=extract_location) - tar.close() - logging.info("Release file uncompressed at : %s", extract_location) - - application = os.path.join(extract_location, "psyneulinkviewer-linux-x64/psyneulinkviewer") - logging.info("Creating symlink at : %s", symlink) - logging.info("Application at : %s", application) - try: - if os.path.islink(symlink): - os.remove(symlink) - os.symlink(application, symlink) - result = subprocess.run( - [symlink] - ) - except OSError as e: - logging.error("Error applying symlin %f ", e) - - logging.info("Symlink created") - - logging.info("*** To launch the application run : **** ") - logging.info(" %s " ,symlink) - -def prerequisites(): - check_os() - check_python() - check_conda() - check_rosetta() - check_graphviz() - check_psyneulink() - if os.path.islink(symlink): - result = subprocess.run( - [symlink] - ) - else: - get_latest_release(os.path.dirname(os.path.realpath(__file__))) - -def main(): - prerequisites() - -if __name__ == "__main__": - main() \ No newline at end of file From bb3b96cde83cbd9796e48dcd81e4fc17f6b81f35 Mon Sep 17 00:00:00 2001 From: jrmartin Date: Fri, 26 Jul 2024 18:52:30 +0200 Subject: [PATCH 23/33] #PSYNEU-135 - Cleanup --- package/psyneulinkviewer/rosetta.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/package/psyneulinkviewer/rosetta.py b/package/psyneulinkviewer/rosetta.py index d710c082..fb79baf0 100644 --- a/package/psyneulinkviewer/rosetta.py +++ b/package/psyneulinkviewer/rosetta.py @@ -22,8 +22,6 @@ def check_rosetta_installation(): capture_output = True, text = True ).stdout - if rosetta_version: - rosetta_version = rosetta_version.split(" ")[1] logging.info("Rosseta version detected : %s", rosetta_version) if rosetta_version is None: From 00b24131b4d67aa67b958ff9e486dad36909f8d7 Mon Sep 17 00:00:00 2001 From: jrmartin Date: Mon, 29 Jul 2024 14:29:52 +0200 Subject: [PATCH 24/33] #PSYNEU-136 - Wrap installation on try/catch, and fix typo --- package/psyneulinkviewer/conda.py | 67 +++++++++++++++++-------------- package/setup.py | 4 +- 2 files changed, 39 insertions(+), 32 deletions(-) diff --git a/package/psyneulinkviewer/conda.py b/package/psyneulinkviewer/conda.py index ae75f62c..17a9313a 100644 --- a/package/psyneulinkviewer/conda.py +++ b/package/psyneulinkviewer/conda.py @@ -37,37 +37,42 @@ def install_conda(): def check_conda_installation(): - conda_version = subprocess.run( - ["conda", "--version"], - capture_output = True, - text = True - ).stdout - if conda_version: - conda_version = conda_version.split(" ")[1] - logging.info("Conda version detected : %s", conda_version) + try: + conda_version = subprocess.run( + ["conda", "--version"], + capture_output = True, + text = True + ).stdout + if conda_version: + conda_version = conda_version.split(" ")[1] + logging.info("Conda version detected : %s", conda_version) - if conda_version is not None: - logging.info("Conda is not installed") - user_input = input("Do you want to continue with conda installation? (yes/no): ") - if user_input.lower() in ["yes", "y"]: - logging.info("Continuing with conda installation...") + if conda_version is None: + logging.info("Conda is not installed") + user_input = input("Do you want to continue with conda installation? (yes/no): ") + if user_input.lower() in ["yes", "y"]: + logging.info("Continuing with conda installation...") + install_conda() + else: + logging.error("Exiting, conda must be installed to continue...") + sys.exit() + + if Version(conda_version) > Version(configuration.conda_required_version): + logging.info("Conda version exists and valid, %s", conda_version) + else: + logging.error("Conda version not up to date, update required") install_conda() + + envs = subprocess.run( + ["conda", "env","list"], + capture_output = True, + text = True + ).stdout.splitlines() + active_env = list(filter(lambda s: '*' in str(s), envs))[0] + env_name = str(active_env).split()[0] + if env_name is not None: + logging.info("Conda environment found and activated %s", env_name) else: - logging.error("Exiting, conda must be installed to continue...") - sys.exit() - - if Version(conda_version) > Version(configuration.conda_required_version): - logging.info("Conda version exists and valid, %s", conda_version) - else: - logging.error("Conda version not up to date, update required") - install_conda() - - envs = subprocess.run( - ["conda", "env","list"], - capture_output = True, - text = True - ).stdout.splitlines() - active_env = list(filter(lambda s: '*' in str(s), envs))[0] - env_name = str(active_env).split()[0] - if env_name is not None: - logging.info("Conda environment found and activated %s", env_name) \ No newline at end of file + activate_env() + except Exception as error: + logging.error("Error %s ", error) \ No newline at end of file diff --git a/package/setup.py b/package/setup.py index 9dabc6c1..8339933a 100644 --- a/package/setup.py +++ b/package/setup.py @@ -34,7 +34,9 @@ def run(self): setup( name="psyneulinkview", version="0.0.1", - setup_requires=['requests'], + install_requires=['requests', + 'wget' + 'packaging'], cmdclass={ 'install': InstallCommand, } From f3add7894e1849668374b289d07927e39dd8a3a0 Mon Sep 17 00:00:00 2001 From: jrmartin Date: Mon, 29 Jul 2024 14:39:28 +0200 Subject: [PATCH 25/33] #PSYNEU-136 - Better logging --- package/psyneulinkviewer/conda.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/psyneulinkviewer/conda.py b/package/psyneulinkviewer/conda.py index 17a9313a..7c075552 100644 --- a/package/psyneulinkviewer/conda.py +++ b/package/psyneulinkviewer/conda.py @@ -75,4 +75,4 @@ def check_conda_installation(): else: activate_env() except Exception as error: - logging.error("Error %s ", error) \ No newline at end of file + logging.error("Error with conda installation: %s ", error) \ No newline at end of file From 0c254d0b5df1c5f822ca6e90065ef3dc74fdb218 Mon Sep 17 00:00:00 2001 From: jrmartin Date: Mon, 29 Jul 2024 14:56:52 +0200 Subject: [PATCH 26/33] #PSYNEU-137 -Wrap rosetta installation into try/catch --- package/psyneulinkviewer/rosetta.py | 39 ++++++++++++++++------------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/package/psyneulinkviewer/rosetta.py b/package/psyneulinkviewer/rosetta.py index d710c082..1ffccc2d 100644 --- a/package/psyneulinkviewer/rosetta.py +++ b/package/psyneulinkviewer/rosetta.py @@ -16,22 +16,25 @@ def install_rosetta(): subprocess.run(configuration.rosetta_installation, shell=True) def check_rosetta_installation(): - if platform.system() == 'Darwin': - rosetta_version = subprocess.run( - ["rosseta", "--version"], - capture_output = True, - text = True - ).stdout - if rosetta_version: - rosetta_version = rosetta_version.split(" ")[1] - logging.info("Rosseta version detected : %s", rosetta_version) + try: + if platform.system() == 'Darwin': + rosetta_version = subprocess.run( + ["rosseta", "--version"], + capture_output = True, + text = True + ).stdout + if rosetta_version: + rosetta_version = rosetta_version.split(" ")[1] + logging.info("Rosseta version detected : %s", rosetta_version) - if rosetta_version is None: - logging.info("Rosetta ist not installed") - user_input = input("Do you want to continue with rosetta installation? (yes/no): ") - if user_input.lower() in ["yes", "y"]: - logging.info("Continuing with rosetta installation...") - install_rosetta() - else: - logging.error("Exiting, rosetta must be installed to continue...") - sys.exit() + if rosetta_version is None: + logging.info("Rosetta ist not installed") + user_input = input("Do you want to continue with rosetta installation? (yes/no): ") + if user_input.lower() in ["yes", "y"]: + logging.info("Continuing with rosetta installation...") + install_rosetta() + else: + logging.error("Exiting, rosetta must be installed to continue...") + sys.exit() + except Exception as error: + logging.error("Error with rosetta installation: %s ", error) From f0ffa0eca74346bdf52bb5bc2d8219b9767cc471 Mon Sep 17 00:00:00 2001 From: jrmartin Date: Mon, 29 Jul 2024 15:11:38 +0200 Subject: [PATCH 27/33] #PSYNEU-135 - Wrap check node installation with try/catch --- package/psyneulinkviewer/node.py | 43 +++++++++++++++++--------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/package/psyneulinkviewer/node.py b/package/psyneulinkviewer/node.py index 93621df7..fa2b8f6c 100644 --- a/package/psyneulinkviewer/node.py +++ b/package/psyneulinkviewer/node.py @@ -14,25 +14,28 @@ def install_node(): subprocess.run(configuration.node_installation, shell=True) def check_node_installation(): - node_version = subprocess.run( - ["node", "--version"], - capture_output = True, - text = True - ).stdout - logging.info("Node version detected : %s", node_version) + try: + node_version = subprocess.run( + ["node", "--version"], + capture_output = True, + text = True + ).stdout + logging.info("Node version detected : %s", node_version) - if node_version is None: - logging.info("Node is not installed") - user_input = input("Do you want to continue with node installation? (yes/no): ") - if user_input.lower() in ["yes", "y"]: - logging.info("Continuing with node installation...") - install_node() + if node_version is None: + logging.info("Node is not installed") + user_input = input("Do you want to continue with node installation? (yes/no): ") + if user_input.lower() in ["yes", "y"]: + logging.info("Continuing with node installation...") + install_node() + else: + logging.error("Exiting, node must be installed to continue...") + sys.exit() + + if Version(node_version) > Version(configuration.node_required_version): + logging.info("Node version exists and valid, %s", node_version) else: - logging.error("Exiting, node must be installed to continue...") - sys.exit() - - if Version(node_version) > Version(configuration.node_required_version): - logging.info("Node version exists and valid, %s", node_version) - else: - logging.error("Node version not up to date, update required") - install_node() \ No newline at end of file + logging.error("Node version not up to date, update required") + install_node() + except Exception as error: + logging.error("Error with node installation: %s ", error) \ No newline at end of file From db37698de8c0040821d3cda3a9d0151eff267b31 Mon Sep 17 00:00:00 2001 From: jrmartin Date: Tue, 6 Aug 2024 14:12:59 +0200 Subject: [PATCH 28/33] #PSYNEU-136 - Handle better errors when conda not present --- package/psyneulinkviewer/conda.py | 50 ++++++++++++++++++------------- 1 file changed, 29 insertions(+), 21 deletions(-) diff --git a/package/psyneulinkviewer/conda.py b/package/psyneulinkviewer/conda.py index 7c075552..dc204307 100644 --- a/package/psyneulinkviewer/conda.py +++ b/package/psyneulinkviewer/conda.py @@ -14,7 +14,7 @@ logging.basicConfig(level=logging.INFO) def activate_env(): - logging.info("Creating conda ") + logging.info("Creating conda environment ") subprocess.run(configuration.create_env, shell=True) logging.info("Activating conda ") @@ -37,6 +37,7 @@ def install_conda(): def check_conda_installation(): + conda_version = None try: conda_version = subprocess.run( ["conda", "--version"], @@ -46,33 +47,40 @@ def check_conda_installation(): if conda_version: conda_version = conda_version.split(" ")[1] logging.info("Conda version detected : %s", conda_version) + except Exception as error: + logging.error("Error with conda installation: %s ", error) - if conda_version is None: - logging.info("Conda is not installed") - user_input = input("Do you want to continue with conda installation? (yes/no): ") - if user_input.lower() in ["yes", "y"]: - logging.info("Continuing with conda installation...") - install_conda() - else: - logging.error("Exiting, conda must be installed to continue...") - sys.exit() - - if Version(conda_version) > Version(configuration.conda_required_version): - logging.info("Conda version exists and valid, %s", conda_version) - else: - logging.error("Conda version not up to date, update required") + if conda_version is None: + logging.info("Conda is not installed") + user_input = input("Do you want to continue with conda installation? (yes/no): ") + if user_input.lower() in ["yes", "y"]: + logging.info("Continuing with conda installation...") install_conda() + else: + logging.error("Exiting, conda must be installed to continue...") + sys.exit() + + if Version(conda_version) > Version(configuration.conda_required_version): + logging.info("Conda version exists and valid, %s", conda_version) + else: + logging.error("Conda version not up to date, update required") + install_conda() + env_name = None + try: envs = subprocess.run( ["conda", "env","list"], capture_output = True, text = True - ).stdout.splitlines() + ).stdout + if envs is not None: + envs = envs.splitlines() active_env = list(filter(lambda s: '*' in str(s), envs))[0] env_name = str(active_env).split()[0] - if env_name is not None: - logging.info("Conda environment found and activated %s", env_name) - else: - activate_env() except Exception as error: - logging.error("Error with conda installation: %s ", error) \ No newline at end of file + logging.error("Environment not found active: %s ", error) + + if env_name is not None: + logging.info("Conda environment found and activated %s", env_name) + else: + activate_env() \ No newline at end of file From a4ffef91c3725eed2d0d3b552d14a349ad573178 Mon Sep 17 00:00:00 2001 From: jrmartin Date: Tue, 6 Aug 2024 14:31:02 +0200 Subject: [PATCH 29/33] #PSYNEU-137 - Handle better lack of rossetta installation, catch error and proceed with installation --- package/psyneulinkviewer/rosetta.py | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/package/psyneulinkviewer/rosetta.py b/package/psyneulinkviewer/rosetta.py index 1ffccc2d..3fc221bd 100644 --- a/package/psyneulinkviewer/rosetta.py +++ b/package/psyneulinkviewer/rosetta.py @@ -16,6 +16,7 @@ def install_rosetta(): subprocess.run(configuration.rosetta_installation, shell=True) def check_rosetta_installation(): + rosetta_version = None try: if platform.system() == 'Darwin': rosetta_version = subprocess.run( @@ -26,15 +27,16 @@ def check_rosetta_installation(): if rosetta_version: rosetta_version = rosetta_version.split(" ")[1] logging.info("Rosseta version detected : %s", rosetta_version) - - if rosetta_version is None: - logging.info("Rosetta ist not installed") - user_input = input("Do you want to continue with rosetta installation? (yes/no): ") - if user_input.lower() in ["yes", "y"]: - logging.info("Continuing with rosetta installation...") - install_rosetta() - else: - logging.error("Exiting, rosetta must be installed to continue...") - sys.exit() except Exception as error: logging.error("Error with rosetta installation: %s ", error) + + if rosetta_version is None: + logging.info("Rosetta ist not installed") + user_input = input("Do you want to continue with rosetta installation? (yes/no): ") + if user_input.lower() in ["yes", "y"]: + logging.info("Continuing with rosetta installation...") + install_rosetta() + else: + logging.error("Exiting, rosetta must be installed to continue...") + sys.exit() + From dc4b700b2d31dbbf9734f02b557678232e74a101 Mon Sep 17 00:00:00 2001 From: jrmartin Date: Tue, 6 Aug 2024 14:34:56 +0200 Subject: [PATCH 30/33] #PSYNEU-135 - Handle better node installation when there's an error --- package/psyneulinkviewer/node.py | 33 ++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/package/psyneulinkviewer/node.py b/package/psyneulinkviewer/node.py index fa2b8f6c..739cfe20 100644 --- a/package/psyneulinkviewer/node.py +++ b/package/psyneulinkviewer/node.py @@ -14,6 +14,7 @@ def install_node(): subprocess.run(configuration.node_installation, shell=True) def check_node_installation(): + node_version = None try: node_version = subprocess.run( ["node", "--version"], @@ -21,21 +22,21 @@ def check_node_installation(): text = True ).stdout logging.info("Node version detected : %s", node_version) + except Exception as error: + logging.error("Error with node installation: %s ", error) - if node_version is None: - logging.info("Node is not installed") - user_input = input("Do you want to continue with node installation? (yes/no): ") - if user_input.lower() in ["yes", "y"]: - logging.info("Continuing with node installation...") - install_node() - else: - logging.error("Exiting, node must be installed to continue...") - sys.exit() - - if Version(node_version) > Version(configuration.node_required_version): - logging.info("Node version exists and valid, %s", node_version) - else: - logging.error("Node version not up to date, update required") + if node_version is None: + logging.info("Node is not installed") + user_input = input("Do you want to continue with node installation? (yes/no): ") + if user_input.lower() in ["yes", "y"]: + logging.info("Continuing with node installation...") install_node() - except Exception as error: - logging.error("Error with node installation: %s ", error) \ No newline at end of file + else: + logging.error("Exiting, node must be installed to continue...") + sys.exit() + + if Version(node_version) > Version(configuration.node_required_version): + logging.info("Node version exists and valid, %s", node_version) + else: + logging.error("Node version not up to date, update required") + install_node() \ No newline at end of file From 87571dad040edd64f48c6866757fa9ad13c74c0c Mon Sep 17 00:00:00 2001 From: jrmartin Date: Tue, 6 Aug 2024 17:32:37 +0200 Subject: [PATCH 31/33] #PSYNEU-136 - Don't log error if exception is FileNotFoundError and continue with process, otherwise log it and exit --- package/psyneulinkviewer/conda.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/package/psyneulinkviewer/conda.py b/package/psyneulinkviewer/conda.py index dc204307..5f52809b 100644 --- a/package/psyneulinkviewer/conda.py +++ b/package/psyneulinkviewer/conda.py @@ -46,9 +46,11 @@ def check_conda_installation(): ).stdout if conda_version: conda_version = conda_version.split(" ")[1] - logging.info("Conda version detected : %s", conda_version) + logging.info("Conda version detected : %s", conda_version) except Exception as error: - logging.error("Error with conda installation: %s ", error) + if not isinstance(error, FileNotFoundError): + logging.error("Error with conda installation, exiting setup: %s ", error) + sys.exit() if conda_version is None: logging.info("Conda is not installed") From 86db20363e9dc04f992295e46831b8ed2f502e2e Mon Sep 17 00:00:00 2001 From: jrmartin Date: Tue, 6 Aug 2024 17:51:07 +0200 Subject: [PATCH 32/33] #PSYNEU-137 - Don't log error if exception is FileNotFoundError and continue with process, otherwise log it and exit --- package/psyneulinkviewer/rosetta.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/package/psyneulinkviewer/rosetta.py b/package/psyneulinkviewer/rosetta.py index 3fc221bd..0e882b91 100644 --- a/package/psyneulinkviewer/rosetta.py +++ b/package/psyneulinkviewer/rosetta.py @@ -26,9 +26,11 @@ def check_rosetta_installation(): ).stdout if rosetta_version: rosetta_version = rosetta_version.split(" ")[1] - logging.info("Rosseta version detected : %s", rosetta_version) + logging.info("Rosseta version detected : %s", rosetta_version) except Exception as error: - logging.error("Error with rosetta installation: %s ", error) + if not isinstance(error, FileNotFoundError): + logging.error("Error with rosetta installation, exiting setup: %s ", error) + sys.exit() if rosetta_version is None: logging.info("Rosetta ist not installed") From 5c37e4f29d30ae0ecc39a7cee1ed8fc607116307 Mon Sep 17 00:00:00 2001 From: jrmartin Date: Tue, 6 Aug 2024 17:53:19 +0200 Subject: [PATCH 33/33] #PSYNEU-135 - Don't log error if exception is FileNotFoundError and continue with process, otherwise log it and exit --- package/psyneulinkviewer/node.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/package/psyneulinkviewer/node.py b/package/psyneulinkviewer/node.py index 739cfe20..7baf555a 100644 --- a/package/psyneulinkviewer/node.py +++ b/package/psyneulinkviewer/node.py @@ -21,9 +21,10 @@ def check_node_installation(): capture_output = True, text = True ).stdout - logging.info("Node version detected : %s", node_version) except Exception as error: - logging.error("Error with node installation: %s ", error) + if not isinstance(error, FileNotFoundError): + logging.error("Error with node installation, exiting setup: %s ", error) + sys.exit() if node_version is None: logging.info("Node is not installed")