@@ -232,17 +232,61 @@ hash = "sha256:..."
232232The ` exe ` field can be specified at three levels, checked in this order:
233233
2342341 . ** Distribution-level** (` [[programs.{name}.dists]] ` entry with ` exe ` field)
235+ - ** Supports any custom path** within the archive
235236 - Use when different platforms have different archive structures
236237 - Most specific - overrides program-level and default
237238 - Example: ` exe = "mf6.7.0_win64/bin/mf6.exe" `
239+ - Example: ` exe = "custom/nested/path/to/program" `
238240
2392412 . ** Program-level** (` [programs.{name}] ` section with ` exe ` field)
242+ - ** Supports any custom path** shared across all platforms
240243 - Use when all platforms share the same relative path structure
241244 - Example: ` exe = "bin/mfnwt" `
245+ - Example: ` exe = "special/location/program" `
242246
2432473 . ** Default** (neither specified)
244- - Falls back to ` bin/{program} `
245- - Example: For ` mf6 ` , defaults to ` bin/mf6 `
248+ - ** Automatically detects** executable location when installing
249+ - Tries common patterns in order:
250+ - ** Nested with bin/** : ` {archive_name}/bin/{program} `
251+ - ** Nested without bin/** : ` {archive_name}/{program} `
252+ - ** Flat with bin/** : ` bin/{program} `
253+ - ** Flat without bin/** : ` {program} `
254+ - Example: For ` mf6 ` , automatically finds binary whether in ` mf6.7.0_linux/bin/mf6 ` , ` bin/mf6 ` , or other common layouts
255+ - Only used when no explicit ` exe ` field is provided
256+
257+ ** Archive structure patterns** :
258+
259+ The API supports four common archive layouts:
260+
261+ 1 . ** Nested with bin/** (e.g., MODFLOW 6):
262+ ```
263+ mf6.7.0_linux.zip
264+ └── mf6.7.0_linux/
265+ └── bin/
266+ └── mf6
267+ ```
268+
269+ 2 . ** Nested without bin/** :
270+ ```
271+ program.1.0_linux.zip
272+ └── program.1.0_linux/
273+ └── program
274+ ```
275+
276+ 3 . ** Flat with bin/** :
277+ ```
278+ program.zip
279+ └── bin/
280+ └── program
281+ ```
282+
283+ 4 . ** Flat without bin/** :
284+ ```
285+ program.zip
286+ └── program
287+ ```
288+
289+ The ` make_registry ` tool automatically detects which pattern each archive uses and only stores non-default exe paths in the registry.
246290
247291** Windows .exe extension handling** :
248292- The ` .exe ` extension is automatically added on Windows platforms if not present
@@ -628,6 +672,12 @@ python -m modflow_devtools.programs.make_registry \
628672- Optionally computes SHA256 hashes from local files with `--compute-hashes`
629673- Creates asset entries from local file names
630674- Auto-detects platform from file names (linux, mac, win64, etc.)
675+ - **Automatic pattern detection**:
676+ - Inspects archives to detect executable locations
677+ - Recognizes nested and flat archive patterns
678+ - Automatically optimizes exe paths (only stores non-default paths)
679+ - Detects when all distributions use the same relative path
680+ - Caches downloaded assets to avoid redundant downloads when multiple programs share the same archive
631681
632682**Example CI integration** (GitHub Actions):
633683```yaml
@@ -662,9 +712,15 @@ python -m modflow_devtools.programs.make_registry \
662712
663713**How it works:**
664714- Fetches release assets from GitHub API using repo and version (tag)
665- - Downloads assets if `--compute-hashes` is specified
715+ - Downloads assets to detect exe paths and enable pattern optimization
716+ - Optionally computes SHA256 hashes with `--compute-hashes`
666717- Useful for testing or regenerating a registry for an existing release
667718- No `--dists` argument needed - pulls from GitHub directly
719+ - **Automatic pattern detection** (same as Mode 1):
720+ - Inspects archives to find executables
721+ - Detects nested/flat patterns automatically
722+ - Only stores non-default exe paths in registry
723+ - Caches downloads when processing multiple programs from same release
668724
669725**Additional options:**
670726```bash
0 commit comments