mirror of
https://github.com/bookwyrm-social/bookwyrm.git
synced 2024-05-31 22:58:18 +00:00
Compare commits
528 commits
Author | SHA1 | Date | |
---|---|---|---|
21f65cac58 | |||
6400a8e234 | |||
a65e6ce423 | |||
e00e7c1890 | |||
419e9f24cb | |||
ffb7f66375 | |||
fe020b7c95 | |||
0c427eaf06 | |||
c58689ae20 | |||
154f23719b | |||
a0b8adf3a9 | |||
6d404558c3 | |||
dd505a8814 | |||
006272306a | |||
cad83a339e | |||
5e2a416d65 | |||
36a43a1996 | |||
013f9ed925 | |||
08f247421f | |||
6fdc9c6118 | |||
cf76173bd1 | |||
54db892b90 | |||
2c5811fb6f | |||
58335539fc | |||
ad75fd1928 | |||
ae1be06bb4 | |||
ef975c3ebc | |||
ed28e2d6e8 | |||
0c220a299d | |||
8da6741cdf | |||
ad25c6c31b | |||
8cdcfe89fb | |||
4501b504ac | |||
e20e009df6 | |||
5651f83389 | |||
3578dc839c | |||
0d86df35ff | |||
d3f1261050 | |||
7cfccf2710 | |||
92b59ff47c | |||
8982637094 | |||
2cbb80305d | |||
b00981c615 | |||
101fd87a55 | |||
29314c6243 | |||
d375518489 | |||
3fd4ab6162 | |||
b34bbac228 | |||
580745bee3 | |||
d5980d2b56 | |||
618c7bbeec | |||
8ba1ccadcc | |||
14b6aa7bbd | |||
372bfa3b28 | |||
99b64ae9e8 | |||
cf595916f9 | |||
7382f233cc | |||
f09fdc865c | |||
2d2d0194a6 | |||
83cb0a9df8 | |||
5d8a1ec24b | |||
0c6f38828b | |||
4097a8989c | |||
3c3eae7b9e | |||
e452aa95b6 | |||
14e73d18dd | |||
02a315be00 | |||
3a8aff938b | |||
e915335932 | |||
b1f3253aa7 | |||
12a5eaba3e | |||
dc0dede105 | |||
05cf3ce344 | |||
3ad09308b5 | |||
c10c14b2c9 | |||
f64a909751 | |||
f27fe05008 | |||
4308137390 | |||
588d2da2c6 | |||
c1c0eed92c | |||
bb89766de0 | |||
e2197b3e7d | |||
4a0e1bdd46 | |||
67bb154008 | |||
6f9488f7a8 | |||
35e27a4443 | |||
3ebdd432ec | |||
a54a8b7573 | |||
91e8a9ac19 | |||
394f6fea87 | |||
4baba480c5 | |||
64b5a18d7b | |||
dfba63f977 | |||
8de5a44181 | |||
3e78164039 | |||
abfd094337 | |||
0e8fffe001 | |||
0f1757b278 | |||
f1381341b4 | |||
6bf9fe7295 | |||
657d7b04c1 | |||
0a6c14dc8a | |||
771435168b | |||
36dbf64b12 | |||
75726460d7 | |||
d04345ec08 | |||
bf573a0871 | |||
43ca5f466c | |||
47be375de3 | |||
cc1496cf8f | |||
dd16ccd093 | |||
4a81786236 | |||
b46ec147da | |||
589a743cfb | |||
2dd39517c3 | |||
4fad83e910 | |||
56c6ee8879 | |||
3d036386f9 | |||
53754546c2 | |||
6a7c38003d | |||
584da682ee | |||
c102106dc2 | |||
9fb7280366 | |||
26482232c9 | |||
1dc5467969 | |||
83964f4e2b | |||
320ac617cb | |||
7ab8209046 | |||
cbfa99a95b | |||
2fccb8ef83 | |||
49bef9a7c5 | |||
2b07e9c485 | |||
c32e5b78ac | |||
637600763b | |||
17d4b60275 | |||
55aa26d2ba | |||
a806264497 | |||
d650585858 | |||
4416ce5069 | |||
f5f861ce25 | |||
5b3ff0cf82 | |||
40bec83833 | |||
3d7f73d73c | |||
7cb7063da5 | |||
93e1beda6e | |||
8b4f93dd4e | |||
82513197fd | |||
2c5265a117 | |||
8b42d58caf | |||
e8c1ca68d1 | |||
638352ba26 | |||
5cc4f9d381 | |||
2e9574d53c | |||
879a410808 | |||
d44a900e0c | |||
cd9acef30a | |||
1c48605418 | |||
4ca0834b43 | |||
2a5012470b | |||
07c190d717 | |||
bdf617d005 | |||
b53d45a19a | |||
4c73e53b9a | |||
c52689c4b8 | |||
620a22bde0 | |||
58b88ef71e | |||
25a7ab7b84 | |||
eff6591727 | |||
db5ec248ef | |||
d62a4e7aa0 | |||
ab06180e41 | |||
02ea4020ea | |||
17294abc13 | |||
327a616779 | |||
9a1ca982c8 | |||
382d98a2e0 | |||
1bc09485ee | |||
b15744cc37 | |||
62b62b5057 | |||
7cb377da6f | |||
9b1a9ec1d4 | |||
8aa920e357 | |||
34e45f3113 | |||
e9f60f93b2 | |||
1b987542a4 | |||
57396499ff | |||
755a6569c6 | |||
7744b9a117 | |||
697924ebc6 | |||
cfc6528d0c | |||
5d19d33a01 | |||
620d3ab804 | |||
2d7047b833 | |||
c03db63bb3 | |||
b5c0c0b52c | |||
75ca011f92 | |||
074a9113e6 | |||
b2bd655a00 | |||
3fb2584c03 | |||
78edfa142e | |||
4515cec7d2 | |||
4c5f5d90ba | |||
5e88e893c7 | |||
2022b3a035 | |||
8f50f8758c | |||
276bded337 | |||
9aa1201cbe | |||
7284a4efad | |||
ed6d35ef72 | |||
8dc8ea2f59 | |||
fad1b8db94 | |||
642ebec5ff | |||
b6b4e36e94 | |||
48c78a9d0e | |||
0f419d2b06 | |||
1d6f30c2df | |||
b0751d0555 | |||
376adc0a9a | |||
6bad4abd63 | |||
a8dbecde57 | |||
470fe576a1 | |||
638bc17724 | |||
8c3b170812 | |||
47b5f8c4f8 | |||
fee03191e8 | |||
847c4b49b4 | |||
5ce86d7b52 | |||
e363d1af11 | |||
c105490178 | |||
3d1f4e3452 | |||
fe0def3de8 | |||
cc9c6ce76c | |||
8f73cd9d89 | |||
c7443c9749 | |||
9bf79bf9b9 | |||
870cf3b60c | |||
375385ea6c | |||
c0fc0431e7 | |||
036463c8d9 | |||
29044517a1 | |||
b0a8d6c9fb | |||
8534e49f96 | |||
c4e66d44c9 | |||
fd0e4c6e13 | |||
7e3627f787 | |||
c3f938d500 | |||
90021ab0e4 | |||
65333b258b | |||
8086b9bca5 | |||
730b6fabc4 | |||
802d28b4a7 | |||
5f9e80ac1d | |||
832a9494b1 | |||
5ba6d8321f | |||
8bb815d5b3 | |||
1e71cf980c | |||
30a67a0221 | |||
9302aa6ce4 | |||
238862a4cf | |||
bad39aef55 | |||
83078cd424 | |||
892d338adc | |||
e8124806b1 | |||
f508b4eb33 | |||
0ff7c84a14 | |||
4fc230ec8b | |||
5ed4dfdb63 | |||
b3e369cdba | |||
4cc2eccaa4 | |||
7aff486a59 | |||
d80623d88d | |||
8761357905 | |||
3d2a56090c | |||
d7a662a39a | |||
b30fab0597 | |||
72f3aff024 | |||
92d58411b9 | |||
834bc08f34 | |||
09ae418881 | |||
b54979d39c | |||
85f1c38ba6 | |||
238e88c9dc | |||
8a1bfc5ffc | |||
1a939ed913 | |||
9d26c0e824 | |||
107d56c494 | |||
9ad369203f | |||
37c5c4979f | |||
5f783e4fd1 | |||
d54286b571 | |||
64e721fb0b | |||
4ee738ae52 | |||
3795d682aa | |||
c33eacaf3d | |||
e35befb6a2 | |||
411dd1b14d | |||
8a0db114d8 | |||
a3d5d352a7 | |||
a8052c2dd0 | |||
c50edc9d3f | |||
d55dafd9be | |||
a5aab26986 | |||
406c94354f | |||
afa831d140 | |||
01f598a951 | |||
32cd7ec32d | |||
5e6b9e44c9 | |||
fd91a79558 | |||
877c90b087 | |||
af92e3e9a4 | |||
d77eb5381d | |||
9189ae2f2d | |||
79fc286ef8 | |||
211bf318c4 | |||
7439adb8e6 | |||
17b289e6e2 | |||
145ea053cb | |||
7730c9f9a7 | |||
bc1a782541 | |||
0abd4e7fc8 | |||
fae72977b6 | |||
18557af41a | |||
e01581c28d | |||
78467190a6 | |||
b8695ae3b7 | |||
6f37a43d33 | |||
34fb1d2526 | |||
3cac69cd2c | |||
f546dfb005 | |||
c3a750f5da | |||
4b44ce691e | |||
9dbd1c674c | |||
80893dd5fd | |||
4ca76ec58d | |||
e3350e58d0 | |||
8b9528ae95 | |||
a26bf2859b | |||
94ef9cdd3e | |||
127881f56a | |||
8e4db60f46 | |||
8277c9e42e | |||
af72488cd9 | |||
f97efc2f86 | |||
d72dc842bd | |||
e37bb809e0 | |||
eca1a87294 | |||
97697ce5d5 | |||
c9f7ab6389 | |||
bb8cac021b | |||
94d18f6c24 | |||
5f1694a7b0 | |||
08cf9b5b40 | |||
8586f0fe75 | |||
a868e6c6fd | |||
fd4b2adb8b | |||
52905a3668 | |||
d202bd1d1d | |||
42ba3753d6 | |||
52cf9c67b9 | |||
e8b89eee73 | |||
a04511ccf7 | |||
fd3c6d1d21 | |||
6a14529893 | |||
36088554e8 | |||
59cc5c112f | |||
b0f78e6d0b | |||
28160137d0 | |||
4bf61e0ef0 | |||
f6366e1c4a | |||
593d5d309a | |||
84b525f83e | |||
015d45ef99 | |||
6c7fcb0dd1 | |||
6f6ca40ce7 | |||
c770b369d2 | |||
88879207b9 | |||
8ac2315cc6 | |||
e5283f9576 | |||
6ecda991d9 | |||
cabb486cb8 | |||
a1428a6030 | |||
489ac29761 | |||
df4def6cef | |||
e36ddb3f9b | |||
396cb30c3a | |||
98f35929b4 | |||
888987f19d | |||
ac80df7ee0 | |||
70bdac3706 | |||
355b2fad35 | |||
f107e3d499 | |||
5d7bd6a92b | |||
a2c7bffec9 | |||
d41c1b7213 | |||
f9da72d957 | |||
6105a6921b | |||
a0b0edbc3e | |||
a3966aa807 | |||
a3768b52a6 | |||
7e7f80d31e | |||
9c5444ad7a | |||
657dff7e95 | |||
bfdfb846da | |||
00c8fab365 | |||
e4001aba0b | |||
6545141bcf | |||
7ef29bb99e | |||
d9d5bc4e31 | |||
7eae4cdebb | |||
1eb979f05d | |||
28a7156f36 | |||
802d12421b | |||
41d9fe9d9d | |||
78d358a916 | |||
6d4335e05b | |||
5e0cb746d4 | |||
c7d6273b3b | |||
5abba57bfe | |||
12dbd47207 | |||
8156f1905d | |||
14e0102694 | |||
aafc9654c1 | |||
97f050c68e | |||
5c24bb6243 | |||
08cf668233 | |||
0a75c33de4 | |||
a29a5dbde9 | |||
636de3ae54 | |||
0f49436475 | |||
79dca312fb | |||
c69fdf7bb6 | |||
2719332e82 | |||
5b397c42f6 | |||
2635d109ed | |||
34ccf60868 | |||
d3192fb1bb | |||
042cfe2dfc | |||
42d50d15f8 | |||
2d21a31c13 | |||
77db2e183d | |||
255261dc3d | |||
44f764a34a | |||
b910be99c3 | |||
f7769db99b | |||
b36cf5a7b8 | |||
c5b48f521a | |||
0cd9f81431 | |||
ad6b2315ab | |||
4c8583bfdb | |||
175eab01f7 | |||
d5cc1d2f02 | |||
4171829626 | |||
f3576d59d7 | |||
e5b850299c | |||
d417f1e09d | |||
cb124e9ba4 | |||
567ea40f52 | |||
8f595b6a35 | |||
e9ed457012 | |||
5cfdc75c5f | |||
0eacee02ac | |||
dac3c9353d | |||
da24241b78 | |||
2d96c8a35a | |||
9ac94543b9 | |||
00752232ff | |||
9db851f2d4 | |||
4424acc5c2 | |||
eb1e4fd24c | |||
abd96717da | |||
29e5c67f83 | |||
0574e36602 | |||
b20de604d3 | |||
de95b60b0b | |||
bc62ed231f | |||
c80d63d184 | |||
46d9a444fd | |||
6dd83d490f | |||
5782961e58 | |||
573bdfd56b | |||
8dc350e8a1 | |||
44b299b28f | |||
4dc53c56d5 | |||
5a051d669f | |||
ecca49f70a | |||
004a3e5e56 | |||
1a61c6eb07 | |||
ea672c74e2 | |||
2823eca70d | |||
88de4ff046 | |||
c577c91912 | |||
dd8f91a044 | |||
de66d77f4b | |||
f6026f5ed8 | |||
17ea59e655 | |||
6b667aa575 | |||
5e2667c297 | |||
7db77c690e | |||
c7b2d7a4b9 | |||
bfef6f2d8a | |||
875b473711 | |||
2b75fd1f14 | |||
d6a166d9db | |||
8d21cfa707 | |||
7da705f87e | |||
7af3afe24b | |||
3cf2c4d1b0 | |||
6d6a16daf3 | |||
0a34cf8821 | |||
d19405f379 | |||
59d0164911 | |||
f23e10f8f7 | |||
19f9b75c6b | |||
9c68b6d430 | |||
d3987756eb | |||
687ff5a6d7 | |||
8b061d63a8 | |||
6826386ea3 | |||
b02a70b484 | |||
c5bcde0ee4 | |||
be1a26d32b | |||
54b924a4e2 | |||
439feac110 | |||
7dd1deb438 | |||
a9a40e4d69 | |||
5446a5b238 | |||
4b32948fd3 | |||
4b993fb5d6 |
|
@ -1,30 +1,54 @@
|
|||
version: '3'
|
||||
|
||||
x-logging:
|
||||
&default-logging
|
||||
driver: "json-file"
|
||||
options:
|
||||
max-size: "150m"
|
||||
max-file: "2"
|
||||
|
||||
services:
|
||||
nginx:
|
||||
image: nginx:latest
|
||||
logging: *default-logging
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "1333:80"
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
depends_on:
|
||||
- web
|
||||
networks:
|
||||
- main
|
||||
volumes:
|
||||
- ./nginx:/etc/nginx/conf.d
|
||||
- ./certbot/conf:/etc/nginx/ssl
|
||||
- ./certbot/data:/var/www/certbot
|
||||
- static_volume:/app/static
|
||||
- media_volume:/app/images
|
||||
certbot:
|
||||
image: certbot/certbot:latest
|
||||
command: certonly --webroot --webroot-path=/var/www/certbot --email ${EMAIL} --agree-tos --no-eff-email -d ${DOMAIN} -d www.${DOMAIN}
|
||||
#command: renew --webroot --webroot-path /var/www/certbot
|
||||
logging: *default-logging
|
||||
volumes:
|
||||
- ./certbot/conf:/etc/letsencrypt
|
||||
- ./certbot/logs:/var/log/letsencrypt
|
||||
- ./certbot/data:/var/www/certbot
|
||||
db:
|
||||
image: postgres:13
|
||||
build: postgres-docker
|
||||
env_file: .env
|
||||
entrypoint: /bookwyrm-entrypoint.sh
|
||||
command: cron postgres
|
||||
volumes:
|
||||
- pgdata:/var/lib/postgresql/data
|
||||
- backups:/backups
|
||||
networks:
|
||||
- main
|
||||
web:
|
||||
build: .
|
||||
env_file: .env
|
||||
command: python manage.py runserver 0.0.0.0:8000
|
||||
command: gunicorn bookwyrm.wsgi:application --bind 0.0.0.0:8000
|
||||
logging: *default-logging
|
||||
volumes:
|
||||
- .:/app
|
||||
- static_volume:/app/static
|
||||
|
@ -40,6 +64,7 @@ services:
|
|||
redis_activity:
|
||||
image: redis
|
||||
command: redis-server --requirepass ${REDIS_ACTIVITY_PASSWORD} --appendonly yes --port ${REDIS_ACTIVITY_PORT}
|
||||
logging: *default-logging
|
||||
volumes:
|
||||
- ./redis.conf:/etc/redis/redis.conf
|
||||
- redis_activity_data:/data
|
||||
|
@ -50,6 +75,7 @@ services:
|
|||
redis_broker:
|
||||
image: redis
|
||||
command: redis-server --requirepass ${REDIS_BROKER_PASSWORD} --appendonly yes --port ${REDIS_BROKER_PORT}
|
||||
logging: *default-logging
|
||||
volumes:
|
||||
- ./redis.conf:/etc/redis/redis.conf
|
||||
- redis_broker_data:/data
|
||||
|
@ -64,6 +90,7 @@ services:
|
|||
- main
|
||||
command: celery -A celerywyrm worker -l info -Q high_priority,medium_priority,low_priority,streams,images,suggested_users,email,connectors,lists,inbox,imports,import_triggered,broadcast,misc
|
||||
|
||||
logging: *default-logging
|
||||
volumes:
|
||||
- .:/app
|
||||
- static_volume:/app/static
|
||||
|
@ -78,6 +105,7 @@ services:
|
|||
networks:
|
||||
- main
|
||||
command: celery -A celerywyrm beat -l INFO --scheduler django_celery_beat.schedulers:DatabaseScheduler
|
||||
logging: *default-logging
|
||||
volumes:
|
||||
- .:/app
|
||||
- static_volume:/app/static
|
||||
|
@ -88,6 +116,7 @@ services:
|
|||
flower:
|
||||
build: .
|
||||
command: celery -A celerywyrm flower --basic_auth=${FLOWER_USER}:${FLOWER_PASSWORD} --url_prefix=flower
|
||||
logging: *default-logging
|
||||
env_file: .env
|
||||
volumes:
|
||||
- .:/app
|
||||
|
@ -104,6 +133,7 @@ services:
|
|||
- .:/app
|
||||
volumes:
|
||||
pgdata:
|
||||
backups:
|
||||
static_volume:
|
||||
media_volume:
|
||||
redis_broker_data:
|
||||
|
|
20
postgres-docker/Dockerfile
Normal file
20
postgres-docker/Dockerfile
Normal file
|
@ -0,0 +1,20 @@
|
|||
FROM postgres:13.0
|
||||
|
||||
# crontab
|
||||
RUN mkdir /backups
|
||||
COPY ./backup.sh /usr/local/bin/bookwyrm-backup.sh
|
||||
COPY ./weed.sh /usr/local/bin/bookwyrm-weed.sh
|
||||
COPY ./cronfile /etc/cron.d/cronfile
|
||||
RUN apt-get update && apt-get -y --no-install-recommends install cron
|
||||
RUN chmod 0644 /etc/cron.d/cronfile
|
||||
RUN crontab /etc/cron.d/cronfile
|
||||
RUN touch /var/log/cron.log
|
||||
|
||||
# The postgres image's entrypoint expects the docker command to only contain flags to
|
||||
# pass postgres. It runs the entrypoint twice, the second times as the postgres user.
|
||||
# We need to start the cron service the first time it runs, when it's still being run
|
||||
# as the root user. We're going to add a check that looks at the first argument and
|
||||
# if it's 'cron', starts the service and then removes that argument.
|
||||
RUN awk '$0 ~ /^\t_main "\$@"$/ { print "\tif [[ $1 == cron ]]; then\n\t\techo \"POSTGRES_DB=${POSTGRES_DB}\" > /backups/.env\n\t\techo \"POSTGRES_USER=${POSTGRES_USER}\" >> /backups/.env\n\t\tservice cron start\n\t\tshift\n\tfi" }{ print }' docker-entrypoint.sh > bookwyrm-entrypoint.sh
|
||||
RUN chown postgres /bookwyrm-entrypoint.sh
|
||||
RUN chmod u=rwx,go=r /bookwyrm-entrypoint.sh
|
13
postgres-docker/backup.sh
Executable file
13
postgres-docker/backup.sh
Executable file
|
@ -0,0 +1,13 @@
|
|||
#!/bin/bash
|
||||
source /backups/.env
|
||||
|
||||
if [ -z "$POSTGRES_DB" ]; then
|
||||
echo "Database not specified, defaulting to bookwyrm"
|
||||
fi
|
||||
if [ -z "$POSTGRES_USER" ]; then
|
||||
echo "Database user not specified, defaulting to bookwyrm"
|
||||
fi
|
||||
BACKUP_DB=${POSTGRES_DB:-bookwyrm}
|
||||
BACKUP_USER=${POSTGRES_USER:-bookwyrm}
|
||||
filename=backup_${BACKUP_DB}_$(date +%F)
|
||||
pg_dump -U $BACKUP_USER $BACKUP_DB > /backups/$filename.sql
|
5
postgres-docker/cronfile
Normal file
5
postgres-docker/cronfile
Normal file
|
@ -0,0 +1,5 @@
|
|||
0 0 * * * /usr/local/bin/bookwyrm-backup.sh
|
||||
# If uncommented, this script will weed the backups directory. It will keep the 14
|
||||
# most-recent backups, then one backup/week for the next four backups, then one
|
||||
# backup/month after that.
|
||||
# 0 5 * * * /usr/local/bin/bookwyrm-weed.sh -d 14 -w 4 -m -1 /backups
|
8
postgres-docker/tests/Dockerfile
Normal file
8
postgres-docker/tests/Dockerfile
Normal file
|
@ -0,0 +1,8 @@
|
|||
FROM postgres:latest
|
||||
|
||||
RUN apt update && apt install -y shellcheck
|
||||
|
||||
COPY ./tests/testing-entrypoint.sh /testing-entrypoint.sh
|
||||
RUN chmod u+rx,go=r /testing-entrypoint.sh
|
||||
COPY ./weed.sh /weed.sh
|
||||
RUN chmod u+rx,go=r /weed.sh
|
9
postgres-docker/tests/docker-compose.yaml
Normal file
9
postgres-docker/tests/docker-compose.yaml
Normal file
|
@ -0,0 +1,9 @@
|
|||
version: "3"
|
||||
|
||||
services:
|
||||
weeding:
|
||||
build:
|
||||
# We need to build from the parent directory so we can access weed.sh
|
||||
context: ..
|
||||
dockerfile: ./tests/Dockerfile
|
||||
entrypoint: /testing-entrypoint.sh
|
426
postgres-docker/tests/testing-entrypoint.sh
Normal file
426
postgres-docker/tests/testing-entrypoint.sh
Normal file
|
@ -0,0 +1,426 @@
|
|||
#!/usr/bin/env bash
|
||||
# These tests are written to run in their own container, using the same image as the
|
||||
# actual postgres service. To run: `docker-compose up --build`
|
||||
set -euo pipefail
|
||||
|
||||
source /weed.sh
|
||||
|
||||
ERROR_COUNT=0
|
||||
FAILURE_COUNT=0
|
||||
|
||||
# compare two sorted files
|
||||
function compare_files {
|
||||
local expected="$1"
|
||||
local actual="$2"
|
||||
|
||||
declare -a missing
|
||||
local missing_index=0
|
||||
declare -a extra
|
||||
local extra_index=0
|
||||
|
||||
old_ifs="$IFS"
|
||||
IFS=$'\n'
|
||||
for line in $(diff --suppress-common-lines "$expected" "$actual"); do
|
||||
if [[ $line =~ ^\< ]]; then
|
||||
missing[missing_index]=${line:1}
|
||||
missing_index=$((missing_index + 1))
|
||||
elif [[ $line =~ ^\> ]]; then
|
||||
extra[extra_index]=${line:1}
|
||||
extra_index=$((extra_index + 1))
|
||||
fi
|
||||
done
|
||||
IFS="$old_ifs"
|
||||
|
||||
if [[ $((missing_index + extra_index)) -gt 0 ]]; then
|
||||
echo 'fail'
|
||||
|
||||
if [[ missing_index -gt 0 ]]; then
|
||||
echo -e "\\t$missing_index missing files:"
|
||||
|
||||
for index in $(seq 0 $((missing_index - 1))); do
|
||||
echo -e "\\t\\t${missing[index]}"
|
||||
done
|
||||
fi
|
||||
|
||||
if [[ extra_index -gt 0 ]]; then
|
||||
echo -e "\\t$extra_index extra files:"
|
||||
|
||||
for index in $(seq 0 $((extra_index - 1))); do
|
||||
echo -e "\\t\\t${extra[index]}"
|
||||
done
|
||||
fi
|
||||
|
||||
FAILURE_COUNT=$((FAILURE_COUNT + 1))
|
||||
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# This is a wrapper function that handles creating a directory with test files in it,
|
||||
# running weed_directory (as the function, as a dry run, then finally actually-deleting
|
||||
# files), marking the test as failed/errored as necessary, then cleaning up after
|
||||
# itself. the first three arguments passed are the thresholds to pass into
|
||||
# weed_directory. The remaining arguments are names of files to create for the test.
|
||||
# Bash isn't great at passing arrays so instead of separately passing in a list of
|
||||
# expected results, flag the files you expect to be deleted by prepending "DELETE:"
|
||||
# to the path.
|
||||
function perform_test {
|
||||
echo "${FUNCNAME[1]}" | sed 's/^test_\(.*\)$/\1/' | tr '_\n' ' :'
|
||||
echo -en '\t'
|
||||
|
||||
local daily_threshold="$1"
|
||||
shift
|
||||
local weekly_threshold="$1"
|
||||
shift
|
||||
local monthly_threshold="$1"
|
||||
shift
|
||||
|
||||
# We might as well name the files we're using for running tests in as inflamatory a
|
||||
# way as possible to increase the chances that bad filtering by weed_directory
|
||||
# results in tests failing.
|
||||
local expected="/testing/expected/backup__2020-02-02.sql"
|
||||
local actual="/testing/backup__2020-02-02.sql.actual"
|
||||
local remaining="/testing/remainbackup__2020-02-02.sql"
|
||||
local temp="/testing/backup__2020-TE-MP.sql"
|
||||
|
||||
# create test files
|
||||
mkdir -p /testing/expected
|
||||
if [[ -e "$expected" ]]; then
|
||||
rm "$expected"
|
||||
fi
|
||||
touch "$expected"
|
||||
echo -e "$expected\\n$actual\\n$remaining\\n$temp" > "$remaining"
|
||||
while [[ "$#" -gt 0 ]]; do
|
||||
if [[ "$1" =~ ^DELETE: ]]; then
|
||||
path="/testing/${1:7}"
|
||||
echo "$path" >> "$expected"
|
||||
else
|
||||
path="/testing/$1"
|
||||
echo "$path" >> "$remaining"
|
||||
fi
|
||||
|
||||
directory=$(dirname "$path")
|
||||
mkdir -p "$directory"
|
||||
touch "$path"
|
||||
|
||||
shift
|
||||
done
|
||||
# We don't make any promise about the order files will be listed in by
|
||||
# weed_directory (it is currently reverse-chronological). We should sort the output
|
||||
# and the expected file instead of forcing tests to list files in that order (or
|
||||
# causing tests to fail if weed_directory's order changes)
|
||||
sort "$expected" > "$temp"
|
||||
mv "$temp" "$expected"
|
||||
sort "$remaining" > "$temp"
|
||||
mv "$temp" "$remaining"
|
||||
|
||||
# Part one: call the function directly
|
||||
set +e
|
||||
(
|
||||
weed_directory \
|
||||
"/testing" \
|
||||
"$daily_threshold" \
|
||||
"$weekly_threshold" \
|
||||
"$monthly_threshold" \
|
||||
2> "$temp" \
|
||||
| sort > "$actual"
|
||||
)
|
||||
local result="$?"
|
||||
set -e
|
||||
|
||||
if [[ "$result" -ne 0 ]]; then
|
||||
echo 'error'
|
||||
ERROR_COUNT=$((ERROR_COUNT + 1))
|
||||
if [[ -s "$temp" ]]; then
|
||||
echo 'stderr:'
|
||||
cat "$temp"
|
||||
fi
|
||||
else
|
||||
set +e
|
||||
compare_files "$expected" "$actual"
|
||||
result="$?"
|
||||
set -e
|
||||
|
||||
if [[ "$result" -eq 0 ]]; then
|
||||
# Part two: as a script with the dry-run flag (-l)
|
||||
set +e
|
||||
(
|
||||
"/weed.sh" \
|
||||
"-d" "$daily_threshold" \
|
||||
"-w" "$weekly_threshold" \
|
||||
"-m" "$monthly_threshold" \
|
||||
"-l" \
|
||||
"/testing" \
|
||||
2> "$temp" \
|
||||
| sort > "$actual"
|
||||
)
|
||||
local result="$?"
|
||||
set -e
|
||||
|
||||
if [[ "$result" -ne 0 ]]; then
|
||||
echo 'error'
|
||||
ERROR_COUNT=$((ERROR_COUNT + 1))
|
||||
if [[ -s "$temp" ]]; then
|
||||
echo 'stderr:'
|
||||
cat "$temp"
|
||||
fi
|
||||
else
|
||||
set +e
|
||||
compare_files "$expected" "$actual"
|
||||
result="$?"
|
||||
set -e
|
||||
|
||||
if [[ "$result" -eq 0 ]]; then
|
||||
# Part three: let's try actually deleting files
|
||||
set +e
|
||||
(
|
||||
"/weed.sh" \
|
||||
"-d" "$daily_threshold" \
|
||||
"-w" "$weekly_threshold" \
|
||||
"-m" "$monthly_threshold" \
|
||||
"/testing" \
|
||||
2> "$temp"
|
||||
)
|
||||
local result="$?"
|
||||
set -e
|
||||
|
||||
if [[ "$result" -ne 0 ]]; then
|
||||
echo 'error'
|
||||
ERROR_COUNT=$((ERROR_COUNT + 1))
|
||||
if [[ -s "$temp" ]]; then
|
||||
echo 'stderr:'
|
||||
cat "$temp"
|
||||
fi
|
||||
else
|
||||
find /testing -type f | sort > "$actual"
|
||||
|
||||
set +e
|
||||
compare_files "$remaining" "$actual"
|
||||
result="$?"
|
||||
set -e
|
||||
|
||||
if [[ "$result" -eq 0 ]]; then
|
||||
echo 'pass'
|
||||
elif [[ -s "$temp" ]]; then
|
||||
echo 'stderr:'
|
||||
cat "$temp"
|
||||
fi
|
||||
fi
|
||||
elif [[ -s "$temp" ]]; then
|
||||
echo 'stderr:'
|
||||
cat "$temp"
|
||||
fi
|
||||
fi
|
||||
elif [[ -s "$temp" ]]; then
|
||||
echo 'stderr:'
|
||||
cat "$temp"
|
||||
fi
|
||||
fi
|
||||
rm -rf /testing
|
||||
}
|
||||
|
||||
# actual tests
|
||||
function test_shellcheck {
|
||||
echo -en 'running shellcheck on scripts:\t'
|
||||
shellcheck /weed.sh
|
||||
# Test the tests too! Writing bash is hard
|
||||
shellcheck -x /testing-entrypoint.sh
|
||||
echo 'pass'
|
||||
}
|
||||
|
||||
function test_empty_directory {
|
||||
perform_test 1 2 3
|
||||
}
|
||||
|
||||
function test_single_file {
|
||||
perform_test 1 2 3 "backup__2021-02-02.sql"
|
||||
}
|
||||
|
||||
function test_keep_everything {
|
||||
perform_test -1 0 0 "backup__2021-02-02.sql" "backup__2021-02-01.sql" "backup__2021-01-31.sql"
|
||||
}
|
||||
|
||||
function test_keep_one {
|
||||
perform_test 1 0 0 "backup__2021-02-02.sql" "DELETE:backup__2021-02-01.sql" "DELETE:backup__2021-01-31.sql"
|
||||
}
|
||||
|
||||
function test_weekly {
|
||||
# weed.sh follows ISO 8601 and uses %W for day of week, so Monday is the first day
|
||||
# of the week.
|
||||
# backup__2021-03-08.sql: Monday (keep)
|
||||
# backup__2021-03-07.sql: Sunday (keep)
|
||||
# backup__2021-02-28.sql: Sunday (keep)
|
||||
# backup__2021-02-22.sql: Monday (delete)
|
||||
# backup__2021-02-20.sql: Saturday (keep)
|
||||
# backup__2021-02-16.sql: Tuesday (delete)
|
||||
# backup__2021-02-15.sql: Monday (delete)
|
||||
# backup__2021-02-14.sql: Sunday (keep)
|
||||
# backup__2020-02-14.sql: Sunday (same week of year) (keep)
|
||||
perform_test 0 -1 0 \
|
||||
"backup__2021-03-08.sql" \
|
||||
"backup__2021-03-07.sql" \
|
||||
"backup__2021-02-28.sql" \
|
||||
"DELETE:backup__2021-02-22.sql" \
|
||||
"backup__2021-02-20.sql" \
|
||||
"DELETE:backup__2021-02-16.sql" \
|
||||
"DELETE:backup__2021-02-15.sql" \
|
||||
"backup__2021-02-14.sql" \
|
||||
"backup__2020-02-14.sql"
|
||||
}
|
||||
|
||||
function test_monthly {
|
||||
perform_test 1 0 -1 \
|
||||
"backup__2021-03-08.sql" \
|
||||
"DELETE:backup__2021-03-07.sql" \
|
||||
"backup__2021-02-28.sql" \
|
||||
"DELETE:backup__2021-02-22.sql" \
|
||||
"DELETE:backup__2021-02-20.sql" \
|
||||
"DELETE:backup__2021-02-16.sql" \
|
||||
"DELETE:backup__2021-02-15.sql" \
|
||||
"DELETE:backup__2021-02-14.sql" \
|
||||
"backup__2021-01-14.sql" \
|
||||
"backup__2020-01-13.sql"
|
||||
}
|
||||
|
||||
function test_annual {
|
||||
perform_test 0 0 0 \
|
||||
"backup__2021-03-08.sql" \
|
||||
"DELETE:backup__2021-03-07.sql" \
|
||||
"DELETE:backup__2021-02-28.sql" \
|
||||
"DELETE:backup__2021-02-22.sql" \
|
||||
"DELETE:backup__2021-02-20.sql" \
|
||||
"DELETE:backup__2021-02-16.sql" \
|
||||
"DELETE:backup__2021-02-15.sql" \
|
||||
"DELETE:backup__2021-02-14.sql" \
|
||||
"DELETE:backup__2021-01-14.sql" \
|
||||
"backup__2020-01-13.sql" \
|
||||
"backup__2019-12-31.sql" \
|
||||
"DELETE:backup__2019-01-13.sql"
|
||||
}
|
||||
|
||||
# Will not pass while maxdepth is set to 1.
|
||||
function skip_test_sort_order {
|
||||
perform_test 0 0 1 \
|
||||
"a/backup__2021-03-08.sql" \
|
||||
"DELETE:b/backup__2021-03-07.sql" \
|
||||
"DELETE:a/backup__2021-02-28.sql" \
|
||||
"DELETE:b/backup__2021-02-22.sql" \
|
||||
"DELETE:a/backup__2021-02-20.sql" \
|
||||
"DELETE:b/backup__2021-02-16.sql" \
|
||||
"DELETE:a/backup__2021-02-15.sql" \
|
||||
"DELETE:b/backup__2021-02-14.sql" \
|
||||
"DELETE:a/backup__2021-01-14.sql" \
|
||||
"b/backup__2020-01-13.sql" \
|
||||
"a/backup__2019-12-31.sql" \
|
||||
"DELETE:b/backup__2019-01-13.sql"
|
||||
}
|
||||
|
||||
function test_ignore_subdirectories {
|
||||
perform_test 0 0 0 "a/backup__2021-03-08.sql" "backup__2021-03-07.sql"
|
||||
}
|
||||
|
||||
function test_standard {
|
||||
perform_test 14 4 1 \
|
||||
"backup__2021-03-08.sql" \
|
||||
"backup__2021-03-07.sql" \
|
||||
"backup__2021-03-06.sql" \
|
||||
"backup__2021-03-05.sql" \
|
||||
"backup__2021-03-04.sql" \
|
||||
"backup__2021-03-03.sql" \
|
||||
"backup__2021-03-02.sql" \
|
||||
"backup__2021-03-01.sql" \
|
||||
"backup__2021-02-28.sql" \
|
||||
"backup__2021-02-27.sql" \
|
||||
"backup__2021-02-26.sql" \
|
||||
"backup__2021-02-25.sql" \
|
||||
"backup__2021-02-24.sql" \
|
||||
"backup__2021-02-23.sql" \
|
||||
"DELETE:backup__2021-02-22.sql" \
|
||||
"backup__2021-02-21.sql" \
|
||||
"DELETE:backup__2021-02-20.sql" \
|
||||
"DELETE:backup__2021-02-19.sql" \
|
||||
"DELETE:backup__2021-02-18.sql" \
|
||||
"DELETE:backup__2021-02-17.sql" \
|
||||
"DELETE:backup__2021-02-16.sql" \
|
||||
"DELETE:backup__2021-02-15.sql" \
|
||||
"backup__2021-02-14.sql" \
|
||||
"DELETE:backup__2021-02-13.sql" \
|
||||
"DELETE:backup__2021-02-12.sql" \
|
||||
"DELETE:backup__2021-02-11.sql" \
|
||||
"DELETE:backup__2021-02-10.sql" \
|
||||
"DELETE:backup__2021-02-09.sql" \
|
||||
"DELETE:backup__2021-02-08.sql" \
|
||||
"backup__2021-02-07.sql" \
|
||||
"DELETE:backup__2021-02-06.sql" \
|
||||
"DELETE:backup__2021-02-05.sql" \
|
||||
"DELETE:backup__2021-02-04.sql" \
|
||||
"DELETE:backup__2021-02-03.sql" \
|
||||
"DELETE:backup__2021-02-02.sql" \
|
||||
"DELETE:backup__2021-02-01.sql" \
|
||||
"backup__2021-01-31.sql" \
|
||||
"DELETE:backup__2021-01-30.sql" \
|
||||
"DELETE:backup__2021-01-29.sql" \
|
||||
"DELETE:backup__2021-01-28.sql" \
|
||||
"DELETE:backup__2021-01-27.sql" \
|
||||
"DELETE:backup__2021-01-26.sql" \
|
||||
"DELETE:backup__2021-01-25.sql" \
|
||||
"DELETE:backup__2021-01-24.sql" \
|
||||
"DELETE:backup__2021-01-23.sql" \
|
||||
"DELETE:backup__2021-01-22.sql" \
|
||||
"DELETE:backup__2021-01-21.sql" \
|
||||
"DELETE:backup__2021-01-20.sql" \
|
||||
"DELETE:backup__2021-01-19.sql" \
|
||||
"DELETE:backup__2021-01-18.sql" \
|
||||
"DELETE:backup__2021-01-17.sql" \
|
||||
"DELETE:backup__2021-01-16.sql" \
|
||||
"DELETE:backup__2021-01-15.sql" \
|
||||
"DELETE:backup__2021-01-14.sql" \
|
||||
"DELETE:backup__2021-01-13.sql" \
|
||||
"DELETE:backup__2021-01-12.sql" \
|
||||
"DELETE:backup__2021-01-11.sql" \
|
||||
"DELETE:backup__2021-01-10.sql" \
|
||||
"DELETE:backup__2021-01-09.sql" \
|
||||
"DELETE:backup__2021-01-08.sql" \
|
||||
"DELETE:backup__2021-01-07.sql" \
|
||||
"DELETE:backup__2021-01-06.sql" \
|
||||
"DELETE:backup__2021-01-05.sql" \
|
||||
"DELETE:backup__2021-01-04.sql" \
|
||||
"DELETE:backup__2021-01-03.sql" \
|
||||
"DELETE:backup__2021-01-02.sql" \
|
||||
"DELETE:backup__2021-01-01.sql" \
|
||||
"backup__2020-12-31.sql"
|
||||
}
|
||||
|
||||
function tests {
|
||||
# Run all functions named test_... in this file in definition order
|
||||
count=0
|
||||
while read -r test; do
|
||||
eval "$test"
|
||||
count=$((count + 1))
|
||||
done < <(awk '$1 == "function" && $2 ~ "^test_" {print $2}' "${BASH_SOURCE[0]}")
|
||||
|
||||
echo "------------------"
|
||||
echo "$((count - ERROR_COUNT - FAILURE_COUNT))/$count tests passed"
|
||||
if [[ $((FAILURE_COUNT + ERROR_COUNT)) -gt 0 ]]; then
|
||||
if [[ "$ERROR_COUNT" -gt 0 ]]; then
|
||||
echo "$ERROR_COUNT tests errored"
|
||||
fi
|
||||
|
||||
if [[ "$FAILURE_COUNT" -gt 0 ]]; then
|
||||
echo "$FAILURE_COUNT tests failed"
|
||||
fi
|
||||
echo 'failure'
|
||||
else
|
||||
echo 'success'
|
||||
fi
|
||||
}
|
||||
|
||||
if [ "${BASH_SOURCE[0]}" -ef "$0" ]; then
|
||||
trap 'echo -e "\\terror (in ${FUNCNAME[1]} ${BASH_SOURCE[1]}:${BASH_LINENO[1]})\naborting"' EXIT
|
||||
tests
|
||||
trap - EXIT
|
||||
|
||||
if [[ $((FAILURE_COUNT + ERROR_COUNT)) -gt 0 ]]; then
|
||||
exit 1
|
||||
fi
|
||||
fi
|
185
postgres-docker/weed.sh
Executable file
185
postgres-docker/weed.sh
Executable file
|
@ -0,0 +1,185 @@
|
|||
#!/usr/bin/env bash
|
||||
# Weed old backups. See HELP for details.
|
||||
# Tests for this script can be found in:
|
||||
# bookwyrm/postgres-docker/tests/testing-entrypoint.sh
|
||||
set -euo pipefail
|
||||
|
||||
DAILY_THRESHOLD=14
|
||||
WEEKLY_THRESHOLD=4
|
||||
MONTHLY_THRESHOLD=-1
|
||||
|
||||
HELP="\
|
||||
NAME
|
||||
|
||||
weed -- remove old backups from the backups directory
|
||||
|
||||
SYNOPSIS
|
||||
|
||||
weed.sh [-d threshold] [-w threshold] [-m threshold] [-l] backup_directory
|
||||
|
||||
DESCRIPTION
|
||||
|
||||
Reduce the number of backups by only keeping a certain number of daily backups before \
|
||||
reducing the frequency to weekly, monthly, and then finaly annually.
|
||||
|
||||
For each threshold, setting it to 0 will skip that frequency (e.g., setting weekly to \
|
||||
0 will mean backups go directly from daily to monthly), and setting it to -1 will \
|
||||
never reduce backups to a lower frequency (e.g., setting weekly to -1 will mean \
|
||||
backups never are reduced to monthly backups).
|
||||
|
||||
-d threshold: Store this many daily backups before switching to weekly \
|
||||
(default $DAILY_THRESHOLD)
|
||||
|
||||
-w threshold: Store this many weekly backups before switching to monthly \
|
||||
(default $WEEKLY_THRESHOLD)
|
||||
|
||||
-m threshold: Store this many monthly backups before switching to annual \
|
||||
(default $MONTHLY_THRESHOLD)
|
||||
|
||||
-l: Dry run. List the files that would be deleted.
|
||||
"
|
||||
|
||||
# fail <message>
|
||||
# Write a message to stderr then exit
|
||||
function fail {
|
||||
echo -e "weed: $1" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
# parse_threshold <hopefully-a-number>
|
||||
# Thresholds should be a non-negative number (or -1 for no threshold)
|
||||
function parse_threshold {
|
||||
if [[ ! $1 =~ ^-?[0-9]+$ || $1 -lt -1 ]]; then
|
||||
fail "Invalid threshold: $1"
|
||||
fi
|
||||
|
||||
echo "$1"
|
||||
}
|
||||
|
||||
# weed_directory <directory> <daily_threshold> <weekly_threshold> <monthly_threshold>
|
||||
# List files to be deleted
|
||||
function weed_directory {
|
||||
local directory=$1
|
||||
local daily_threshold=$2
|
||||
local weekly_threshold=$3
|
||||
local monthly_threshold=$4
|
||||
|
||||
local count=0
|
||||
local thresholds=("$daily_threshold" "$weekly_threshold" "$monthly_threshold" -1)
|
||||
local date_formats=("%Y %m %d" "%Y %W" "%Y %m" "%Y")
|
||||
local index=0
|
||||
local last_date=""
|
||||
local last_format=""
|
||||
local date=""
|
||||
|
||||
# We would like to loop through all the backup files in the backup directory in
|
||||
# reverse-chronological order. Bookwyrm backup files are named such that
|
||||
# chronological and lexical order match. So we should be safe to find all backup
|
||||
# files and reverse sort them. We should be terrified of deleting a backup an
|
||||
# instance maintainer wants to keep, so we will be extra cautious. We're ignoring
|
||||
# any subdirectories in case someone moves an important backup into a meaningfully
|
||||
# named folder. We are also prepending the date to the path before sorting so that
|
||||
# the ordering would be correct even if we were allowed to find backup files in
|
||||
# subdirectories where chronological and lexical order don't match.
|
||||
for date_file in $(
|
||||
find "$directory" \
|
||||
-maxdepth 1 \
|
||||
-name 'backup_[a-z]*_[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]\.sql' \
|
||||
| sed 's/\(^.*backup_[a-z]*_\([0-9-]*\)\.sql$\)/\2\1/' \
|
||||
| sort --reverse
|
||||
); do
|
||||
date="${date_file:0:10}"
|
||||
file="${date_file:10}"
|
||||
date="${date_file:0:10}"
|
||||
file="${date_file:10}"
|
||||
|
||||
# We can't fall off the end because we set annual backups to unlimited. It seems
|
||||
# unlikely that instance maintainers would have enough concern about the space
|
||||
# one backup/year takes to warrant supporting a cutoff.
|
||||
while [[ ${thresholds[index]} -ne -1 && $count -ge ${thresholds[index]} ]]; do
|
||||
index=$((index + 1))
|
||||
last_format=""
|
||||
count=0
|
||||
done
|
||||
|
||||
if [[ -z "$last_date" ]]; then
|
||||
count=$((count + 1))
|
||||
last_date=$date
|
||||
last_format=""
|
||||
else
|
||||
if [[ -z "$last_format" ]]; then
|
||||
last_format=$(date --date="$last_date" +"${date_formats[index]}")
|
||||
fi
|
||||
|
||||
format=$(date --date="$date" +"${date_formats[index]}")
|
||||
|
||||
if [[ "$format" == "$last_format" ]]; then
|
||||
echo "$file"
|
||||
else
|
||||
count=$((count + 1))
|
||||
last_date="$date"
|
||||
last_format="$format"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
function main(){
|
||||
local daily_threshold=$DAILY_THRESHOLD
|
||||
local weekly_threshold=$WEEKLY_THRESHOLD
|
||||
local monthly_threshold=$MONTHLY_THRESHOLD
|
||||
local dry_run=""
|
||||
|
||||
while getopts "hd:w:m:l" OPTION; do
|
||||
case "$OPTION" in
|
||||
h)
|
||||
echo "$HELP";
|
||||
exit
|
||||
;;
|
||||
d)
|
||||
daily_threshold=$(parse_threshold "$OPTARG")
|
||||
;;
|
||||
w)
|
||||
weekly_threshold=$(parse_threshold "$OPTARG")
|
||||
;;
|
||||
m)
|
||||
monthly_threshold=$(parse_threshold "$OPTARG")
|
||||
;;
|
||||
l)
|
||||
dry_run="true"
|
||||
;;
|
||||
:)
|
||||
fail "Missing argument for '$OPTARG'. To see help run: weed.sh -h"
|
||||
;;
|
||||
?)
|
||||
fail "Unknown option '$OPTION'. To see help run: weed.sh -h"
|
||||
esac
|
||||
done
|
||||
shift "$((OPTIND - 1))"
|
||||
|
||||
if [[ $# -ne 1 ]]; then
|
||||
fail "expected a single argument, directory"
|
||||
fi
|
||||
|
||||
local count=0
|
||||
for file in $(weed_directory "$1" "$daily_threshold" "$weekly_threshold" "$monthly_threshold"); do
|
||||
count=$((count + 1))
|
||||
if [[ -n "$dry_run" ]]; then
|
||||
echo "$file"
|
||||
else
|
||||
echo "deleting $file" >&2
|
||||
rm "$file"
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ -n "$dry_run" ]]; then
|
||||
optional_words="would be "
|
||||
else
|
||||
optional_words=""
|
||||
fi
|
||||
echo -e "$count files ${optional_words}deleted" >&2
|
||||
}
|
||||
|
||||
if [ "${BASH_SOURCE[0]}" -ef "$0" ]; then
|
||||
main "$@"
|
||||
fi
|
|
@ -11,8 +11,10 @@ django-sass-processor==1.2.2
|
|||
django-csp==3.7
|
||||
environs==9.5.0
|
||||
flower==1.2.0
|
||||
gunicorn==20.0.4
|
||||
libsass==0.22.0
|
||||
Markdown==3.4.1
|
||||
packaging==21.3
|
||||
Pillow==9.4.0
|
||||
psycopg2==2.9.5
|
||||
pycryptodome==3.16.0
|
||||
|
@ -34,12 +36,3 @@ opentelemetry-sdk==1.16.0
|
|||
protobuf==3.20.*
|
||||
pyotp==2.8.0
|
||||
qrcode==7.3.1
|
||||
|
||||
# Dev
|
||||
pytest-django==4.1.0
|
||||
pytest==6.1.2
|
||||
pytest-cov==2.10.1
|
||||
pytest-env==0.6.2
|
||||
pytest-xdist==2.3.0
|
||||
pytidylib==0.3.2
|
||||
pylint==2.14.0
|
||||
|
|
Loading…
Reference in a new issue