From ca342ee9d3b8955e6f945c56929122ccbac6966d Mon Sep 17 00:00:00 2001 From: rly Date: Thu, 14 Sep 2023 05:14:10 -0400 Subject: [PATCH 01/22] Update mac deploy docs and build for x64 and arm64 --- .github/workflows/Build-and-deploy-mac.yml | 14 +++++++++++++- package.json | 16 ++++++++++++++-- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/.github/workflows/Build-and-deploy-mac.yml b/.github/workflows/Build-and-deploy-mac.yml index dd7a77988..7bd6e14c1 100644 --- a/.github/workflows/Build-and-deploy-mac.yml +++ b/.github/workflows/Build-and-deploy-mac.yml @@ -50,6 +50,18 @@ jobs: # Use Keychain Access to export the certificate as a .p12 # base64 -i cent.p12 -o base64.txt # Open base64.txt and copy the contents to the nwb-guide repository secret for MACOS_CERTIFICATE + # For local development, download the appropriate Apple Intermediate Certificate + # from https://www.apple.com/certificateauthority/ to make certificate trusted/valid + # See https://developer.apple.com/forums/thread/705473 + # For this, it is Worldwide Developer Relations - G3 + # Confirm that the certificate now shows up as trusted in Keychain Access + # Then go to https://appleid.apple.com/account/manage + # and create an App-Specific Password + # Use that for local building and in the secrets.APPLE_PASSWORD repository secret + # Also review and agree to any pending agreements in + # https://appstoreconnect.apple.com/agreements/#/ for Free Apps + # and the Apple Developer Program License Agreement, which updates periodically + # Currently this is set up to use Ryan's account and certificate p12-file-base64: ${{ secrets.MACOS_CERTIFICATE }} p12-password: ${{ secrets.MACOS_CERTIFICATE_PWD }} @@ -57,6 +69,6 @@ jobs: - name: Build and deploy on MAC env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - appleId: ${{ secrets.APPLE_ID }} # currently this is set to Ryan's Apple ID and password + appleId: ${{ secrets.APPLE_ID }} # currently this is set to Ryan's Apple ID and app-specific password appleIdPassword: ${{ secrets.APPLE_PASSWORD }} run: npm run deploy:mac diff --git a/package.json b/package.json index 3bcb3133a..dd1038059 100644 --- a/package.json +++ b/package.json @@ -76,8 +76,20 @@ "mac": { "asar": true, "target": [ - "dmg", - "zip" + { + "target": "dmg", + "arch": [ + "x64", + "arm64" + ] + }, + { + "target": "zip", + "arch": [ + "x64", + "arm64" + ] + } ], "icon": "src/renderer/assets/img/logo-guide-draft.png", "darkModeSupport": false, From f5aa819432b37f169fa3650fdfb7aa0dad20fa09 Mon Sep 17 00:00:00 2001 From: Garrett Date: Mon, 18 Sep 2023 11:05:55 -0700 Subject: [PATCH 02/22] Update main.ts --- src/main/main.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/main.ts b/src/main/main.ts index 582090189..af34032f6 100755 --- a/src/main/main.ts +++ b/src/main/main.ts @@ -126,6 +126,7 @@ const pythonIsClosed = (err = globals.python.latestError) => { */ const getPackagedPath = () => { const scriptPath = isWindows ? path.join(__dirname, PY_FLASK_DIST_FOLDER, PYFLASK_BUILD_SUBFOLDER_NAME, `${PYINSTALLER_NAME}.exe`) : path.join(process.resourcesPath, PYFLASK_BUILD_SUBFOLDER_NAME, PYINSTALLER_NAME) + console.warn('Packaged Script Path', scriptPath) if (fs.existsSync(scriptPath)) return scriptPath; }; @@ -134,6 +135,8 @@ const createPyProc = async () => { return new Promise(async (resolve, reject) => { let script = getPackagedPath() || path.join(__dirname, PY_FLASK_FOLDER, "app.py"); + console.warn('Resolved Script Path', script) + await killAllPreviousProcesses(); const defaultPort = PORT as number From fdaaf79b9c56f873cbdbd8065dbe6f84a0ee5829 Mon Sep 17 00:00:00 2001 From: rly Date: Mon, 18 Sep 2023 14:15:21 -0400 Subject: [PATCH 03/22] Move documentation on codesigning --- .github/workflows/Build-and-deploy-mac.yml | 29 ++------------ docs/developer_guide.rst | 46 ++++++++++++++++++++++ 2 files changed, 49 insertions(+), 26 deletions(-) diff --git a/.github/workflows/Build-and-deploy-mac.yml b/.github/workflows/Build-and-deploy-mac.yml index b3c6282dd..310b5cc2d 100644 --- a/.github/workflows/Build-and-deploy-mac.yml +++ b/.github/workflows/Build-and-deploy-mac.yml @@ -37,37 +37,14 @@ jobs: - uses: apple-actions/import-codesign-certs@v1 with: - # https://developer.apple.com/account/resources/certificates/add - # Sign up for an Apple Developer account (annual fee) - # Create a new certificate for Mac development at website above (max 1 certificate) - # Create a Certificate Signing Request (CSR) on your Mac -- - # see https://developer.apple.com/help/account/create-certificates/create-a-certificate-signing-request - # Keychain Access > Certificate Assistant > Request a Certificate from a Certificate Authority... - # Enter email address, common name - # Download the new certificate (.cer file) - # Double click the .cer file to install in Keychain Access - # Use Keychain Access to export the certificate as a .p12 - # base64 -i cent.p12 -o base64.txt - # Open base64.txt and copy the contents to the nwb-guide repository secret for MACOS_CERTIFICATE - # For local development, download the appropriate Apple Intermediate Certificate - # from https://www.apple.com/certificateauthority/ to make certificate trusted/valid - # See https://developer.apple.com/forums/thread/705473 - # For this, it is Worldwide Developer Relations - G3 - # Confirm that the certificate now shows up as trusted in Keychain Access - # Then go to https://appleid.apple.com/account/manage - # and create an App-Specific Password - # Use that for local building and in the secrets.APPLE_PASSWORD repository secret - # Also review and agree to any pending agreements in - # https://appstoreconnect.apple.com/agreements/#/ for Free Apps - # and the Apple Developer Program License Agreement, which updates periodically - - # Currently this is set up to use Ryan's account and certificate + # Currently this is set to Ryan's Developer ID certificate p12-file-base64: ${{ secrets.MACOS_CERTIFICATE }} p12-password: ${{ secrets.MACOS_CERTIFICATE_PWD }} - name: Build and deploy on MAC env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - appleId: ${{ secrets.APPLE_ID }} # currently this is set to Ryan's Apple ID and app-specific password + # Currently this is set to Ryan's Apple ID and app-specific password + appleId: ${{ secrets.APPLE_ID }} appleIdPassword: ${{ secrets.APPLE_PASSWORD }} run: npm run deploy:mac diff --git a/docs/developer_guide.rst b/docs/developer_guide.rst index eb206f426..0602e31a1 100644 --- a/docs/developer_guide.rst +++ b/docs/developer_guide.rst @@ -125,3 +125,49 @@ Pre-Commit We use an automated pre-commit bot to enforce these on the main repo, but contributions from external forks would either have to grant bot permissions on their own fork (via :pre-commit-bot:`the pre-commit bot website <>`) or run pre-commit manually. For instructions to install pre-commit, as well as some other minor coding styles we follow, refer to the :neuroconv-coding-style:`NeuroConv style guide <>`. + +Code signing on Mac OS +--------------------------- + +1. Sign up for an Apple Developer account (99 USD annual fee). + +2. Follow steps in https://developer.apple.com/help/account/create-certificates/create-developer-id-certificates/ + a. Browse current Certificates at https://developer.apple.com/account/resources/certificates/list. + b. Click Certificates in the sidebar. On the top left, click the add button (+). + c. Under Software, select Developer ID Application. + d. Select Profile Type: G2 Sub-CA (Xcode 11.4.1 or later). + e. Create a certificate signing request (CSR) by following the steps in https://developer.apple.com/help/account/create-certificates/create-a-certificate-signing-request + i. Open Keychain Access. + ii. Choose Keychain Access > Certificate Assistant > Request a Certificate from a Certificate Authority. + iii. In the Certificate Assistant dialog, enter an email address in the User Email Address field. + iv. In the Common Name field, enter a name for the key (for example, John Doe Dev Key). Ryan entered "Ryan Ly". + v. Leave the CA Email Address field empty. + vi. Choose “Saved to disk”, and click Continue. + vii. Save the certificate request file to disk. + f. Select the certificate request file (a file with a .certSigningRequest file extension), then click Choose. + g. Click Continue, click Download - The certificate file (.cer file) appears in your Downloads folder. + h. To install the certificate in your keychain, double-click the downloaded certificate file. + i. The certificate appears in the My Certificates category in Keychain Access, but may not be trusted. + j. For local development, download the appropriate Apple Intermediate Certificate. + k. from https://www.apple.com/certificateauthority/ to make certificate trusted/valid. + l. For this, it is Developer ID - G2 (Expiring 09/17/2031 00:00:00 UTC). + m. Double-click the downloaded file. + n. Confirm that the certificate now shows up as trusted in Keychain Access. + +3. Provide a p12 file for notarizing via GitHub Action. + a. Open Keychain Access. + b. Select the Developer ID Application certificate. + c. Choose Keychain Access > Export Items... + d. Export the certificate to a file with a password. + e. Get a base64 version of the certificate by running: base64 -i Certificate.p12 -o base64.txt + f. Open base64.txt and copy the contents to the nwb-guide repository secret MACOS_CERTIFICATE. + g. Set the password for the certificate in the nwb-guide repository secret MACOS_CERTIFICATE_PASSWORD. + +4. Create an app-specific password for building locally and via the GitHub Action. + a. Go to https://appleid.apple.com/account/manage. + b. Follow the steps to create an App-Specific Password. + c. Use that for local building and in the secrets.APPLE_PASSWORD repository secret. + +5. Review and agree to any pending agreements. + a. Go to https://appstoreconnect.apple.com/agreements/#/ and agree to pending agreements for Free Apps. + b. Review and agree to the Apple Developer Program License Agreement, which updates periodically. \ No newline at end of file From d34dd90ada331b9af12a169a13478640c479ff86 Mon Sep 17 00:00:00 2001 From: rly Date: Mon, 18 Sep 2023 14:15:41 -0400 Subject: [PATCH 04/22] Update version to 0.0.6 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3653a3054..9d3d15ed8 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "nwb-guide", "productName": "NWB GUIDE", - "version": "0.0.5", + "version": "0.0.6", "description": "", "main": "./build/main/main.js", "scripts": { From 8a97fa1be0e828ff1820b5fa6d7110db95da6748 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 18 Sep 2023 18:16:43 +0000 Subject: [PATCH 05/22] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- docs/developer_guide.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/developer_guide.rst b/docs/developer_guide.rst index 0602e31a1..e191ff894 100644 --- a/docs/developer_guide.rst +++ b/docs/developer_guide.rst @@ -170,4 +170,4 @@ Code signing on Mac OS 5. Review and agree to any pending agreements. a. Go to https://appstoreconnect.apple.com/agreements/#/ and agree to pending agreements for Free Apps. - b. Review and agree to the Apple Developer Program License Agreement, which updates periodically. \ No newline at end of file + b. Review and agree to the Apple Developer Program License Agreement, which updates periodically. From 61be1292d7b72f06f7ac2fc25f1c3e4994ae0750 Mon Sep 17 00:00:00 2001 From: Ryan Ly Date: Mon, 18 Sep 2023 11:20:24 -0700 Subject: [PATCH 06/22] Revert version bump --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9d3d15ed8..3653a3054 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "nwb-guide", "productName": "NWB GUIDE", - "version": "0.0.6", + "version": "0.0.5", "description": "", "main": "./build/main/main.js", "scripts": { From 379f0981554ac67955ea97d6f68c787247334ceb Mon Sep 17 00:00:00 2001 From: Garrett Date: Mon, 18 Sep 2023 12:04:40 -0700 Subject: [PATCH 07/22] Remove extra subfolder --- src/main/main.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/main/main.ts b/src/main/main.ts index af34032f6..508b7016b 100755 --- a/src/main/main.ts +++ b/src/main/main.ts @@ -125,8 +125,7 @@ const pythonIsClosed = (err = globals.python.latestError) => { * @returns {boolean} True if the app is packaged, false if it is running from a dev version. */ const getPackagedPath = () => { - const scriptPath = isWindows ? path.join(__dirname, PY_FLASK_DIST_FOLDER, PYFLASK_BUILD_SUBFOLDER_NAME, `${PYINSTALLER_NAME}.exe`) : path.join(process.resourcesPath, PYFLASK_BUILD_SUBFOLDER_NAME, PYINSTALLER_NAME) - console.warn('Packaged Script Path', scriptPath) + const scriptPath = isWindows ? path.join(__dirname, PY_FLASK_DIST_FOLDER, `${PYINSTALLER_NAME}.exe`) : path.join(process.resourcesPath, PYFLASK_BUILD_SUBFOLDER_NAME, PYINSTALLER_NAME) if (fs.existsSync(scriptPath)) return scriptPath; }; @@ -135,8 +134,6 @@ const createPyProc = async () => { return new Promise(async (resolve, reject) => { let script = getPackagedPath() || path.join(__dirname, PY_FLASK_FOLDER, "app.py"); - console.warn('Resolved Script Path', script) - await killAllPreviousProcesses(); const defaultPort = PORT as number From dd7abc81476672e248c75b1609c12d6106cdcb4e Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 18 Sep 2023 19:21:57 +0000 Subject: [PATCH 08/22] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/renderer/src/stories/pages/Page.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/renderer/src/stories/pages/Page.js b/src/renderer/src/stories/pages/Page.js index cfd4cc474..49b22071b 100644 --- a/src/renderer/src/stories/pages/Page.js +++ b/src/renderer/src/stories/pages/Page.js @@ -64,7 +64,7 @@ export class Page extends LitElement { this.beforeTransition(); // Otherwise note unsaved updates if present - if (this.unsavedUpdates || ('states' in this.info && !this.info.states.saved)) { + if (this.unsavedUpdates || ("states" in this.info && !this.info.states.saved)) { if (transition === 1) await this.save(); // Save before a single forward transition else { Swal.fire({ From 7065653d41c242aefee8d9113aa955b016525207 Mon Sep 17 00:00:00 2001 From: Cody Baker <51133164+CodyCBakerPhD@users.noreply.github.com> Date: Tue, 19 Sep 2023 12:24:53 -0400 Subject: [PATCH 09/22] Update prepare_pyinstaller_spec.py --- prepare_pyinstaller_spec.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/prepare_pyinstaller_spec.py b/prepare_pyinstaller_spec.py index db06d8e91..a71d0923e 100644 --- a/prepare_pyinstaller_spec.py +++ b/prepare_pyinstaller_spec.py @@ -20,9 +20,11 @@ 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 +app_py_line_index, app_py_line = next((index, line) for index, line in enumerate(lines) if "app.py" in line) +pyflask_start = app_py_line.find("pyflask") # Can change on certain systems +injected_app_py_line_base = app_py_line[: (pyflask_start - 1)] +injected_app_py_line = injected_app_py_line_base + "f\"{Path('pyflask') / 'app.py'}\"],\n" +lines[app_py_line_index] = injected_app_py_line with open(file=Path(__file__).parent / "nwb-guide.spec", mode="w") as io: io.writelines(lines) From a4d20cf92e478e49e9564e1cba4bcbab24d60f6d Mon Sep 17 00:00:00 2001 From: Garrett Date: Tue, 19 Sep 2023 11:02:51 -0700 Subject: [PATCH 10/22] Ensure processes are closed --- src/main/main.ts | 68 +++++++++++++++++++++++++++--------------------- 1 file changed, 38 insertions(+), 30 deletions(-) diff --git a/src/main/main.ts b/src/main/main.ts index 582090189..4777e87c6 100755 --- a/src/main/main.ts +++ b/src/main/main.ts @@ -223,6 +223,8 @@ let hasBeenOpened = false; function initialize() { + if (globals.mainWindow) return // Do not re-initialize if the main window is already declared + makeSingleInstance(); function createWindow() { @@ -254,42 +256,39 @@ function initialize() { }) .then((responseObject) => { let { response } = responseObject; - if (response === 0) quit_app() + if (response === 0) app.quit(); else globals.mainWindowReady = true }); } } else { - await exitPyProc(); - app.exit(); + app.quit(); } }); } - const quit_app = () => { - globals.mainWindow.close(); - if (!globals.mainWindow.closed) globals.mainWindow.destroy() - }; - function onAppReady () { - const promise = createPyProc(); - - // Listen after first load - promise.then(() => { - const chokidar = require('chokidar'); - chokidar.watch(path.join(__dirname, "../../pyflask"), { - ignored: ['**/__pycache__/**'] - }).on('all', async (event: string) => { - if (event === 'change' && !globals.python.restart) { - globals.python.restart = true - await exitPyProc(); - setTimeout(async () => { - await createPyProc(); - globals.python.restart = false - }, 1000) - } - }); - }) + // Only create one python process + if (!pyflaskProcess) { + const promise = createPyProc(); + + // Listen after first load + promise.then(() => { + const chokidar = require('chokidar'); + chokidar.watch(path.join(__dirname, "../../pyflask"), { + ignored: ['**/__pycache__/**'] + }).on('all', async (event: string) => { + if (event === 'change' && !globals.python.restart) { + globals.python.restart = true + await exitPyProc(); + setTimeout(async () => { + await createPyProc(); + globals.python.restart = false + }, 1000) + } + }); + }) + } const windowOptions = { minWidth: 1121, @@ -394,13 +393,22 @@ app.on('activate', () => { if (BrowserWindow.getAllWindows().length === 0) initialize() }) -app.on("window-all-closed", async () => { - if (process.platform != 'darwin') { - await exitPyProc(); - app.quit(); +app.on('will-quit', async () => { + try { + await exitPyProc() + if (globals.mainWindow) { + globals.mainWindow.close(); + if (!globals.mainWindow.closed) globals.mainWindow.destroy() + } + } catch (err) { + console.error(err); } }); +app.on("window-all-closed", async () => { + if (process.platform != 'darwin') app.quit(); +}); + // app.on("will-quit", () => app.quit()); app.on("open-file", onFileOpened) From 3631687a0295e7e8761c28f5c04c7a657441ce92 Mon Sep 17 00:00:00 2001 From: Garrett Date: Tue, 19 Sep 2023 11:04:13 -0700 Subject: [PATCH 11/22] Update main.ts --- src/main/main.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/main.ts b/src/main/main.ts index 4777e87c6..f286dfe1c 100755 --- a/src/main/main.ts +++ b/src/main/main.ts @@ -190,7 +190,7 @@ const exitPyProc = async () => { "/t", ]) // Windows does not properly shut off the python server process. This ensures it is killed. - else pyflaskProcess.kill() + pyflaskProcess.kill() // Try killing twice on Windows pyflaskProcess = null; }; From bbdfe1106b42136e3dc4b319d5ca0848ff39f7d7 Mon Sep 17 00:00:00 2001 From: Garrett Date: Tue, 19 Sep 2023 11:05:41 -0700 Subject: [PATCH 12/22] Re-add logs --- src/main/main.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/main.ts b/src/main/main.ts index 508b7016b..a108cbf66 100755 --- a/src/main/main.ts +++ b/src/main/main.ts @@ -126,6 +126,7 @@ const pythonIsClosed = (err = globals.python.latestError) => { */ const getPackagedPath = () => { const scriptPath = isWindows ? path.join(__dirname, PY_FLASK_DIST_FOLDER, `${PYINSTALLER_NAME}.exe`) : path.join(process.resourcesPath, PYFLASK_BUILD_SUBFOLDER_NAME, PYINSTALLER_NAME) + console.warn('Packaged Script Path', scriptPath) if (fs.existsSync(scriptPath)) return scriptPath; }; @@ -134,6 +135,8 @@ const createPyProc = async () => { return new Promise(async (resolve, reject) => { let script = getPackagedPath() || path.join(__dirname, PY_FLASK_FOLDER, "app.py"); + console.warn('Resolved Script Path', script) + await killAllPreviousProcesses(); const defaultPort = PORT as number From 88009720bf15fb9175bf2b991c8f1d6ae7be8c8c Mon Sep 17 00:00:00 2001 From: Cody Baker <51133164+CodyCBakerPhD@users.noreply.github.com> Date: Wed, 20 Sep 2023 12:50:12 -0400 Subject: [PATCH 13/22] Update testing.yml --- .github/workflows/testing.yml | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index 0cfb20d1b..052813f42 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -27,17 +27,14 @@ jobs: - python-version: "3.9" os: ubuntu-latest label: environments/environment-Linux.yml - prefix: /usr/share/miniconda3/envs/env-electron-python - python-version: "3.10" os: macos-latest label: environments/environment-Mac.yml - prefix: /Users/runner/miniconda3/envs/env-electron-python - python-version: "3.9" os: windows-latest label: environments/environment-Windows.yml - prefix: C:\Miniconda3\envs\env-electron-python steps: @@ -50,7 +47,7 @@ jobs: with: miniforge-variant: Mambaforge miniforge-version: latest - activate-environment: env-electron-python + activate-environment: nwb-guide use-mamba: true - name: Set cache date @@ -62,11 +59,7 @@ jobs: uses: actions/cache@v2 with: path: ${{ env.CONDA }}/envs - key: - conda-${{ runner.os }}-${{ runner.arch }}-${{steps.get-date.outputs.today }}-${{ hashFiles(matrix.label) }}-${{ env.CACHE_NUMBER }} - env: - # Increase this value to reset cache if environment file has not changed - CACHE_NUMBER: 0 + key: conda-${{ runner.os }}-${{ runner.arch }}-${{steps.get-date.outputs.today }}-${{ hashFiles(matrix.label) }}-${{ env.CACHE_NUMBER }} id: cache - name: Update environment From 1e0ca3225f8dbac99a2b62263ed7ce190c52c494 Mon Sep 17 00:00:00 2001 From: Garrett Michael Flynn <46533749+GarrettMFlynn@users.noreply.github.com> Date: Wed, 20 Sep 2023 10:21:11 -0700 Subject: [PATCH 14/22] Update main.ts --- src/main/main.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/main/main.ts b/src/main/main.ts index a108cbf66..53c027eb2 100755 --- a/src/main/main.ts +++ b/src/main/main.ts @@ -125,8 +125,7 @@ const pythonIsClosed = (err = globals.python.latestError) => { * @returns {boolean} True if the app is packaged, false if it is running from a dev version. */ const getPackagedPath = () => { - const scriptPath = isWindows ? path.join(__dirname, PY_FLASK_DIST_FOLDER, `${PYINSTALLER_NAME}.exe`) : path.join(process.resourcesPath, PYFLASK_BUILD_SUBFOLDER_NAME, PYINSTALLER_NAME) - console.warn('Packaged Script Path', scriptPath) + const scriptPath = isWindows ? path.join(__dirname, PY_FLASK_DIST_FOLDER, PYINSTALLER_NAME, `${PYINSTALLER_NAME}.exe`) : path.join(process.resourcesPath, PYFLASK_BUILD_SUBFOLDER_NAME, PYINSTALLER_NAME) if (fs.existsSync(scriptPath)) return scriptPath; }; @@ -135,8 +134,6 @@ const createPyProc = async () => { return new Promise(async (resolve, reject) => { let script = getPackagedPath() || path.join(__dirname, PY_FLASK_FOLDER, "app.py"); - console.warn('Resolved Script Path', script) - await killAllPreviousProcesses(); const defaultPort = PORT as number From 02dba465a1cdd559028da0f56b0420ba9722ca2e Mon Sep 17 00:00:00 2001 From: Cody Baker <51133164+CodyCBakerPhD@users.noreply.github.com> Date: Wed, 20 Sep 2023 13:52:44 -0400 Subject: [PATCH 15/22] test bump --- .github/workflows/testing.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index 052813f42..5b414c18c 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -9,7 +9,7 @@ concurrency: # Cancel previous workflows on the same pull request cancel-in-progress: true env: - CACHE_NUMBER: 1 # increase to reset cache manually + CACHE_NUMBER: 2 # increase to reset cache manually jobs: testing: From 761e3fbe43e219c9aec79355515c6649155f1194 Mon Sep 17 00:00:00 2001 From: Cody Baker <51133164+CodyCBakerPhD@users.noreply.github.com> Date: Wed, 20 Sep 2023 14:03:39 -0400 Subject: [PATCH 16/22] Update testing.yml --- .github/workflows/testing.yml | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index 5b414c18c..a56f4e4e8 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -62,10 +62,15 @@ jobs: key: conda-${{ runner.os }}-${{ runner.arch }}-${{steps.get-date.outputs.today }}-${{ hashFiles(matrix.label) }}-${{ env.CACHE_NUMBER }} id: cache - - name: Update environment - run: - mamba env update -n env-electron-python -f ${{ matrix.label }} - if: steps.cache.outputs.cache-hit != 'true' + - if: steps.cache.outputs.cache-hit != 'true' + name: Create and activate environment + run: | + mamba env create -n nwb-guide -f ${{ matrix.label }} + mamba activate nwb-guide + + - if: steps.cache.outputs.cache-hit == 'true' + name: Activate environment + run: mamba activate nwb-guide - name: Use Node.js 18 uses: actions/setup-node@v3 From af34c42b8442837734558a6c950ed511294fba34 Mon Sep 17 00:00:00 2001 From: Cody Baker <51133164+CodyCBakerPhD@users.noreply.github.com> Date: Wed, 20 Sep 2023 14:07:09 -0400 Subject: [PATCH 17/22] Update testing.yml --- .github/workflows/testing.yml | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index a56f4e4e8..0ef322e2c 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -24,16 +24,13 @@ jobs: matrix: os: [ubuntu-latest, macos-latest, windows-latest] include: - - python-version: "3.9" - os: ubuntu-latest + - os: ubuntu-latest label: environments/environment-Linux.yml - - python-version: "3.10" - os: macos-latest + - os: macos-latest label: environments/environment-Mac.yml - - python-version: "3.9" - os: windows-latest + - os: windows-latest label: environments/environment-Windows.yml @@ -64,13 +61,7 @@ jobs: - if: steps.cache.outputs.cache-hit != 'true' name: Create and activate environment - run: | - mamba env create -n nwb-guide -f ${{ matrix.label }} - mamba activate nwb-guide - - - if: steps.cache.outputs.cache-hit == 'true' - name: Activate environment - run: mamba activate nwb-guide + run: mamba env update -n nwb-guide -f ${{ matrix.label }} - name: Use Node.js 18 uses: actions/setup-node@v3 From c4564840b8cf37842f821f78cf4dbffd972c74ab Mon Sep 17 00:00:00 2001 From: rly Date: Wed, 20 Sep 2023 15:44:28 -0700 Subject: [PATCH 18/22] Fix error in updating project name, edit error msg --- src/renderer/src/progress/update.js | 12 +++++------- .../pages/guided-mode/setup/GuidedNewDatasetInfo.js | 2 +- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/renderer/src/progress/update.js b/src/renderer/src/progress/update.js index 8756db83a..4983aef65 100644 --- a/src/renderer/src/progress/update.js +++ b/src/renderer/src/progress/update.js @@ -2,15 +2,15 @@ import { updateURLParams } from "../../utils/url.js"; import { guidedProgressFilePath } from "../dependencies/simple.js"; import { fs } from "../electron/index.js"; import { joinPath } from "../globals.js"; -import { get } from "./index.js"; +import { get, hasEntry } from "./index.js"; export const update = (newDatasetName, previousDatasetName) => { - //If updataing the dataset, update the old banner image path with a new one + //If updating the dataset, update the old banner image path with a new one if (previousDatasetName) { - if (previousDatasetName === newDatasetName) return "No changes made to dataset name"; + if (previousDatasetName === newDatasetName) return; if (hasEntry(newDatasetName)) - throw new Error("An existing progress file already exists with that name. Please choose a different name."); + throw new Error("An existing project already exists with that name. Please choose a different name."); // update old progress file with new dataset name const oldProgressFilePath = `${guidedProgressFilePath}/${previousDatasetName}.json`; @@ -20,9 +20,7 @@ export const update = (newDatasetName, previousDatasetName) => { localStorage.setItem(newProgressFilePath, localStorage.getItem(oldProgressFilePath)); localStorage.removeItem(oldProgressFilePath); } - - return "Dataset name updated"; - } else throw new Error("No previous dataset name provided"); + } else throw new Error("No previous project name provided"); }; export const updateAppProgress = ( pageId, diff --git a/src/renderer/src/stories/pages/guided-mode/setup/GuidedNewDatasetInfo.js b/src/renderer/src/stories/pages/guided-mode/setup/GuidedNewDatasetInfo.js index e39b8fe4e..cdb2c6f62 100644 --- a/src/renderer/src/stories/pages/guided-mode/setup/GuidedNewDatasetInfo.js +++ b/src/renderer/src/stories/pages/guided-mode/setup/GuidedNewDatasetInfo.js @@ -61,7 +61,7 @@ export class GuidedNewDatasetPage extends Page { const has = await hasEntry(name); if (has) { this.notify( - "An existing progress file already exists with that name. Please choose a different name.", + "An existing project already exists with that name. Please choose a different name.", "error" ); return; From f643c12d0ebb4c5e2b8fb7bf1fd97f0467a0ea75 Mon Sep 17 00:00:00 2001 From: Garrett Date: Thu, 21 Sep 2023 10:37:54 -0700 Subject: [PATCH 19/22] Change update to rename --- src/renderer/src/progress/update.js | 5 +++-- .../stories/pages/guided-mode/setup/GuidedNewDatasetInfo.js | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/renderer/src/progress/update.js b/src/renderer/src/progress/update.js index 8756db83a..8c5fc7e30 100644 --- a/src/renderer/src/progress/update.js +++ b/src/renderer/src/progress/update.js @@ -4,8 +4,8 @@ import { fs } from "../electron/index.js"; import { joinPath } from "../globals.js"; import { get } from "./index.js"; -export const update = (newDatasetName, previousDatasetName) => { - //If updataing the dataset, update the old banner image path with a new one +export const rename = (newDatasetName, previousDatasetName) => { + //If updating the dataset, update the old banner image path with a new one if (previousDatasetName) { if (previousDatasetName === newDatasetName) return "No changes made to dataset name"; @@ -24,6 +24,7 @@ export const update = (newDatasetName, previousDatasetName) => { return "Dataset name updated"; } else throw new Error("No previous dataset name provided"); }; + export const updateAppProgress = ( pageId, dataOrProjectName = {}, diff --git a/src/renderer/src/stories/pages/guided-mode/setup/GuidedNewDatasetInfo.js b/src/renderer/src/stories/pages/guided-mode/setup/GuidedNewDatasetInfo.js index e39b8fe4e..7b081e41c 100644 --- a/src/renderer/src/stories/pages/guided-mode/setup/GuidedNewDatasetInfo.js +++ b/src/renderer/src/stories/pages/guided-mode/setup/GuidedNewDatasetInfo.js @@ -1,5 +1,5 @@ import { html } from "lit"; -import { global, hasEntry, update } from "../../../../progress/index.js"; +import { global, hasEntry, rename } from "../../../../progress/index.js"; import { JSONSchemaForm } from "../../../JSONSchemaForm.js"; import { Page } from "../../Page.js"; import { validateOnChange } from "../../../../validation/index.js"; @@ -50,7 +50,7 @@ export class GuidedNewDatasetPage extends Page { // Update existing progress file if (globalState.initialized) { try { - const res = update(name, globalState.name); + const res = rename(name, globalState.name); if (typeof res === "string") this.notify(res); if (res === false) return; } catch (e) { From b9e67f1a8c76c8bb6293603e6ef6ebbd28b25255 Mon Sep 17 00:00:00 2001 From: Garrett Date: Thu, 21 Sep 2023 10:38:22 -0700 Subject: [PATCH 20/22] Add test --- src/renderer/src/progress/index.js | 23 +++++--------------- src/renderer/src/progress/operations.js | 23 ++++++++++++++++++++ tests/progress.test.ts | 29 +++++++++++++++++++++++-- 3 files changed, 55 insertions(+), 20 deletions(-) create mode 100644 src/renderer/src/progress/operations.js diff --git a/src/renderer/src/progress/index.js b/src/renderer/src/progress/index.js index 8e39c7e97..7de0bb38e 100644 --- a/src/renderer/src/progress/index.js +++ b/src/renderer/src/progress/index.js @@ -14,6 +14,8 @@ import { merge } from "../stories/pages/utils.js"; import { updateAppProgress, updateFile } from "./update.js"; import { updateURLParams } from "../../utils/url.js"; +import * as operations from './operations' + export * from "./update"; class GlobalAppConfig { @@ -56,6 +58,8 @@ export const save = (page, overrides = {}) => { export const getEntries = () => { if (fs && !fs.existsSync(guidedProgressFilePath)) fs.mkdirSync(guidedProgressFilePath, { recursive: true }); //Check if progress folder exists. If not, create it. const progressFiles = fs ? fs.readdirSync(guidedProgressFilePath) : Object.keys(localStorage); + console.log(progressFiles) + return progressFiles.filter((path) => path.slice(-5) === ".json"); }; @@ -122,24 +126,7 @@ export const remove = async (name) => { focusCancel: true, }); - if (result.isConfirmed) { - //Get the path of the progress file to delete - const progressFilePathToDelete = joinPath(guidedProgressFilePath, name + ".json"); - - //delete the progress file - if (fs) fs.unlinkSync(progressFilePathToDelete); - else localStorage.removeItem(progressFilePathToDelete); - - if (fs) { - // delete default stub location - fs.rmSync(joinPath(stubSaveFolderPath, name), { recursive: true, force: true }); - - // delete default conversion location - fs.rmSync(joinPath(conversionSaveFolderPath, name), { recursive: true, force: true }); - } - - return true; - } + if (result.isConfirmed) return operations.remove(name) return false; }; diff --git a/src/renderer/src/progress/operations.js b/src/renderer/src/progress/operations.js new file mode 100644 index 000000000..7cd8df54d --- /dev/null +++ b/src/renderer/src/progress/operations.js @@ -0,0 +1,23 @@ +import { joinPath } from "../globals"; +import { conversionSaveFolderPath, guidedProgressFilePath, stubSaveFolderPath } from "../dependencies/simple"; +import { fs } from "../electron"; + + +export const remove = (name) => { + //Get the path of the progress file to delete + const progressFilePathToDelete = joinPath(guidedProgressFilePath, name + ".json"); + + //delete the progress file + if (fs) fs.unlinkSync(progressFilePathToDelete); + else localStorage.removeItem(progressFilePathToDelete); + + if (fs) { + // delete default stub location + fs.rmSync(joinPath(stubSaveFolderPath, name), { recursive: true, force: true }); + + // delete default conversion location + fs.rmSync(joinPath(conversionSaveFolderPath, name), { recursive: true, force: true }); + } + + return true; +} \ No newline at end of file diff --git a/tests/progress.test.ts b/tests/progress.test.ts index 52f68b634..4e8e9da72 100644 --- a/tests/progress.test.ts +++ b/tests/progress.test.ts @@ -1,4 +1,29 @@ -import { test } from 'vitest' -import { updateAppProgress } from '../src/renderer/src/progress/update' +import { expect, test } from 'vitest' +import { updateAppProgress, updateFile, rename } from '../src/renderer/src/progress/update' +import { get } from '../src/renderer/src/progress' +import { remove } from '../src/renderer/src/progress/operations' test('updates to app progress do not fail', () => updateAppProgress('/', {})) + +const initialName = '.progressTestPipelineName' +const renameName = initialName + 2 +const info = { random: Math.random() } + +// Remove before tests +remove(initialName) +remove(renameName) + +// create pipeline +test('pipeline creation works', () => { + updateFile(initialName, () => info) + const result = get(initialName) + expect(result.random).toEqual(info.random) // NOTE: Result has an extra lastModified field +}) + +// rename pipeline +test('pipeline renaming works', () => rename(renameName, initialName)) + +// delete pipeline +test('pipeline deletion works', () => remove(renameName)) + + From 98b2077126f933cd9aa905c3606150939476fa4e Mon Sep 17 00:00:00 2001 From: Garrett Date: Thu, 21 Sep 2023 10:38:48 -0700 Subject: [PATCH 21/22] Update index.js --- src/renderer/src/progress/index.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/renderer/src/progress/index.js b/src/renderer/src/progress/index.js index 7de0bb38e..f303dabd2 100644 --- a/src/renderer/src/progress/index.js +++ b/src/renderer/src/progress/index.js @@ -58,8 +58,6 @@ export const save = (page, overrides = {}) => { export const getEntries = () => { if (fs && !fs.existsSync(guidedProgressFilePath)) fs.mkdirSync(guidedProgressFilePath, { recursive: true }); //Check if progress folder exists. If not, create it. const progressFiles = fs ? fs.readdirSync(guidedProgressFilePath) : Object.keys(localStorage); - console.log(progressFiles) - return progressFiles.filter((path) => path.slice(-5) === ".json"); }; From e7af457fa38b356c23bada5e15f42a9a533e6c6d Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 21 Sep 2023 17:39:19 +0000 Subject: [PATCH 22/22] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/renderer/src/progress/index.js | 4 ++-- src/renderer/src/progress/operations.js | 27 ++++++++++++------------- tests/progress.test.ts | 2 -- 3 files changed, 15 insertions(+), 18 deletions(-) diff --git a/src/renderer/src/progress/index.js b/src/renderer/src/progress/index.js index f303dabd2..212954f47 100644 --- a/src/renderer/src/progress/index.js +++ b/src/renderer/src/progress/index.js @@ -14,7 +14,7 @@ import { merge } from "../stories/pages/utils.js"; import { updateAppProgress, updateFile } from "./update.js"; import { updateURLParams } from "../../utils/url.js"; -import * as operations from './operations' +import * as operations from "./operations"; export * from "./update"; @@ -124,7 +124,7 @@ export const remove = async (name) => { focusCancel: true, }); - if (result.isConfirmed) return operations.remove(name) + if (result.isConfirmed) return operations.remove(name); return false; }; diff --git a/src/renderer/src/progress/operations.js b/src/renderer/src/progress/operations.js index 7cd8df54d..20ec92b2c 100644 --- a/src/renderer/src/progress/operations.js +++ b/src/renderer/src/progress/operations.js @@ -2,22 +2,21 @@ import { joinPath } from "../globals"; import { conversionSaveFolderPath, guidedProgressFilePath, stubSaveFolderPath } from "../dependencies/simple"; import { fs } from "../electron"; - export const remove = (name) => { - //Get the path of the progress file to delete - const progressFilePathToDelete = joinPath(guidedProgressFilePath, name + ".json"); + //Get the path of the progress file to delete + const progressFilePathToDelete = joinPath(guidedProgressFilePath, name + ".json"); - //delete the progress file - if (fs) fs.unlinkSync(progressFilePathToDelete); - else localStorage.removeItem(progressFilePathToDelete); + //delete the progress file + if (fs) fs.unlinkSync(progressFilePathToDelete); + else localStorage.removeItem(progressFilePathToDelete); - if (fs) { - // delete default stub location - fs.rmSync(joinPath(stubSaveFolderPath, name), { recursive: true, force: true }); + if (fs) { + // delete default stub location + fs.rmSync(joinPath(stubSaveFolderPath, name), { recursive: true, force: true }); - // delete default conversion location - fs.rmSync(joinPath(conversionSaveFolderPath, name), { recursive: true, force: true }); - } + // delete default conversion location + fs.rmSync(joinPath(conversionSaveFolderPath, name), { recursive: true, force: true }); + } - return true; -} \ No newline at end of file + return true; +}; diff --git a/tests/progress.test.ts b/tests/progress.test.ts index 4e8e9da72..f00782f73 100644 --- a/tests/progress.test.ts +++ b/tests/progress.test.ts @@ -25,5 +25,3 @@ test('pipeline renaming works', () => rename(renameName, initialName)) // delete pipeline test('pipeline deletion works', () => remove(renameName)) - -