forked from rdmolony/devenv-django
-
Notifications
You must be signed in to change notification settings - Fork 0
/
devenv.nix
149 lines (134 loc) · 3.83 KB
/
devenv.nix
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
{ pkgs, ... }:
let
db_user = "admin";
db_host = "localhost";
db_port = 3306;
db_name = "local_dev_db";
db_password = "not4production";
python_version = "3.10";
django_port = "8000";
in
{
packages = [
pkgs.gcc # This is only needed so that the mysqlclient can get installed
pkgs.git
# mysqlclient requires pkg-config or else we will get errors similar to
# https://stackoverflow.com/questions/76585758/mysqlclient-cannot-install-via-pip-cannot-find-pkg-config-name-in-ubuntu
pkgs.pkg-config
];
languages.python = {
enable = true;
poetry.enable = true;
};
env = {
PYTHON_VERSION = python_version;
DATABASE_URL = "mysql://${db_user}:${db_password}@${db_host}:${builtins.toString db_port}/${db_name}";
DEBUG = true;
STATIC_ROOT = "/tmp/static";
};
enterShell = ''
# If poetry environment is broken we can check this env var in CI & recache
export POETRY_STATUS=$(check-poetry-status)
echo "POETRY_STATUS=$POETRY_STATUS"
'';
services.mysql.enable = true;
# The default is MariaDB. To use MySQL instead:
services.mysql.package = pkgs.mysql80;
services.mysql.initialDatabases = [ { name = db_name; } ];
services.mysql.ensureUsers = [
{
name = db_user;
password = db_password;
ensurePermissions = {"${db_user}.*" = "ALL PRIVILEGES"; };
}
];
# If you prefer postgres, uncomment the following lines and comment out the
# mysql lines above. You will also need to change the DATABASE_URL env var
# above to use postgres.
# services.postgres = {
# enable = true;
# initialScript = "CREATE USER ${db_user} SUPERUSER;";
# initialDatabases = [ { name = db_name; } ];
# listen_addresses = db_host;
# port = db_port;
# };
scripts = {
dj.exec = ''
python manage.py $@
'';
check-poetry-status.exec = ''
STATUS=$(poetry check)
if [[ "$STATUS" == 'All set!' ]]; then
echo "clean"
else
echo "broken"
fi
'';
start-services-in-background.exec = ''
if ! nc -z ${db_host} ${builtins.toString db_port};
then
printf "Starting database in background ...\n"
nohup devenv up > /tmp/devenv.log 2>&1 &
fi
'';
kill-services.exec = ''
printf "Killing background services ...\n"
fuser -k ${builtins.toString db_port}/tcp
fuser -k ${django_port}/tcp
'';
wait-for-db.exec = ''
printf "Waiting for database to start ...\n"
printf "(if wait exceeds 100 percent then check /tmp/devenv.log for errors)\n"
# wait up to 20s for the database to launch ...
n_loops=20;
timer=0;
while true;
do
if nc -z ${db_host} ${builtins.toString db_port}; then
printf "\nDatabase is running!\n\n"
exit 0
elif [ $timer -gt $n_loops ]; then
printf "\nDatabase failed to launch!\n\n"
exit 1
else
sleep 1
let timer++
percent=$((timer*100/n_loops))
bar+="#"
printf "\r[%-100s] %d%%" "$bar" "$percent"
fi
done
'';
launch-django.exec = ''
interrupt_handler() {
kill-services
exit 1
}
trap 'interrupt_handler' SIGINT
launch_django() {
printf "Launching Django ...\n\n"
start-services-in-background
wait-for-db || exit 1 # if wait-for-db fails, exit!
dj runserver ${django_port}
}
launch_django
'';
test-all.exec = ''
interrupt_handler() {
kill-services
exit 1
}
trap 'interrupt_handler' SIGINT
run_tests() {
printf "Running tests...\n\n"
start-services-in-background
wait-for-db || exit 1 # if wait-for-db fails, exit!
dj collectstatic --noinput
dj test $@
kill-services
exit 0
}
run_tests
'';
};
}