Skip to content

Commit cbeb7c8

Browse files
committedMar 8, 2023
Add corgi script and leashed mode
1 parent 4e10704 commit cbeb7c8

8 files changed

+211
-36
lines changed
 

‎README.md

+63-15
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,40 @@ The full explanation of Enki it is out of scope for this documentation. To learn
4848
> After installing Docker, navigate to the Docker Desktop GUI preferences and increase the `Memory` value to at least `8GiB`.
4949
> [Here's where you can find the Docker Desktop GUI settings](https://docs.docker.com/docker-for-windows/#resources)
5050
51-
### Local development
51+
52+
53+
## Local development
54+
55+
**General Workflow**
56+
1. Start stack with or without GitHub OAuth (see below)
57+
1. Visit http://localhost/ to see the frontend
58+
1. Make modifications
59+
1. Wait for automatic reload
60+
61+
**NOTE**: You might get 502 when visiting http://localhost/ at first: this is normal. Wait a few seconds and try again.
62+
63+
### GitHub OAuth Disabled (Leashed Mode)
64+
65+
To start corgi without GitHub OAuth, in the project root directory, run:
66+
67+
```bash
68+
./corgi start-leashed
69+
```
70+
71+
or
72+
73+
```bash
74+
./corgi start
75+
```
76+
77+
78+
In leashed mode, corgi only uses data that is stored locally.
79+
80+
Currently, that data is stored in `backend/app/tests/unit/data`.
81+
82+
**NOTE:** By default, you will only be able to use `tiny-book` as the repository and `book-slug1` as the book when queuing jobs. This data can be updated: see [Run backend unit tests](#run-backend-unit-tests) for more information.
83+
84+
### GitHub OAuth Enabled
5285

5386
**Prerequisites**
5487
* You will need access to a GitHub OAuth app. You can [create your own](https://docs.github.com/en/developers/apps/building-oauth-apps/creating-an-oauth-app) if you do not have one already.
@@ -57,9 +90,11 @@ The full explanation of Enki it is out of scope for this documentation. To learn
5790
2. `GITHUB_OAUTH_SECRET` (your oauth app client secret)
5891
3. `SESSION_SECRET` (secret used to encrypt session cookies)
5992

60-
Build/start the stack with Docker Compose:
93+
Build/start the stack with the Corgi script:
6194

62-
docker-compose -f docker-compose.stack.dev.yml up -d
95+
```bash
96+
./corgi start-dev
97+
```
6398

6499
View the API Docs here:
65100

@@ -68,15 +103,20 @@ View the API Docs here:
68103

69104
To check the logs run:
70105

71-
docker-compose logs backend/frontend/etc.
106+
```bash
107+
./corgi logs backend/frontend/etc.
108+
```
109+
110+
### Functions Patched in Leashed Mode
72111

112+
Leashed mode attempts to patch any `app.github.api` function functions starting with "get_". It looks for the associated mock functions in `backend/app/tests/unit/init_test_data.py`.
113+
114+
### Hot Reloading
73115

74116
Using the development stack, the Svelte frontend is rebuilt inside the container
75117
as you make changes: no restarts required. The page should reload automatically
76-
as well.
77-
78-
NOTE: The dev frontend server can take a while to start up. You might get 502
79-
responses at first: this is normal. Wait a few seconds and try again.
118+
as well. The same is true for the backend: as you make modifications, the
119+
backend server should reload with your latest changes.
80120

81121

82122
### View the Docs
@@ -119,19 +159,25 @@ Note: Can be done in container or outside the container, with installed requirem
119159

120160
To run unit tests:
121161

122-
cd backend/app
123-
poetry run pytest tests/unit
162+
```bash
163+
cd backend/app
164+
poetry run pytest tests/unit
165+
```
124166

125-
The unit tests use vcr to store response from GitHub. To initialize test data:
167+
The unit tests use vcr to store response from GitHub. To update the test data:
126168

127-
cd backend/app
128-
poetry run pytest tests/unit --init-test-data --github-token "<token>"
169+
```bash
170+
cd backend/app
171+
poetry run pytest tests/unit --init-test-data --github-token "<token>"
172+
```
129173

130174
### Run integration and UI tests
131175

132176
To run the tests execute:
133177

134-
./scripts/tests.ci.sh
178+
```bash
179+
./scripts/tests.ci.sh
180+
```
135181

136182
### How to develop UI tests
137183

@@ -143,7 +189,9 @@ In the [./scripts/tests.ci.local](./scripts/tests.ci.local) file comment out the
143189

144190
In order to view the browser first list all the containers for the docker-stack.yml file:
145191

146-
$ docker-compose -f docker-stack.yml ps
192+
```bash
193+
docker-compose -f docker-stack.yml ps
194+
```
147195

148196
A table will be displayed with column names. Find the one labeled PORTS for the backend-tests container.
149197

‎backend/app/app/leashed.py

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import logging
2+
3+
from fastapi.responses import RedirectResponse
4+
5+
6+
def get_server():
7+
from app.main import server
8+
9+
return server
10+
11+
12+
logger = logging.getLogger("uvicorn")
13+
14+
15+
def patch_github_api():
16+
import app.github
17+
import app.github.api
18+
import tests.unit.init_test_data
19+
20+
github_getters = [s for s in dir(app.github.api) if s.startswith("get_")]
21+
mock_map = []
22+
for getter in github_getters:
23+
mock_function = getattr(
24+
tests.unit.init_test_data, f"mock_{getter}", None
25+
)
26+
if mock_function is None:
27+
logger.warn(
28+
f"Missing mock function for {getter}. "
29+
"This is probably fine, but I thought you should know."
30+
)
31+
else:
32+
mock_map.append((getter, mock_function))
33+
34+
for module in (app.github.api, app.github):
35+
for getter, mock_function in mock_map:
36+
setattr(module, getter, mock_function)
37+
38+
39+
def disable_auth():
40+
import app.api.endpoints.auth
41+
import app.core.auth
42+
43+
class MockOAuth:
44+
async def authorize_redirect(self, _, redirect_uri):
45+
return RedirectResponse(redirect_uri)
46+
47+
async def authorize_access_token(self, *_):
48+
from uuid import uuid4
49+
50+
return {"access_token": str(uuid4())}
51+
52+
async def nop(*_args, **_kwargs):
53+
pass
54+
55+
app.api.endpoints.auth.github_oauth = MockOAuth()
56+
app.api.endpoints.auth.sync_user_repositories = nop
57+
58+
59+
patch_github_api()
60+
disable_auth()
61+
62+
# Delay the loading of the server module until after everything is patched
63+
server = get_server()

‎backend/app/bin/live-reload.sh

+4-1
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,7 @@
22

33
cd /app/app || exit
44

5-
uvicorn main:server --host 0.0.0.0 --port 80 --debug
5+
MODULE_NAME=${MODULE_NAME:-main}
6+
CALLABLE_NAME=${CALLABLE_NAME:-server}
7+
8+
uvicorn "${MODULE_NAME}:${CALLABLE_NAME}" --host 0.0.0.0 --port 80 --debug

‎backend/app/bin/prestart-leashed.sh

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#! /usr/bin/env bash
2+
3+
# Let the DB start
4+
python ./bin/db_wait.py
5+
6+
# Run migrations
7+
alembic upgrade head
8+
9+
export MODULE_NAME=leashed
10+
11+
# shellcheck source=SCRIPTDIR/live-reload.sh
12+
source ./bin/live-reload.sh

‎backend/backend.dockerfile

-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ COPY ./docker/start.sh /start.sh
5454
RUN chmod +x /start.sh
5555

5656
COPY ./docker/gunicorn.conf /gunicorn.conf
57-
RUN echo "reload = True" >> /gunicorn.conf
5857

5958
COPY ./app /app
6059
WORKDIR /app

‎corgi

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#!/usr/bin/env bash
2+
3+
set -eo pipefail
4+
5+
log() {
6+
echo $* >&2
7+
}
8+
9+
die() {
10+
log $*
11+
exit 1
12+
}
13+
14+
usage() {
15+
cat <<EOF
16+
Manage your local corgi stack
17+
Usage:
18+
19+
corgi <COMMAND>
20+
21+
The commands are:
22+
start Alias for start-leashed
23+
start-dev Start corgi in dev mode (requires oauth app, see README
24+
for more details)
25+
start-leashed Start corgi in leashed mode (uses mocked GitHub API)
26+
logs See logs (supports same options as docker-compose logs)
27+
stop Stop corgi
28+
29+
EOF
30+
31+
if [[ -n "$1" ]]; then
32+
log $*
33+
fi
34+
exit 1
35+
}
36+
37+
COMMAND="$1"
38+
[[ -n "$COMMAND" ]] || usage
39+
shift
40+
41+
42+
here="$(cd "$(dirname "$0")" && pwd)"
43+
dev_stack="$here/docker-compose.stack.dev.yml"
44+
leash_stack="$here/docker-compose.stack.leashed.yml"
45+
readonly here
46+
readonly dev_stack
47+
readonly leash_stack
48+
49+
50+
if [[ "$COMMAND" == "start-dev" ]]; then
51+
docker-compose -f "$dev_stack" up -d
52+
elif [[ "$COMMAND" == "start-leashed" || "$COMMAND" == "start" ]]; then
53+
docker-compose -f "$dev_stack" -f "$leash_stack" up -d
54+
elif [[ "$COMMAND" == "logs" ]]; then
55+
docker-compose -f "$dev_stack" logs $*
56+
elif [[ "$COMMAND" == "stop" ]]; then
57+
docker-compose -f "$dev_stack" down
58+
else
59+
usage "Unknown command \"$COMMAND\""
60+
fi

‎docker-compose.stack.dev.yml

+5-19
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,13 @@ services:
3232
ports:
3333
- '35729:35729'
3434

35-
backend-tests:
35+
backend:
3636
build:
3737
context: ./backend
38-
dockerfile: tests.dockerfile
38+
dockerfile: backend.dockerfile
39+
target: dev-runner
3940
volumes:
40-
- /tmp/test-results:/tmp/test-results
4141
- ./backend/app:/app
42-
ports:
43-
- '5900'
44-
command: bash -c "while true; do sleep 1; done"
4542
env_file:
4643
- env-backend.env
4744
environment: &testenv
@@ -55,32 +52,21 @@ services:
5552
- TAG=${TAG}
5653
- STACK_NAME=${STACK_NAME}
5754
- DEPLOYED_AT=${DEPLOYED_AT}
58-
backend:
59-
build:
60-
context: ./backend
61-
dockerfile: backend.dockerfile
62-
target: dev-runner
63-
volumes:
64-
- ./backend/app:/app
65-
env_file:
66-
- env-backend.env
67-
environment: *testenv
6855
labels:
6956
- traefik.frontend.rule=PathPrefix:/api,/docs,/redoc,/openapi.json
7057
- traefik.enable=true
7158
- traefik.port=80
7259
- traefik.tags=${TRAEFIK_TAG}
73-
# Uncomment lines below to create Infinite loop to keep container live doing nothing
74-
# backend:
75-
# command: bash -c "while true; do sleep 1; done"
7660
command: ./bin/prestart-dev.sh
7761
networks:
7862
default:
7963
aliases:
8064
- ${DOMAIN}
65+
8166
db:
8267
image: postgres:12
8368
environment: *testenv
69+
8470
docs:
8571
build:
8672
context: ./docs

‎docker-compose.stack.leashed.yml

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
version: '3.7'
2+
services:
3+
backend:
4+
command: ./bin/prestart-leashed.sh

0 commit comments

Comments
 (0)
Please sign in to comment.