Repository navigation
Expand file tree
/
Copy pathJustfile
More file actions
138 lines (123 loc) · 6.88 KB
/
Copy pathJustfile
File metadata and controls
138 lines (123 loc) · 6.88 KB
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
# Bathymetry tiling pipeline. The build itself is one Snakemake DAG in one entry file (the
# repo-root Snakefile; `pipelines/build.smk` is included from it, gated on the `cover`
# checkpoint) — run via `snakemake` / `./docker.sh snakemake`, not this file. What remains here
# is the test suite, the dev servers, and the one-time mask prep. See CONTRIBUTING.md.
set working-directory := 'pipelines'
# Prepare the OSM land mask once (download -> unzip -> EPSG:3857 FlatGeobuf at
# store/landmask/land.fgb). Flagged coarse sources (GEBCO/EMODnet) clamp negative
# land pixels against it during the merge. LANDMASK overrides the output path.
landmask:
uv run python landmask.py prep
# Prepare the inland-water mask once (Overture water theme -> EPSG:3857 FlatGeobuf at
# store/landmask/water.fgb). The land clamp subtracts it so flagged coarse sources keep
# their depths inside mapped rivers/lakes. Optional — absent, the clamp stays land-only.
# WATERMASK overrides the output path.
watermask:
uv run python landmask.py prep-water
# Regional preview: sources streamed from R2 (a locally-prepped source wins), the whole
# cartographic chain (depth areas included) into store/bundle, then seed the local Worker.
# SKIP_DEPARE=1 opts out of the (now-bounded) depare fork if you only need the raster preview.
preview bbox="-74.30,40.40,-73.75,40.80":
#!/usr/bin/env bash
set -euo pipefail
export BBOX="{{bbox}}"
export SOURCE_VSI_BASE="${SOURCE_VSI_BASE:-/vsicurl/https://data.openwaters.io/bathymetry/source}"
export LANDMASK="${LANDMASK:-/vsicurl/https://data.openwaters.io/bathymetry/landmask/land.fgb}"
export WATERMASK="${WATERMASK:-/vsicurl/https://data.openwaters.io/bathymetry/landmask/water.fgb}"
export LANDRASTER="${LANDRASTER:-/vsicurl/https://data.openwaters.io/bathymetry/landmask/land-z8.tif}"
# One invocation: the `cover` checkpoint runs inside the bundles build (streamed sources),
# then the DAG re-evaluates into the per-stem mosaic/fork/terrain jobs.
# mem_gb budget from the actual environment (the Docker VM's memory, not the host's), minus
# a 2 GB reserve — without it snakemake admits concurrent heavy forks the VM OOM-kills (137).
# A dense-harbor z14 contour reserves ~10 GB: give the Docker Desktop VM >=16 GB for those.
mem_gb=$(free -g 2>/dev/null | awk 'NR==2{print $2}' || sysctl -n hw.memsize | awk '{print int($1/1073741824)}')
uv run snakemake -s ../Snakefile bundles --config stream=1 --cores 8 --resources mem_gb=$((mem_gb > 4 ? mem_gb - 2 : mem_gb))
# seed.sh needs manifest.json; stage_build writes it locally (publish is a separate, box-only step)
uv run python -c "import bundle; bundle.stage_build()"
../worker/seed.sh
# One dev server on :5173 — Vite serves the viewer and runs the tile Worker
# in-process (Cloudflare Vite plugin), so tiles are same-origin and no
# VITE_TILES_BASE is needed. Works in the container too (`./docker.sh dev`):
# --host binds 0.0.0.0 so the published port reaches it.
dev:
#!/usr/bin/env bash
set -euo pipefail
cd "{{justfile_directory()}}"
# -x check, not -d: in the container node_modules is a (possibly empty) named volume.
[ -x node_modules/.bin/vite ] || npm ci
npm run dev -- --host
# The whole test suite.
test: test-sources test-engine test-workflows
# Offline self-checks (synthetic data, no network).
test-sources:
uv run python config.py --check
uv run python source_enumerate.py --check
uv run python source_mirror.py --check
uv run python source_catalog.py --check
uv run python source_remote.py
uv run python source_fetch.py --check
uv run python source_prep.py --check
uv run python source_normalize.py --check
uv run python convert_gldb.py --check
uv run python source_polygonize.py --check
uv run python source_check.py --check
uv run python source_datum.py --check
uv run python datum_grid.py --check
uv run python datum_grid_fr.py --check
uv run snakemake -s ../Snakefile -n sources > /dev/null
# Build self-checks: the e2e (real stage-1 CLIs + the unified DAG), the `cover` checkpoint
# seam (test_build), each module's --check, and the cross-layer agreement of the three
# products that reduce the mosaic separately (test_consistency).
test-engine:
uv run python test_engine.py
uv run python aggregation_reproject.py --check
uv run python aggregation_covering.py --check
uv run python landmask.py --check
uv run python mosaic.py --check
uv run python bundle.py --check
uv run python test_build.py
uv run python terrain.py --check
# The forks off the merged DEM, each the shape of a whole product: their self-checks are
# where the geometry invariants live, so CI must run them and not just the modules around
# them. A collinear sounding field reached a planet build because this line was missing.
uv run python soundings_run.py check
uv run python depare_run.py check
uv run python contour_run.py check
uv run python smooth.py
uv run python heal_depare_schema.py --check
uv run python test_consistency.py
# Repo root: the logger plugin has to sit on sys.path under its discoverable name.
cd "{{justfile_directory()}}" && uv run python -m snakemake_logger_plugin_seascape --check
# Lint the GitHub Actions workflows.
test-workflows:
cd "{{justfile_directory()}}" && actionlint
# Test the GC's Collect step (scripts/gc-collect.sh — the exact script gc.yml runs, local
# backend) against a synthetic store tree: happy path + every refusal guard. Needs bash + jq +
# python3/pyarrow; ci.yml runs it on every push.
test-gc:
bash test_gc.sh
# Cut the local marsh profiling fixtures (small real windows over the Gulf, range-read from the
# published mosaic COGs) into store/profile/root. Needs R2 read creds — the public host refuses
# range requests.
perf-fixtures *sites:
uv run python perf/fixtures.py build {{sites}}
uv run python perf/fixtures.py masks
# Profile one real stage against a fixture and record wall / peak RSS / parts / vertices.
# just perf depare 12-1015-1699-15 base
perf stage stem label="adhoc":
uv run python perf/bench.py run {{stage}} {{stem}} --label {{label}}
# Compare two labelled runs; nonzero exit on a regression past threshold.
perf-compare a b:
uv run python perf/bench.py compare {{a}} {{b}}
# Safety gates for a generalization change: shoal-bias, water-network connectivity, drying
# growth on connected water (raster); partition contract, bounded displacement, named-route
# continuity (vector). Hard assertions — a failure is a defect, not a threshold to widen.
perf-gate kind before after *args:
uv run python perf/gates.py {{kind}} {{before}} {{after}} {{args}}
# Every self-check in the profiling harness.
test-perf:
uv run python perf/fixtures.py --check
uv run python perf/metrics.py --check
uv run python perf/bench.py --check
uv run python perf/soundings.py --check
uv run python perf/gates.py --check