Update all non-major dependencies - #75
Merged
Merged
Conversation
Contributor
Author
ℹ️ Artifact update noticeFile name: go.modIn order to perform the update(s) described in the table above, Renovate ran the
Details:
|
renovate
Bot
force-pushed
the
renovate/all-minor-patch
branch
3 times, most recently
from
September 16, 2026 12:40
274e67b to
ba41db1
Compare
renovate
Bot
force-pushed
the
renovate/all-minor-patch
branch
from
September 17, 2026 21:38
ba41db1 to
bfec941
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.
This PR contains the following updates:
v1.8.0→v1.11.0v0.45.0→v0.46.0v0.41.0→v0.42.0v3.1.0→v3.2.0Release Notes
creasty/defaults (github.com/creasty/defaults)
v1.11.0Compare Source
v1.10.0 ended with six known issues. This release fixes three of them — data with a cycle crashed the process, a
SetDefaultsran after an unmarshaler had taken the tag, and a failed default left part of itself behind — and half of a fourth:Setno longer writes to a map of slices or maps. The other two, and the rest of the fourth, stay as they are, now documented as intended. The API is unchanged, and so isgo.mod.Behavior changes come first, as before. Two of them can change what a working program does, and neither announces itself: one stops a
SetDefaultscall, and the other changes whatSetleaves behind when it returns an error.[BREAKING]
SetDefaultsis skipped behind a pointer once an unmarshaler took the tag (#97)The README says that when a tag is handed to
UnmarshalText,SetDefaultsis not called. v1.10.0 made that hold for a struct, behind a pointer or not, and listed the rest as a known issue: a pointer to any other type still gotSetDefaultsafter its unmarshaler took the tag. It no longer does:Level, left zero*Leveldefault:"3"**Leveldefault:"3"*Leveldefault:"3"*Level, withUnmarshalJSONin place ofUnmarshalText*Leveldefault:"", which no unmarshaler is offered*Leveldefault:"0x10", whichUnmarshalTextrejects and parsing by kind takesLeveldefault:"3"Nothing reports the missing call. How to tell whether you are affected: look for a type that is not a struct — a named
int,stringor slice — with bothSetDefaultsandUnmarshalTextorUnmarshalJSON, behind a pointer a tag allocates. If itsSetDefaultsadjusted what the unmarshaler produced, that adjustment is gone; make it in the unmarshaler instead. A field of the type itself never got the call, and a pointer the caller allocated is still left alone.[BREAKING] A failed default no longer leaves part of itself behind (#98)
When a default failed,
Setreturned the error but kept what it had filled on the way down. The value was then no longer zero, so a secondSetcould skip the tag and returnnil, which v1.10.0 listed as a known issue for*scalar,*[]Tand*mapfields. Now each valueSetfound zero on the way to the failing default is put back to zero, whatever part of the default it had taken:Setreturned the error*intdefault:"eighty"&0, and a secondSetreturnsnilnil, and a secondSetreturns the error again*[]stringdefault:"[1]"&[], and a secondSetreturnsnilnil, and a secondSetreturns the error againdefault:"{\"X\": 1, \"Y\": \"two\"}"{X:1 Y:0}{X:0 Y:0}Atook7beforeBfailed{A:7 B:0}{A:0 B:0}big.Intdefault:"12x", which itsUnmarshalTextfills partway before rejecting120[]Tdefault:"[{}]", whose element's default failsnilOnly values that were zero are put back. A pointer, slice or map the caller provided is kept, and the fields of the struct passed to
Setkeep the defaults they took before the failure: there,Astays7. The*uuid.UUIDrow in the v1.10.0 notes changes the same way, to an error with the pointer leftnil.Who is affected: code that ignores
Set's error, or recovers fromMustSet's panic, and then uses the value. Where it found an allocated pointer it now findsnil, so reading through it panics; where it found part of a default it finds a zero value; and a secondSetreturns the error again, where it could returnnil.Data with a cycle ends instead of crashing the process (#104, #108)
Setfollowed wherever the caller's data pointed, so data with a way back to itself, such as a child pointing up to its parent, was walked until the stack overflowed. That is a fatal error rather than a panic: norecovercatches it, and the process exits.Setnow keeps track of the structs, slices and maps on the path it is walking. Where the data leads back to one of them, it goes no further, and the walk already under way finishes that value, so a struct gets no secondSetDefaultsfrom its own cycle. Down to 64 values deep the check scans the path and allocates nothing; below that it builds an index of the path and looks values up in it, so deep data costs a few allocations rather than time growing with the square of the depth (#108). See Performance.A walk that finished in v1.10.0 finishes the same way, with one exception: if a
SetDefaultsbelow a repeated value broke the cycle as a side effect, say by clearing the pointer back, v1.10.0 walked that value a second time, and this release does not. The check covers the current path only, so a value that two paths reach, neither through the other, is still walked on both, as described below.Setno longer writes to a map of slices or maps (#105)A map value is not addressable, so
Setfills a copy and stores it back under its key. It stored back every struct, slice and map value it walked, changed or not, which v1.10.0 listed as a known issue: a goroutine reading the map meanwhile raced withSet, and could crash. A slice or map copy shares its array or table with the value in the map, so storing it back never changed anything, and it no longer happens:map[string][]TthatSetwalksSetconcurrent map read and map writeSetonly reads the mapSetDefaultsdeletes the key its slice is underSetstores the key backThe same holds for a map of maps. A struct value is still stored back, changed or not, so a map of structs still must not be read during
Set; that is now documented as intended, below.An int64 default neither parser takes reports both reasons (#96)
An int64-kinded field is offered to
time.ParseDurationand then tostrconv.ParseInt, since reflection cannot tell atime.Durationfrom a plainint64(#66). When both rejected the tag, onlyParseInt's error was reported, so a duration with a unit Go does not know read as bad integer syntax:time.Durationdefault:"1d"strconv.ParseInt: parsing "1d": invalid syntaxtime: unknown unit "d" in duration "1d"; strconv.ParseInt: parsing "1d": invalid syntaxint64default:"abc"strconv.ParseInt: parsing "abc": invalid syntaxtime: invalid duration "abc"; strconv.ParseInt: parsing "abc": invalid syntaxintdefault:"1d"strconv.ParseInt: parsing "1d": invalid syntaxThe
field X: invalid default "…":prefix is unchanged, and on a plainint64the duration half is noise, the cost of the shared parser. A type whose own unmarshaler rejected the tag still reports only that rejection (#90). Both errors are wrapped, soerrors.Asstill reaches the*strconv.NumErroranderrors.Isstill matchesstrconv.ErrSyntaxandstrconv.ErrRange, buterrors.Unwrapno longer reaches it in one step:errors.Unwrap(err).(*strconv.NumError)stops matching. An empty tag is still no error, and no longer pays for an error message it throws away (#107).Kept as they are, and now documented
Three behaviors that look wrong were weighed and kept. The README now describes each, and a test marked
// QUIRKor// BUGpins it, so changing one later means flipping that test:SetDefaultscall on each, as v1.10.0's known issues said. #99 filled such a value once per call, at the cost of an allocation on everySetthat entered a value, and was closed in favor of #103 and #104. ASetDefaultsthat is not idempotent applies once per path, and a chain of values each shared by two pointers takes time that doubles with every link.Setwhile another goroutine reads a map of structs it walks. #101 stored a struct back only when it changed, at the cost of an allocation for each struct a tag or setter touched, and was closed in favor of #105.*[]T,*map[K]Tor**Tholds gets no defaults, and a default that would fail there is not reported, though a*[]Tor*map[K]Theld as a map value is descended into, as it has been since v1.6.0. #100 descended into all three and was closed in favor of #106, which pins the skip: nobody had asked for the descent, and it would bring new errors and new cycles.#95 pins more behavior no test covered, marking what looks wrong
// QUIRK, and corrects documentation that described behaviorSetdoes not have:default:"0644"is 420, anddefault:"08080"is an error. Slice and map tags are JSON, where a number rejects a leading zero and an integer map key"010"is 10.{}and[]are never handed toUnmarshalJSONdirectly, thoughencoding/jsonmay call it while parsing the other literal.API and minimum Go version: unchanged
Set,MustSet,CanUpdate,SetterandErrInvalidTypeare as in v1.10.0.go.modstill saysgo 1.22, and CI tests 1.22, 1.26 and 1.27.Performance
Measured with
make bench-compare BASE=v1.10.0, the suite from #102: 6 interleaved rounds at 400ms, Go 1.26.5, darwin/arm64 (M1 Max). Every difference shown is significant at p < 0.05. Allocations are unchanged on every row but those named below.Faster: slices and maps of scalars.
Setwalked every element of a slice and every entry of a map whatever their type, though only a struct, pointer, slice or map element can hold a default. It now skips the rest (#103). Tagged fields also got cheaper, since the tag is offered to a field's unmarshalers through one interface conversion rather than two (#110):[]intof 1000map[string]intof 1000map[string]intdefault parsed from its tagSet, a struct, a pointer, a slice and a map*intfieldsSeton four scalar fields is unchanged, at 547 ns against 538 ns (p=0.18).Slower: walking values that could hold a default, by 3 to 14%. Each struct, slice and map
Setenters now checks the path above it for a cycle (#104), and each field it visits takes one more call (#98):Deep data costs a little more, and a few allocations. Down to 64 values deep the cycle check scans the path; below that it builds an index of the path, which is what keeps the cost from growing with the square of the depth (#108).
Seton an already-filled linked list of structs, one tagged field each, measured withtesting.Benchmarkoutside the committed suite (the last row is a single call):A slice of pointers to structs runs in one of two modes. A filled
[]*Tof 1000 elements takes about 187 µs in some processes and about 313 µs in others, where v1.10.0 took 183 µs in every process. A process picks a mode as it starts and keeps it for its whole run. Over twelve fresh processes each, v1.10.0 was fast in twelve, this release's #111 was fast in twelve, and #112 — which only stopped aliasing a struct field to a local — was fast in four. That change removes no work and alters no behavior: the cost is in the machine code the compiler generates around it. The alias stays gone by choice, since keeping a local to steer code generation would argue for hoisting the tag's other fields into locals too. A map of slices moves with it, at 30 µs against 38 µs.Parse/unmarshaler/textreads 23% faster than on v1.10.0. That is code placement rather than work removed: the same row moved as far with dead code added to an unchanged tree (#108).Documentation
Setdescends into. (#95, #97, #98, #104, #105, #106)Set's doc comment says what it fills, what it descends into, what it writes to a map and what a failure leaves behind.Setter's saysSetDefaultsis called once for each path to its struct, but not again from a cycle.MustSetexample; the package example calls it. (#95)Internals
benchmark_test.gois a suite of 46 cases: whole calls, the zero check, each parse path, walks with nothing left to fill, and failures.make bench-compare BASE=<ref>runs it against another commit in interleaved rounds and compares them with benchstat, and CI runs every case once on each Go version. Every number under Performance but the deep-nesting table comes from it. (#102, #108)Setnow live in files of their own, with their tests beside them inpackage defaults: the promoted-method check (method.go), the unmarshaler handoff (unmarshal.go) and the path check and its index (path.go). They are the only exception to this repository's black-box test rule, since nothing else can reach them. (#109, #110, #111)path.goimportsunsafeto hold each value on the path as anunsafe.Pointer, which keeps that value alive so nothing allocated below it can reuse its address, and its index keys hold addresses asuintptrso that entries stay off the heap. There is no pointer arithmetic. (#104, #108)make covernow measures./...rather than the root package alone. (#109)Upgrading
Run your tests. If a value that a
SetDefaultsused to adjust comes back as its unmarshaler left it, see the first section. If code carries on afterSetreturns an error, expectniland zero values where part of a default used to be. If you match the text of errors from anint64ortime.Durationfield, they now name both parsers.Full Changelog: creasty/defaults@v1.10.0...v1.11.0
v1.10.0Compare Source
v1.9.0 ended with a list of four known issues. This release fixes three of them — #67, #71 and #79 — and two more bugs, #69 and #89, and exports the error
Setreturns for an argument it cannot fill (#70).Behavior changes come first again. Two of them can change what a working program does. One is loud: a tag that was never applied is now an error. The other is quiet — a
SetDefaultsthat ran only through method promotion no longer runs — so it comes first.[BREAKING]
SetDefaultsruns once per value, and not through promotion (#85, #86)In v1.9.0 a
SetDefaultscould run two or three times on the same value. A struct behind a pointer got one call as its fields were filled and another from the pointer (#67). A method promoted from an embedded field ran once for the field and again through the struct embedding it, and once more for each further level of embedding.A value reached by one path now gets one call, and an embedded field gets exactly the calls a named field of its type would get. For a setter that is idempotent — the usual
if c.Port == 0 { c.Port = 8080 }— this first table changes nothing:SetDefaultscalls*Tfield, taggeddefault:"{}"or allocated by the caller[]*T**TfieldTT, two levels deep*TThat count is per path. A value reached by more than one path — two pointers to one struct, two slices over one array, one map held in two fields — still gets one call from each: two pointers to one struct went from 4 calls to 2, not to 1. See Known issues.
The second table is the one to read twice. These calls happened only through promotion, or after an unmarshaler had already taken the tag, and nothing reports that they are gone:
SetDefaultscallsTtaggeddefault:"-"SetterTwhoseUnmarshalTexttook the tag*Tfield,Ta struct, whoseUnmarshalTexttook the tag*TleftnilnilreceivernilThe
*Tfield row is not an embedding. A*Tfield ranSetDefaultsafterUnmarshalTextwhere aTfield does not; it now agrees with theTfield and with the README, which says the tag is handed toUnmarshalTextandSetDefaultsis not called. That holds only whenTis a struct: a pointer to a non-struct type with both methods, such as*Levelfortype Level int, still getsSetDefaultsafterUnmarshalTexttook the tag, as in v1.9.0.How to tell whether you are affected: look for a type whose
SetDefaultsyou rely on, embedded where it gets no call of its own. A value it used to fill now stays zero:To keep the call, declare
SetDefaultson the embedding struct and forward it:Forward only to a field the second table says gets no call. An exported embedded struct is visited and already gets its call, so forwarding to it runs the setter twice.
Also check any setter that is not idempotent. One that appends, counts or toggles now runs once where it ran two or three times — that is the fix, but it undoes anything that compensated for the repeat.
An embedded non-struct type with a setter, such as
type Level int, loses one call too, behind a pointer or not. A struct that declares its ownSetDefaultsnext to an embedded one still gets both calls.[BREAKING] An array or complex type whose unmarshaler rejects its tag is now an error (#92)
v1.9.0 made an invalid default an error, but missed one path. A type's own
UnmarshalTextorUnmarshalJSONis offered the tag first, and when it refuses,Setfalls back to parsing by kind. Arrays and complex numbers have no parsing by kind, so the refusal went nowhere: the field stayed zero andSetreturnednil. Foruuid.UUID, a[16]byte, that zero is a nil UUID that looks legitimate. Now:uuid.UUIDdefault:"not-a-uuid"*uuid.UUIDdefault:"not-a-uuid"complex128whoseUnmarshalTextrejects the tag0, no error[3]intdefault:"[1,2,3]", no unmarshalerAs with v1.9.0's change, this can stop a program at startup, and only over a tag that never applied. An array type with no unmarshaler has nothing to reject its tag, so the last row is unchanged.
A rejected tag reports the unmarshaler's reason (#90)
When a type's own unmarshaler refused a tag and parsing by kind failed as well,
Setreported the second failure — often fromencoding/json, a parser the tag was never written for. It now reports the unmarshaler's:time.Timedefault:"garbage"invalid character 'g' looking for beginning of valueparsing time "garbage" as "2006-01-02T15:04:05Z07:00": cannot parse "garbage" as "2006"slog.Leveldefault:"bogus"strconv.ParseInt: parsing "bogus": invalid syntaxslog: level string "bogus": unknown nametime.DurationwithUnmarshalText,default:"garbage"invalid character 'g' looking for beginning of valuetime: invalid duration "garbage"The
field X: invalid default "…":prefix is unchanged and the cause is still wrapped with%w, buterrors.Asnow reaches the unmarshaler's error type — a*time.ParseErrorfortime.Time, where it used to be a*json.SyntaxError.Nothing that succeeded fails now. The fall-back to parsing by kind stays, so
slog.Levelwithdefault:"4"— which its unmarshalers reject, since they take names only — is stillWARN.One message gets worse. When both of a type's unmarshalers reject a tag,
UnmarshalText's reason is the one reported, since it was asked first. For a JSON-quotedtime.Timewith a bad date,default:"\"2020-13-01T00:00:00Z\"", that is a complaint about the quote, where v1.9.0 saidmonth out of range.A default that recurses without end is an error, not a crash (#87)
A type that refers to itself through a field whose tag creates another of it recursed until the stack overflowed. A stack overflow is fatal rather than a panic, so no
recovercould catch it.Next *Nodedefault:"{}"fatal error: stack overflowfield Next: default "{}" recurses without endChildren []Treedefault:"[{}]"fatal error: stack overflowfield Children: default "[{}]" recurses without endEdges map[string]Graphdefault:"{\"a\":{}}"fatal error: stack overflowfield Edges: default "{\"a\":{}}" recurses without endThe check is exact, not a depth limit: it stops where the same tag is about to fill a zero value of the same type inside itself, which is the one case that cannot end. A recursive type that does end — at a field with no tag, a tag that creates nothing, or a value already filled in — is walked as before.
A nil argument is an error, not a panic (#84)
Set(nil)runtime error: invalid memory address or nil pointer dereferenceErrInvalidTypeSet((*Config)(nil))reflect: call of reflect.Value.Type on zero ValueErrInvalidTypeMustSetwith eitherSetdoesErrInvalidTypeCode that panicked was never working, so nothing regresses. One consequence: if you ignore
Set's error, a nil*Configno longer crashes insideSet, so it crashes later, wherever it is first dereferenced.API: one addition,
ErrInvalidType(#93)The error for an argument that is not a non-nil pointer to a struct is exported, so it can be told apart from a bad tag without matching its text:
Its message is still
not a struct pointer, so code matching the text keeps working. Test for it witherrors.Israther than==, as its doc comment says.MustSetpanics with the sentinel itself.Set,MustSet,CanUpdateandSetterare unchanged.Minimum Go version
go.modmoves fromgo 1.21togo 1.22. The zero-value check now usesreflect.Value.IsZero(#83), which until Go 1.22 compared a float's bits and so read-0.0as non-zero (golang/go#61827). On 1.21 a float field holding-0.0would have kept it instead of taking its default; on 1.22 and later it takes the default, as in v1.9.0. CI tests 1.22, 1.26 and 1.27.Go 1.21 has been out of support since 1.23 shipped. A module still on it can stay on v1.9.0;
go getof v1.10.0 raises the module'sgoline to 1.22.Performance
The zero-value check uses
reflect.Value.IsZerorather thanreflect.DeepEqualagainst a fresh zero value (#83), andSetruns it once per field. A struct with aSetDefaultsnow also pays for the promotion check from #86, which outweighs that saving on a small struct. Measured withmake benchplus a struct that has a setter — Go 1.26.5, darwin/arm64, medians of six interleaved runs:Set, four scalar fieldsSet, a struct, a pointer, a slice and a mapSet, two fields and aSetDefaultsCanUpdate, scalarCanUpdate, four-field structDocumentation
example/main.go. The zero-value caveat gets its own section, and the design principles from #61,default:"-", an install line and a pkg.go.dev badge are new. (#82)example/is replaced by a package example on pkg.go.dev whose outputgo testchecks; the old program's expected output had gone stale. (#91)Setter's doc comment says whenSetDefaultsis called (#86), andErrInvalidType's how to test for it (#93).Internals
reflectlists a promoted method and a declared one alike, so #86 tells them apart by where the method's code lives: the compiler positions the wrapper it generates for a promoted method in<autogenerated>. The Go spec does not promise that. The suite pins both directions, so if a Go release changes it, the tests fail; CI runs the gc toolchain on 1.22, 1.26 and 1.27.defaults.gois split intoset.go,mustset.goandcanupdate.go, each beside its tests, andinternal/fixtureis gone. (#82)test-okcheck for a branch rule to require, whatever Go versions the matrix holds. (#88)make benchbenchmarksSetandCanUpdate. Statement coverage stays at 100%.Known issues, unchanged by this release
time.Durationand a plainint64share one parser, sodefault:"1"on a Duration means 1ns and anint64accepts"1h"(#66). It is the last of v1.9.0's four.SetDefaultsonce per path, as described above.recovercannot catch.UnmarshalTexttook the tag still getsSetDefaultsafterwards.Setwrites back every struct, slice and map value it visits in a map, changed or not, so calling it while another goroutine reads that map is a data race, and can crash withconcurrent map read and map writeeven when there is nothing to fill.*scalar,*[]Tor*mapfield, the pointer stays allocated, so a secondSeton the same value returnsniland leaves the zero value behind. The*uuid.UUIDrow above is the same case.Upgrading
Run your tests. If
Setnow fails for an array or complex type, that tag was never applied, and the message gives the unmarshaler's reason. If a value that aSetDefaultsused to fill comes back zero, find the embedded type it belongs to and forward the call, as shown above. If you inspect errors from a type with its own unmarshaler, the messages anderrors.Astargets now follow that unmarshaler.Thanks
To @dima-starosud, whose review on #64 suggested
reflect.Value.IsZero— taken up in #83.Full Changelog: creasty/defaults@v1.9.0...v1.10.0
v1.9.0Compare Source
The first release since v1.8.0 (August 2024), and almost entirely other people's
work: seven pull requests that had been waiting between eight months and two years,
adapted onto a rebuilt test suite.
Behavior changes come first, because there are four of them and one is loud. The
exported API is unchanged, so dependent code keeps compiling; what moved is what the
library does with tags that never worked.
[BREAKING] An invalid default value is now an error (#59, by @marxoffice)
A tag that failed to parse used to be discarded silently: the field kept its zero
value and
Setreturnednil. It now returns an error naming the field, the tag andthe cause.
This is the one to read twice. If you use the idiom from the README —
— then a tag that has been quietly broken for years will now stop your program at
startup. That is the point of the change, not a side effect of it.
How to tell whether you are affected: look for a tag that never actually applied.
intdefault:"abc"0, no errorint8default:"999"(overflows the type)0, no errorint32default:"1h"(onlyint64takes durations)0, no errorintdefault:" 1 "(padded number)0, no errorErrors also gained the field name and tag as a prefix, so string matching on errors
needs updating even where an error was already returned: a malformed JSON container
tag reported
unexpected end of JSON inputand now reportsfield V: invalid default "[1,2,3": unexpected end of JSON input. The cause iswrapped with
%w, soerrors.Isanderrors.Asreach through to it —*strconv.NumError,*json.SyntaxErrorand*json.UnmarshalTypeErrorare all still matchable.[BREAKING]
default:""now allocates (#63, by @5p2O5pe25ouT)An empty tag used to be indistinguishable from no tag at all.
Setreads tags withStructTag.Lookupnow, sodefault:""means give me this type's zero value while anabsent tag still means leave this field alone.
*stringdefault:""nil""[]stringdefault:""nilmap[string]intdefault:""nilUntagged fields are unchanged and still come back
nil. The visible consequence isserialization:
nullbecomes"",[]or{}, so snapshot and golden-file testsdownstream will move.
A padded duration tag now parses (#55, by @boskuv)
time.Durationwithdefault:" 10s "produced0and now produces10s.The trim belongs to the duration attempt alone, which is why a padded number is now
an error rather than silently zero (above). Named duration types are covered too —
type Timeout time.Durationparses" 10s "— because the trim sits in theint64branch instead of keying off
time.Duration's exact type.CanUpdate(nil)no longer panics (#64, by @lovewave02)It used to panic with
reflect: call of reflect.Value.Type on zero Value. It returnstruenow. Code that panicked was never working, so nothing can regress here.Minimum Go version
go.modmoves fromgo 1.14togo 1.21. CI tests the declared floor plus everycurrently supported release: 1.21, 1.26 and 1.27.
testifyis a test-only dependency —consumers never build it.
No API change
Set,MustSet,CanUpdateandSetterare unchanged, and nothing was added orremoved. That is deliberate: this release is behavior and tests, not surface.
Documentation
how you keep the distinction —
*boolis how you let an explicitfalsesurvivedefault:"true". Six separate reports had run into this: #60, #49, #37, #31, #30 and#15. (#51, by @fchikwekwe)
encoding.TextUnmarshaleris documented as a second way to set defaults, and it takesprecedence over
defaults.Setter. (#56, by @llorllale)Internals
struct became 15 black-box files exercising only the public API, at 100% statement
coverage with a
make covergate that fails the build below it. Today's behavior ispinned test by test, including the parts that look wrong — those carry a
QUIRKorBUGcomment with a link, so changing one shows up as a deliberate test diff.(#65, #72)
(#65)
shouldInitializeFieldnow reads only thefield with the tag hoisted to its caller. Neither changes behavior. (#58, by @gitsang)
Known issues, unchanged by this release
time.Durationand a plainint64share one parser, sodefault:"1"on a Durationmeans 1ns and an
int64accepts"1h". Not cleanly fixable — reflection cannot tella named duration type from a named
int64(#66).UnmarshalTextorUnmarshalJSONis discarded, so the error you see canname the wrong parser (#79).
SetDefaultsis called twice on a pointer-to-struct field (#67).overflows (#71).
Upgrading
Run your tests. If
Setnow returns an error, that tag was not working before — themessage names the field and the value. If a
nilpointer, slice or map became an emptyone, check whether anything downstream serializes it.
Thanks
To everyone whose pull request sat unreviewed and is in this release anyway:
@lovewave02, @5p2O5pe25ouT, @boskuv, @fchikwekwe, @marxoffice, @gitsang and
@llorllale.
Full Changelog: creasty/defaults@v1.8.0...v1.9.0
isbang/compose-action (isbang/compose-action)
v3.2.0Compare Source
Release Summary
Compose logs are now streamed during post-job cleanup, improving visibility into service shutdown and troubleshooting.
Internal updates include refreshed documentation, developer-experience improvements, and dependency/tooling upgrades across GitHub Actions, devcontainers, and npm development dependencies.
Breaking changes
There are no breaking changes.
What's Changed
Full Changelog: hoverkraft-tech/compose-action@v3.1.0...v3.2.0
Configuration
📅 Schedule: (UTC)
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
👻 Immortal: This PR will be recreated if closed unmerged. Get config help if that's undesired.
This PR was generated by Mend Renovate. View the repository job log.