19 Commits

Author SHA1 Message Date
Billy Keyes 08f3e635d6 Run 'go fix' to modernize code (#69)
This only updates to Go 1.21 baseline, which is what the module still
specifies as the minimum version. I'll need to run this again when
moving to Go 1.25 or 1.26 as minimum.
2026-05-25 09:11:07 -07:00
Billy Keyes 071689e91f Test with Go 1.19, upgrade golangci-lint (#35)
The previous version of the golangci-lint action would install its own
version of Go, which eventually conflicted with the old pinned version
of the linter I was using. Upgrade the action to avoid this, but also
update Go and the linter while I'm here.
2022-09-30 22:41:17 -07:00
Billy Keyes 75930390c9 Split apply logic by fragment type (#32)
Remove the Applier type and replace it with TextApplier and
BinaryApplier, both of which operate on fragments instead of on full
files. Move the logic that previously existed in Applier.ApplyFile to
the top-level Apply function.

Also restructure arguments and methods to make it clear that appliers
are one-time-use objects. The destination is now set when creating an
applier and the Reset() method was replaced by Close().
2022-03-20 12:20:17 -07:00
Billy Keyes 53bcdf7e5d Fix EOF error for some files without final newline (#27)
If a file was an exact multiple of 1024 bytes (the size of an internal
buffer) and was missing a final newline, the LineReaderAt implementation
would drop the last line, leading to an unexpected EOF error on apply.

In addition to fixing the bug, slightly change the behavior of
ReadLineAt to reflect how it is actually used:

  1. Clarify that the return value n includes all lines instead of only
     lines with a final newline. This was already true except in the
     case of the bug fixed by this commit.

  2. Only return io.EOF if fewer lines are read than requested. The
     previous implementation also returned io.EOF if the last line was
     missing a final newline, but this was confusing and didn't really
     serve a purpose.

This is technically a breaking change for external implementations but
an implementation that exactly followed the "spec" was already broken in
certain edge cases.
2021-08-19 17:32:18 -07:00
Billy Keyes 4fa9801742 Check for leftover content after a full delete (#9)
When applying a text fragment that deletes all content in the file, make
sure there is no content left in the source after using all the lines in
the fragment. If there is is extra content, it's a conflict: something
added more lines to the file after generating the patch.
2020-05-03 13:39:08 -07:00
Billy Keyes c2035adeda Add Apply convenience function to match Parse (#5) 2020-04-11 15:21:23 -07:00
Billy Keyes 19ec1a24b4 Improve detection of in-progress application
Applying a file now rejects future text fragment applies under the
assumption that all relevant fragments were part of the file.
2020-01-26 15:02:42 -08:00
Billy Keyes 18058d1e15 Move apply methods to an Applier type
This removes the distinction between "strict" and "fuzzy" application
by allowing future methods on Applier that control settings. It also
avoids state tracking in the text fragment apply signature by moving it
into the Applier type.

While in practice, an Applier will be used once and discarded, the
capability is provided to reset it for multiple uses.
2020-01-25 17:01:43 -08:00
Billy Keyes 0b7af3feaa Implement text application using LineReaderAt
This is functionally equivalent to the previous version (except for one
error case), but uses the new interface. I think the code is simpler
overall because it removes the line tracking.
2020-01-25 16:56:33 -08:00
Billy Keyes 131a046908 Use io.ReaderAt to implement binary applies
This better matches the actual contract of the delta patch, which reads
fixed size chunks of the source files at arbitrary positions.
2020-01-25 16:48:07 -08:00
Billy Keyes 194589f001 Add test for large binary delta application
This ensures a default size is used for large copy instructions.
2020-01-16 21:52:41 -08:00
Billy Keyes 79aa2a9a77 Add positive tests for BinaryFragment#Apply
Covers basic literal and delta application. Input files were created by
using dd and the 'conv=notrunc' option to modify sections of files
created from /dev/urandom. All file start with two null bytes to
convince Git they are binary.
2020-01-16 21:52:40 -08:00
Billy Keyes a1d21957e2 Implement binary fragment application
Currently untested, but based on code I validated against some generated
patches. Tests comming in a future commit.
2020-01-14 22:49:14 -08:00
Billy Keyes eb5f3de78c Improve conflict error detection
Conflict errors are now represented by an exported type that is
compatible with errors.Is instead of using the method defined on
ApplyError. This makes the tests slightly cleaner and should be more
idiomatic for clients.
2020-01-12 22:09:08 -08:00
Billy Keyes 774281f01b Standardize on int64 for line numbers
This matches the type used for positions in text fragments.
2020-01-09 22:11:25 -08:00
Billy Keyes 7bd4e0bb0e Fix EOF handling in TextFragment#ApplyStrict
io.EOF was not properly accounted for when dealing with patches that are
missing trailing newline characters.
2020-01-09 22:05:24 -08:00
Billy Keyes 02f7ff4f79 Add positive tests for TextFragment#ApplyStrict
These cover all of the cases (I think) where application should succeed.
2020-01-08 23:04:44 -08:00
Billy Keyes ae704236bb Return ApplyError when ApplyString fails
This wraps the underlying error with optional position information and
provides a way to test if the error was due to a conflict. At the
moment, details about the conflict are not exposed outside of the
message string.
2020-01-07 22:59:25 -08:00
Billy Keyes 93d46e805c Add initial pass at ApplyStrict functions
Text fragment application is implemented but untested and with several
TODOs, binary fragment application is unimplemented and will panic.
2020-01-05 20:37:59 -08:00