diff --git a/.github/workflows/Build-and-deploy-mac.yml b/.github/workflows/Build-and-deploy-mac.yml index dd7a77988..7e8afcfe5 100644 --- a/.github/workflows/Build-and-deploy-mac.yml +++ b/.github/workflows/Build-and-deploy-mac.yml @@ -22,7 +22,6 @@ jobs: - uses: conda-incubator/setup-miniconda@v2 with: activate-environment: nwb-guide - #mamba-version: "*" environment-file: environments/environment-MAC.yml auto-activate-base: false diff --git a/.github/workflows/pyflask-build-and-dist-tests.yml b/.github/workflows/pyflask-build-and-dist-tests.yml index 5fbea858d..b2b89d50b 100644 --- a/.github/workflows/pyflask-build-and-dist-tests.yml +++ b/.github/workflows/pyflask-build-and-dist-tests.yml @@ -30,19 +30,16 @@ jobs: os: ubuntu-latest label: environments/environment-Linux.yml prefix: /usr/share/miniconda3/envs/nwb-guide - shorthand: unix - - python-version: "3.10" + - python-version: "3.9" os: macos-latest label: environments/environment-Mac.yml prefix: /Users/runner/miniconda3/envs/nwb-guide - shorthand: unix - - python-version: "3.10" + - python-version: "3.9" os: windows-latest label: environments/environment-Windows.yml prefix: C:\Miniconda3\envs\nwb-guide - shorthand: win steps: - uses: actions/checkout@v3 @@ -88,15 +85,7 @@ jobs: run: rm -f /Users/runner/miniconda3/envs/nwb-guide/lib/python3.9/site-packages/sonpy/linux/sonpy.so - name: Build PyFlask distribution - run: npm run build:flask:${{ matrix.shorthand }} - - #- if: matrix.os == 'windows-latest' - # name: Run test on build executable - # run: node tests/testPyinstallerExecutable.js --script ./build/nwb-guide/nwb-guide.exe - - #- if: matrix.os != 'windows-latest' - # name: Run test on build executable - # run: node tests/testPyinstallerExecutable.js --script ./build/nwb-guide/nwb-guide + run: npm run build:flask - name: Run test on distributed executable run: node tests/testPyinstallerExecutable.js diff --git a/.gitignore b/.gitignore index 852548470..0cda7e019 100644 --- a/.gitignore +++ b/.gitignore @@ -19,8 +19,6 @@ semantic.json build/ yarn.lock -*.spec - *.pyc src/.DS_Store .DS_Store diff --git a/nwb-guide.spec b/nwb-guide.spec new file mode 100644 index 000000000..8b4f5649d --- /dev/null +++ b/nwb-guide.spec @@ -0,0 +1,74 @@ +# -*- mode: python ; coding: utf-8 -*- +import sys +from pathlib import Path + +sys.setrecursionlimit(sys.getrecursionlimit() * 5) + +from PyInstaller.utils.hooks import collect_data_files +from PyInstaller.utils.hooks import collect_all + +datas = [('./paths.config.json', '.'), ('./package.json', '.')] +binaries = [] +hiddenimports = ['scipy._distributor_init', 'scipy._lib.messagestream', 'scipy._lib._ccallback', 'scipy._lib._testutils', 'email_validator'] +datas += collect_data_files('jsonschema_specifications') +tmp_ret = collect_all('nwbinspector') +datas += tmp_ret[0]; binaries += tmp_ret[1]; hiddenimports += tmp_ret[2] +tmp_ret = collect_all('neuroconv') +datas += tmp_ret[0]; binaries += tmp_ret[1]; hiddenimports += tmp_ret[2] +tmp_ret = collect_all('pynwb') +datas += tmp_ret[0]; binaries += tmp_ret[1]; hiddenimports += tmp_ret[2] +tmp_ret = collect_all('hdmf') +datas += tmp_ret[0]; binaries += tmp_ret[1]; hiddenimports += tmp_ret[2] +tmp_ret = collect_all('ndx_dandi_icephys') +datas += tmp_ret[0]; binaries += tmp_ret[1]; hiddenimports += tmp_ret[2] +tmp_ret = collect_all('ci_info') +datas += tmp_ret[0]; binaries += tmp_ret[1]; hiddenimports += tmp_ret[2] + + +block_cipher = None + + +a = Analysis( + [f"{Path('pyflask') / 'app.py'}"], + pathex=[], + binaries=binaries, + datas=datas, + hiddenimports=hiddenimports, + hookspath=[], + hooksconfig={}, + runtime_hooks=[], + excludes=[], + win_no_prefer_redirects=False, + win_private_assemblies=False, + cipher=block_cipher, + noarchive=False, +) +pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) + +exe = EXE( + pyz, + a.scripts, + [], + exclude_binaries=True, + name='nwb-guide', + debug=False, + bootloader_ignore_signals=False, + strip=False, + upx=True, + console=True, + disable_windowed_traceback=False, + argv_emulation=False, + target_arch=None, + codesign_identity=None, + entitlements_file=None, +) +coll = COLLECT( + exe, + a.binaries, + a.zipfiles, + a.datas, + strip=False, + upx=True, + upx_exclude=[], + name='nwb-guide', +) diff --git a/package.json b/package.json index 3bcb3133a..28727a469 100644 --- a/package.json +++ b/package.json @@ -11,13 +11,14 @@ "dev:app": "vite src/renderer", "dev:server": "cd pyflask && python -m flask run --port 4242", "build": "npm run build:app", + "echo": "python -c \"print('hello')\"", "build:app": "electron-vite build --outDir build", - "build:win": "npm run build && npm run build:flask:win && npm run build:electron:win", - "build:mac": "npm run build && npm run build:flask:unix && npm run build:electron:mac", - "build:linux": "npm run build && npm run build:flask:unix && npm run build:electron:linux", - "build:flask:base": "python -m PyInstaller --log-level DEBUG --name nwb-guide --onedir --clean --noconfirm ./pyflask/app.py --distpath ./build/flask --collect-data jsonschema_specifications --collect-all nwbinspector --collect-all neuroconv --collect-all pynwb --collect-all hdmf --collect-all ci_info --collect-all ndx_dandi_icephys --hidden-import scipy._distributor_init --hidden-import scipy._lib.messagestream --hidden-import scipy._lib._ccallback --hidden-import scipy._lib._testutils --hidden-import email_validator", - "build:flask:win": "npm run build:flask:base -- --add-data ./paths.config.json;. --add-data ./package.json;.", - "build:flask:unix": "npm run build:flask:base -- --add-data ./paths.config.json:. --add-data ./package.json:.", + "build:win": "npm run build && npm run build:flask && npm run build:electron:win", + "build:mac": "npm run build && npm run build:flask && npm run build:electron:mac", + "build:linux": "npm run build && npm run build:flask && npm run build:electron:linux", + "build:flask": "python -m PyInstaller nwb-guide.spec --log-level DEBUG --clean --noconfirm --distpath ./build/flask", + "build:flask:spec:base": "pyi-makespec --name nwb-guide --onedir --collect-data jsonschema_specifications --collect-all nwbinspector --collect-all neuroconv --collect-all pynwb --collect-all hdmf --collect-all ndx_dandi_icephys --collect-all ci_info --hidden-import scipy._distributor_init --hidden-import scipy._lib.messagestream --hidden-import scipy._lib._ccallback --hidden-import scipy._lib._testutils --hidden-import email_validator ./pyflask/app.py", + "build:flask:spec": "npm run build:flask:spec:base && python prepare_pyinstaller_spec.py", "build:electron:win": "electron-builder build --win --publish never", "build:electron:mac": "electron-builder build --mac --publish never", "build:electron:linux": "electron-builder build --linux --publish never", diff --git a/prepare_pyinstaller_spec.py b/prepare_pyinstaller_spec.py new file mode 100644 index 000000000..db06d8e91 --- /dev/null +++ b/prepare_pyinstaller_spec.py @@ -0,0 +1,30 @@ +""" +Calling `pyi-makespec` regenerates the base spec file, but we need to extend the recursion limit. + +This script is run automatically as a part of `npm run build:flask:spec` after the `pyi-makespec` call. +""" +from pathlib import Path + +with open(file=Path(__file__).parent / "nwb-guide.spec", mode="r") as io: + lines = io.readlines() + +lines.insert(1, "import sys\n") +lines.insert(2, "from pathlib import Path\n") +lines.insert(3, "\n") +lines.insert(4, "sys.setrecursionlimit(sys.getrecursionlimit() * 5)\n") +lines.insert(5, "\n") + +# Originally this was a separate `npm` command per platform to account for CLI syntax differences between ; and : +# The spec file is, however, the same across platforms +data_line_index = lines.index("datas = []\n") +lines[data_line_index] = "datas = [('./paths.config.json', '.'), ('./package.json', '.')]\n" + +# Another platform specific difference is the app.py location +app_py_line_index = next(index for index, line in enumerate(lines) if "app.py" in line) +app_py_line = " [f\"{Path('pyflask') / 'app.py'}\"],\n" +lines[app_py_line_index] = app_py_line + +with open(file=Path(__file__).parent / "nwb-guide.spec", mode="w") as io: + io.writelines(lines) + +print("Sucessfully injected recursion depth extension and json paths!")