Hello from Next.js with Bun!
+Package Manager: Bun
+Framework: Next.js 14 (App Router)
+diff --git a/.gitignore b/.gitignore index 01c8bbf..36345c2 100644 --- a/.gitignore +++ b/.gitignore @@ -36,3 +36,4 @@ tmp/ # Generated migration files (local testing) /migrations/ *.sql +scripts/.cache/ diff --git a/templates/django/config.json b/templates/django/config.json index e9a3ee0..3fdc5ea 100644 --- a/templates/django/config.json +++ b/templates/django/config.json @@ -42,6 +42,7 @@ "options": [ "pip", "poetry", + "uv", "pipenv" ], "type": "select", diff --git a/templates/django/template.tmpl b/templates/django/template.tmpl index 38aa0bb..9e780dd 100644 --- a/templates/django/template.tmpl +++ b/templates/django/template.tmpl @@ -9,6 +9,11 @@ RUN pip install --no-cache-dir --user -r requirements.txt {{ .wsgi_server }} RUN pip install --no-cache-dir poetry COPY pyproject.toml poetry.lock* ./ RUN poetry config virtualenvs.create false && poetry install --only main --no-root && pip install --no-cache-dir {{ .wsgi_server }} +{{ else if eq .dependency_manager "uv" }} +RUN pip install --no-cache-dir uv +COPY pyproject.toml uv.lock* ./ +RUN uv pip install --system --no-cache-dir . && \ + uv pip install --system --no-cache-dir {{ .wsgi_server }} {{ else }} RUN pip install --no-cache-dir pipenv COPY Pipfile Pipfile.lock* ./ diff --git a/templates/expressjs/config.json b/templates/expressjs/config.json index df5af99..127c297 100644 --- a/templates/expressjs/config.json +++ b/templates/expressjs/config.json @@ -35,7 +35,8 @@ "options": [ "npm", "yarn", - "pnpm" + "pnpm", + "bun" ], "type": "select", "category": "required" diff --git a/templates/expressjs/template.tmpl b/templates/expressjs/template.tmpl index 128cb61..e9698a3 100644 --- a/templates/expressjs/template.tmpl +++ b/templates/expressjs/template.tmpl @@ -1,4 +1,8 @@ +{{ if eq .package_manager "bun" }} +FROM oven/bun:1-alpine +{{ else }} FROM node:{{ .node_version }}-alpine +{{ end }} WORKDIR /app @@ -6,9 +10,11 @@ WORKDIR /app COPY package*.json ./ {{ else if eq .package_manager "yarn" }} COPY package.json yarn.lock* ./ -{{ else }} +{{ else if eq .package_manager "pnpm" }} COPY package.json pnpm-lock.yaml* ./ RUN npm install -g pnpm +{{ else }} +COPY package.json bun.lockb* ./ {{ end }} {{ if eq .build_mode "production" }} @@ -16,16 +22,20 @@ RUN npm install -g pnpm RUN npm install --only=production --no-audit --prefer-offline {{ else if eq .package_manager "yarn" }} RUN yarn install --production -{{ else }} +{{ else if eq .package_manager "pnpm" }} RUN pnpm install --prod +{{ else }} +RUN bun install --production {{ end }} {{ else }} {{ if eq .package_manager "npm" }} RUN npm install --no-audit --prefer-offline {{ else if eq .package_manager "yarn" }} RUN yarn install -{{ else }} +{{ else if eq .package_manager "pnpm" }} RUN pnpm install +{{ else }} +RUN bun install {{ end }} {{ end }} @@ -46,5 +56,9 @@ CMD ["pm2-runtime", "start", "{{ .entry_file }}", "--name", "express-app"] {{ else if eq .process_manager "nodemon" }} CMD ["nodemon", "{{ .entry_file }}"] {{ else }} +{{ if eq .package_manager "bun" }} +CMD ["bun", "run", "{{ .entry_file }}"] +{{ else }} CMD ["node", "{{ .entry_file }}"] +{{ end }} {{ end }} \ No newline at end of file diff --git a/templates/fastapi/config.json b/templates/fastapi/config.json index 0fd1132..172122e 100644 --- a/templates/fastapi/config.json +++ b/templates/fastapi/config.json @@ -38,6 +38,7 @@ "options": [ "pip", "poetry", + "uv", "pipenv" ], "type": "select", diff --git a/templates/fastapi/template.tmpl b/templates/fastapi/template.tmpl index 77394df..989d41b 100644 --- a/templates/fastapi/template.tmpl +++ b/templates/fastapi/template.tmpl @@ -9,6 +9,11 @@ RUN pip install --no-cache-dir --user -r requirements.txt {{ .asgi_server }} RUN pip install --no-cache-dir poetry COPY pyproject.toml poetry.lock* ./ RUN poetry config virtualenvs.create false && poetry install --only main --no-root && pip install --no-cache-dir {{ .asgi_server }} +{{ else if eq .dependency_manager "uv" }} +RUN pip install --no-cache-dir uv +COPY pyproject.toml uv.lock* ./ +RUN uv pip install --system --no-cache-dir . && \ + uv pip install --system --no-cache-dir {{ .asgi_server }} {{ else }} RUN pip install --no-cache-dir pipenv COPY Pipfile Pipfile.lock* ./ diff --git a/templates/flask/config.json b/templates/flask/config.json index fe46597..18c8f6a 100644 --- a/templates/flask/config.json +++ b/templates/flask/config.json @@ -42,6 +42,7 @@ "options": [ "pip", "poetry", + "uv", "pipenv" ], "type": "select", diff --git a/templates/flask/template.tmpl b/templates/flask/template.tmpl index 5814574..0faa871 100644 --- a/templates/flask/template.tmpl +++ b/templates/flask/template.tmpl @@ -9,6 +9,11 @@ RUN pip install --no-cache-dir -r requirements.txt {{ .wsgi_server }} RUN pip install --no-cache-dir poetry COPY pyproject.toml poetry.lock* ./ RUN poetry config virtualenvs.create false && poetry install --only main --no-root && pip install --no-cache-dir {{ .wsgi_server }} +{{ else if eq .dependency_manager "uv" }} +RUN pip install --no-cache-dir uv +COPY pyproject.toml uv.lock* ./ +RUN uv pip install --system --no-cache-dir . && \ + uv pip install --system --no-cache-dir {{ .wsgi_server }} {{ else }} RUN pip install --no-cache-dir pipenv COPY Pipfile Pipfile.lock* ./ diff --git a/templates/nestjs/config.json b/templates/nestjs/config.json index 579eb68..c7d1d25 100644 --- a/templates/nestjs/config.json +++ b/templates/nestjs/config.json @@ -35,7 +35,8 @@ "options": [ "npm", "yarn", - "pnpm" + "pnpm", + "bun" ], "type": "select", "category": "required" diff --git a/templates/nestjs/template.tmpl b/templates/nestjs/template.tmpl index 6fc1afa..aba25d9 100644 --- a/templates/nestjs/template.tmpl +++ b/templates/nestjs/template.tmpl @@ -1,4 +1,8 @@ +{{ if eq .package_manager "bun" }} +FROM oven/bun:1-alpine AS builder +{{ else }} FROM node:{{ .node_version }}-alpine AS builder +{{ end }} WORKDIR /app @@ -8,9 +12,12 @@ RUN npm install --no-audit --prefer-offline {{ else if eq .package_manager "yarn" }} COPY package.json yarn.lock* ./ RUN yarn install -{{ else }} +{{ else if eq .package_manager "pnpm" }} COPY package.json pnpm-lock.yaml* ./ RUN npm install -g pnpm && pnpm install +{{ else }} +COPY package.json bun.lockb* ./ +RUN bun install {{ end }} COPY . . @@ -19,11 +26,17 @@ COPY . . RUN npm run build {{ else if eq .package_manager "yarn" }} RUN yarn build -{{ else }} +{{ else if eq .package_manager "pnpm" }} RUN pnpm build +{{ else }} +RUN bun run build {{ end }} +{{ if eq .package_manager "bun" }} +FROM oven/bun:1-alpine +{{ else }} FROM node:{{ .node_version }}-alpine +{{ end }} WORKDIR /app @@ -33,13 +46,20 @@ RUN npm install --only=production --no-audit --prefer-offline {{ else if eq .package_manager "yarn" }} COPY package.json yarn.lock* ./ RUN yarn install --production -{{ else }} +{{ else if eq .package_manager "pnpm" }} COPY package.json pnpm-lock.yaml* ./ RUN npm install -g pnpm && pnpm install --prod +{{ else }} +COPY package.json bun.lockb* ./ +RUN bun install --production {{ end }} COPY --from=builder /app/dist ./dist EXPOSE 3000 -CMD ["node", "dist/main"] \ No newline at end of file +{{ if eq .package_manager "bun" }} +CMD ["bun", "run", "dist/main"] +{{ else }} +CMD ["node", "dist/main"] +{{ end }} \ No newline at end of file diff --git a/templates/nextjs/config.json b/templates/nextjs/config.json index fbb8f9d..7d8039e 100644 --- a/templates/nextjs/config.json +++ b/templates/nextjs/config.json @@ -35,7 +35,8 @@ "options": [ "npm", "yarn", - "pnpm" + "pnpm", + "bun" ], "type": "select", "category": "required" diff --git a/templates/nextjs/template.tmpl b/templates/nextjs/template.tmpl index c5998cb..a1aac0d 100644 --- a/templates/nextjs/template.tmpl +++ b/templates/nextjs/template.tmpl @@ -1,4 +1,8 @@ +{{ if eq .package_manager "bun" }} +FROM oven/bun:1-alpine AS deps +{{ else }} FROM node:{{ .node_version }}-alpine AS deps +{{ end }} WORKDIR /app @@ -8,12 +12,19 @@ RUN npm install --no-audit --prefer-offline {{ else if eq .package_manager "yarn" }} COPY package.json yarn.lock* ./ RUN yarn install -{{ else }} +{{ else if eq .package_manager "pnpm" }} COPY package.json pnpm-lock.yaml* ./ RUN npm install -g pnpm && pnpm install +{{ else }} +COPY package.json bun.lockb* ./ +RUN bun install {{ end }} +{{ if eq .package_manager "bun" }} +FROM oven/bun:1-alpine AS builder +{{ else }} FROM node:{{ .node_version }}-alpine AS builder +{{ end }} WORKDIR /app @@ -30,11 +41,17 @@ RUN mkdir -p public RUN npm run build {{ else if eq .package_manager "yarn" }} RUN yarn build -{{ else }} +{{ else if eq .package_manager "pnpm" }} RUN pnpm build +{{ else }} +RUN bun run build {{ end }} +{{ if eq .package_manager "bun" }} +FROM oven/bun:1-alpine AS runner +{{ else }} FROM node:{{ .node_version }}-alpine AS runner +{{ end }} WORKDIR /app @@ -50,7 +67,7 @@ RUN npm install -g pnpm COPY --from=deps /app/node_modules ./node_modules COPY --from=builder --chown=nextjs:nodejs /app/.next ./.next COPY --from=builder /app/public ./public -COPY --from=builder /app/package.json ./package.json +COPY --from=builder --chown=nextjs:nodejs /app/package.json ./package.json USER nextjs @@ -60,6 +77,8 @@ EXPOSE 3000 CMD ["npm", "start"] {{ else if eq .package_manager "yarn" }} CMD ["yarn", "start"] -{{ else }} +{{ else if eq .package_manager "pnpm" }} CMD ["pnpm", "start"] +{{ else }} +CMD ["bun", "--bun", "run", "start"] {{ end }} \ No newline at end of file diff --git a/templates/react/config.json b/templates/react/config.json index 199452c..ba9cc5c 100644 --- a/templates/react/config.json +++ b/templates/react/config.json @@ -37,7 +37,8 @@ "options": [ "npm", "yarn", - "pnpm" + "pnpm", + "bun" ], "type": "select", "category": "required" diff --git a/templates/react/template.tmpl b/templates/react/template.tmpl index 9138fc8..cce021d 100644 --- a/templates/react/template.tmpl +++ b/templates/react/template.tmpl @@ -1,4 +1,8 @@ +{{ if eq .package_manager "bun" }} +FROM oven/bun:1-alpine AS builder +{{ else }} FROM node:{{ .node_version }}-alpine AS builder +{{ end }} WORKDIR /app @@ -8,9 +12,12 @@ RUN npm install --no-audit --prefer-offline {{ else if eq .package_manager "yarn" }} COPY package.json yarn.lock* ./ RUN yarn install -{{ else }} +{{ else if eq .package_manager "pnpm" }} COPY package.json pnpm-lock.yaml* ./ RUN npm install -g pnpm && pnpm install +{{ else }} +COPY package.json bun.lockb* ./ +RUN bun install {{ end }} COPY . . @@ -19,8 +26,10 @@ COPY . . RUN npm run build {{ else if eq .package_manager "yarn" }} RUN yarn build -{{ else }} +{{ else if eq .package_manager "pnpm" }} RUN pnpm build +{{ else }} +RUN bun run build {{ end }} FROM nginx:alpine diff --git a/templates/vuejs/config.json b/templates/vuejs/config.json index ada0c88..c95321e 100644 --- a/templates/vuejs/config.json +++ b/templates/vuejs/config.json @@ -37,7 +37,8 @@ "options": [ "npm", "yarn", - "pnpm" + "pnpm", + "bun" ], "type": "select", "category": "required" diff --git a/templates/vuejs/template.tmpl b/templates/vuejs/template.tmpl index 05c7a38..2d9ecf8 100644 --- a/templates/vuejs/template.tmpl +++ b/templates/vuejs/template.tmpl @@ -1,4 +1,8 @@ +{{ if eq .package_manager "bun" }} +FROM oven/bun:1-alpine AS builder +{{ else }} FROM node:{{ .node_version }}-alpine AS builder +{{ end }} WORKDIR /app {{ if eq .package_manager "npm" }} @@ -7,9 +11,12 @@ RUN npm install --no-audit --prefer-offline {{ else if eq .package_manager "yarn" }} COPY package.json yarn.lock* ./ RUN yarn install -{{ else }} +{{ else if eq .package_manager "pnpm" }} COPY package.json pnpm-lock.yaml* ./ RUN npm install -g pnpm && pnpm install +{{ else }} +COPY package.json bun.lockb* ./ +RUN bun install {{ end }} COPY . . @@ -18,8 +25,10 @@ COPY . . RUN npm run build {{ else if eq .package_manager "yarn" }} RUN yarn build -{{ else }} +{{ else if eq .package_manager "pnpm" }} RUN pnpm build +{{ else }} +RUN bun run build {{ end }} FROM nginx:alpine diff --git a/test-projects/backend/django-uv/Dockerfile b/test-projects/backend/django-uv/Dockerfile new file mode 100644 index 0000000..47a6989 --- /dev/null +++ b/test-projects/backend/django-uv/Dockerfile @@ -0,0 +1,30 @@ +FROM python:3.12-slim AS builder + +WORKDIR /app + +RUN pip install --no-cache-dir uv +COPY pyproject.toml uv.lock* ./ +RUN uv pip install --system --no-cache-dir . && \ + uv pip install --system --no-cache-dir gunicorn + +FROM python:3.12-slim + +WORKDIR /app + +COPY --from=builder /usr/local/lib /usr/local/lib +COPY --from=builder /usr/local/bin /usr/local/bin + +COPY . . + +ENV DJANGO_SETTINGS_MODULE=config.settings +RUN python manage.py collectstatic --noinput || echo "Warning: collectstatic failed, continuing..." + +RUN addgroup --system --gid 1001 app && \ + adduser --system --uid 1001 --gid 1001 app && \ + chown -R app:app /app + +USER app + +EXPOSE 8000 + +CMD ["gunicorn", "--bind", "0.0.0.0:8000", "--workers", "4", "config.wsgi"] diff --git a/test-projects/backend/django-uv/config/__init__.py b/test-projects/backend/django-uv/config/__init__.py new file mode 100644 index 0000000..233c831 --- /dev/null +++ b/test-projects/backend/django-uv/config/__init__.py @@ -0,0 +1 @@ +# Django configuration package diff --git a/test-projects/backend/django-uv/config/settings.py b/test-projects/backend/django-uv/config/settings.py new file mode 100644 index 0000000..55a5b2f --- /dev/null +++ b/test-projects/backend/django-uv/config/settings.py @@ -0,0 +1,58 @@ +""" +Django settings for django-uv-test project. +""" + +from pathlib import Path + +BASE_DIR = Path(__file__).resolve().parent.parent + +SECRET_KEY = 'django-insecure-test-key-for-uv-template-testing-only' + +DEBUG = True + +ALLOWED_HOSTS = ['*'] + +INSTALLED_APPS = [ + 'django.contrib.contenttypes', + 'django.contrib.staticfiles', +] + +MIDDLEWARE = [ + 'django.middleware.security.SecurityMiddleware', + 'django.middleware.common.CommonMiddleware', +] + +ROOT_URLCONF = 'config.urls' + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.debug', + 'django.template.context_processors.request', + ], + }, + }, +] + +WSGI_APPLICATION = 'config.wsgi.application' + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': BASE_DIR / 'db.sqlite3', + } +} + +LANGUAGE_CODE = 'en-us' +TIME_ZONE = 'UTC' +USE_I18N = True +USE_TZ = True + +STATIC_URL = 'static/' +STATIC_ROOT = BASE_DIR / 'staticfiles' + +DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' diff --git a/test-projects/backend/django-uv/config/urls.py b/test-projects/backend/django-uv/config/urls.py new file mode 100644 index 0000000..cc845e6 --- /dev/null +++ b/test-projects/backend/django-uv/config/urls.py @@ -0,0 +1,19 @@ +""" +URL configuration for django-uv-test project. +""" +from django.http import JsonResponse +from django.urls import path + + +def hello_world(request): + return JsonResponse({ + 'message': 'Hello from Django with uv!', + 'dependency_manager': 'uv', + 'framework': 'Django' + }) + + +urlpatterns = [ + path('', hello_world), + path('health/', hello_world), +] diff --git a/test-projects/backend/django-uv/config/wsgi.py b/test-projects/backend/django-uv/config/wsgi.py new file mode 100644 index 0000000..409fc63 --- /dev/null +++ b/test-projects/backend/django-uv/config/wsgi.py @@ -0,0 +1,11 @@ +""" +WSGI config for django-uv-test project. +""" + +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings') + +application = get_wsgi_application() diff --git a/test-projects/backend/django-uv/manage.py b/test-projects/backend/django-uv/manage.py new file mode 100644 index 0000000..8e7ac79 --- /dev/null +++ b/test-projects/backend/django-uv/manage.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python +"""Django's command-line utility for administrative tasks.""" +import os +import sys + + +def main(): + """Run administrative tasks.""" + os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings') + try: + from django.core.management import execute_from_command_line + except ImportError as exc: + raise ImportError( + "Couldn't import Django. Are you sure it's installed and " + "available on your PYTHONPATH environment variable? Did you " + "forget to activate a virtual environment?" + ) from exc + execute_from_command_line(sys.argv) + + +if __name__ == '__main__': + main() diff --git a/test-projects/backend/django-uv/pyproject.toml b/test-projects/backend/django-uv/pyproject.toml new file mode 100644 index 0000000..c77fc18 --- /dev/null +++ b/test-projects/backend/django-uv/pyproject.toml @@ -0,0 +1,8 @@ +[project] +name = "django-uv-test" +version = "0.1.0" +description = "Django test project with uv dependency manager" +requires-python = ">=3.12" +dependencies = [ + "django>=5.0,<6.0", +] diff --git a/test-projects/backend/expressjs-bun-prod-none/Dockerfile b/test-projects/backend/expressjs-bun-prod-none/Dockerfile new file mode 100644 index 0000000..847dab9 --- /dev/null +++ b/test-projects/backend/expressjs-bun-prod-none/Dockerfile @@ -0,0 +1,15 @@ +FROM oven/bun:1-alpine + +WORKDIR /app + +COPY package.json bun.lockb* ./ + +RUN bun install + +COPY . . + +ENV NODE_ENV=production + +EXPOSE 3000 + +CMD ["bun", "run", "index.js"] diff --git a/test-projects/backend/expressjs-bun-prod-none/index.js b/test-projects/backend/expressjs-bun-prod-none/index.js new file mode 100644 index 0000000..5d0b65f --- /dev/null +++ b/test-projects/backend/expressjs-bun-prod-none/index.js @@ -0,0 +1,21 @@ +import express from 'express'; + +const app = express(); +const PORT = process.env.PORT || 3000; + +app.get('/', (req, res) => { + res.json({ + message: 'Hello from Express.js with Bun!', + package_manager: 'bun', + framework: 'Express.js', + runtime: 'Bun' + }); +}); + +app.get('/health', (req, res) => { + res.json({ status: 'healthy' }); +}); + +app.listen(PORT, () => { + console.log(`Server running on port ${PORT}`); +}); diff --git a/test-projects/backend/expressjs-bun-prod-none/package.json b/test-projects/backend/expressjs-bun-prod-none/package.json new file mode 100644 index 0000000..8861613 --- /dev/null +++ b/test-projects/backend/expressjs-bun-prod-none/package.json @@ -0,0 +1,12 @@ +{ + "name": "expressjs-bun-test", + "version": "0.1.0", + "type": "module", + "scripts": { + "start": "bun run index.js", + "dev": "bun run --watch index.js" + }, + "dependencies": { + "express": "^4.18.0" + } +} diff --git a/test-projects/backend/fastapi-uv/Dockerfile b/test-projects/backend/fastapi-uv/Dockerfile new file mode 100644 index 0000000..c029d09 --- /dev/null +++ b/test-projects/backend/fastapi-uv/Dockerfile @@ -0,0 +1,28 @@ +FROM python:3.12-slim AS builder + +WORKDIR /app + +RUN pip install --no-cache-dir uv +COPY pyproject.toml uv.lock* ./ +RUN uv pip install --system --no-cache-dir . && \ + uv pip install --system --no-cache-dir uvicorn + +FROM python:3.12-slim + +WORKDIR /app + +RUN addgroup --system --gid 1001 app && \ + adduser --system --uid 1001 --gid 1001 app + +COPY --from=builder /usr/local/lib /usr/local/lib +COPY --from=builder /usr/local/bin /usr/local/bin + +COPY . . + +RUN chown -R app:app /app + +USER app + +EXPOSE 8000 + +CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000", "--workers", "4"] diff --git a/test-projects/backend/fastapi-uv/main.py b/test-projects/backend/fastapi-uv/main.py new file mode 100644 index 0000000..a0cee3b --- /dev/null +++ b/test-projects/backend/fastapi-uv/main.py @@ -0,0 +1,20 @@ +""" +FastAPI test application with uv dependency manager +""" +from fastapi import FastAPI + +app = FastAPI(title="FastAPI uv Test") + + +@app.get("/") +async def root(): + return { + "message": "Hello from FastAPI with uv!", + "dependency_manager": "uv", + "framework": "FastAPI" + } + + +@app.get("/health") +async def health(): + return {"status": "healthy"} diff --git a/test-projects/backend/fastapi-uv/pyproject.toml b/test-projects/backend/fastapi-uv/pyproject.toml new file mode 100644 index 0000000..9305726 --- /dev/null +++ b/test-projects/backend/fastapi-uv/pyproject.toml @@ -0,0 +1,8 @@ +[project] +name = "fastapi-uv-test" +version = "0.1.0" +description = "FastAPI test project with uv dependency manager" +requires-python = ">=3.12" +dependencies = [ + "fastapi>=0.100.0", +] diff --git a/test-projects/backend/flask-uv/Dockerfile b/test-projects/backend/flask-uv/Dockerfile new file mode 100644 index 0000000..ad9c654 --- /dev/null +++ b/test-projects/backend/flask-uv/Dockerfile @@ -0,0 +1,20 @@ +FROM python:3.12-slim + +WORKDIR /app + +RUN pip install --no-cache-dir uv +COPY pyproject.toml uv.lock* ./ +RUN uv pip install --system --no-cache-dir . && \ + uv pip install --system --no-cache-dir gunicorn + +COPY . . + +RUN addgroup --system --gid 1001 app && \ + adduser --system --uid 1001 --gid 1001 app && \ + chown -R app:app /app + +USER app + +EXPOSE 8000 + +CMD ["gunicorn", "--bind", "0.0.0.0:8000", "--workers", "4", "app:app"] diff --git a/test-projects/backend/flask-uv/app.py b/test-projects/backend/flask-uv/app.py new file mode 100644 index 0000000..7037f7f --- /dev/null +++ b/test-projects/backend/flask-uv/app.py @@ -0,0 +1,24 @@ +""" +Flask test application with uv dependency manager +""" +from flask import Flask, jsonify + +app = Flask(__name__) + + +@app.route('/') +def hello(): + return jsonify({ + 'message': 'Hello from Flask with uv!', + 'dependency_manager': 'uv', + 'framework': 'Flask' + }) + + +@app.route('/health') +def health(): + return jsonify({'status': 'healthy'}) + + +if __name__ == '__main__': + app.run(host='0.0.0.0', port=5000) diff --git a/test-projects/backend/flask-uv/pyproject.toml b/test-projects/backend/flask-uv/pyproject.toml new file mode 100644 index 0000000..9ea8893 --- /dev/null +++ b/test-projects/backend/flask-uv/pyproject.toml @@ -0,0 +1,8 @@ +[project] +name = "flask-uv-test" +version = "0.1.0" +description = "Flask test project with uv dependency manager" +requires-python = ">=3.12" +dependencies = [ + "flask>=3.0.0", +] diff --git a/test-projects/backend/nestjs-bun/Dockerfile b/test-projects/backend/nestjs-bun/Dockerfile new file mode 100644 index 0000000..e5e2476 --- /dev/null +++ b/test-projects/backend/nestjs-bun/Dockerfile @@ -0,0 +1,23 @@ +FROM oven/bun:1-alpine AS builder + +WORKDIR /app + +COPY package.json bun.lockb* ./ +RUN bun install + +COPY . . + +RUN bun run build + +FROM oven/bun:1-alpine + +WORKDIR /app + +COPY package.json bun.lockb* ./ +RUN bun install --production + +COPY --from=builder /app/dist ./dist + +EXPOSE 3000 + +CMD ["bun", "run", "dist/main"] diff --git a/test-projects/backend/nestjs-bun/nest-cli.json b/test-projects/backend/nestjs-bun/nest-cli.json new file mode 100644 index 0000000..f9aa683 --- /dev/null +++ b/test-projects/backend/nestjs-bun/nest-cli.json @@ -0,0 +1,8 @@ +{ + "$schema": "https://json.schemastore.org/nest-cli", + "collection": "@nestjs/schematics", + "sourceRoot": "src", + "compilerOptions": { + "deleteOutDir": true + } +} diff --git a/test-projects/backend/nestjs-bun/package.json b/test-projects/backend/nestjs-bun/package.json new file mode 100644 index 0000000..318511c --- /dev/null +++ b/test-projects/backend/nestjs-bun/package.json @@ -0,0 +1,23 @@ +{ + "name": "nestjs-bun-test", + "version": "0.1.0", + "scripts": { + "build": "nest build", + "start": "node dist/main", + "start:dev": "nest start --watch" + }, + "dependencies": { + "@nestjs/common": "^10.0.0", + "@nestjs/core": "^10.0.0", + "@nestjs/platform-express": "^10.0.0", + "reflect-metadata": "^0.1.13", + "rxjs": "^7.8.0" + }, + "devDependencies": { + "@nestjs/cli": "^10.0.0", + "@nestjs/schematics": "^10.0.0", + "@types/express": "^4.17.0", + "@types/node": "^20.0.0", + "typescript": "^5.0.0" + } +} diff --git a/test-projects/backend/nestjs-bun/src/app.controller.ts b/test-projects/backend/nestjs-bun/src/app.controller.ts new file mode 100644 index 0000000..b698b3e --- /dev/null +++ b/test-projects/backend/nestjs-bun/src/app.controller.ts @@ -0,0 +1,17 @@ +import { Controller, Get } from '@nestjs/common'; +import { AppService } from './app.service'; + +@Controller() +export class AppController { + constructor(private readonly appService: AppService) {} + + @Get() + getHello() { + return this.appService.getHello(); + } + + @Get('health') + getHealth() { + return { status: 'healthy' }; + } +} diff --git a/test-projects/backend/nestjs-bun/src/app.module.ts b/test-projects/backend/nestjs-bun/src/app.module.ts new file mode 100644 index 0000000..8662803 --- /dev/null +++ b/test-projects/backend/nestjs-bun/src/app.module.ts @@ -0,0 +1,10 @@ +import { Module } from '@nestjs/common'; +import { AppController } from './app.controller'; +import { AppService } from './app.service'; + +@Module({ + imports: [], + controllers: [AppController], + providers: [AppService], +}) +export class AppModule {} diff --git a/test-projects/backend/nestjs-bun/src/app.service.ts b/test-projects/backend/nestjs-bun/src/app.service.ts new file mode 100644 index 0000000..9635b05 --- /dev/null +++ b/test-projects/backend/nestjs-bun/src/app.service.ts @@ -0,0 +1,12 @@ +import { Injectable } from '@nestjs/common'; + +@Injectable() +export class AppService { + getHello() { + return { + message: 'Hello from NestJS with Bun!', + package_manager: 'bun', + framework: 'NestJS', + }; + } +} diff --git a/test-projects/backend/nestjs-bun/src/main.ts b/test-projects/backend/nestjs-bun/src/main.ts new file mode 100644 index 0000000..a913660 --- /dev/null +++ b/test-projects/backend/nestjs-bun/src/main.ts @@ -0,0 +1,9 @@ +import { NestFactory } from '@nestjs/core'; +import { AppModule } from './app.module'; + +async function bootstrap() { + const app = await NestFactory.create(AppModule); + await app.listen(3000); + console.log('NestJS application with Bun is running on port 3000'); +} +bootstrap(); diff --git a/test-projects/backend/nestjs-bun/tsconfig.json b/test-projects/backend/nestjs-bun/tsconfig.json new file mode 100644 index 0000000..95f5641 --- /dev/null +++ b/test-projects/backend/nestjs-bun/tsconfig.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + "module": "commonjs", + "declaration": true, + "removeComments": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "allowSyntheticDefaultImports": true, + "target": "ES2021", + "sourceMap": true, + "outDir": "./dist", + "baseUrl": "./", + "incremental": true, + "skipLibCheck": true, + "strictNullChecks": false, + "noImplicitAny": false, + "strictBindCallApply": false, + "forceConsistentCasingInFileNames": false, + "noFallthroughCasesInSwitch": false + } +} diff --git a/test-projects/frontend/nextjs-bun/Dockerfile b/test-projects/frontend/nextjs-bun/Dockerfile new file mode 100644 index 0000000..8afc383 --- /dev/null +++ b/test-projects/frontend/nextjs-bun/Dockerfile @@ -0,0 +1,37 @@ +FROM oven/bun:1-alpine AS deps + +WORKDIR /app + +COPY package.json bun.lockb* ./ +RUN bun install + +FROM oven/bun:1-alpine AS builder + +WORKDIR /app + +COPY --from=deps /app/node_modules ./node_modules +COPY . . + +RUN mkdir -p public + +RUN bun run build + +FROM oven/bun:1-alpine AS runner + +WORKDIR /app + +ENV NODE_ENV=production + +RUN addgroup --system --gid 1001 nodejs && \ + adduser --system --uid 1001 nextjs + +COPY --from=deps /app/node_modules ./node_modules +COPY --from=builder --chown=nextjs:nodejs /app/.next ./.next +COPY --from=builder /app/public ./public +COPY --from=builder --chown=nextjs:nodejs /app/package.json ./package.json + +USER nextjs + +EXPOSE 3000 + +CMD ["bun", "--bun", "run", "start"] diff --git a/test-projects/frontend/nextjs-bun/app/layout.tsx b/test-projects/frontend/nextjs-bun/app/layout.tsx new file mode 100644 index 0000000..d295378 --- /dev/null +++ b/test-projects/frontend/nextjs-bun/app/layout.tsx @@ -0,0 +1,16 @@ +export const metadata = { + title: 'Next.js Bun Test', + description: 'Testing Next.js with Bun package manager', +}; + +export default function RootLayout({ + children, +}: { + children: React.ReactNode; +}) { + return ( + +
{children} + + ); +} diff --git a/test-projects/frontend/nextjs-bun/app/page.tsx b/test-projects/frontend/nextjs-bun/app/page.tsx new file mode 100644 index 0000000..02fc6b6 --- /dev/null +++ b/test-projects/frontend/nextjs-bun/app/page.tsx @@ -0,0 +1,9 @@ +export default function Home() { + return ( +Package Manager: Bun
+Framework: Next.js 14 (App Router)
+Package Manager: Bun
+Framework: React 18 + Vite
+Package Manager: Bun
+Framework: Vue.js 3 + Vite
+