-
Notifications
You must be signed in to change notification settings - Fork 0
/
Justfile
319 lines (267 loc) · 8.53 KB
/
Justfile
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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
# TODOs {{-
#
# + **cut this file up into multiple justfiles**
# reasons: no lazy loading (and those vars are only needed by a few recipes)
# some recipes are just useful by themselves without any dependency (i.e., without in the nix-shell
# A solution is using `just -f` and/or justfiles in different dirs (https://just.systems/man/en/chapter_51.html)
#
# + **Replace `just`?** (It's super slow...)
# }}-
# VARIABLES
# =========
# WARNING **Not lazy!**
# https://github.com/casey/just/issues/953 (open@5/4/2023)
db_user := `get_db_settings 'USER'`
db_port := `get_db_settings 'PORT'`
db_schema := `get_db_settings 'SCHEMA'`
db_name := `get_db_settings 'NAME'`
timestamp := `date "+%Y-%m-%d_%H-%M-%S"`
# NOTE override `psql` username {{-
#
# The username is hard-coded, but it can be easily
# overridden by adding `-U` or `--username` again.
#
# For example:
#
# $ just c -U postgres
#
# lynx=> \conninfo
# ...as user "postgres"...
# }}-
psql_flags := (
" --host=$PGDATA" +
" --port=" + db_port +
" --username=" + `whoami` +
" --dbname=" + db_name +
" "
)
# COMPOSITE RECIPES
# =================
serve_empty: db deps migrate prep add_django_superuser serve
# USAGE NOTES {{- {{-
#
# For example:
#
# just serve_from backup/lynx_2023_07_04-exclude_account-fix_sipplan_17615.sql
#
# Once the a database has been set up, simply use one
# of the `serve` recipes (e.g., `just serve`).
# }}- }}-
serve_from dumpfile: db && deps migrate prep serve
just c -f {{dumpfile}}
just c --command="ANALYZE"
db_from dumpfile: db
just c -f {{dumpfile}}
just c --command="ANALYZE"
# alias: d
django_prep: deps migrate prep
# alias: s
setup_from dumpfile:
just db_from {{dumpfile}}
just django_prep
db: create_db add_role grant_schema
# BASE RECIPES {{-
# ============
# == `db` PARTS: `create_db`, `add_role`, `grant_schema` == {{-
# TODO Add ICU? (postgres15)
create_db: # {{-
createdb \
{{db_name}} \
--host=$PGDATA \
--port={{db_port}}
# }}-
# NOTE Why doesn't this use `just c`? (or merged with `grant_schema`) {{- {{-
# ------------------------------
# This recipe is very resistant to refactoring, and my
# every attempt failed thus far. One of the reasons is
# that `PASSWORD` changes often, and if a particular
# instance has dollar sign(s) in it, then this seems
# to be the only way to do it.
# }}- }}-
add_role: # {{-
psql \
{{psql_flags}} \
--command="CREATE ROLE {{db_user}} WITH LOGIN PASSWORD '$(get_db_settings 'PASSWORD')'"
# }}-
# NOTE Why is this not a Django migration? {{- {{-
# -----------------------------------
# Because this is necessary for Django to even be able
# to touch the database. From PostgreSQL 15, no user
# has access to the `public` schema and it is treated
# just like any other. Therefore, unless someone is a
# superuser, extra privileges have to be granted to
# touch anything inside it.
# }}- }}-
grant_schema: # {{-
echo " \
GRANT USAGE, CREATE ON SCHEMA {{db_schema}} TO {{db_user}}; \
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA {{db_schema}} TO {{db_user}}; \
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA {{db_schema}} TO {{db_user}}; \
" | just c
# }}-
# }}-
# == `django` == {{-
deps: # {{-
pip install --upgrade pip
pip install lynx/.
# }}-
migrate *flag: # {{-
just m showmigrations
just m makemigrations
just m migrate {{flag}}
# }}-
# NOTE Apply Django migrations when database is **not** empty {{- {{-
# ------------------------------------------------------
# This may not be used much after getting the upgraded
# version of Lynx into production, but for now
# it is needed when the production database gets
# `pg_dump`-ed, replayed it to a fresh cluster, and
# this recipe will apply only the migrations that
# are necessery (e.g., production Lynx only has 81
# migrations, but development Lynx has 82 after all
# the dependency upgrades).
#
# https://docs.djangoproject.com/en/4.2/topics/migrations/#adding-migrations-to-apps
# }}- }}-
fake: # {{-
just migrate --fake-initial
# }}-
add_django_superuser: # {{-
just m createsuperuser
# }}-
prep: # {{-
just m collectstatic
just m check --deploy
# }}-
serve: # {{-
just m runserver 0:8000
# }}-
# }}-
# == gunicorn == {{-
# NOTE Sockets (UDS vs TCP) {{- {{-
# ====================
# Decided to use Unix Domain Sockets (UDS) instead of
# internet (TCP) sockets when implementing the systemd
# unit files, because UDS is faster and also wanted to
# get familiar with them. Leaving these Just recipes
# here in case a quick test in dev is necessary.
# Good resources:
# + https://www.baeldung.com/linux/unix-vs-tcp-ip-sockets
# + https://serverfault.com/questions/124517/what-is-the-difference-between-unix-sockets-and-tcp-ip-sockets
# + https://stackoverflow.com/questions/14973942/tcp-loopback-connection-vs-unix-domain-socket-performance
# + https://lists.freebsd.org/pipermail/freebsd-performance/2005-February/001143.html
# }}- }}-
gunicorn ip_address port *extra_flags: # {{-
cd {{justfile_directory()}}/lynx && \
gunicorn \
--bind {{ip_address}}:{{port}} \
--workers 3 \
--log-level 'debug' \
--preload \
--capture-output \
--pid "${GUNICORN_DIR}/gunicorn_{{timestamp}}.pid" \
--access-logfile "${GUNICORN_DIR}/gunicorn_access_{{timestamp}}.log" \
--error-logfile "${GUNICORN_DIR}/gunicorn_error_{{timestamp}}.log" \
mysite.wsgi:application \
{{extra_flags}}
# }}-
gunicorn_zeros port *extra_flags:
just gunicorn 0.0.0.0 {{port}} {{extra_flags}}
gunicorn_local port *extra_flags:
just gunicorn 127.0.0.1 {{port}} {{extra_flags}}
# }}-
# }}-
# ALIASES {{-
# =======
# USAGE NOTE "Stack quote" `extra_flags` with special chars {{-
# ---------------------------------------------
#
# For example, to invoke "backslash commands" in
# `psql` from the terminal, two distinct quotes are
# needed:
#
# just c -c "'\dt'"
#
# Sometimes it is not possible at all (or not worth
# the effort); see note at `add_role` recipe.
# }}-
alias c := _connect_lynx_db
alias m := _django_manage
alias n := _shell_nixes
alias p := my_process_tree
alias d := django_prep
alias s := setup_from
# }}-
# UTILITIES {{-
# =========
# WARNING sometimes works, other times it doesn't
reldoc host driver:
schemaspy -t pgsql11 -host {{host}} -port {{db_port}} -db {{db_name}} -s public -u {{db_user}} -o . -dp {{driver}}
# alias: m
_django_manage +sub_commands:
python lynx/manage.py {{sub_commands}}
# alias: n
_shell_nixes:
source <(curl https://raw.githubusercontent.com/toraritte/shell.nixes/main/run.sh) -n 23.05
# CAVEAT `extra_flags` variadic parameter {{-
# ================================
# is almost useless, unless very simple `psql`
# `extra_flags` are provided (e.g., `-U postgres`
# to override the hard-coded user). Anything that
# requires quoting and/or has spaces in it will turn
# the whole thing into an unmanageable mess, and one
# is better off using workarounds (such as the shell
# function `get_db_settings`in `dev_shell.nix`).
# }}-
# alias: c
_connect_lynx_db *extra_flags:
psql \
{{psql_flags}} \
{{extra_flags}}
# Examples:
#
# just dump -Fd -f <dump_name>
# just dump -Fc <dump_name>
#
# (The database name is not needed because it is
# already provided by `just c`.)
#
# To restore:
#
# pg_restore -h localhost -d <dn_name> <dump_name>
# pg_restore -h localhost -d <db_name> -t <table_name> <dump_name>
dump *extra:
pg_dump \
{{psql_flags}} \
{{extra}}
# }}-
# DEBUG {{-
# =====
# A better alternative to
#
# watch -n 1 "ps xf"
# alias: p
my_process_tree:
htop --user $(whoami) --tree
# }}-
# NOTES FOR FUTURE SELF
# =====================
# 1. SPACES IN VARIADIC ARGUMENTS {{-
# ===============================
#
# WRONG: just aaa 'not simply' dev_shell.nix
#
# Will be called as
#
# grep not simply dev_shell.nix
#
# RIGHT: just aaa "'not simply' dev_shell.nix"
# RIGHT: just aaa "'not simply'" dev_shell.nix
#
# Both will be called as intended:
#
# grep 'not simply' dev_shell.nix
aaa *params:
grep {{params}}
# }}-
# vim: set foldmethod=marker foldmarker={{-,}}- foldlevelstart=0 tabstop=2 shiftwidth=2 expandtab: