mirror of
https://github.com/storytold/artcraft.git
synced 2026-10-20 17:02:53 -04:00
ArtCraft Desktop (fresh start)
This is a fresh start for the `artcraft` repo. The old monorepo, which included our web API gateway, job services, SRE tools, various frontends, and more has moved to `artcraft-services` You can find the full git history here: https://github.com/storytold/artcraft-services This change was motivated by the fact that the entire git history was hundreds of gigabytes in size, which is unwieldy for anyone not in the core team that doesn't care about support services outside of the core artcraft app. We wanted to keep this repo in its well-known place since we already have users and activity here. Please update your remotes to either `artcraft-services` or make a fresh clone of this repo. History can be found at the artcraft-services repo.
This commit is contained in:
+144
@@ -0,0 +1,144 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Bump the ArtCraft desktop app version across all three version files.
|
||||
|
||||
Usage:
|
||||
python bump_artcraft_desktop_version.py # auto-bump minor (0.9.x -> 0.10.0)
|
||||
python bump_artcraft_desktop_version.py 1.2.3 # set explicit version
|
||||
|
||||
The auto-bump reads the highest current version found across all three files,
|
||||
increments the minor component by 1, and resets the patch to 0.
|
||||
e.g. 0.9.4 -> 0.10.0, 0.22.3 -> 0.23.0
|
||||
"""
|
||||
|
||||
import re
|
||||
import sys
|
||||
import json
|
||||
import os
|
||||
|
||||
REPO_ROOT = os.path.join(os.path.dirname(__file__), "..", "..")
|
||||
|
||||
VERSION_RS = os.path.join(REPO_ROOT, "crates/desktop/artcraft/src/version.rs")
|
||||
TAURI_CONF = os.path.join(REPO_ROOT, "crates/desktop/artcraft/tauri.conf.json")
|
||||
TAURI_MAC = os.path.join(REPO_ROOT, "crates/desktop/artcraft/tauri-mac.conf.json")
|
||||
|
||||
VERSION_RE = re.compile(r"\d+\.\d+\.\d+")
|
||||
|
||||
|
||||
def read_version_rs(path):
|
||||
with open(path) as f:
|
||||
content = f.read()
|
||||
m = re.search(r'ARTCRAFT_VERSION:\s*&str\s*=\s*"(\d+\.\d+\.\d+)"', content)
|
||||
if not m:
|
||||
return None
|
||||
return m.group(1)
|
||||
|
||||
|
||||
def read_json_version(path):
|
||||
with open(path) as f:
|
||||
data = json.load(f)
|
||||
v = data.get("version")
|
||||
if v and VERSION_RE.fullmatch(v):
|
||||
return v
|
||||
return None
|
||||
|
||||
|
||||
def bump_minor(version):
|
||||
major, minor, _patch = version.split(".")
|
||||
return f"{major}.{int(minor) + 1}.0"
|
||||
|
||||
|
||||
def write_version_rs(path, new_version):
|
||||
with open(path) as f:
|
||||
content = f.read()
|
||||
updated = re.sub(
|
||||
r'(ARTCRAFT_VERSION:\s*&str\s*=\s*)"(\d+\.\d+\.\d+)"',
|
||||
rf'\g<1>"{new_version}"',
|
||||
content,
|
||||
)
|
||||
if updated == content:
|
||||
raise ValueError(f"Could not find ARTCRAFT_VERSION in {path}")
|
||||
with open(path, "w") as f:
|
||||
f.write(updated)
|
||||
|
||||
|
||||
def write_json_version(path, new_version):
|
||||
with open(path) as f:
|
||||
content = f.read()
|
||||
updated = re.sub(
|
||||
r'("version"\s*:\s*)"(\d+\.\d+\.\d+)"',
|
||||
rf'\g<1>"{new_version}"',
|
||||
content,
|
||||
)
|
||||
if updated == content:
|
||||
raise ValueError(f"Could not find version field in {path}")
|
||||
with open(path, "w") as f:
|
||||
f.write(updated)
|
||||
|
||||
|
||||
def parse_tuple(version):
|
||||
return tuple(int(x) for x in version.split("."))
|
||||
|
||||
|
||||
def main():
|
||||
# --- Determine new version ---
|
||||
if len(sys.argv) > 2:
|
||||
print("Usage: bump_artcraft_desktop_version.py [VERSION]", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
if len(sys.argv) == 2:
|
||||
arg = sys.argv[1]
|
||||
if not re.fullmatch(r"\d+\.\d+\.\d+", arg):
|
||||
print(f"Error: version argument '{arg}' does not match \\d+\\.\\d+\\.\\d+", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
new_version = arg
|
||||
print(f"Using explicit version: {new_version}")
|
||||
else:
|
||||
# Read all three and take the highest
|
||||
versions = {}
|
||||
for label, reader, path in [
|
||||
("version.rs", read_version_rs, VERSION_RS),
|
||||
("tauri.conf.json", read_json_version, TAURI_CONF),
|
||||
("tauri-mac.conf.json",read_json_version, TAURI_MAC),
|
||||
]:
|
||||
try:
|
||||
v = reader(path)
|
||||
if v:
|
||||
versions[label] = v
|
||||
print(f" {label}: {v}")
|
||||
else:
|
||||
print(f" {label}: (could not parse version)")
|
||||
except Exception as e:
|
||||
print(f" {label}: (error reading: {e})")
|
||||
|
||||
if not versions:
|
||||
print("Error: could not read version from any file. Supply a version argument.", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
highest = max(versions.values(), key=parse_tuple)
|
||||
new_version = bump_minor(highest)
|
||||
print(f"Highest current version: {highest} -> bumped to: {new_version}")
|
||||
|
||||
# --- Write new version to all three files ---
|
||||
errors = []
|
||||
for label, writer, path in [
|
||||
("version.rs", write_version_rs, VERSION_RS),
|
||||
("tauri.conf.json", write_json_version, TAURI_CONF),
|
||||
("tauri-mac.conf.json",write_json_version, TAURI_MAC),
|
||||
]:
|
||||
try:
|
||||
writer(path, new_version)
|
||||
print(f" Updated {label}")
|
||||
except Exception as e:
|
||||
errors.append(f" Failed to update {label}: {e}")
|
||||
|
||||
if errors:
|
||||
for err in errors:
|
||||
print(err, file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
print(f"\nDone. All files set to {new_version}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Executable
+8
@@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
|
||||
# NB: This only works on Mac, not Linux.
|
||||
rm ~/Library/Caches/ai.artcraft.app/.cookies
|
||||
rm -r ~/Library/Caches/artcraft/
|
||||
rm -r ~/Library/Caches/ai.artcraft.app/
|
||||
rm -r ~/Library/Caches/tauri-artcraft/
|
||||
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -euxo pipefail
|
||||
|
||||
declare -r RELEASE_BRANCH="artcraft-release"
|
||||
|
||||
if git show-ref --verify --quiet "refs/heads/${RELEASE_BRANCH}"; then
|
||||
git branch -D artcraft-release
|
||||
fi
|
||||
|
||||
git checkout main
|
||||
git pull
|
||||
|
||||
git checkout -b "${RELEASE_BRANCH}"
|
||||
git push origin "${RELEASE_BRANCH}"
|
||||
|
||||
git checkout main
|
||||
|
||||
Executable
+36
@@ -0,0 +1,36 @@
|
||||
#!/usr/bin/env bash
|
||||
# This works on Linux and MacOS to build production Artcraft
|
||||
|
||||
set -euxo pipefail
|
||||
|
||||
echo "Building production Artcraft..."
|
||||
echo ""
|
||||
|
||||
root_dir=$(pwd)
|
||||
frontend_path="${root_dir}/frontend"
|
||||
rust_crate_path="${root_dir}/crates/desktop/artcraft"
|
||||
|
||||
# Build with the desktop app configuration.
|
||||
config_path="${rust_crate_path}/tauri.conf.json"
|
||||
|
||||
pushd "${frontend_path}" || exit
|
||||
|
||||
npm install --verbose
|
||||
|
||||
popd || exit
|
||||
|
||||
export TAURI_FRONTEND_PATH="${frontend_path}"
|
||||
export TAURI_APP_PATH="${rust_crate_path}"
|
||||
|
||||
# NB: The "frontend dev" script sets "production" too, so this must only control the
|
||||
# hostnames we use, not minification, etc.
|
||||
export VITE_ENVIRONMENT_TYPE="production"
|
||||
export SQLX_OFFLINE=true
|
||||
|
||||
# This appears to trigger "nx build" instead of "nx dev".
|
||||
cargo tauri build --config "${config_path}"
|
||||
|
||||
echo "Done!"
|
||||
|
||||
date "+Finished on %A, %B %e - %H:%M:%S (local timezone)"
|
||||
|
||||
Executable
+32
@@ -0,0 +1,32 @@
|
||||
#!/usr/bin/env bash
|
||||
# This works on Linux and MacOS to launch the frontend dev server
|
||||
|
||||
root_dir=$(pwd)
|
||||
frontend_path="${root_dir}/frontend"
|
||||
|
||||
source "${root_dir}/script/common/frontend_preflight.sh"
|
||||
frontend_preflight "${frontend_path}"
|
||||
|
||||
echo "Running Artcraft Frontend in Dev Mode..."
|
||||
echo ""
|
||||
|
||||
echo "You'll need to launch the Rust dev server as a second script!"
|
||||
echo ""
|
||||
|
||||
# Kill any process running on port 5741, which will block startup
|
||||
if lsof -i tcp:5173 &>/dev/null; then
|
||||
lsof -i tcp:5173 -t | xargs kill -9
|
||||
echo "Killed process running on port 5173"
|
||||
else
|
||||
echo "No process running on port 5173"
|
||||
fi
|
||||
|
||||
pushd "${frontend_path}" || exit
|
||||
|
||||
frontend_npm_install
|
||||
|
||||
export VITE_ENVIRONMENT_TYPE="production"
|
||||
|
||||
nx dev artcraft
|
||||
|
||||
popd || exit
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env bash
|
||||
# This works on Linux and MacOS to launch the frontend dev server
|
||||
|
||||
root_dir=$(pwd)
|
||||
frontend_path="${root_dir}/frontend"
|
||||
|
||||
echo "Running Artcraft Frontend Build..."
|
||||
echo ""
|
||||
|
||||
pushd "${frontend_path}" || exit
|
||||
|
||||
npm install --verbose
|
||||
|
||||
export VITE_ENVIRONMENT_TYPE="production"
|
||||
|
||||
nx build artcraft
|
||||
|
||||
popd || exit
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
#!/usr/bin/env bash
|
||||
# This works on Linux and MacOS to launch the frontend dev server
|
||||
|
||||
root_dir=$(pwd)
|
||||
frontend_path="${root_dir}/frontend"
|
||||
|
||||
echo "Running Artcraft Frontend in Production Build + Preview Mode... (It won't hot reload!)"
|
||||
echo ""
|
||||
|
||||
echo "You'll need to launch the Rust dev server as a second script!"
|
||||
echo ""
|
||||
|
||||
# Kill any process running on port 5741, which will block startup
|
||||
if lsof -i tcp:5173 &>/dev/null; then
|
||||
lsof -i tcp:5173 -t | xargs kill -9
|
||||
echo "Killed process running on port 5173"
|
||||
else
|
||||
echo "No process running on port 5173"
|
||||
fi
|
||||
|
||||
pushd "${frontend_path}" || exit
|
||||
|
||||
npm install --verbose
|
||||
|
||||
export VITE_ENVIRONMENT_TYPE="production"
|
||||
|
||||
nx production-preview artcraft
|
||||
|
||||
popd || exit
|
||||
Executable
+59
@@ -0,0 +1,59 @@
|
||||
#!/usr/bin/env bash
|
||||
# This works on Linux and MacOS to launch the Rust dev server
|
||||
|
||||
set -euxo pipefail
|
||||
|
||||
echo "Running Artcraft Rust in Dev Mode..."
|
||||
echo ""
|
||||
|
||||
echo "You'll need to launch the frontend dev server as a second script!"
|
||||
echo ""
|
||||
|
||||
root_dir=$(pwd)
|
||||
frontend_path="${root_dir}/frontend"
|
||||
rust_crate_path="${root_dir}/crates/desktop/artcraft"
|
||||
|
||||
sqlite_db_file="/tmp/tasks.sqlite"
|
||||
|
||||
# The tauri dev server integration is super annoying: It eats ctrl-c interrupts,
|
||||
# it decoheres the and corrupts terminal output, and it's slow. This configuration
|
||||
# allows us to start without it. Simply launch `nx` and the dev server as a separate
|
||||
# process and leave tauri out of the loop
|
||||
config_path="${rust_crate_path}/tauri-dev-hot-reload.conf.json"
|
||||
|
||||
export TAURI_FRONTEND_PATH="${frontend_path}"
|
||||
export TAURI_APP_PATH="${rust_crate_path}"
|
||||
|
||||
echo "Create database file..."
|
||||
touch "${sqlite_db_file}"
|
||||
|
||||
sqlx_migrate() {
|
||||
echo "SQLx migrate database file..."
|
||||
sqlx migrate run \
|
||||
--database-url "sqlite:${sqlite_db_file}" \
|
||||
--source "${root_dir}/_database/sql/artcraft_migrations"
|
||||
|
||||
export DATABASE_URL="sqlite:${sqlite_db_file}"
|
||||
}
|
||||
|
||||
sqlx_offline() {
|
||||
echo "SQLx offline..."
|
||||
export SQLX_OFFLINE=true
|
||||
}
|
||||
|
||||
# NB: Switch this for actively developing queries.
|
||||
#sqlx_migrate
|
||||
sqlx_offline
|
||||
|
||||
# Issue with Linux performance
|
||||
# https://github.com/tauri-apps/tauri/issues/13498
|
||||
export WEBKIT_DISABLE_DMABUF_RENDERER=1
|
||||
export WEBKIT_DISABLE_COMPOSITING_MODE=1
|
||||
|
||||
echo "Build and run..."
|
||||
RUSTFLAGS="-Awarnings" cargo tauri dev \
|
||||
--verbose \
|
||||
--no-dev-server \
|
||||
--no-dev-server-wait \
|
||||
--no-watch \
|
||||
--config "${config_path}"
|
||||
@@ -0,0 +1,58 @@
|
||||
#!/usr/bin/env bash
|
||||
# This works on Linux and MacOS to launch the Rust dev server
|
||||
|
||||
set -euxo pipefail
|
||||
|
||||
echo "Running Artcraft Rust in Dev Mode..."
|
||||
echo ""
|
||||
|
||||
echo "You'll need to launch the frontend dev server as a second script!"
|
||||
echo ""
|
||||
|
||||
root_dir=$(pwd)
|
||||
frontend_path="${root_dir}/frontend"
|
||||
rust_crate_path="${root_dir}/crates/desktop/artcraft"
|
||||
|
||||
sqlite_db_file="/tmp/tasks.sqlite"
|
||||
|
||||
# The tauri dev server integration is super annoying: It eats ctrl-c interrupts,
|
||||
# it decoheres the and corrupts terminal output, and it's slow. This configuration
|
||||
# allows us to start without it. Simply launch `nx` and the dev server as a separate
|
||||
# process and leave tauri out of the loop
|
||||
config_path="${rust_crate_path}/tauri-dev-static.conf.json"
|
||||
|
||||
export TAURI_FRONTEND_PATH="${frontend_path}"
|
||||
export TAURI_APP_PATH="${rust_crate_path}"
|
||||
|
||||
echo "Create database file..."
|
||||
touch "${sqlite_db_file}"
|
||||
|
||||
sqlx_migrate() {
|
||||
echo "SQLx migrate database file..."
|
||||
sqlx migrate run \
|
||||
--database-url "sqlite:${sqlite_db_file}" \
|
||||
--source "${root_dir}/_database/sql/artcraft_migrations"
|
||||
|
||||
export DATABASE_URL="sqlite:${sqlite_db_file}"
|
||||
}
|
||||
|
||||
sqlx_offline() {
|
||||
echo "SQLx offline..."
|
||||
export SQLX_OFFLINE=true
|
||||
}
|
||||
|
||||
# NB: Switch this for actively developing queries.
|
||||
#sqlx_migrate
|
||||
sqlx_offline
|
||||
|
||||
# Issue with Linux performance
|
||||
# https://github.com/tauri-apps/tauri/issues/13498
|
||||
export WEBKIT_DISABLE_DMABUF_RENDERER=1
|
||||
export WEBKIT_DISABLE_COMPOSITING_MODE=1
|
||||
|
||||
echo "Build and run..."
|
||||
RUSTFLAGS="-Awarnings" cargo tauri dev \
|
||||
--no-dev-server \
|
||||
--no-dev-server-wait \
|
||||
--no-watch \
|
||||
--config "${config_path}"
|
||||
@@ -0,0 +1,37 @@
|
||||
# Build Production Artcraft
|
||||
|
||||
Write-Host "Building production Artcraft..."
|
||||
Write-Host ""
|
||||
|
||||
try
|
||||
{
|
||||
Push-Location -Path ".\frontend"
|
||||
|
||||
Write-Host "Installing latest dependencies..."
|
||||
Write-Host ""
|
||||
Write-Host "You may need to run ./clean_modules.sh or manually clean up occasionally!" -ForegroundColor red -BackgroundColor white
|
||||
Write-Host ""
|
||||
|
||||
npm install --verbose
|
||||
}
|
||||
finally
|
||||
{
|
||||
Pop-Location
|
||||
}
|
||||
|
||||
$env:VITE_ENVIRONMENT_TYPE="production"
|
||||
$env:SQLX_OFFLINE="true"
|
||||
|
||||
# This tells Tauri *which* frontend and *which* Rust app to use since we're in a monorepo with several apps.
|
||||
$env:TAURI_FRONTEND_PATH=".\frontend"
|
||||
$env:TAURI_APP_PATH=".\crates\desktop\artcraft"
|
||||
|
||||
# The config file tells Tauri more instructions for the frontend build.
|
||||
cargo tauri build --config ".\crates\desktop\artcraft\tauri.conf.json"
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "Production Build Done!" -ForegroundColor green -BackgroundColor white
|
||||
Write-Host ""
|
||||
Write-Host "You can find the installer in: target\release\bundle\nsis\ArtCraft_(version_info)-setup.exe"
|
||||
|
||||
Start-Process "explorer.exe" -ArgumentList ".\target\release\bundle\nsis"
|
||||
@@ -0,0 +1,31 @@
|
||||
# This runs Artcraft Frontend in dev mode on Windows
|
||||
|
||||
Write-Host "Running Artcraft Frontend in Dev Mode..."
|
||||
Write-Host ""
|
||||
Write-Host "You'll need to launch the Rust dev server as a second script!" -ForegroundColor red -BackgroundColor white
|
||||
Write-Host ""
|
||||
|
||||
Push-Location -Path ".\frontend"
|
||||
|
||||
$env:VITE_ENVIRONMENT_TYPE="production"
|
||||
|
||||
try
|
||||
{
|
||||
Write-Host "Installing latest dependencies..."
|
||||
Write-Host ""
|
||||
Write-Host "You may need to run ./clean_modules.sh or manually clean up occasionally!" -ForegroundColor red -BackgroundColor white
|
||||
Write-Host ""
|
||||
|
||||
npm install --verbose
|
||||
|
||||
Write-Host "Running dev server..."
|
||||
Write-Host ""
|
||||
Write-Host "If this isn't running on port 5173, you may need to kill a zombie process!" -ForegroundColor red -BackgroundColor white
|
||||
Write-Host ""
|
||||
|
||||
npx nx dev artcraft
|
||||
}
|
||||
finally
|
||||
{
|
||||
Pop-Location
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
# This runs Artcraft Rust in dev mode on Windows
|
||||
|
||||
Write-Host "Running Artcraft Rust in Dev Mode..."
|
||||
Write-Host ""
|
||||
Write-Host "You'll need to launch the frontend dev server as a second script!" -ForegroundColor red -BackgroundColor white
|
||||
Write-Host ""
|
||||
|
||||
# This tells Tauri *which* frontend and *which* Rust app to use since we're in a monorepo with several apps.
|
||||
$env:TAURI_FRONTEND_PATH=".\frontend"
|
||||
$env:TAURI_APP_PATH=".\crates\desktop\artcraft"
|
||||
|
||||
# Put SQLx into offline mode (no DB hits / migrations).
|
||||
$env:SQLX_OFFLINE = "true"
|
||||
|
||||
# The config file tells Tauri more instructions for the frontend build.
|
||||
cargo tauri dev --config ".\crates\desktop\artcraft\tauri-dev-hot-reload.conf.json"
|
||||
Executable
+86
@@ -0,0 +1,86 @@
|
||||
#!/usr/bin/env bash
|
||||
# Shared preflight checks for the frontend dev/build scripts.
|
||||
#
|
||||
# Usage (from a script that has set ${frontend_path}):
|
||||
#
|
||||
# source "${root_dir}/script/common/frontend_preflight.sh"
|
||||
# frontend_preflight "${frontend_path}"
|
||||
# ...
|
||||
# pushd "${frontend_path}"
|
||||
# frontend_npm_install
|
||||
#
|
||||
|
||||
# Node 20+ is required by Nx 21 and comfortably covers Vite 6.
|
||||
FRONTEND_MINIMUM_NODE_MAJOR=20
|
||||
|
||||
frontend_preflight() {
|
||||
local frontend_path="$1"
|
||||
|
||||
if [ ! -d "${frontend_path}" ]; then
|
||||
echo "ERROR: frontend directory not found at: ${frontend_path}"
|
||||
echo "Run this script from the repository root."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# --- Node and npm must be installed ---
|
||||
if ! command -v node &>/dev/null; then
|
||||
echo "ERROR: node is not installed (or not on PATH)."
|
||||
echo "Install Node.js ${FRONTEND_MINIMUM_NODE_MAJOR}+ via nvm (https://github.com/nvm-sh/nvm),"
|
||||
echo "https://nodejs.org, or:"
|
||||
echo " brew install node"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v npm &>/dev/null; then
|
||||
echo "ERROR: npm is not installed (or not on PATH). It normally ships with Node.js."
|
||||
echo "Reinstall Node.js to get it back."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# --- Node must be recent enough for Nx 21 / Vite 6 ---
|
||||
local node_major
|
||||
node_major=$(node --version | sed -E 's/^v([0-9]+).*/\1/')
|
||||
if [ "${node_major}" -lt "${FRONTEND_MINIMUM_NODE_MAJOR}" ]; then
|
||||
echo "ERROR: Node.js ${FRONTEND_MINIMUM_NODE_MAJOR}+ is required (found $(node --version))."
|
||||
echo "Upgrade via nvm ('nvm install --lts') or https://nodejs.org."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# --- The frontend uses npm; stale pnpm state breaks installs ---
|
||||
# pnpm was briefly adopted ("add pnpm to solve build issues") and then dropped
|
||||
# ("fix(frontend): consume video-editor libs via nx path aliases, drop pnpm").
|
||||
# A node_modules tree written by pnpm makes npm fail with ENOTEMPTY errors.
|
||||
if [ -e "${frontend_path}/pnpm-lock.yaml" ] \
|
||||
|| [ -e "${frontend_path}/pnpm-workspace.yaml" ] \
|
||||
|| [ -d "${frontend_path}/node_modules/.pnpm" ]; then
|
||||
echo "ERROR: Stale pnpm artifacts detected in ${frontend_path}."
|
||||
echo "The frontend uses npm (pnpm was dropped; see frontend/README.md)."
|
||||
echo "Clean up with:"
|
||||
echo " cd ${frontend_path} && rm -rf node_modules pnpm-lock.yaml pnpm-workspace.yaml && npm install"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Run `npm install` in the current directory. If it fails (typically from a
|
||||
# corrupted node_modules tree, eg. an interrupted install or a leftover pnpm
|
||||
# layout causing ENOTEMPTY rename errors), wipe node_modules and the nx cache
|
||||
# and retry once before giving up.
|
||||
frontend_npm_install() {
|
||||
if npm install; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "WARNING: npm install failed. node_modules may be corrupted (eg. an"
|
||||
echo "interrupted install or a mixed npm/pnpm tree). Wiping and retrying..."
|
||||
echo ""
|
||||
|
||||
rm -rf node_modules .nx
|
||||
|
||||
if ! npm install; then
|
||||
echo ""
|
||||
echo "ERROR: npm install failed again. See the npm output above and the"
|
||||
echo "troubleshooting section in frontend/README.md."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
Executable
+105
@@ -0,0 +1,105 @@
|
||||
#!/bin/bash
|
||||
|
||||
declare -r entropy=$(xxd -l16 -ps /dev/urandom)
|
||||
|
||||
#declare -r CHROME_DIR="${HOME}/.chromeDevTemp"
|
||||
declare -r chrome_dir="/tmp/chrome/${entropy}"
|
||||
|
||||
# See flags available and documentation:
|
||||
# https://chromium.googlesource.com/chromium/src/+/HEAD/chrome/common/chrome_switches.cc
|
||||
# https://github.com/GoogleChrome/chrome-launcher/blob/main/docs/chrome-flags-for-tools.md
|
||||
# https://peter.sh/experiments/chromium-command-line-switches/
|
||||
|
||||
# Seed the profile with DevTools preferences before Chrome starts.
|
||||
# This sets: dock position = bottom, default panel = network.
|
||||
# Chrome stores these in <user-data-dir>/Default/Preferences.
|
||||
seed_devtools_preferences() {
|
||||
local prefs='{"devtools":{"preferences":{"currentDockState":"\"bottom\"","panel-selected-tab":"\"network\""}}}'
|
||||
|
||||
# Seed both Default and Guest Profile — Chrome uses Guest Profile when
|
||||
# launched with --guest, and Default otherwise.
|
||||
for profile_name in "Default" "Guest Profile"; do
|
||||
local prefs_dir="${chrome_dir}/${profile_name}"
|
||||
mkdir -p "${prefs_dir}"
|
||||
echo "${prefs}" > "${prefs_dir}/Preferences"
|
||||
done
|
||||
}
|
||||
|
||||
# TODO(bt): Math to determine better window placement.
|
||||
|
||||
# Flags reference:
|
||||
# --auto-open-devtools-for-tabs Open DevTools automatically for every tab on launch.
|
||||
# Dock position and default panel are set via seeded
|
||||
# preferences (see seed_devtools_preferences above).
|
||||
# --allow-running-insecure-content Allow HTTPS pages to load HTTP resources (mixed content).
|
||||
# --disable-features=ChromeLabs, Disable Chrome Labs experiments UI and the
|
||||
# DefaultBrowserPrompt feature-flag-based default browser prompt.
|
||||
# --disable-site-isolation-trials Disable site isolation (allows cross-origin iframes
|
||||
# to share process, useful for local dev).
|
||||
# --disable-web-security Disable same-origin policy. Required for local dev
|
||||
# where the frontend talks to a different-origin API.
|
||||
# --ignore-certificate-errors Accept self-signed / invalid TLS certs.
|
||||
# --no-default-browser-check Skip the "set as default browser" check on startup.
|
||||
# --no-first-run Suppress the "Welcome to Google Chrome" first-run
|
||||
# dialog (default browser checkbox, crash reporting, etc.).
|
||||
# --install-autogenerated-theme Set a custom window color so the dev browser is
|
||||
# visually distinct from your normal Chrome.
|
||||
# --unsafely-treat-insecure-origin-as-secure
|
||||
# Treat the given HTTP origin as secure. Required for
|
||||
# APIs like getUserMedia() / navigator.mediaDevices
|
||||
# which need a "secure context".
|
||||
# --user-data-dir Use a throwaway profile directory so dev sessions
|
||||
# don't pollute your real Chrome profile.
|
||||
# --guest (Mac only) Launch in guest mode — no Google login screen.
|
||||
# --window-position / --window-size Place the dev window predictably on screen.
|
||||
|
||||
launch_linux() {
|
||||
seed_devtools_preferences
|
||||
chromium \
|
||||
--auto-open-devtools-for-tabs \
|
||||
--allow-running-insecure-content \
|
||||
--disable-features=ChromeLabs,DefaultBrowserPrompt \
|
||||
--disable-site-isolation-trials \
|
||||
--disable-web-security \
|
||||
--ignore-certificate-errors \
|
||||
--no-default-browser-check \
|
||||
--no-first-run \
|
||||
--install-autogenerated-theme="100,150,255" \
|
||||
--unsafely-treat-insecure-origin-as-secure="http://localhost:5173" \
|
||||
--user-data-dir="${chrome_dir}" \
|
||||
--window-position=1200,300 \
|
||||
--window-size=1500,1700 \
|
||||
http://localhost:5173
|
||||
}
|
||||
|
||||
launch_mac() {
|
||||
seed_devtools_preferences
|
||||
open -na "Google Chrome" --args \
|
||||
--auto-open-devtools-for-tabs \
|
||||
--disable-features=ChromeLabs,DefaultBrowserPrompt \
|
||||
--disable-site-isolation-trials \
|
||||
--disable-web-security \
|
||||
--ignore-certificate-errors \
|
||||
--no-default-browser-check \
|
||||
--no-first-run \
|
||||
--install-autogenerated-theme="100,150,255" \
|
||||
--unsafely-treat-insecure-origin-as-secure="http://localhost:5173" \
|
||||
--user-data-dir="${chrome_dir}" \
|
||||
--window-position=1200,300 \
|
||||
--window-size=1500,1700 \
|
||||
--guest \
|
||||
http://localhost:5173
|
||||
}
|
||||
|
||||
case $OSTYPE in
|
||||
linux*)
|
||||
launch_linux
|
||||
;;
|
||||
darwin*)
|
||||
launch_mac
|
||||
;;
|
||||
*)
|
||||
echo "Unknown OS"
|
||||
;;
|
||||
esac
|
||||
|
||||
Executable
+15
@@ -0,0 +1,15 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -euxo pipefail
|
||||
|
||||
echo 'Looking for unused dependencies'
|
||||
|
||||
# NB(bt,2025-05-26): Previous version was "cargo-udeps 0.1.48"
|
||||
# https://github.com/est31/cargo-udeps
|
||||
# https://stackoverflow.com/a/72082679
|
||||
# Needs nightly to run
|
||||
cargo +nightly udeps --all-targets
|
||||
|
||||
# TODO: Ask for user input before applying some automated heuristics
|
||||
|
||||
echo 'Done.'
|
||||
Executable
+17
@@ -0,0 +1,17 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -euxo pipefail
|
||||
|
||||
echo 'Run cargo check...'
|
||||
|
||||
#RUSTFLAGS=-Awarnings cargo check
|
||||
cargo check
|
||||
|
||||
echo 'Run lints...'
|
||||
./execute_lints.sh
|
||||
|
||||
echo 'Run tests...'
|
||||
./execute_tests.sh
|
||||
|
||||
echo 'All tests and lints passed successfully!'
|
||||
|
||||
Executable
+20
@@ -0,0 +1,20 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -euxo pipefail
|
||||
|
||||
echo 'Running lints...'
|
||||
|
||||
# TODO: 'fakeyou_client' is broken
|
||||
# TODO: 'sqlite_queries' and 'aichatbot-sidecar' are broken due to sqlite
|
||||
# newrelic excluded since we don't author it
|
||||
|
||||
# --no-deps prevents running on path dependencies within workspaces
|
||||
cargo cranky \
|
||||
--no-deps \
|
||||
--workspace \
|
||||
--exclude aichatbot-sidecar \
|
||||
--exclude fakeyou_client \
|
||||
--exclude sqlite_queries \
|
||||
--exclude newrelic-telemetry
|
||||
|
||||
echo 'Lints passed.'
|
||||
Executable
+31
@@ -0,0 +1,31 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -euxo pipefail
|
||||
|
||||
echo 'Running tests...'
|
||||
|
||||
# TODO: Fix 'fakeyou_client' and 'billing_component'
|
||||
# TODO: Run 'sqlite_queries' and 'aichatbot-sidecar' after postgres migrations
|
||||
|
||||
cargo test \
|
||||
--workspace \
|
||||
--exclude aichatbot-sidecar \
|
||||
--exclude billing_component \
|
||||
--exclude fakeyou_client \
|
||||
--exclude inference-job \
|
||||
--exclude mysql_queries \
|
||||
--exclude sqlite_queries
|
||||
|
||||
# Single broken tests
|
||||
cargo test \
|
||||
--package inference-job \
|
||||
-- \
|
||||
--skip util::audiowmark::tests::test_audiowmark \
|
||||
--skip util::common_commands::audiowmark::tests::test_audiowmark
|
||||
|
||||
cargo test \
|
||||
--package mysql_queries \
|
||||
-- \
|
||||
--skip queries::model_weights::tests
|
||||
|
||||
echo 'Tests passed.'
|
||||
Executable
+75
@@ -0,0 +1,75 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Fast, safe cleanup of the cargo ./target directory.
|
||||
#
|
||||
# Why this script exists:
|
||||
# - `rm -rf target` hangs on huge target dirs (millions of small files).
|
||||
# - `rm target/prefix*` blows up the shell glob with too many completions.
|
||||
#
|
||||
# Strategy:
|
||||
# - Resolve target dir relative to the repo root, then sanity-check we're
|
||||
# actually inside it before touching anything.
|
||||
# - Walk the tree with `find -delete` (a single in-process traversal that
|
||||
# unlinks as it goes — much faster than spawning rm per file).
|
||||
# - Stream progress to stdout every N entries so it's clear something is
|
||||
# happening.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# --- locate repo root and target dir -----------------------------------------
|
||||
|
||||
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
||||
REPO_ROOT="$(cd -- "$SCRIPT_DIR/../.." && pwd)"
|
||||
TARGET_DIR="${1:-$REPO_ROOT/target}"
|
||||
|
||||
# --- safety checks -----------------------------------------------------------
|
||||
|
||||
if [[ ! -d "$TARGET_DIR" ]]; then
|
||||
echo "target dir does not exist: $TARGET_DIR"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Resolve to absolute path and refuse anything that doesn't end in /target.
|
||||
TARGET_DIR="$(cd -- "$TARGET_DIR" && pwd)"
|
||||
case "$TARGET_DIR" in
|
||||
*/target) ;;
|
||||
*)
|
||||
echo "refusing to clean a path that doesn't end in /target: $TARGET_DIR"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# Refuse paths suspiciously close to root.
|
||||
if [[ "$TARGET_DIR" == "/target" || "${#TARGET_DIR}" -lt 12 ]]; then
|
||||
echo "refusing to clean suspicious path: $TARGET_DIR"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Cleaning: $TARGET_DIR"
|
||||
START=$(date +%s)
|
||||
|
||||
# --- delete with progress ----------------------------------------------------
|
||||
|
||||
# `find -delete` removes files and (now-empty) directories during traversal.
|
||||
# We pipe -print through awk to emit a progress line every 5000 entries.
|
||||
# Note: -print fires before -delete for files, after for dirs — fine for progress.
|
||||
COUNT=$(
|
||||
find "$TARGET_DIR" -mindepth 1 -print -delete 2>/dev/null \
|
||||
| awk -v start="$START" '
|
||||
{
|
||||
n++
|
||||
if (n % 5000 == 0) {
|
||||
elapsed = systime() - start
|
||||
rate = (elapsed > 0) ? n / elapsed : n
|
||||
printf " deleted %d entries (%.0f/s)\n", n, rate > "/dev/stderr"
|
||||
}
|
||||
}
|
||||
END { print n }
|
||||
'
|
||||
)
|
||||
|
||||
ELAPSED=$(( $(date +%s) - START ))
|
||||
echo "Done. Removed $COUNT entries in ${ELAPSED}s."
|
||||
|
||||
# Recreate empty target/ so cargo doesn't complain on next build.
|
||||
mkdir -p "$TARGET_DIR"
|
||||
@@ -0,0 +1,13 @@
|
||||
# This script is a little rough
|
||||
|
||||
# Step 1
|
||||
cargo sqlx migrate run \
|
||||
--database-url "sqlite:C:\Users\Bombay\AppData\Local\Temp\tasks.sqlite" \
|
||||
--source "C:\Users\Bombay\Documents\GitHub\storyteller-rust\_sql\artcraft_migrations"
|
||||
|
||||
# Step 2
|
||||
Push-Location -Path ".\crates\schema\database\sqlite_tasks"
|
||||
cargo sqlx prepare \
|
||||
--database-url "sqlite:C:\Users\Bombay\AppData\Local\Temp\tasks.sqlite"
|
||||
Pop-Location
|
||||
|
||||
Reference in New Issue
Block a user