Merged
Conversation
There was a problem hiding this comment.
Pull request overview
Adds first-class multipart form handling to muxt template call-site identifiers, enabling generated handlers to parse multipart/form-data requests and bind uploaded files into strongly-typed receiver method parameters.
Changes:
- Introduces a new
multiparttemplate call-site identifier (mutually exclusive withform) and adds generation support for raw*multipart.Formand struct-binding modes. - Adds
--output-multipart-max-memory=<size>CLI flag (human-readable bytes) to controlrequest.ParseMultipartForm’smaxMemory. - Updates docs and expands txtar-based generator tests for multipart parsing, binding, and error cases.
Reviewed changes
Copilot reviewed 15 out of 16 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| internal/muxt/definition.go | Extends the recognized template call-site scope identifiers to include multipart. |
| internal/generate/routes.go | Implements multipart parsing + struct binding (including *multipart.FileHeader and []*multipart.FileHeader) and enforces form/multipart mutual exclusion. |
| internal/cli/commands.go | Adds CLI flag parsing for multipart max memory via go-humanize. |
| go.mod | Adds github.com/dustin/go-humanize dependency. |
| go.sum | Updates sums for the new dependency and dependency graph changes. |
| docs/reference/template-names.md | Documents multipart identifier semantics, supported types, mutual exclusion, and maxMemory flag. |
| cmd/muxt/testdata/reference_multipart_basic.txt | Adds generator + runtime test for single *multipart.FileHeader binding. |
| cmd/muxt/testdata/reference_multipart_multiple_files.txt | Adds generator + runtime test for []*multipart.FileHeader binding. |
| cmd/muxt/testdata/reference_multipart_mixed.txt | Adds generator + runtime test for mixed text + file multipart struct binding. |
| cmd/muxt/testdata/reference_multipart_raw.txt | Adds generator + runtime test for raw *multipart.Form parameter mode. |
| cmd/muxt/testdata/reference_multipart_with_name_tag.txt | Adds generator + runtime test for name tag rebinding with multipart fields. |
| cmd/muxt/testdata/reference_multipart_max_memory_flag.txt | Adds test asserting ParseMultipartForm(<bytes>) literal respects the new flag. |
| cmd/muxt/testdata/reference_multipart_parse_error.txt | Adds runtime test asserting malformed multipart bodies produce 400 via td.errStatusCode. |
| cmd/muxt/testdata/err_multipart_with_form.txt | Adds negative test ensuring form and multipart are rejected together. |
| cmd/muxt/testdata/err_multipart_unsupported_field_type.txt | Adds negative test for unsupported multipart-bound field types. |
| cmd/muxt/testdata/howto_multipart_file_upload.txt | Adds a task-oriented walkthrough test case for multipart file uploads. |
32cd910 to
ac54a7d
Compare
4 tasks
ac54a7d to
2dbde2d
Compare
Adds a peer to the existing form identifier: multipart triggers request.ParseMultipartForm and supports binding *multipart.FileHeader and []*multipart.FileHeader fields on the receiver method's struct param, alongside all existing form field types. - Raw mode: receiver param is *multipart.Form (escape hatch). - Struct mode: receiver param is a struct; text fields bind via request.PostForm, file fields via request.MultipartForm.File. - form and multipart are mutually exclusive in one call site. - ParseMultipartForm errors are captured into td.errList with td.errStatusCode = http.StatusBadRequest (real client-side faults). - Default maxMemory is 32 MiB; override with the generator flag --output-multipart-max-memory=<size> (parses 32MB, 64MiB, etc.). Assisted-by: Claude:claude-opus-4-7 gopls staticcheck gofumpt
2dbde2d to
a9b3bba
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
multipartcall-site identifier to muxt template names, peer to the existingformidentifier, that triggersrequest.ParseMultipartFormand supports binding*multipart.FileHeader/[]*multipart.FileHeaderstruct fields alongside all existingformfield types.form): raw mode (param type*multipart.Form— the parsed form is handed over directly) and struct-binding mode (text fields parsed via the existinggenerateParseValueFromStringStatementscodepath; file fields bound fromrequest.MultipartForm.File).--output-multipart-max-memory=<size>accepts human-readable byte sizes (32MB,64MiB,1GB) viagithub.com/dustin/go-humanize. Default 32 MiB.ParseMultipartFormerrors are captured intotd.errListwithtd.errStatusCode = http.StatusBadRequest(diverges from the silent-ignore behavior ofParseFormbecause multipart parse errors are real client-side faults). File reads are guarded byif request.MultipartForm != nilsince the stdlib leaves it nil on parse failure.formandmultipartin the same call site is a generation error.nameandtemplatestruct tags — no new tag namespace.docs/reference/template-names.mdparameter-source table.Test plan
go test ./...passescmd/muxt/testdata/:reference_multipart_basic,_multiple_files,_mixed,_raw,_with_name_tagreference_multipart_max_memory_flag— asserts the literalParseMultipartForm(<bytes>)and a functional upload testreference_multipart_parse_error— functional test: malformed multipart body → 400 viatd.errListerr_multipart_with_form,err_multipart_unsupported_field_typehowto_multipart_file_upload— task-oriented walkthroughgofumptcleanOut of scope
multipart32MBfor per-route limitsmaxsize,accept)*multipart.ReaderContent-Typeat runtimeParseFormerror-handling semantics for the existingformidentifierNote: humanize uses standards-correct unit semantics —
KB/MB/GBare decimal (1000-based),KiB/MiB/GiBare binary (1024-based). UseMiBif you want power-of-two values.Assisted-by: Claude:claude-opus-4-7 gopls staticcheck gofumpt