From 16f4d8b19441ab9e62143cf738d2774baf34a828 Mon Sep 17 00:00:00 2001 From: Shohan Dutta Roy Date: Mon, 1 Apr 2024 23:52:39 +0530 Subject: [PATCH] feat: Add script to download npm dependencies and update installer script --- README.md | 6 +--- install/install_openadapt.ps1 | 41 ++++++++++++++++++++++++++ install/install_openadapt.sh | 25 ++++++++++++++++ openadapt/app/dashboard/__init__.py | 20 +++++++++++++ openadapt/app/dashboard/api/index.py | 6 ++-- openadapt/app/dashboard/entrypoint.ps1 | 3 ++ openadapt/app/dashboard/entrypoint.sh | 9 ++++++ openadapt/app/dashboard/index.js | 33 ++++++++++++++------- openadapt/app/dashboard/package.json | 3 ++ pyproject.toml | 1 + 10 files changed, 128 insertions(+), 19 deletions(-) create mode 100644 openadapt/app/dashboard/__init__.py create mode 100755 openadapt/app/dashboard/entrypoint.ps1 create mode 100755 openadapt/app/dashboard/entrypoint.sh diff --git a/README.md b/README.md index 9aff871d2..ee7033f34 100644 --- a/README.md +++ b/README.md @@ -96,11 +96,7 @@ pip3 install poetry poetry install poetry shell alembic upgrade head - -cd openadapt/app/dashboard -nvm install 21 -nvm use -npm install +poetry run dashbaord pytest ``` diff --git a/install/install_openadapt.ps1 b/install/install_openadapt.ps1 index d16ac6fb7..570eff803 100644 --- a/install/install_openadapt.ps1 +++ b/install/install_openadapt.ps1 @@ -16,6 +16,10 @@ $pythonMaxVersion = "3.10.12" # Change this if a different Higher version are su $pythonInstaller = "python-3.10.11-amd64.exe" $pythonInstallerLoc = "https://www.python.org/ftp/python/3.10.11/python-3.10.11-amd64.exe" +$nvmCmd = "nvm" +$nvmInstaller = "nvm-setup.exe" +$nvmInstallerLoc = "https://github.com/coreybutler/nvm-windows/releases/download/1.1.12/nvm-setup.exe" + $gitCmd = "git" $gitInstaller = "Git-2.40.1-64-bit.exe" $gitInstallerLoc = "https://github.com/git-for-windows/git/releases/download/v2.40.1.windows.1/Git-2.40.1-64-bit.exe" @@ -226,6 +230,39 @@ function GetPythonCMD { exit } +# Check and Install NVM and return the nvm command +function GetNVMCMD { + $nvmExists = CheckCMDExists $nvmCmd + if (!$nvmExists) { + # Install NVM + Write-Host "Downloading NVM installer..." + $ProgressPreference = 'SilentlyContinue' + Invoke-WebRequest -Uri $nvmInstallerLoc -OutFile $nvmInstaller + $exists = Test-Path -Path $nvmInstaller -PathType Leaf + if (!$exists) { + Write-Host "Failed to download NVM installer" -ForegroundColor Red + exit + } + + Write-Host "Installing NVM..." + Start-Process -FilePath $nvmInstaller -Verb runAs -ArgumentList '/VERYSILENT /NORESTART /NOCANCEL /SP-' -Wait + Remove-Item $nvmInstaller + + RefreshPathVariables + + # Make sure NVM is now available + $nvmExists = CheckCMDExists $nvmCmd + if (!$nvmExists) { + Write-Host "Error after installing NVM. Uninstalling..." + Start-Process -FilePath $nvmInstaller -Verb runAs -ArgumentList '/VERYSILENT /NORESTART /NOCANCEL /SP-' -Wait + Cleanup + exit + } + } + # Return the nvm command + return $nvmCmd +} + # Check and Install Git and return the git command function GetGitCMD { @@ -310,6 +347,9 @@ RunAndCheck "$tesseract --version" "check TesseractOCR" $python = GetPythonCMD RunAndCheck "$python --version" "check Python" +$nvm = GetNVMCMD +RunAndCheck "$nvm --version" "check NVM" + $git = GetGitCMD RunAndCheck "$git --version" "check Git" @@ -321,6 +361,7 @@ Set-Location .\OpenAdapt RunAndCheck "pip install poetry" "Run ``pip install poetry``" RunAndCheck "poetry install" "Run ``poetry install``" RunAndCheck "poetry run alembic upgrade head" "Run ``alembic upgrade head``" -SkipCleanup:$true +RunAndCheck "poetry run dashboard" "Install dashboard dependencies" -SkipCleanup:$true RunAndCheck "poetry run pytest" "Run ``Pytest``" -SkipCleanup:$true Write-Host "OpenAdapt installed Successfully!" -ForegroundColor Green Start-Process powershell -Verb RunAs -ArgumentList "-NoExit", "-Command", "Set-Location -Path '$pwd'; poetry shell" diff --git a/install/install_openadapt.sh b/install/install_openadapt.sh index 10c2d5865..54897a794 100644 --- a/install/install_openadapt.sh +++ b/install/install_openadapt.sh @@ -8,6 +8,8 @@ set -x pythonCmd="python3.10" pythonVerStr="Python 3.10*" pythonInstallerLoc="https://www.python.org/ftp/python/3.10.11/python-3.10.11-macos11.pkg" +nvmCmd="nvm" +nvmInstallerLoc="https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh" # Set default values when no parameters are provided BRANCH=${BRANCH:-main} @@ -93,6 +95,27 @@ CheckPythonExists() { exit 1 } +CheckNVMExists() { + if CheckCMDExists $nvmCmd; then + return + fi + + # Install NVM + echo Installing NVM + + curl -o- $nvmInstallerLoc | bash + + export NVM_DIR="$HOME/.nvm" + [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm + [ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion + + if ! CheckCMDExists $nvmCmd; then + echo "Failed to install NVM" + Cleanup + exit 1 + fi +} + ################################ INSTALLATION ################################ # Download brew @@ -125,6 +148,7 @@ if ! CheckCMDExists "tesseract"; then fi CheckPythonExists +CheckNVMExists [ -d "OpenAdapt" ] && mv OpenAdapt OpenAdapt-$(date +%Y-%m-%d_%H-%M-%S) RunAndCheck "git clone $REPO_URL" "Clone git repo" @@ -134,6 +158,7 @@ RunAndCheck "git checkout $BRANCH" "Checkout branch $BRANCH" RunAndCheck "pip3.10 install poetry" "Install Poetry" RunAndCheck "poetry install" "Install Python dependencies" RunAndCheck "poetry run alembic upgrade head" "Update database" +RunAndCheck "poetry run dashboard" "Install dashboard dependencies" RunAndCheck "poetry run pytest" "Run tests" if [ -z "$SKIP_POETRY_SHELL" ]; then RunAndCheck "poetry shell" "Activate virtual environment" diff --git a/openadapt/app/dashboard/__init__.py b/openadapt/app/dashboard/__init__.py new file mode 100644 index 000000000..33edc2e6e --- /dev/null +++ b/openadapt/app/dashboard/__init__.py @@ -0,0 +1,20 @@ +"""Script to install dependencies needed for the dashboard.""" + +import os +import subprocess +import sys + + +def _run(bash_script: str) -> int: + return subprocess.call(bash_script, shell=True) + + +def entrypoint() -> None: + """Entrypoint for the installation script.""" + cwd = os.path.dirname(os.path.realpath(__file__)) + os.chdir(cwd) + + if sys.platform == "win32": + _run("powershell -File entrypoint.ps1") + return + _run("source ./entrypoint.sh") diff --git a/openadapt/app/dashboard/api/index.py b/openadapt/app/dashboard/api/index.py index 775b8fd5f..e7a887018 100644 --- a/openadapt/app/dashboard/api/index.py +++ b/openadapt/app/dashboard/api/index.py @@ -4,18 +4,16 @@ from fastapi import FastAPI from openadapt.app.cards import is_recording, quick_record, stop_record -from openadapt.db.crud import get_all_recordings -from openadapt.db.db import Session +from openadapt.db import crud from openadapt.models import Recording app = FastAPI() -db = Session() @app.get("/api/recordings", response_model=None) def get_recordings() -> dict[str, list[Recording]]: """Get all recordings.""" - recordings = get_all_recordings() + recordings = crud.get_all_recordings() return {"recordings": recordings} diff --git a/openadapt/app/dashboard/entrypoint.ps1 b/openadapt/app/dashboard/entrypoint.ps1 new file mode 100755 index 000000000..e551b4b97 --- /dev/null +++ b/openadapt/app/dashboard/entrypoint.ps1 @@ -0,0 +1,3 @@ +nvm install 21 +nvm use 21 +npm install diff --git a/openadapt/app/dashboard/entrypoint.sh b/openadapt/app/dashboard/entrypoint.sh new file mode 100755 index 000000000..1a0d811b4 --- /dev/null +++ b/openadapt/app/dashboard/entrypoint.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +export NVM_DIR="$HOME/.nvm" +[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm +[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion + +nvm install 21 +nvm use +npm install diff --git a/openadapt/app/dashboard/index.js b/openadapt/app/dashboard/index.js index 6fdee4462..e296a66a3 100644 --- a/openadapt/app/dashboard/index.js +++ b/openadapt/app/dashboard/index.js @@ -33,17 +33,30 @@ Promise.all([checkPort(DASHBOARD_CLIENT_PORT), checkPort(DASHBOARD_SERVER_PORT)] function spawnChildProcess() { // Spawn child process to run `npm run dev` - const childProcess = spawn('npm', ['run', 'dev'], { stdio: 'inherit' }) - // wait for 1 second - setTimeout(() => { - import('open').then(({ default: open }) => { - open(`http://localhost:${DASHBOARD_CLIENT_PORT}`) - }) - }, 3000) + let childProcess; + + if (process.platform === 'win32') { + childProcess = spawn('npm', ['run', 'dev:windows'], { stdio: 'inherit', shell: true }) + } else { + childProcess = spawn('npm', ['run', 'dev'], { stdio: 'inherit' }) + } + + childProcess.on('spawn', () => { + // wait for 3 seconds before opening the browser + setTimeout(() => { + import('open').then(({ default: open }) => { + open(`http://localhost:${DASHBOARD_CLIENT_PORT}`) + }) + }, 3000) + }) - // Handle SIGTERM signal - process.on('SIGTERM', () => { - childProcess.kill('SIGTERM') + // Handle SIG signals + const signals = ['SIGINT', 'SIGTERM', 'SIGQUIT', 'SIGHUP', 'SIGKILL'] + + signals.forEach(signal => { + process.on(signal, () => { + childProcess.kill(signal) + }) }) // Listen for child process error event diff --git a/openadapt/app/dashboard/package.json b/openadapt/app/dashboard/package.json index 693f76517..f26fbea7c 100644 --- a/openadapt/app/dashboard/package.json +++ b/openadapt/app/dashboard/package.json @@ -4,8 +4,11 @@ "private": true, "scripts": { "fastapi-dev": "python3 -m uvicorn api.index:app --port $DASHBOARD_SERVER_PORT --reload", + "fastapi-dev:windows": "python -m uvicorn api.index:app --port %DASHBOARD_SERVER_PORT% --reload", "next-dev": "next dev -p $DASHBOARD_CLIENT_PORT", + "next-dev:windows": "next dev -p %DASHBOARD_CLIENT_PORT%", "dev": "concurrently \"npm run next-dev\" \"npm run fastapi-dev\"", + "dev:windows": "concurrently \"npm run next-dev:windows\" \"npm run fastapi-dev:windows\"", "build": "next build", "start": "next start", "lint": "next lint", diff --git a/pyproject.toml b/pyproject.toml index 5a36a967b..423cd2e9a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -115,6 +115,7 @@ replay = "openadapt.replay:start" app = "openadapt.app.tray:_run" reset = "openadapt.scripts.reset_db:reset_db" capture = "openadapt.capture:test" +dashboard = 'openadapt.app.dashboard:entrypoint' [tool.black]