From 52f36e0483e7cb031280bdb9d9ae00feb8da3f09 Mon Sep 17 00:00:00 2001 From: mmcardle Date: Mon, 14 Nov 2022 20:49:51 +0000 Subject: [PATCH] Cli rendering (#170) * WIP with dummy data * Vite/Node loading static files * CLI with dummy data * Project json parsing * Github action test * Update Tests * Wait for curl * Update readme Co-authored-by: mmcardle --- .github/workflows/ci.yml | 9 + .gitignore | 4 +- README.md | 22 ++ bin/django-builder | 4 + example-project.json | 35 ++ package.json | 6 +- script/run.sh | 24 ++ src/cli.js | 133 +++++++ src/components/DirectoryView.vue | 6 +- src/components/Project.vue | 5 +- src/django/python/urls.py | 3 +- src/django/rendering.js | 330 +++++++++++----- src/store.js | 2 +- src/tar/index.js | 4 + yarn.lock | 655 +++++++++++++++---------------- 15 files changed, 797 insertions(+), 445 deletions(-) create mode 100755 bin/django-builder create mode 100644 example-project.json create mode 100755 script/run.sh create mode 100644 src/cli.js diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index baae687..1cd1c4a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,6 +41,15 @@ jobs: - run: yarn - run: yarn test:unit + cli_tests: + name: CLI Tests + needs: [build] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - run: yarn + - run: script/run.sh + e2e_tests: name: E2E Tests needs: [build] diff --git a/.gitignore b/.gitignore index 2e6ebb7..97b13c3 100644 --- a/.gitignore +++ b/.gitignore @@ -40,4 +40,6 @@ coverage/ # Build if changed .bic_cache -**/.venv \ No newline at end of file +**/.venv +DjangoProject/ +output.tar \ No newline at end of file diff --git a/README.md b/README.md index 5206153..0cc5c2d 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,28 @@ http://mmcardle.github.io/django_builder/ yarn install ``` +### CLI interface + +You can create and run a basic Django project from the command line + +See [example-project.json](example-project.json) + +``` +./bin/django-builder example-project.json DjangoProject.tar + +tar -xvf DjangoProject.tar + +cd DjangoProject +python3 -m venv .venv +source .venv/bin/activate +pip install -r requirements.txt +python manage.py makemigrations +python manage.py migrate +python manage.py runserver +``` + +Head to http://127.0.0.1:8000 + #### Firebase ``` npm install -g firebase-tools diff --git a/bin/django-builder b/bin/django-builder new file mode 100755 index 0000000..329027e --- /dev/null +++ b/bin/django-builder @@ -0,0 +1,4 @@ +#!/usr/bin/env node + +require = require('esm')(module /*, options*/); +require('../src/cli').cli(process.argv); diff --git a/example-project.json b/example-project.json new file mode 100644 index 0000000..e7a8b56 --- /dev/null +++ b/example-project.json @@ -0,0 +1,35 @@ +{ + "name": "DjangoProject", + "description": "A Django Project with great potential", + "htmx": false, + "apps": [ + { + "name": "DjangoApp1", + "models": [ + { + "name":"DjangoModel1", + "fields": [ + { + "name": "field1", + "type": "CharField", + "args": "max_length=30" + }, + { + "name": "field2", + "type": "TextField", + "args": "max_length=100" + } + ], + "relationships": [ + { + "name": "relationship1", + "type": "django.db.models.ForeignKey", + "to": "django.contrib.auth.models.User", + "args": "on_delete=models.CASCADE" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/package.json b/package.json index f2ebf15..a33e63a 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,9 @@ "name": "djangobuilder", "version": "0.1.0", "private": true, + "bin": { + "django-builder": "bin/django-builder" + }, "scripts": { "dev": "vite --port 8080", "build": "vite build", @@ -18,6 +21,7 @@ "ci": "start-server-and-test test:e2e_serve http://localhost:8082 test:e2e" }, "dependencies": { + "esm": "^3.2.25", "firebase": "^9.1.0", "firebase-tools": "^9.19.0", "highlight.js": "^11.2.0", @@ -81,7 +85,7 @@ "no-console": "off", "no-empty-pattern": "error", "no-unused-vars": [ - "error", + "off", { "vars": "all", "args": "after-used", diff --git a/script/run.sh b/script/run.sh new file mode 100755 index 0000000..48b1bd8 --- /dev/null +++ b/script/run.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +set -ex + +./bin/django-builder example-project.json output.tar + +tar -xvf output.tar + +cd DjangoProject +python3 -m venv .venv +source .venv/bin/activate +pip install -r requirements.txt +python manage.py makemigrations +python manage.py migrate +python manage.py runserver & +ID=$! +curl --connect-timeout 5 \ + --retry-connrefused \ + --max-time 5 \ + --retry 5 \ + --retry-delay 2 \ + --retry-max-time 60 \ + 'http://127.0.0.1:8000' +kill ${ID} \ No newline at end of file diff --git a/src/cli.js b/src/cli.js new file mode 100644 index 0000000..0b37093 --- /dev/null +++ b/src/cli.js @@ -0,0 +1,133 @@ +import Renderer from "./django/rendering" +import fs from 'fs'; +import { logger } from "firebase-tools"; + +class Colors { + static Reset = "\x1b[0m"; + static Bright = "\x1b[1m" + static Dim = "\x1b[2m" + static Underscore = "\x1b[4m" + static Blink = "\x1b[5m" + static Reverse = "\x1b[7m" + static Hidden = "\x1b[8m" + + static FgBlack = "\x1b[30m" + static FgRed = "\x1b[31m" + static FgGreen = "\x1b[32m" + static FgYellow = "\x1b[33m" + static FgBlue = "\x1b[34m" + static FgMagenta = "\x1b[35m" + static FgCyan = "\x1b[36m" + static FgWhite = "\x1b[37m" + + static BgBlack = "\x1b[40m" + static BgRed = "\x1b[41m" + static BgGreen = "\x1b[42m" + static BgYellow = "\x1b[43m" + static BgBlue = "\x1b[44m" + static BgMagenta = "\x1b[45m" + static BgCyan = "\x1b[46m" + static BgWhite = "\x1b[47m" +} + + +function project_data_to_store(project_data) { + + const apps = project_data.apps; + + const appData = {}; + const modelData = {}; + const fields = {}; + const relationships = {}; + + apps.forEach((app, i) => { + const singleAppData = { + name: app.name, + models: {} + } + Object.assign(appData, { [`${i}`]: singleAppData}); + + app.models.forEach((model, i) => { + const singleModelData = { + ...model, + parents: model.parents || [], + fields: {}, + relationships: {}, + } + singleAppData.models[`${model.name}`] = true + + Object.assign(modelData, { [`${model.name}`]: singleModelData}); + + model.fields.forEach((field, i) => { + const singleFieldData = { + data: () => { + return { + ...field, + args: field.args || "", + } + }, + } + Object.assign(fields, { [`${field.name}`]: singleFieldData}); + singleModelData.fields[`${field.name}`] = true + }) + + model.relationships.forEach((relationship, i) => { + const singleRelationshipData = { + data: () => { + return { + ...relationship, + to: relationship.to, + } + }, + } + Object.assign(relationships, { [`${relationship.name}`]: singleRelationshipData}); + singleModelData.relationships[`${relationship.name}`] = true + }) + + }) + + }) + + const projectData = { + ...project_data, + apps: apps.map((_, i) => { return { [`${i}`]: true} }), + } + + return { + getters: { + projectData: () => projectData, + appData: (app_id) => appData[app_id], + modelData: (model_id) => modelData[model_id], + fields: () => fields, + relationships: () => relationships, + ordered_models: () => { + return Object.values(modelData) + } + } + } +} + +export function cli(args) { + if (args.length != 4){ + console.error(`${Colors.FgRed}Please supply an input json file and output tar file.${Colors.Reset}`) + console.error(`${Colors.FgRed}Usage: ./bin/django-builder example-project.json output.tar.${Colors.Reset}`) + return + } + + const input_file = args[2]; + const output_file = args[3]; + + let rawdata = fs.readFileSync(input_file); + let project_json = JSON.parse(rawdata); + + const store = project_data_to_store(project_json) + const renderer = new Renderer(store); + const tar_content = renderer.tarball_content() + + try { + fs.writeFileSync(output_file, tar_content); + console.log(`${Colors.FgGreen}File written to ${output_file} ${Colors.Reset}`); //cyan + } catch (err) { + console.error(err); + } +} \ No newline at end of file diff --git a/src/components/DirectoryView.vue b/src/components/DirectoryView.vue index a0e52b4..6e247b6 100644 --- a/src/components/DirectoryView.vue +++ b/src/components/DirectoryView.vue @@ -97,10 +97,10 @@