Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
918d9de
chore: git-ignore the .superpowers scratch directory
samsrabin Aug 31, 2026
ff40fca
tests(rimport): red tests for walk_files
samsrabin Aug 31, 2026
8b1b94e
tests(rimport): red tests for expand_directories
samsrabin Aug 31, 2026
5a50396
tests(rimport): red tests for empty-argument rejection
samsrabin Aug 31, 2026
7fcc0d1
tests(rimport): red tests for main's provenance split and exit codes
samsrabin Aug 31, 2026
65f9de6
tests(rimport): pin the named-vs-discovered count in the abort-everyt…
samsrabin Aug 31, 2026
7405fce
tests(rimport): assert the relink half of staging, not just the copy
samsrabin Aug 31, 2026
f3e66a5
tests(rimport): red tests for directory and exit-code help text
samsrabin Aug 31, 2026
3905824
tests(rimport): fix round 1 – strengthen discriminators in help-text …
samsrabin Aug 31, 2026
cdeea46
tests(rimport): red end-to-end tests for directory enumeration
samsrabin Aug 31, 2026
b80f41d
rimport: Add walk_files and the Entry/Skip types
samsrabin Aug 31, 2026
bc7679d
rimport: Add expand_directories with named-vs-discovered provenance
samsrabin Aug 31, 2026
13e5854
rimport: Fix expand_directories count to report distinct files, not sum
samsrabin Aug 31, 2026
3722d36
rimport: Reject empty filename arguments
samsrabin Aug 31, 2026
1aa596b
rimport: Enumerate directory arguments instead of rejecting them
samsrabin Aug 31, 2026
8a9e245
rimport: Document exit code 3 and annotate two locals in main
samsrabin Aug 31, 2026
4685ca1
rimport: Document directory expansion and exit codes in --help
samsrabin Aug 31, 2026
166e3fc
rimport: Use custom formatter to wrap description while preserving ep…
samsrabin Aug 31, 2026
24d9eae
tests(rimport): red test for a named unreadable directory
samsrabin Aug 31, 2026
4d3040c
tests(rimport): pin the pre-flight count for a named unreadable direc…
samsrabin Aug 31, 2026
bbfed34
rimport: Treat a named unreadable directory as a named failure
samsrabin Aug 31, 2026
9798d27
tests(rimport): red tests for how walk skips are reported
samsrabin Aug 31, 2026
bf26267
rimport: Report walk skips, and only claim emptiness when true
samsrabin Aug 31, 2026
3e1df18
tests(rimport): red tests for the skip-warning guard's real question
samsrabin Aug 31, 2026
666daa9
rimport: Ask whether a skip was named, not whether it is the walk root
samsrabin Aug 31, 2026
8bf484f
docs(rimport): Exit 3 also means a directory could not be read
samsrabin Aug 31, 2026
bc326e3
tests(rimport): red test for a path under an unreadable parent
samsrabin Aug 31, 2026
6fe8f09
rimport: Do not crash probing a path under an unreadable parent
samsrabin Aug 31, 2026
9c45f82
rimport: Correct a false claim about which Python versions crash
samsrabin Aug 31, 2026
455ffa0
docs: Describe rimport directory enumeration in the README
samsrabin Aug 31, 2026
0ce3e6f
docs: Match the README's em-dash voice
samsrabin Aug 31, 2026
f5e37a0
docs: Scope the all-or-nothing promise to named paths
samsrabin Aug 31, 2026
5f1cb23
tests(rimport): red tests for skips that duplicate themselves
samsrabin Aug 31, 2026
7b64004
rimport: Give Skip its provenance, and collapse duplicate skips
samsrabin Aug 31, 2026
3bd5a06
rimport: Name exit 2's real triggers in --help, and state the precedence
samsrabin Aug 31, 2026
5ea1a5e
tests(rimport): Pin directory expansion on --file and --list
samsrabin Aug 31, 2026
4d41034
tests(rimport): red test for a named directory outside the root
samsrabin Sep 9, 2026
402dbf3
rimport: Scope directory expansion to the inputdata tree
samsrabin Sep 9, 2026
c3c7a63
rimport: Pin the check order, and scope the enumeration promise
samsrabin Sep 9, 2026
0d14917
docs: Say why a symlink to a directory is not enumerated
samsrabin Sep 9, 2026
8df280e
rimport: Name the expansion flag for what it means, and drop a rename
samsrabin Sep 10, 2026
faa6a0c
rimport: Say "item(s)", and stop printing the path twice
samsrabin Sep 10, 2026
fff73d4
tests(rimport): State what each test pins, not how it got there
samsrabin Sep 10, 2026
6523dc6
tests(rimport): Make three tests check what they claim to
samsrabin Sep 10, 2026
2bcba2b
tests(rimport): Pair every exit-code test with its --check twin
samsrabin Sep 10, 2026
9fa0db6
docs: Give exit codes their own README section
samsrabin Sep 10, 2026
d1d8992
Pin reason_text, and say "anything" where a directory can be skipped
samsrabin Sep 10, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
__pycache__
.coverage
.vscode
.superpowers/
29 changes: 26 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,32 @@ Notes:
- The `relink.py` script was previously used for step 3 above, but that functionality is now built into `rimport`. It's still there if you want to use it by itself.
- A relative filename passed to `rimport` directly (via `--file` or as a positional argument) is always resolved against your current directory — never against the inputdata root, and it doesn't matter whether you're running from inside or outside the inputdata tree. Pass an absolute path if you want to name a file without regard to your current directory.
- A relative entry in a `--list` file is always resolved against that list file's own directory — again never against the inputdata root, wherever the list file itself lives. Pass absolute entries in the list if you want them independent of the list file's location.
- Before staging anything, `rimport` validates every file it's about to process (all `--file`/`--list`/positional entries together). If any of them fail — missing, a directory, a broken symlink, outside the inputdata root, etc. — none of them are touched, and every failing path is reported at once so you can fix them all in one pass. This is a promise about rejected input, not about success: pre-flight passing doesn't guarantee the whole batch will finish, since a file can still fail later for a reason pre-flight can't see (e.g. a runtime/relink failure partway through).
- `--check` is gated by the same pre-flight validation as a real run: if any file in the batch fails validation, `rimport` reports the failures and exits without checking (or reporting on) any of the other files. This is deliberate, not a bug — fix the bad entries and re-run to see the rest.
- Exit codes: `0` means everything succeeded (or, under `--check`, everything checked cleanly); `2` means the run was rejected before touching anything (bad arguments, a missing/empty list file, or a pre-flight validation failure); `1` means pre-flight passed but something failed for real while actually being staged or relinked.
- Before staging anything, `rimport` validates every path you named (all `--file`/`--list`/positional entries together). If any of them fail — missing, a broken symlink, outside the inputdata root, etc. — none of them are touched, and every failing path is reported at once so you can fix them all in one pass. Anything found by expanding a directory you named — an invalid file, or a subdirectory that cannot be read — is not covered by this promise; it is skipped on its own, and the rest of the run continues (see "Directory arguments" below). This is a promise about rejected input, not about success: pre-flight passing doesn't guarantee the whole batch will finish, since a file can still fail later for a reason pre-flight can't see (e.g. a runtime/relink failure partway through).
- `--check` is gated by the same pre-flight validation as a real run: if any path you named fails validation, `rimport` reports the failures and exits without checking (or reporting on) any of the other files. This is deliberate, not a bug — fix the bad entries and re-run to see the rest.

### Directory arguments

Any name you give `rimport` — positional, `--file`, or a `--list` entry — may be a directory inside the inputdata tree. Every file beneath it is enumerated recursively and acted on. A directory outside the tree is rejected without being enumerated, exactly as a file outside it is. The directory itself is never copied to staging or replaced with a symlink. A symlink to a directory is the one carve-out: it is not expanded, but treated as a single entry — reported as already published if it points into the staging directory, and an error otherwise.

Why symlinks to directories are left alone, rather than enumerated:

- A symlink into staging is what `rimport` itself creates, so a symlink here is usually a published file rather than a detour to follow. Treating it as a single entry is what lets you re-run `rimport` over a tree it has already published.
- Enumeration never follows a directory symlink either, so it cannot loop on a link that points at its own ancestor, and cannot wander outside the directory you named and publish files you did not ask for. The rule for a name you give matches the rule used while walking, so a path behaves the same whichever way `rimport` reaches it.
Comment thread
samsrabin marked this conversation as resolved.

Anything found by enumeration that cannot be staged does not abort the run — an unstageable file, or a subdirectory that cannot be read. It is reported, skipped, and repeated in a summary at the end so it does not scroll away. A bad name you gave directly is still fatal, and nothing is published.

## Exit codes

| Code | Meaning |
|------|---------|
| 0 | Everything staged or checked, nothing skipped |
| 1 | A file could not be staged |
| 2 | A name you gave failed validation; nothing was published |
| 3 | Finished, but one or more items were skipped (listed at the end) |

When more than one code applies, the precedence is 2 > 1 > 3 > 0.

A name you gave failing is fatal (2). Anything found by expanding a directory you named is skipped instead, and the run continues (3).

## Filenames and metadata:

Expand Down
Loading
Loading