Add --archive option to ./mfc.sh run for interactive runs#1376
Add --archive option to ./mfc.sh run for interactive runs#1376drcole17 wants to merge 4 commits intoMFlowCode:masterfrom
Conversation
Bundles case source, namelists, stdout log, and output dirs (D/, p_all/, restart_data/, silo_hdf5/) into a timestamped snapshot with a manifest.yaml capturing git rev, build lock, and invocation. Supports dir, tar, and tar.zst formats. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Covers source collection, dir/tar/tar.zst round-trips, the no-op path when --archive is unset, and destination-collision errors. Registered in toolchain/bootstrap/lint.sh alongside the other module test suites. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
📝 WalkthroughWalkthroughThis pull request introduces archiving functionality to the MFC toolchain's 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (3)
toolchain/mfc/run/test_archive.py (1)
90-110: Unusual contextmanager-as-method pattern; consider simplifying.
from contextlib import contextmanager as _cminside the class body and then using it as a decorator on an instance method works, but is hard to read and unidiomatic. A plain helper function (or@contextlib.contextmanagerat module scope withself-less args) would be clearer. Non-blocking.toolchain/mfc/run/archive.py (2)
112-153: Minor: redundant arcname computation and missing tar archive hardening.
- Line 132:
rel = arcname(src)[len(arcroot) + 1:]reconstructs whatos.path.relpath(src, dirpath)already produces; callingarcnamejust to strip its prefix is confusing. Factor out a single_rel_for(src)helper.- Line 150-153: the uncompressed
tarbranch relies entirely onarcname(src)being safe. Combined with theoutput_summaryissue above, a badsrcturns into a tar member with..segments. Consider assertingnot arcname(src).startswith("..")beforetf.add, or reusing the staging-dir approach for both branches for symmetry.Non-blocking once the
output_summaryissue is fixed, but worth hardening defensively.
156-201: LGTM overall, two small nits.
- Line 169:
suffix = {...}[archive_format]willKeyErrorif called with an unexpected format; argparsechoicesprotects callers today, but a defensivesuffix = {...}.get(archive_format)with an explicitMFCExceptionwould give a friendlier error for programmatic callers.- Lines 180-201:
cons.indent()is called before thewith tempfile.NamedTemporaryFile(...). If that construction raises,cons.unindent()in thefinallyis never reached (thetrydoesn't cover it) — indent state leaks. Minor, but movingcons.indent()inside thetry(with a matchingunindentinfinally) makes it symmetric.Otherwise the orchestration (abspath/expanduser on archive_root, pre-existence check, no-op on empty sources, manifest-on-disk then copy/tar) reads cleanly.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 286685a4-ed7b-4b4b-81dc-c5f3bb688fb5
📒 Files selected for processing (5)
toolchain/bootstrap/lint.shtoolchain/mfc/cli/commands.pytoolchain/mfc/run/archive.pytoolchain/mfc/run/run.pytoolchain/mfc/run/test_archive.py
- Skip output_summary when it lives outside case dir (prevents '..' arcnames escaping the archive root in copy/tar writers) - Raise MFCException on unknown archive_format instead of KeyError - Move cons.indent() inside the try so unindent() in finally runs only when paired - Extract rel_for() helper in __write_tar; add defensive '..' checks in both tar branches - Hoist _run_archive context manager out of the class body in tests - Add test covering the output_summary escape fix Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
Nice feature. Seems like a good idea! I do wonder if the |
|
@sbryngelson Sure, I will push a more appropriate flag choice. Thanks! |
|
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #1376 +/- ##
=======================================
Coverage 64.75% 64.75%
=======================================
Files 71 71
Lines 18711 18711
Branches 1549 1549
=======================================
Hits 12117 12117
Misses 5638 5638
Partials 956 956 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Address @sbryngelson's review comment: -A would be confusing next to sbatch's -A (account) convention even though MFC's --account is -a. Just use the long --archive form; single-letter flags are scarce real estate and this isn't something users type often enough to earn one. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Description
Adds an
--archive PATHoption (short-A) to./mfc.sh runthat, after an interactive run completes, collects the case inputs and produced artifacts into a timestamped archive alongside amanifest.yaml(invocation, git tagline, build lock, targets, contents). A companion--archive-formatflag selects the container:dir(default),tar, ortar.zst.Motivation: make it easy to snapshot a run (case.py, generated
*.inpfiles,<name>.sh/<name>.out,equations.dat,time_data.dat,D/,p_all/,restart_data/, etc.) for later reference or sharing without manually copying files.Scope is currently limited to interactive runs; for batch submissions the flag is ignored with a yellow warning, since outputs are produced asynchronously after
qsub/sbatchreturns. Would like to implement for batch runs as well.What it adds
toolchain/mfc/cli/commands.py— two newrunflags with help text, examples, and shell-completion entries.toolchain/mfc/run/archive.py— new module: source collection, manifest build, dir/tar writers, andtar --zstdsubprocess path.toolchain/mfc/run/run.py— wires the archive call after__execute_job_scriptwhen the queue system is interactive.toolchain/mfc/run/test_archive.py— unit tests (registered intoolchain/bootstrap/lint.sh).Type of change
Scope
How Has This Been Tested?
Smoke-tested with
examples/1D_sodshocktube/case.pyacross all three formats:./mfc.sh run examples/1D_sodshocktube/case.py --archive /tmp/mfc-archives— produced aMFC-<timestamp>/directory containingcase.py,simulation.inp,pre_process.inp,equations.dat,time_data.dat,D/,p_all/,restart_data/, andmanifest.yaml.--archive-format tar— produced a valid.tarreadable bytarfile/tar -tf.--archive-format tar.zst— produced a valid.tar.zstreadable bytar --zstd -tf.Unit tests (
toolchain/mfc/run/test_archive.py, 7 tests) cover:__collect_sourcespicks up case file, namelist, and artifact files/dirs; skips missing artifacts.dir,tar,tar.zstformats (the zst test skips iftar --zstdis unavailable).--archiveis unset.MFCExceptionis raised when the destination already exists.Tests registered in
toolchain/bootstrap/lint.shand run as part of./mfc.sh lint.Checklist
GPU Changes
No GPU code paths were touched; this is a toolchain-only change.