diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..ce0d77c --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,12 @@ +--- +version: 2 +updates: +# Maintain dependencies for GitHub Actions + - package-ecosystem: github-actions + directory: / + schedule: + interval: monthly + groups: + gha-dependencies: + patterns: + - '*' diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 316bc70..297a9ad 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,12 +13,12 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Setup Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v5 with: - python-version: 3.8 + python-version: 3.11 - name: Install dependencies run: | diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ae09e4f..5906064 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -9,7 +9,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: softprops/action-gh-release@v0.1.14 + - uses: softprops/action-gh-release@v2.0.5 name: Create release. with: generate_release_notes: true diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index fb4d053..1938ed9 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,7 +5,7 @@ ci: repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.4.0 + rev: v4.5.0 hooks: - id: check-json - id: check-yaml @@ -13,42 +13,30 @@ repos: - id: trailing-whitespace exclude: miscellaneous/structures/SiO2.xyz + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.3.5 + hooks: + - id: ruff-format + exclude: ^docs/.* + - id: ruff + args: [--fix, --exit-non-zero-on-fix, --show-fixes] + - repo: https://github.com/jumanjihouse/pre-commit-hook-yamlfmt rev: 0.2.3 hooks: - id: yamlfmt - - repo: https://github.com/psf/black - rev: 23.3.0 - hooks: - - id: black - language_version: python3 # Should be a command that runs python3.6+ - - - repo: https://github.com/PyCQA/flake8 - rev: 6.0.0 - hooks: - - id: flake8 - args: [--count, --show-source, --statistics] - additional_dependencies: - - flake8-bugbear - - - repo: https://github.com/pycqa/isort - rev: 5.12.0 - hooks: - - id: isort - args: [--profile, black, --filter-files] - - repo: https://github.com/asottile/setup-cfg-fmt - rev: v2.4.0 + rev: v2.5.0 hooks: - id: setup-cfg-fmt - repo: https://github.com/sirosen/check-jsonschema - rev: 0.23.2 + rev: 0.28.1 hooks: - id: check-github-workflows - repo: https://github.com/kynan/nbstripout - rev: 0.6.1 + rev: 0.7.1 hooks: - id: nbstripout diff --git a/appstore.ipynb b/appstore.ipynb index 10b15c9..e478093 100644 --- a/appstore.ipynb +++ b/appstore.ipynb @@ -19,6 +19,9 @@ "%%javascript\n", "IPython.OutputArea.prototype._should_scroll = function(lines) {\n", " return false;\n", + "}\n", + "if (document.getElementById('appmode-busy')) {\n", + " window.onbeforeunload = function() {return}\n", "}" ] }, diff --git a/home/app_manager.py b/home/app_manager.py index 1577306..a18b9e7 100644 --- a/home/app_manager.py +++ b/home/app_manager.py @@ -1,5 +1,5 @@ -# -*- coding: utf-8 -*- """Module that contains widgets for managing AiiDAlab applications.""" + from subprocess import CalledProcessError import ipywidgets as ipw @@ -69,9 +69,9 @@ def __init__(self, *args, **kwargs): ) super().__init__( + *args, children=[self.installed_version, self.version_to_install, self.info], layout={"min_width": "300px"}, - *args, **kwargs, ) @@ -207,7 +207,7 @@ def __init__(self, app, minimalistic=False): self.app.observe( self._refresh_prereleases, names=["has_prereleases", "installed_version"] ) - self._refresh_prereleases(change=dict(owner=self.app)) # initialize + self._refresh_prereleases(change={"owner": self.app}) # initialize children = [ ipw.HBox([self.header_warning]), diff --git a/home/app_store.py b/home/app_store.py index f159f3f..e040229 100644 --- a/home/app_store.py +++ b/home/app_store.py @@ -1,5 +1,5 @@ -# -*- coding: utf-8 -*- """AiiDAlab app store.""" + import logging import ipywidgets as ipw @@ -21,7 +21,7 @@ def __init__(self): self.index = load_app_registry_index() except RuntimeError as error: logger.warning(error) - self.index = dict(apps=[], categories=[]) + self.index = {"apps": [], "categories": []} self.output = ipw.Output() # Apps per page. @@ -120,12 +120,8 @@ def change_vis_list(self, _=None): if self.category_filter.value: all_apps = self.apps_to_display - self.apps_to_display = ( - [] - ) # clear the array that contains all the apps to be displayed - self.app_corresponding_categories = ( - [] - ) # create a parallel array that contains corresponding category names + self.apps_to_display = [] # clear the array that contains all the apps to be displayed + self.app_corresponding_categories = [] # create a parallel array that contains corresponding category names # iterate over all categories for category in self.category_filter.value: category_key = self.category_title_key_mapping[category] diff --git a/home/start_page.py b/home/start_page.py index d6a10bb..f67d126 100644 --- a/home/start_page.py +++ b/home/start_page.py @@ -1,4 +1,5 @@ """Module to generate AiiDAlab home page.""" + import json from functools import wraps from glob import glob @@ -60,7 +61,7 @@ class AiidaLabHome: def __init__(self): self.config_fn = ".launcher.json" self.output = ipw.Output() - self._app_widgets = dict() + self._app_widgets = {} def _create_app_widget(self, name): """Create the widget representing the app on the home screen.""" @@ -92,7 +93,7 @@ def write_config(self, config): def read_config(self): if path.exists(self.config_fn): - return json.load(open(self.config_fn, "r")) + return json.load(open(self.config_fn)) return {"order": [], "hidden": []} # default config def render(self): @@ -124,7 +125,7 @@ def load_apps(self): apps.sort(key=lambda x: order.index(x) if x in order else -1) config["order"] = apps self.write_config(config) - return ["home"] + apps + return ["home", *apps] def move_updown(self, name, delta): """Move the app up/down on the start page.""" diff --git a/home/utils.py b/home/utils.py index 71ca51d..6bdfe49 100644 --- a/home/utils.py +++ b/home/utils.py @@ -33,7 +33,7 @@ def load_start_py(name): except TypeError: return mod.get_start_widget(appbase=appbase, jupbase=jupbase) except Exception: # pylint: disable=broad-except - return ipw.HTML("
{}".format(sys.exc_info())) + return ipw.HTML(f"
{sys.exc_info()}") def load_start_md(name): @@ -41,7 +41,7 @@ def load_start_md(name): fname = path.join(AIIDALAB_APPS, name, "start.md") try: md_src = open(fname).read() - md_src = md_src.replace("](./", "](../{}/".format(name)) + md_src = md_src.replace("](./", f"](../{name}/") html = markdown(md_src) # open links in new window/tab @@ -52,7 +52,7 @@ def load_start_md(name): return ipw.HTML(html) except Exception as exc: # pylint: disable=broad-except - return ipw.HTML("Could not load start.md: {}".format(str(exc))) + return ipw.HTML(f"Could not load start.md: {exc!s}") def load_logo(app): diff --git a/home/widgets.py b/home/widgets.py index a0ac4cc..64dd0f9 100644 --- a/home/widgets.py +++ b/home/widgets.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """AiiDAlab basic widgets.""" from threading import Timer @@ -104,7 +103,7 @@ class AppStatusInfoWidget(ipw.HTML): "and avoid compatibility isssues." ) - MESSAGES_UPDATES = { + MESSAGES_UPDATES = { # noqa: RUF012 AppStatus.CANNOT_REACH_REGISTRY: f'