Batch Texture Renamer
You have a folder of textures named rock albedo 2.png, Rock_Albedo_FINAL.png, and rockalbedo-old(1).png. Build the tool that fixes it - safely - and you've got your first real pipeline piece.
On this page
The brief Constraints Acceptance criteria Suggested approach Stretch goals Breakdown template§the brief
Build a command-line tool that renames files to an agreed convention. A teammate should be able to preview the changes, understand any errors, and recover from a mistake. Those behaviours are part of the tool, rather than extras to add later.
This is a useful first pipeline project because it combines messy inputs, naming rules, and files that need protecting. Folder traversal, string handling, and dry runs will carry across to other batch tools.
§constraints
Use these constraints to keep the first version focused and testable:
- Standard library only. Avoid extra packages for this exercise. Check the Python version in the DCC before reusing the script there.
- The default mode must change nothing. Running the tool with no flags prints what it would do and touches zero files. Renaming only happens with an explicit --apply.
- No data loss, ever. If two files would end up with the same name, the tool refuses and explains - it doesn't silently overwrite.
- Cross-platform paths. Use pathlib. No hand-built "\\" strings.
§acceptance criteria
You're done when all of these are true. Copy this into your README and tick them off:
- Running with just a folder path prints a before → after plan and renames nothing.
- Adding --apply performs the rename and writes a log file recording every change.
- Two files that would collide on the same target name cause a clear error, and no files are renamed in that run.
- Files already matching the convention are skipped, not needlessly rewritten.
- --help produces usage text someone else could follow without reading your code.
- Running it twice in a row is safe - the second run reports "nothing to do".
§suggested approach
Don't build it all at once. Build it in the order that keeps you safe:
- List the files first. Start with a loop over
Path.iterdir()that prints names without changing them. - Write the naming function. Convert one input name to the target format and test unusual names before using it on real files.
- Build the plan. Create and print the old and new name pairs. Review the output before adding the code that renames files.
- Add the safety rails. Collision detection, then the undo log.
- Make it a tool. Wrap it in argparse so it has flags and help text. Now it's something a teammate can run.
The First Pipeline Script tutorial walks through this build and includes a reference script. Try your own version first, then compare the decisions and checks.
§stretch goals
Once the core works, choose an extension that adds a useful behaviour:
- Suffix detection: files containing "normal"/"nrm" get a _N suffix, "roughness" gets _R, and so on. Now it understands texture types, not just names.
- Add an undo script that reads the log and reverses a rename. Test that it detects conflicts before making changes.
- Recursion with --recursive (mind the log file - don't rename your own log).
- A dry-run diff view that highlights only the part of each name that changed.
§breakdown template
Include a breakdown that explains the problem, your approach, and how you checked the result. Use the template to make those decisions easy to review:
## Batch Texture Renamer **The problem** (one sentence): artists were spending ~10 min per drop hand-renaming textures to our convention. **Constraints:** stdlib only, must be safe to run on a live library. **What it does:** [screenshot or a 20-second GIF of the dry-run + apply] **The approach - including the dead end:** - First version renamed on the first pass. Then I fed it two files that collided and it ate one. That's why the plan/apply split exists now. **Result:** ~10 min/drop -> ~5 seconds, and nobody has lost a file. **What I'd do next:** [suffix detection / the undo script / ...]
Include an approach that didn't work and explain what you learned from it. That gives the reader context for the final design.
